Generare un set di documenti PDF da un file di dati XML
Creato per:
- Esperto
- Sviluppatore
AEM Forms 6.5
OutputService fornisce una serie di metodi per creare documenti utilizzando una struttura di modulo e dati da unire con la struttura del modulo. L’articolo seguente spiega il caso d’uso per generare più PDF da un unico file xml di grandi dimensioni contenente più record singoli.
Di seguito è riportata la schermata di un file xml contenente più record.
L’XML dati ha 2 record. Ogni record è rappresentato dall'elemento form1. Questo xml viene passato al metodo OutputService generatePDFOutputBatch. Viene visualizzato un elenco di documenti PDF (uno per record)
La firma del metodo generatePDFOutputBatch accetta i seguenti parametri
- modelli: mappa contenente il modello, identificato da una chiave
- data: mappa contenente documenti di dati xml, identificati dalla chiave
- pdfOutputOptions: opzioni per configurare la generazione di pdf
- batchOptions: opzioni per configurare il batch
Dettagli del caso d’uso
In questo caso d’uso forniremo una semplice interfaccia web per caricare il modello e il file di dati (xml). Una volta completato il caricamento dei file e inviata la richiesta POST al servlet AEM. Questo servlet estrae i documenti e chiama il metodo generatePDFOutputBatch di OutputService. I PDF generati vengono compressi in un file zip e resi disponibili per il download dall’utente finale dal browser web.
Codice servlet
Di seguito è riportato lo snippet di codice del servlet. Il codice estrae il modello (xdp) e il file di dati (xml) dalla richiesta. Il file modello viene salvato nel file system. Vengono create due mappe: templateMap e dataFileMap che contengono rispettivamente il modello e i file xml(data). Viene quindi effettuata una chiamata al metodo generateMultipleRecords del servizio DocumentServices.
for (final java.util.Map.Entry < String, org.apache.sling.api.request.RequestParameter[] > pairs: params
.entrySet()) {
final String key = pairs.getKey();
final org.apache.sling.api.request.RequestParameter[] pArr = pairs.getValue();
final org.apache.sling.api.request.RequestParameter param = pArr[0];
try {
if (!param.isFormField()) {
if (param.getFileName().endsWith("xdp")) {
final InputStream xdpStream = param.getInputStream();
com.adobe.aemfd.docmanager.Document xdpDocument = new com.adobe.aemfd.docmanager.Document(xdpStream);
xdpDocument.copyToFile(new File(saveLocation + File.separator + "fromui.xdp"));
templateMap.put("key1", "file://///" + saveLocation + File.separator + "fromui.xdp");
System.out.println("#### " + param.getFileName());
}
if (param.getFileName().endsWith("xml")) {
final InputStream xmlStream = param.getInputStream();
com.adobe.aemfd.docmanager.Document xmlDocument = new com.adobe.aemfd.docmanager.Document(xmlStream);
dataFileMap.put("key1", xmlDocument);
}
}
Document zippedDocument = documentServices.generateMultiplePdfs(templateMap, dataFileMap,saveLocation);
.....
.....
....
Codice di implementazione dell’interfaccia
Il codice seguente genera più file PDF utilizzando generatePDFOutputBatch di OutputService e restituisce un file zip contenente i file PDF al servlet chiamante
public Document generateMultiplePdfs(HashMap < String, String > templateMap, HashMap < String, Document > dataFileMap, String saveLocation) {
log.debug("will save generated documents to " + saveLocation);
com.adobe.fd.output.api.PDFOutputOptions pdfOptions = new com.adobe.fd.output.api.PDFOutputOptions();
pdfOptions.setAcrobatVersion(com.adobe.fd.output.api.AcrobatVersion.Acrobat_11);
com.adobe.fd.output.api.BatchOptions batchOptions = new com.adobe.fd.output.api.BatchOptions();
batchOptions.setGenerateManyFiles(true);
com.adobe.fd.output.api.BatchResult batchResult = null;
try {
batchResult = outputService.generatePDFOutputBatch(templateMap, dataFileMap, pdfOptions, batchOptions);
FileOutputStream fos = new FileOutputStream(saveLocation + File.separator + "zippedfile.zip");
ZipOutputStream zipOut = new ZipOutputStream(fos);
FileInputStream fis = null;
for (int i = 0; i < batchResult.getGeneratedDocs().size(); i++) {
com.adobe.aemfd.docmanager.Document dataMergedDoc = batchResult.getGeneratedDocs().get(i);
log.debug("Got document " + i);
dataMergedDoc.copyToFile(new File(saveLocation + File.separator + i + ".pdf"));
log.debug("saved file " + i);
File fileToZip = new File(saveLocation + File.separator + i + ".pdf");
fis = new FileInputStream(fileToZip);
ZipEntry zipEntry = new ZipEntry(fileToZip.getName());
zipOut.putNextEntry(zipEntry);
byte[] bytes = new byte[1024];
int length;
while ((length = fis.read(bytes)) >= 0) {
zipOut.write(bytes, 0, length);
}
fis.close();
}
zipOut.close();
fos.close();
Document zippedDocument = new Document(new File(saveLocation + File.separator + "zippedfile.zip"));
log.debug("Got zipped file from file system");
return zippedDocument;
} catch (OutputServiceException | IOException e) {
e.printStackTrace();
}
return null;
}
Distribuisci sul server
Per testare questa funzionalità sul server, attieniti alle seguenti istruzioni:
- Scarica le risorse di esempio. Questo file zip contiene il modello e il file di dati xml.
- Puntare il browser alla console Web Felix
- Distribuisci il bundle DevelopingWithServiceUser.
- Aggiungi la seguente voce nel servizio User Mapper di Apache Sling Service utilizzando configMgr.
DevelopingWithServiceUser.core:getformsresourceresolver=fd-service
- Distribuisci bundle AEMFormsDocumentServices personalizzato.Pacchetto personalizzato che genera i PDF utilizzando l'API OutputService
- Puntare il browser al gestore di pacchetti
- Importare e installare il pacchetto. Questo pacchetto contiene una pagina HTML che consente di rilasciare il modello e i file di dati.
- Puntare il browser a MultiRecords.html
- Trascina e rilascia il modello e il file di dati xml insieme
- Scarica il file zip creato. Questo file zip contiene i file pdf generati dal servizio di output.