Java pdfBox: fill out the pdf form, add it to pddocument and repeat

I have a PDF form and am trying to use pdfBox to fill out a form and print a document. I got an excellent job for 1 page of print jobs, but I had to try and change for several pages. This is basically a form with basic information at the top and a list of contents. Well, if the content is larger than the form, I have the opportunity to make it a multi-page document. I get a document with a beautiful page, and then all the other pages are a blank template. What am I doing wrong?

PDDocument finalDoc = new PDDocument(); File template = new File("path/to/template.pdf"); //Declare basic info to be put on every page String name = "John Smith"; String phoneNum = "555-555-5555"; //Get list of contents for each page List<List<Map<String, String>>> pageContents = methodThatReturnsMyInfo(); for (List<Map<String, String>> content : pageContents) { PDDocument doc = new PDDocument().load(template); PDDocumentCatlog docCatalog = doc.getDocumentCatalog(); PDAcroForm acroForm = docCatalog.getAcroForm(); acroForm.getField("name").setValue(name); acroForm.getField("phoneNum").setValue(phoneNum); for (int i=0; i<content.size(); i++) { acroForm.getField("qty"+i).setValue(content.get(i).get("qty")); acroForm.getField("desc"+i).setValue(content.get(i).get("desc")); } List<PDPage> pages = docCatalog.getAllPages(); finalDoc.addPage(pages.get(0)); } //Then prints/saves finalDoc 
+6
source share
1 answer

There are two main problems in your code:

  • The AcroForm PDF element is a document-level object. Copy only the completed template page in finalDoc . Thus, form fields are added to finalDoc only as annotations of their corresponding page, but they are not added to AcroForm from finalDoc .

    This is not obvious in Adobe Reader, but form filling services often identify available fields from the AcroForm level at the document level and do not browse pages for additional form fields.

  • Actual stop show: you add fields with the same name in the PDF. But PDF forms are document-based documents. That is, in PDF there can be only one field entity with a given name. (This field object can have multiple aka widgets, but it requires you to build one field object with several child widgets. In addition, these are expected to display the same value that you do not need ...)

    Therefore, you must rename the fields uniquely before adding them to finalDoc .

Here's a simplified example that works with a template with only one "SampleField" field:

 byte[] template = generateSimpleTemplate(); Files.write(new File(RESULT_FOLDER, "template.pdf").toPath(), template); try ( PDDocument finalDoc = new PDDocument(); ) { List<PDField> fields = new ArrayList<PDField>(); int i = 0; for (String value : new String[]{"eins", "zwei"}) { PDDocument doc = new PDDocument().load(new ByteArrayInputStream(template)); PDDocumentCatalog docCatalog = doc.getDocumentCatalog(); PDAcroForm acroForm = docCatalog.getAcroForm(); PDField field = acroForm.getField("SampleField"); field.setValue(value); field.setPartialName("SampleField" + i++); List<PDPage> pages = docCatalog.getAllPages(); finalDoc.addPage(pages.get(0)); fields.add(field); } PDAcroForm finalForm = new PDAcroForm(finalDoc); finalDoc.getDocumentCatalog().setAcroForm(finalForm); finalForm.setFields(fields); finalDoc.save(new File(RESULT_FOLDER, "form-two-templates.pdf")); } 

As you can see, all fields are renamed before they are added to finalForm :

 field.setPartialName("SampleField" + i++); 

and they are collected in the fields list, which is finally added to finalForm AcroForm:

  fields.add(field); } ... finalForm.setFields(fields); 
+10
source

Source: https://habr.com/ru/post/984503/


All Articles