Your achievements

Level 1

0% to

Level 2

Tip /
Sign in

Sign in to Community

to gain points, level up, and earn exciting badges like the new
Bedrock Mission!

Learn more

View all

Sign in to view all badges

Download Document of Record PDF with Form Data with Button In Adaptive Form

techddx
Level 4
Level 4

Hello,

 

I currently have a use case where the user fills in the adaptive form and should be able to download the Document of Record PDF (XDP template) with the form data by clicking a button. The purpose of this use case is so the entered data is not stored in AEM or a database, so the adaptive form only serves as a form filler.

 

From my initial findings, there is a Java API you can use to generate the DoR:

https://helpx.adobe.com/experience-manager/6-3/forms/javadocs/com/adobe/aemds/guide/addon/dor/DoRSer...

 

What would be the best way to implement this API for use in an adaptive form? I would like this to be used for a majority of my forms. Thank you

0 Replies
PulkitJain
Employee
Employee

@techddx Please refer to the snippet provided here[0].

This sample uses the same "com.adobe.aemds.guide.addon.dor.DoROptions" class you were referring previously. This help doc also provides relevant packages/configs, so should suffice your requirement. 

 

 

[0] - https://experienceleague.adobe.com/docs/experience-manager-learn/forms/adaptive-forms/document-of-re... 

techddx
Level 4
Level 4
Hi @PulkitJain, thank you for this document. I tried the sample implementation, but found the resulting PDF is saved in the AEM CRX under "/content/usergenerated/content/aemformsenablement". Is there a way to only provide the download to the PDF, and not save the PDF within AEM CRX?
workflowuser
Employee
Employee
you will have to modify the code to stream the pdf back to the browser
PulkitJain
Employee
Employee

@techddx 

To stream the pdf back to the browser, you may have to add the below piece here[0]. 

byte[] byteInfo = dorResult.ToArray();
dorResult.Write(byteInfo, 0, byteInfo.Length);
dorResult.Position = 0;
HttpContext.Response.AddHeader("content-disposition","inline; filename=form.pdf"); //for browser rendering
return new FileStreamResult(dorResult, "application/pdf");

 [0] - https://experienceleague.adobe.com/docs/experience-manager-learn/forms/adaptive-forms/document-of-re... 

techddx
Level 4
Level 4

Hi @PulkitJain, thank you for your help.

 

I added the following code to the POST.jsp, but the PDF download is not appearing in the browser. I checked the logs and there are no errors either.

 

	Session session;
    com.adobe.aemds.guide.addon.dor.DoRService dorService = sling.getService(com.adobe.aemds.guide.addon.dor.DoRService.class);
	System.out.println("Got ... DOR Service");
	com.mergeandfuse.getserviceuserresolver.GetResolver aemDemoListings = sling.getService(com.mergeandfuse.getserviceuserresolver.GetResolver.class);
	System.out.println("Got aem DemoListings");
	resourceResolver = aemDemoListings.getFormsServiceResolver(); // used to resolve the template path
	session = resourceResolver.adaptTo(Session.class);
	resource = resourceResolver.getResource(templatePath);
	com.adobe.aemds.guide.addon.dor.DoROptions dorOptions =  new com.adobe.aemds.guide.addon.dor.DoROptions();
	dorOptions.setData(dataXml);
	dorOptions.setFormResource(resource);
	java.util.Locale locale = new java.util.Locale("en");
	dorOptions.setLocale(locale);
	com.adobe.aemds.guide.addon.dor.DoRResult dorResult = dorService.render(dorOptions);
	byte[] fileBytes = dorResult.getContent();
	com.adobe.aemfd.docmanager.Document dorDocument = new com.adobe.aemfd.docmanager.Document(fileBytes); // DoR

	// Output Service Testing
	java.util.Random r1 = new java.util.Random();
	String randomName = Long.toString(Math.abs(r1.nextLong()), 36);
	String fileName = formName + " - " + currentDate + " - " + randomName +".pdf";
	File pdfFile = new File(fileName);
	dorDocument.copyToFile(pdfFile);
	response.setContentType("application/octet-stream");
	response.setContentLength((int) pdfFile.length());
	response.setHeader( "Content-Disposition",String.format("inline; filename=\"%s\"", pdfFile.getName()));
	FileInputStream fis = new FileInputStream(pdfFile);
	byte[] buffer = new byte[(int)pdfFile.length()];
	fis.close();
	ServletOutputStream os = response.getOutputStream();
    os.write(buffer);
    os.close();

 

LGND_DOLLA
Level 1
Level 1
Thank you so much for your help. Keep doing what you do my great man
techddx
Level 4
Level 4

I have created a servlet based on the DoR with API implementation with JSP. However when deploying the bundle, the servlet component is in the "satisfied" state. How can I get it to activate? Below is the servlet code:

 

 

public class StreamPDF extends SlingAllMethodsServlet{
	private static final long serialVersionUID = 1L;
	
	@SlingObject
    private ResourceResolver resourceResolver;
	@SlingObject
	private Resource resource;
	
	//OSGi Services
	@Reference
	private com.adobe.aemds.guide.addon.dor.DoRService dorService;
	@Reference
	private GetResolver AEMResourceResolver;
	
	protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException{
	    performTask(request, response);
	  }
	
	protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException{
		performTask(request, response);
	}
	
	private void performTask(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
		try {
			String dataXml = request.getParameter("data");
			// get path to DoR template from xml
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			DocumentBuilder builder;
			builder = factory.newDocumentBuilder();
			org.w3c.dom.Document doc = builder.parse(new InputSource(new StringReader(dataXml)));
			XPath xPath = XPathFactory.newInstance().newXPath();
			String templatePath = xPath.compile("//templatePath").evaluate(doc);
			String formName = xPath.compile("//formName").evaluate(doc);
			
			// get current date for filename
			SimpleDateFormat sdf = new SimpleDateFormat("MM.dd.yy");
			String currentDate = sdf.format(new Date());
			
			// Begin generate DoR
			Session session;
			resourceResolver = AEMResourceResolver.getFormsServiceResolver();
			session = resourceResolver.adaptTo(Session.class);
			resource = resourceResolver.getResource(templatePath);
			// dorService
			com.adobe.aemds.guide.addon.dor.DoROptions dorOptions =  new com.adobe.aemds.guide.addon.dor.DoROptions();
			dorOptions.setData(dataXml);
			dorOptions.setFormResource(resource);
			java.util.Locale locale = new java.util.Locale("en");
			dorOptions.setLocale(locale);
			com.adobe.aemds.guide.addon.dor.DoRResult dorResult = dorService.render(dorOptions);
			byte[] fileBytes = dorResult.getContent();
			com.adobe.aemfd.docmanager.Document dorDocument = new com.adobe.aemfd.docmanager.Document(fileBytes); // DoR
			java.util.Random r1 = new java.util.Random();
			String randomName = Long.toString(Math.abs(r1.nextLong()), 36);
			String fileName = formName + " - " + currentDate + " - " + randomName +".pdf";
			InputStream fileInputStream = dorDocument.getInputStream();
			dorDocument.close();
			response.setContentType("application/pdf");
			response.addHeader("Content-Disposition", "attachment; filename=" + fileName);
			response.setContentLength(fileInputStream.available());
			ServletOutputStream servletOutputStream = response.getOutputStream();
			int bytes;
			while ((bytes = fileInputStream.read()) != -1) {
		        servletOutputStream.write(bytes); 
			}
		      servletOutputStream.flush();
		      servletOutputStream.close();

		} catch (ParserConfigurationException e) {	
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (XPathExpressionException e) {
			e.printStackTrace();
		} catch (DoRGenerationException e) {
			e.printStackTrace();
		}

	}
}

 

 

techddx
Level 4
Level 4
I checked the error log and found this: *ERROR* [FelixDispatchQueue] org.apache.sling.servlets.resolver FrameworkEvent ERROR (org.osgi.framework.ServiceException: Service factory exception: Could not load implementation object class dgs.aem.core.servlets.StreamPDF) org.osgi.framework.ServiceException: Service factory exception: Could not load implementation object class dgs.aem.core.servlets.StreamPDF
techddx
Level 4
Level 4

Issue was resolved, it was due to another bundle deployed with the same groupId and it had to be uninstalled.

techddx
Level 4
Level 4

The servlet is working and the PDF is being generated with a button ajax call. However the generated PDF is corrupt. Here is my code in the button:

 

/**
* Get pdf
* @Return {OPTIONS} drop down options 
 */
function getPdf()
{
    console.log("in view pdf");
    window.guideBridge.getDataXML(
        {
        	success: function(result) {
             var formData = new FormData();
             formData.append("dataXml",result.data);
			console.log("got data"+result.data);
           	var settings ={
            				"async": true,
							"url": "/bin/streampdf",
							"method": "POST",
                			data:{'data':result.data},
   						}
            $.ajax(settings).done(function(response)
            {
                console.log("got response from POST");
				var file = new Blob([response], {
                type : 'application/pdf'
                });
                var fileURL = URL.createObjectURL(file);

                var a         = document.createElement('a');
                a.href        = fileURL; 
                a.target      = '_blank';
                a.download    = 'form.pdf';
                document.body.appendChild(a);
                a.click();
            })

    	},
    	error:function(guideResultObject) {console.log("got error"); },
        guideState : null,
        boundData  : true});

}
GirishBedekar
Level 9
Level 9

Save the pdf to local file system after it is generated 

techddx
Level 4
Level 4
I am testing by saving it to local system first, and the PDF is successfully generated. However, when trying to get the file from button AJAX call, the PDF is corrupt.
gbedekar
Level 4
Level 4
Your Adaptive Form is based on the XDP template? and you are able to merge the data with the xdp template using the DoR API. Can you please confirm?
techddx
Level 4
Level 4
Yes, the adaptive form is based on an XDP template and the data is being merged with the DoR API. I was able to resolve my issues and generate a functional PDF. I will share my solution shortly.