Téléchargement d’un document d’enregistrement interactif

Un cas d’utilisation courant consiste à télécharger un document d’enregistrement interactif avec les données de formulaire adaptatif. Le document d’enregistrement téléchargé sera alors terminé à l’aide d’Adobe Acrobat ou d’Adobe Reader.

Le formulaire adaptatif n’est pas basé sur un schéma XSD

Si votre formulaire XDP et adaptatif ne sont basés sur aucun schéma, procédez comme suit pour générer un document d’enregistrement interactif.

Créer un formulaire adaptatif

Créez un formulaire adaptatif et assurez-vous que les noms des champs du formulaire adaptatif sont nommés de la même manière que les noms des champs dans votre modèle xdp.
Notez le nom de l’élément racine de votre modèle xdp.
root-element

Lien client

Le code suivant est déclenché lorsque le bouton Télécharger le PDF est déclenché.

$(document).ready(function() {
    $(".downloadPDF").click(function() {
        window.guideBridge.getDataXML({
            success: function(guideResultObject) {
                var req = new XMLHttpRequest();
                req.open("POST", "/bin/generateinteractivedor", true);
                req.responseType = "blob";
                var postParameters = new FormData();
                postParameters.append("dataXml", guideResultObject.data);
                postParameters.append("xdpName","two.xdp")
                postParameters.append("formBasedOnSchema", "false");
                postParameters.append("xfaRootElement","form1");
                console.log(guideResultObject.data);
                req.send(postParameters);
                req.onreadystatechange = function() {
                    if (req.readyState == 4 && req.status == 200) {
                        download(this.response, "report.pdf", "application/pdf");
                    }


                }
            }
        });

    });
});

Formulaire adaptatif basé sur un schéma XSD

Si votre fichier xdp n’est pas basé sur XSD, procédez comme suit pour créer un schéma XSD(schéma) sur lequel vous baserez votre formulaire adaptatif.

Générer des exemples de données pour le XDP

  • Ouvrez le fichier XDP dans AEM Forms Designer.
  • Cliquez sur Fichier | Propriétés du formulaire | Aperçu
  • Cliquez sur Générer les données d’aperçu
  • Cliquez sur Générer
  • Fournissez un nom de fichier significatif tel que "form-data.xml".

Générer un fichier XSD à partir des données xml

Vous pouvez utiliser n’importe quel outil en ligne gratuit pour générer XSD des données xml générées à l’étape précédente.

Créer un formulaire adaptatif

Créez un formulaire adaptatif basé sur le schéma XSD de l’étape précédente. Associez le formulaire pour utiliser la bibliothèque cliente "irs". Cette bibliothèque cliente dispose du code pour effectuer un appel POST vers la servlet qui renvoie le PDF à l’application qui l’appelle. Le code suivant est déclenché lorsque la variable PDF de téléchargement est cliqué

$(document).ready(function() {
    $(".downloadPDF").click(function() {
        window.guideBridge.getDataXML({
            success: function(guideResultObject) {
                var req = new XMLHttpRequest();
                req.open("POST", "/bin/generateinteractivedor", true);
                req.responseType = "blob";
                var postParameters = new FormData();
                postParameters.append("dataXml", guideResultObject.data);
                postParameters.append("xdpName","f8918-r14e_redo-barcode_3 2.xdp")
                postParameters.append("formBasedOnSchema", "true");
                postParameters.append("dataNodeToExtract","afData/afBoundData/topmostSubform");
                console.log(guideResultObject.data);
                req.send(postParameters);
                req.onreadystatechange = function() {
                    if (req.readyState == 4 && req.status == 200) {
                        download(this.response, "report.pdf", "application/pdf");
                    }


                }
            }
        });

    });
});

Création d’un servlet personnalisé

Créez un servlet personnalisé qui fusionnera les données avec le modèle XDP et renverra le pdf. Le code permettant d’y parvenir est répertorié ci-dessous. Le servlet personnalisé fait partie de la variable Groupe AEMFormsDocumentServices.core-1.0-SNAPSHOT).

public class GenerateIInteractiveDor extends SlingAllMethodsServlet {
	private static final long serialVersionUID = 1 L;
	@Reference
	DocumentServices documentServices;
	@Reference
	FormsService formsService;
	private static final Logger log = LoggerFactory.getLogger(GenerateIInteractiveDor.class);

	protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) {
		doPost(request, response);
	}
	protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) {
		String xdpName = request.getParameter("xdpName");

		boolean formBasedOnXSD = Boolean.parseBoolean(request.getParameter("formBasedOnSchema"));

		XPathFactory xfact = XPathFactory.newInstance();
		XPath xpath = xfact.newXPath();
		String dataXml = request.getParameter("dataXml");
		log.debug("The data xml is " + dataXml);
		org.w3c.dom.Document xmlDataDoc = documentServices.w3cDocumentFromStrng(dataXml);
		Document renderedPDF = null;
		try {
			if (!formBasedOnXSD) {
				String xfaRootElement = request.getParameter("xfaRootElement");
				DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
				DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
				org.w3c.dom.Document newXMLDocument = dBuilder.newDocument();
				Element rootElement = newXMLDocument.createElement(xfaRootElement);
				String unboundData = "afData/afUnboundData/data";
				Node dataNode = (Node) xpath.evaluate(unboundData, xmlDataDoc, XPathConstants.NODE);
				NodeList dataChildNodes = dataNode.getChildNodes();
				for (int i = 0; i<dataChildNodes.getLength(); i++) {
					Node childNode = dataChildNodes.item(i);
					if (childNode.getNodeType() == 1) {
						Element newElement = newXMLDocument.createElement(childNode.getNodeName());
						newElement.setTextContent(childNode.getTextContent());
						rootElement.appendChild(newElement);
						log.debug("the node name is  " + childNode.getNodeName() + " and its value is " + childNode.getTextContent());
					}
				}
				newXMLDocument.appendChild(rootElement);
				Document xmlDataDocument = documentServices.orgw3cDocumentToAEMFDDocument(newXMLDocument);
				String xdpTemplatePath = "crx:///content/dam/formsanddocuments";
				com.adobe.fd.forms.api.PDFFormRenderOptions renderOptions = new com.adobe.fd.forms.api.PDFFormRenderOptions();
				renderOptions.setAcrobatVersion(com.adobe.fd.forms.api.AcrobatVersion.Acrobat_11);
				renderOptions.setContentRoot(xdpTemplatePath);
				renderOptions.setRenderAtClient(com.adobe.fd.forms.api.RenderAtClient.NO);
				renderedPDF = formsService.renderPDFForm(xdpName, xmlDataDocument, renderOptions);

			} else {
				// form is based on xsd
				// get the actual xml data that needs to be merged with the template. This can be made more generic
				String nodeToExtract = request.getParameter("dataNodeToExtract");
				Node dataNode = (Node) xpath.evaluate(nodeToExtract, xmlDataDoc, XPathConstants.NODE);
				StringWriter writer = new StringWriter();
				Transformer transformer = TransformerFactory.newInstance().newTransformer();
				transformer.transform(new DOMSource(dataNode), new StreamResult(writer));
				String xml = writer.toString();
				System.out.println(xml);
				xmlDataDoc = documentServices.w3cDocumentFromStrng(xml);
				Document xmlDataDocument = documentServices.orgw3cDocumentToAEMFDDocument(xmlDataDoc);
				String xdpTemplatePath = "crx:///content/dam/formsanddocuments";
				com.adobe.fd.forms.api.PDFFormRenderOptions renderOptions = new com.adobe.fd.forms.api.PDFFormRenderOptions();
				renderOptions.setAcrobatVersion(com.adobe.fd.forms.api.AcrobatVersion.Acrobat_11);
				renderOptions.setContentRoot(xdpTemplatePath);
				renderOptions.setRenderAtClient(com.adobe.fd.forms.api.RenderAtClient.NO);
				renderedPDF = formsService.renderPDFForm(xdpName, xmlDataDocument, renderOptions);
			}
			InputStream fileInputStream = renderedPDF.getInputStream();
			response.setContentType("application/pdf");
			response.addHeader("Content-Disposition", "attachment; filename=" + xdpName.replace("xdp", "pdf"));
			response.setContentLength((int) fileInputStream.available());
			OutputStream responseOutputStream = response.getOutputStream();
			int bytes;
			while ((bytes = fileInputStream.read()) != -1) {
				responseOutputStream.write(bytes);
			}
			responseOutputStream.flush();
			responseOutputStream.close();

		} catch (XPathExpressionException | TransformerException | FormsServiceException | IOException | ParserConfigurationException e) {
			log.debug(e.getMessage());
		}

	}

}

Dans l’exemple de code, nous extrayons le nom xdp et d’autres paramètres de l’objet de requête. Si le formulaire n’est pas basé sur XSD, le document XML à fusionner avec xdp est créé. Si le formulaire est basé sur XSD, nous extrayons simplement le noeud approprié à partir des données du formulaire adaptatif envoyé pour générer un document XML à fusionner avec le modèle xdp.

Déployer l’exemple sur votre serveur

Pour le tester sur votre serveur local, procédez comme suit :

  1. Télécharger et installer le bundle DevelopingWithServiceUser
  2. Ajoutez l’entrée suivante dans le service Apache Sling User Mapper du service DevelopingWithServiceUser.core:getformsresourceresolver=fd-service
  3. Télécharger et installer le lot Document Services personnalisé. Il dispose du servlet pour fusionner les données avec le modèle XDP et diffuser le pdf en continu.
  4. Importation de la bibliothèque cliente
  5. Importation des actifs d’article (formulaire adaptatif, modèles XDP et schéma XSD)
  6. Aperçu du formulaire adaptatif
  7. Renseignez quelques champs de formulaire.
  8. Cliquez sur Télécharger le PDF pour obtenir le PDF. Vous devrez peut-être attendre quelques secondes pour que le PDF soit téléchargé.
REMARQUE

Vous pouvez essayer le même cas d’utilisation avec formulaire adaptatif non basé sur xsd. Veillez à transmettre les paramètres appropriés au point de terminaison post dans streampdf.js situé dans leur clientlib.

Sur cette page