gpt4 book ai didi

java - 将 XFA 与 PDFBox 相结合

转载 作者:搜寻专家 更新时间:2023-10-31 08:28:27 28 4
gpt4 key购买 nike

我想用 PDFBox java 库填写 PDF 表单。PDF 表单是使用 Adob​​e Live Designer 创建的,因此它使用 XFA 格式。

我试图找到有关使用 PDFBox 填写 XFA PDF 表单的资源,但到目前为止我还没有找到任何运气。我看到 API 中提供了 PDAcroForm.setXFA 方法,但我不知道如何使用它。

您知道是否可以使用 PDFBox 填写 PDF 表单吗?如果是,是否有代码示例或教程可以实现此目的?如果否,实现此目标的最佳替代方案是什么?

最佳答案

这是我在分配给这个问题的时间里所能做到的最好的。我将 pdf 保存(在生命周期中)进行了优化(我不是做 pdf 的人)。这是PDF打开部分,XML复制然后保存:

    PDDocument document = PDDocument.load(fileInputStream);
fileInputStream.close();
document.setAllSecurityToBeRemoved(true);

Map<String, String> values = new HashMap<String, String>();
values.put("variable_name", "value");


setFields(document, values); // see code below

PDAcroForm form = document.getDocumentCatalog().getAcroForm();
Document documentXML = form.getXFA().getDocument();

NodeList dataElements = documentXML.getElementsByTagName("xfa:data");
if (dataElements != null) {
for (int i = 0; i < dataElements.getLength(); i++) {
setXFAFields(dataElements.item(i), values);
}
}

COSStream cosout = new COSStream(new RandomAccessBuffer());

TransformerFactory.newInstance().newTransformer()
.transform(new DOMSource(documentXML), new StreamResult(cosout.createUnfilteredStream()));

form.setXFA(new PDXFA(cosout));

FileOutputStream fios = new FileOutputStream(new File(docOut + ".pdf"));
document.save(fios);
document.close();
try {
fios.flush();
} finally {
fios.close();
}

然后是为字段设置值的方法。我同时设置了 XFA 和 AcroForm:

public void setXFAFields(Node pNode, Map<String, String> values) throws IOException {
if (values.containsKey(pNode.getNodeName())) {
pNode.setTextContent(values.get(pNode.getNodeName()));
} else {
NodeList childNodes = pNode.getChildNodes();
if (childNodes != null) {
for (int i = 0; i < childNodes.getLength(); i++) {
setXFAFields(childNodes.item(i), values);
}
}
}
}

public void setFields(PDDocument pdfDocument, Map<String, String> values) throws IOException {

@SuppressWarnings("unchecked")
List<PDField> fields = pdfDocument.getDocumentCatalog().getAcroForm().getFields();
for (PDField pdField : fields) {
setFields(pdField, values);
}
}

private void setFields(PDField field, Map<String, String> values) throws IOException {
List<COSObjectable> kids = field.getKids();
if (kids != null) {
for (COSObjectable pdfObj : kids) {
if (pdfObj instanceof PDField) {
setFields((PDField) pdfObj, values);
}
}
} else {
// remove the [0] from the name to match values in our map
String partialName = field.getPartialName().replaceAll("\\[\\d\\]", "");
if (!(field instanceof PDSignatureField) && values.containsKey(partialName)) {
field.setValue(values.get(partialName));
}
}
}

这项工作,但不是针对所有“种类”的 PDF 生命周期产品,一些收到关于“扩展功能”不再启用但仍然有效的警告消息。优化版是我发现的唯一一个填充后打开不提示的版本。

我填写了 XFA 和 Acroform,否则它不适用于所有查看器。

关于java - 将 XFA 与 PDFBox 相结合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10536334/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com