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

Avatar

Avatar

techddx

Avatar

techddx

techddx

29-03-2021

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

Replies

Avatar

Avatar

workflowuser

Employee

Avatar

workflowuser

Employee

workflowuser
Employee

29-03-2021

I will get back to you on this

Avatar

Avatar

PulkitJain

Employee

Avatar

PulkitJain

Employee

PulkitJain
Employee

30-03-2021

@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... 

Avatar

Avatar

techddx

Avatar

techddx

techddx

01-04-2021

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?

Avatar

Avatar

workflowuser

Employee

Avatar

workflowuser

Employee

workflowuser
Employee

01-04-2021

you will have to modify the code to stream the pdf back to the browser

Avatar

Avatar

techddx

Avatar

techddx

techddx

01-04-2021

@workflowuser, I see. Is there an example you can provide to do that?

Avatar

Avatar

PulkitJain

Employee

Avatar

PulkitJain

Employee

PulkitJain
Employee

06-04-2021

@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... 

Avatar

Avatar

techddx

Avatar

techddx

techddx

06-04-2021

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();

 

Avatar

Avatar

techddx

Avatar

techddx

techddx

07-04-2021

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();
		}

	}
}

 

 

Avatar

Avatar

techddx

Avatar

techddx

techddx

07-04-2021

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