3

I have a XFA based pdf form that we need to be populate using java. Can you suggest the best approach. I was able to generate the xfa xml for the pdf using iText.

public void readXfa(String srcPdfFilename, String destXMLFilename) throws IOException, ParserConfigurationException, SAXException, TransformerFactoryConfigurationError, TransformerException {

    PdfReader reader = new PdfReader(srcPdfFilename);
    XfaForm xfa = new XfaForm(reader);
    Document doc = xfa.getDomDocument();

    Transformer tf = TransformerFactory.newInstance().newTransformer();
    tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
    tf.setOutputProperty(OutputKeys.INDENT, "yes");

    FileOutputStream os = new FileOutputStream(destXMLFilename);
    tf.transform(new DOMSource(doc), new StreamResult(os));

    reader.close();
}

I have the Pdf and Xfa XML generated from code above. Can you please suggest me how to proceed further as I seem to be out of ideas. I tried to check the XFA documentation but does not seem right. I do not have an xml and the pdf is very complex as it has many fields and is a dynamic XFA pdf form.

Your help and suggestions will be sincerely appreciated.

Bruno Lowagie
  • 75,994
  • 9
  • 109
  • 165
bhrt
  • 72
  • 1
  • 2
  • 12

1 Answers1

3

Please take a look at the FillXFA example. This example has a form (purchase_order.pdf) that contains a dynamic table:

enter image description here

Now we add data.xml, which is a set of data in the form of an XML file, we get this result: purchase_order_filled.pdf

enter image description here

As you can see, the data present in the XML file was added, as well as a number of empty rows (which correspond with empty data rows in the XML). As we added many rows, we even triggered a new page to be added to the PDF.

This is how it's done:

public void manipulatePdf(String src, String dest)
    throws IOException, DocumentException {
    PdfReader reader = new PdfReader(src);
    PdfStamper stamper = new PdfStamper(reader,
            new FileOutputStream(dest));
    AcroFields form = stamper.getAcroFields();
    XfaForm xfa = form.getXfa();
    xfa.fillXfaForm(new FileInputStream(XML));
    stamper.close();
    reader.close();
}

There's another example here: XfaMovies. The xfa_movies.pdf document is a single page PDF without any buttons. We inject the data of 120 movies: movies.xml. The result is the 23-page PDF, xfa_filled_in.pdf.

NOTE: reading your code, you get an XML that contains the complete XFA stream. You don't need that, you only need the data. That's why I added the links to the XML files: they don't contain any XFA specific tags.

Bruno Lowagie
  • 75,994
  • 9
  • 109
  • 165
  • Thanks for your help. My question is: 1. What use is the XML generated from XFA pdf form. 2. How do we create an XML for populating the PDF considering I have the form and the XML generated using code. Also, please suggest on using how to handle the dynamic elements of the form. – bhrt Jul 02 '14 at 08:33
  • 1
    (1) The full XML you've pulled from the form contains the template, the data description, maybe the datasets, javascript and more. You can use it if you want to change the form (and if you know the XFA syntax, because iText won't help you here; it's a matter of XML manipulation). – Bruno Lowagie Jul 02 '14 at 08:44
  • 1
    (2) The person who created the form used a schema of his choice, based on his preferred data structure, using the tags that correspond best with his needs,... That's the power of XFA: that somebody can create a form using his own XML schema. Use that schema. It's not in the XFA form, apart from some XSD-style of data description (that isn't really XSD). – Bruno Lowagie Jul 02 '14 at 08:46
  • (3) *How to handle the dynamic elements of the form?* I don't understand the question. If you have repeating subforms, they will adapt to the data you feed. Why would they need extra handling? – Bruno Lowagie Jul 02 '14 at 08:47
  • Thanks, so unless I have the format for the input XML for populating the PDF, there is no way to generate the input XML format. From what you say, I concur that I cannot go ahead further without input XML format. Can you confirm this. I was supposing to use the values from the XfaForm API for identifying nodes and generate this. The Pdf has fields that dynamically affect each other. Like some of the drop downs once selected enable/disable other fields or populate other fields with values. So, my question was with identifying on populating the drop down with appropriate values – bhrt Jul 02 '14 at 08:53
  • Population drop downs would be done by changing the template in the XFA stream. Why wouldn't you use Adobe LiveCycle Designer to do that manually? Of course: if the options in the drop down box are already correct, it's just a matter of using the correct value in the data you're feeding to the form. – Bruno Lowagie Jul 02 '14 at 08:57