作者:圈儿丫头1986 | 来源:互联网 | 2024-12-17 16:01
在您的代码实现过程中,存在两个关键问题需要解决:
- 首先,PDF中的AcroForm元素属于文档级别。当您将填好的模板页复制到
finalDoc
时,表单字段仅作为页面上的注释被添加,而非被整合进finalDoc
的AcroForm中。这意味着虽然在Adobe Reader中可能不会立即显现问题,但大多数表单处理服务依赖于文档级别的AcroForm条目来识别可用字段,而不是单独搜索每个页面上的表单字段。 - 更重要的是: 您尝试向PDF中添加具有相同名称的字段。然而,在PDF表单中,字段是文档范围内的实体,意味着一个字段可以有多个视觉表现(即小部件),但这些小部件应当显示相同的数据。如果多个小部件显示不同的数据,则不符合标准。
为了解决这些问题,您需要确保每个字段在添加到finalDoc
之前都有唯一的名称。下面是一个简化示例,展示了如何处理只有一个名为“SampleField”的字段的模板:
byte[] template = generateSimpleTemplate();
Files.write(new File(RESULT_FOLDER, "template.pdf").toPath(), template);
try (PDDocument finalDoc = new PDDocument()) {
List fields = new ArrayList<>();
int index = 0;
for (String value : new String[]{"one", "two"}) {
try (PDDocument doc = PDDocument.load(new ByteArrayInputStream(template))) {
PDDocumentCatalog catalog = doc.getDocumentCatalog();
PDAcroForm form = catalog.getAcroForm();
PDField field = form.getField("SampleField");
field.setValue(value);
field.setPartialName("SampleField" + index++);
List pages = catalog.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, "merged-form.pdf"));
}
上述代码中,所有字段在被添加到finalForm
前都进行了重命名:
field.setPartialName("SampleField" + index++);
并且这些字段被收集在一个列表中,最终添加到finalForm
的AcroForm中:
fields.add(field);
...
finalForm.setFields(fields);