【问题标题】:Java pdfBox: Fill out pdf form, append it to pddocument, and repeatJava pdfBox:填写 pdf 表单,将其附加到 pddocument,然后重复
【发布时间】:2015-06-04 22:32:46
【问题描述】:

我制作了一个 pdf 表格,我正在尝试使用 pdfBox 填写表格并打印文档。我让它适用于 1 页打印作业,但我不得不尝试修改多页。基本上它是一个顶部有基本信息和内容列表的表格。好吧,如果内容大于表单的空间,我必须将其设为多页文档。我最终得到一个带有漂亮第一页的文档,然后所有剩余的页面都是空白模板。我做错了什么?

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

【问题讨论】:

    标签: java pdf pdfbox pdf-form


    【解决方案1】:

    您的代码中有两个主要问题:

    • PDF 的 AcroForm 元素是文档级对象。您只需将填写好的模板页面复制到finalDoc。因此,表单字段仅作为各自页面的注释添加到finalDoc,而不是添加到finalDoc 的AcroForm。

      这在 Adob​​e Reader 中并不明显,但表单填写服务通常会从文档级别的 AcroForm 条目中识别可用字段,并且不会在页面中搜索其他表单字段。

    • 实际显示停止器:您将具有相同名称的字段添加到 PDF。但 PDF 表单是文档范围的实体。 IE。 在 PDF 中只能有一个具有给定名称的字段实体。(此字段实体可能有多个可视化,即小部件,但这需要您构造一个带有多个子小部件的单个字段对象。此外,这些小部件应显示与您不想要的相同的值...)

      因此,您必须在将字段添加到finalDoc 之前唯一地重命名字段。

    这里是simplified example,它适用于只有一个字段“SampleField”的模板:

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

    正如您所见,所有字段在添加到 finalForm 之前都已重命名:

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

    它们被收集在列表fields 中,最终添加到finalForm AcroForm:

        fields.add(field);
    }
    ...
    finalForm.setFields(fields);
    

    【讨论】:

      猜你喜欢
      • 2011-10-15
      • 2018-02-07
      • 1970-01-01
      • 2023-04-09
      • 1970-01-01
      • 2012-11-07
      • 2012-10-27
      • 2022-08-02
      • 1970-01-01
      相关资源
      最近更新 更多