我想,以填补在PDFBox的Java库PDF表单。 PDF格式是与Adobe现场设计员创建的,所以它使用XFA格式。
我试图找到填充XFA PDF表单与PDFBox的资源,但我没有任何运气至今。 我看到一个PDAcroForm.setXFA方法是在API中可用,但我不明白如何使用它。
你知道,如果有可能,以填补PDFBox的PDF表单? 如果是的话,有没有什么地方代码示例或教程来实现这一目标? 如果没有,是什么的最佳替代品,以实现这一目标?
我想,以填补在PDFBox的Java库PDF表单。 PDF格式是与Adobe现场设计员创建的,所以它使用XFA格式。
我试图找到填充XFA PDF表单与PDFBox的资源,但我没有任何运气至今。 我看到一个PDAcroForm.setXFA方法是在API中可用,但我不明白如何使用它。
你知道,如果有可能,以填补PDFBox的PDF表单? 如果是的话,有没有什么地方代码示例或教程来实现这一目标? 如果没有,是什么的最佳替代品,以实现这一目标?
问题具体地标识所述受试者中的PDFBox的文库; 你不需要iText的,在XFA操作可以使用PDFBox的1.8提供的PDXFA对象来完成。
非常感谢Maruan Sahyoun他在PDFBox的+ XFA伟大的工作。
当你卸下PDDocument所有安全验证码才有效。
它还假定在PDXFA的COS对象是COSStream。 下面的简单的例子读取XML流,并将其写回PDF。
PDDocument doc = PDDocument.load("filename");
doc.setAllSecurityToBeRemoved(true);
PDDocumentCatalog docCatalog = doc.getDocumentCatalog();
PDAcroForm form = docCatalog.getAcroForm();
PDXFA xfa = form.getXFA();
COSBase cos = xfa.getCOSObject();
COSStream coss = (COSStream) cos;
InputStream cosin = coss.getUnfilteredStream();
Document document = documentBuilder.parse(cosin);
COSStream cosout = new COSStream(new RandomAccessBuffer());
OutputStream out = cosout.createUnfilteredStream();
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer();
DOMSource source = new DOMSource(xmlDoc);
StreamResult result = new StreamResult(out);
transformer.transform(source, result);
PDXFA xfaout = new PDXFA(cosout);
form.setXFA(xfaout);
这一点,我能在我的问题,分配的时间来管理最好的。 我得到优化的保存(生命周期)的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生命周期生产的“厚道”,有的得到了一个警告消息有关“扩展fonction”不再启用,但仍然可以工作。 该优化的版本是唯一一个我发现当填充后openned谁不提示消息。
我填写XFA和Acroform否则它并不适用于所有浏览器的工作。
我不熟悉PDFBOX,但你可以做到这一点与iText的( http://itextpdf.com/ )一旦你获得了XFA(XML)DOM。
AcroForm是与静态字段PDF。 如果PDF有XFA表单,您可以使用的iText(爪哇)或iTextSharp的(.NET)来填充数据。 只有XFA表单的问题是它们无法与iText的被压扁只有这样,才能拼合我发现使用的BullZip或类似的PDF创建打开与iText的创建PDF XFA,并使之通过的BullZip它会吐出拼合PDF版本。 希望这将要给你一些想法。
下面的代码只是一个粗略的想法XFA填充方式。
XfaForm xfa = pdfFormFields.Xfa;
dynamic bytes = Encoding.UTF8.GetBytes("<?xml version=\"1.0\" encoding=\"UTF-8\"?> <form1> <staticform>" + "\r\n<barcode>" + barcode + "</barcode></staticform> <flowForm><Extra>" + Extra + "</Extra></flowForm> </form1>");
MemoryStream ms = new MemoryStream(bytes);
pdfStamper.AcroFields.Xfa.FillXfaForm(ms);
您现在可以使用您创建的PDF XFA通过的BullZip打印
常量字符串PRINTER_NAME = “的BullZip PDF打印机”;
PdfSettings pdfSettings = new PdfSettings();
pdfSettings.PrinterName = Printer_Name;
pdfSettings.SetValue("Output", flatten_pdf);
pdfSettings.SetValue("ShowPDF", "no");
pdfSettings.SetValue("ShowSettings", "never");
pdfSettings.SetValue("ShowSaveAS", "never");
pdfSettings.SetValue("ShowProgress", "no");
pdfSettings.SetValue("ShowProgressFinished", "no");
pdfSettings.SetValue("ConfirmOverwrite", "no");
pdfSettings.WriteSettings(PdfSettingsFileType.RunOnce);
PdfUtil.PrintFile(xfa_pdffile, Printer_Name);
输出文件将被拉平PDF ..