Show Menu
TOPICS×

Generate a set of PDF Documents from one xml data file

OutputService provides a number of methods to create documents using a form design and data to merge with the form design. The following article explains the use case to generate multiple pdf's from one large xml containing multiple individual records. The following is the screen-shot of xml file containing multiple records.
Data xml has 2 records. Each record is represented by the form1 element. This xml is passed to the OutputService generatePDFOutputBatch method we get list of pdf documents(one per record) The signature of the generatePDFOutputBatch method takes the following parameters
  • templates - Map containing the template, identified by a key
  • data - Map containing xml data documents, identified by key
  • pdfOutputOptions - options to configure pdf generation
  • batchOptions - options to configure batch
This use case is available as live example on this website .

Use case Details

In this use case we are going to provide a simple web interface to upload the template and data(xml) file. Once the upload of the files is complete and POST request is sent to AEM servlet. This servlet extracts the documents and calls the generatePDFOutputBatch method of the OutputService. The generated pdf's are zipped into a zip file and made available to the end user to download from the web browser.

Servlet Code

The following is the code snippet from the servlet. Code extracts the template(xdp) and the data file(xml) from the request. Template file is saved to the file system. Two maps are created- templateMap and dataFileMap which contain the template and the xml(data) files respectively. A call is then made to generateMultipleRecords method of the DocumentServices service.
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);
.....
.....
....

Interface Implementation Code

The following code generates multiple pdf's using the OutputService's generatePDFOutputBatch and returns a zip file containing the pdf files to the calling servlet
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;


}

Deploy on your server

To test this capability on your server, please follow the below instructions:
There are multiple ways to trigger this capability. In this example we have used a web interface to drop the template and data file to demonstrate the capability.