PDFBox 2.0.7 无法设置 XFA
PDFBox 2.0.7 Unable to set XFA
我正在尝试在具有动态输入字段的 pdf 表单中设置值,但我不断收到流编写器的错误。
我研究了填写表格的步骤 (http://mail-archives.apache.org/mod_mbox/pdfbox-users/201510.mbox/browser) and read similar questions Combining XFA with PDFBox and PDFBox bloated PDF file size
有没有不同的方法呢?有什么提示可以引导我朝着正确的方向前进吗?
这是我的代码
PDDocument doc = null;
FileOutputStream fos = null;
COSStream cosout = null;
try {
doc = PDDocument.load(new File(pdfTemplatePath));
doc.setAllSecurityToBeRemoved(true);
PDDocumentCatalog cat = doc.getDocumentCatalog();
PDAcroForm aform = cat.getAcroForm();
if (aform.hasXFA()) {
PDXFAResource xfa = aform.getXFA();
org.w3c.dom.Document xmlDoc = xfa.getDocument();
Node xfaData = xmlDoc.getElementsByTagName("xfa:data").item(0);
HashMap<String, String> xmlFields = new HashMap<String, String>();
setDataElements(xfaData, xmlFields); //I set node contents here
//System.out.println(xmlFields);
cosout = new COSStream(new ScratchFile(new File("C://tests//")));
TransformerFactory.newInstance().newTransformer()
.transform(new DOMSource(xmlDoc), new StreamResult(cosout.createOutputStream()));
PDXFAResource resout = new PDXFAResource(cosout);
aform.setXFA(resout);
}
fos = new FileOutputStream(tempFilePath);
doc.save(fos);
doc.close();
} catch (Exception e) {
e.printStackTrace();
success = false;
} catch (Error err) {
err.printStackTrace();
success = false;
} finally {
if (doc != null)
doc.close();
if (fos != null)
fos.close();
if (cosout != null)
cosout.close();
}
这是我得到的错误
*java.lang.IllegalStateException: Cannot read while there is an open stream writer
at org.apache.pdfbox.cos.COSStream.createRawInputStream(COSStream.java:133)
at org.apache.pdfbox.pdfwriter.COSWriter.visitFromStream(COSWriter.java:1203)
at org.apache.pdfbox.cos.COSStream.accept(COSStream.java:388)
at org.apache.pdfbox.pdfwriter.COSWriter.doWriteObject(COSWriter.java:522)
at org.apache.pdfbox.pdfwriter.COSWriter.doWriteObjects(COSWriter.java:460)
at org.apache.pdfbox.pdfwriter.COSWriter.doWriteBody(COSWriter.java:444)
at org.apache.pdfbox.pdfwriter.COSWriter.visitFromDocument(COSWriter.java:1099)
at org.apache.pdfbox.cos.COSDocument.accept(COSDocument.java:419)
at org.apache.pdfbox.pdfwriter.COSWriter.write(COSWriter.java:1370)
at org.apache.pdfbox.pdfwriter.COSWriter.write(COSWriter.java:1257)
at org.apache.pdfbox.pdmodel.PDDocument.save(PDDocument.java:1278)*
我尝试在保存文档之前立即关闭流(我没有看到有人在我阅读的示例中这样做),但随后又出现另一个错误
*java.io.IOException: COSStream has been closed and cannot be read. Perhaps its enclosing PDDocument has been closed?
at org.apache.pdfbox.cos.COSStream.checkClosed(COSStream.java:82)
at org.apache.pdfbox.cos.COSStream.createRawInputStream(COSStream.java:130)
at org.apache.pdfbox.pdfwriter.COSWriter.visitFromStream(COSWriter.java:1203)
at org.apache.pdfbox.cos.COSStream.accept(COSStream.java:388)
at org.apache.pdfbox.pdfwriter.COSWriter.doWriteObject(COSWriter.java:522)
at org.apache.pdfbox.pdfwriter.COSWriter.doWriteObjects(COSWriter.java:460)
at org.apache.pdfbox.pdfwriter.COSWriter.doWriteBody(COSWriter.java:444)
at org.apache.pdfbox.pdfwriter.COSWriter.visitFromDocument(COSWriter.java:1099)
at org.apache.pdfbox.cos.COSDocument.accept(COSDocument.java:419)
at org.apache.pdfbox.pdfwriter.COSWriter.write(COSWriter.java:1370)
at org.apache.pdfbox.pdfwriter.COSWriter.write(COSWriter.java:1257)
at org.apache.pdfbox.pdmodel.PDDocument.save(PDDocument.java:1278)*
非常感谢任何帮助
我用 document.getDocument().createCOSStream()
解决了这个问题,按照 Tilman Hausherr 的建议并在设置 XFA 资源后关闭创建的输出流,代码如下所示
COSStream cs = doc.getDocument().createCOSStream();
OutputStream os = cs.createOutputStream();
Result outputTarget = new StreamResult(os);
Transformer t = TransformerFactory.newInstance().newTransformer();
t.transform(new DOMSource(xmlDoc), outputTarget);
PDXFAResource resout = new PDXFAResource(cs);
aform.setXFA(resout);
os.close();
doc.save( "test.pdf" );
我正在尝试在具有动态输入字段的 pdf 表单中设置值,但我不断收到流编写器的错误。
我研究了填写表格的步骤 (http://mail-archives.apache.org/mod_mbox/pdfbox-users/201510.mbox/browser) and read similar questions Combining XFA with PDFBox and PDFBox bloated PDF file size
有没有不同的方法呢?有什么提示可以引导我朝着正确的方向前进吗?
这是我的代码
PDDocument doc = null;
FileOutputStream fos = null;
COSStream cosout = null;
try {
doc = PDDocument.load(new File(pdfTemplatePath));
doc.setAllSecurityToBeRemoved(true);
PDDocumentCatalog cat = doc.getDocumentCatalog();
PDAcroForm aform = cat.getAcroForm();
if (aform.hasXFA()) {
PDXFAResource xfa = aform.getXFA();
org.w3c.dom.Document xmlDoc = xfa.getDocument();
Node xfaData = xmlDoc.getElementsByTagName("xfa:data").item(0);
HashMap<String, String> xmlFields = new HashMap<String, String>();
setDataElements(xfaData, xmlFields); //I set node contents here
//System.out.println(xmlFields);
cosout = new COSStream(new ScratchFile(new File("C://tests//")));
TransformerFactory.newInstance().newTransformer()
.transform(new DOMSource(xmlDoc), new StreamResult(cosout.createOutputStream()));
PDXFAResource resout = new PDXFAResource(cosout);
aform.setXFA(resout);
}
fos = new FileOutputStream(tempFilePath);
doc.save(fos);
doc.close();
} catch (Exception e) {
e.printStackTrace();
success = false;
} catch (Error err) {
err.printStackTrace();
success = false;
} finally {
if (doc != null)
doc.close();
if (fos != null)
fos.close();
if (cosout != null)
cosout.close();
}
这是我得到的错误
*java.lang.IllegalStateException: Cannot read while there is an open stream writer
at org.apache.pdfbox.cos.COSStream.createRawInputStream(COSStream.java:133)
at org.apache.pdfbox.pdfwriter.COSWriter.visitFromStream(COSWriter.java:1203)
at org.apache.pdfbox.cos.COSStream.accept(COSStream.java:388)
at org.apache.pdfbox.pdfwriter.COSWriter.doWriteObject(COSWriter.java:522)
at org.apache.pdfbox.pdfwriter.COSWriter.doWriteObjects(COSWriter.java:460)
at org.apache.pdfbox.pdfwriter.COSWriter.doWriteBody(COSWriter.java:444)
at org.apache.pdfbox.pdfwriter.COSWriter.visitFromDocument(COSWriter.java:1099)
at org.apache.pdfbox.cos.COSDocument.accept(COSDocument.java:419)
at org.apache.pdfbox.pdfwriter.COSWriter.write(COSWriter.java:1370)
at org.apache.pdfbox.pdfwriter.COSWriter.write(COSWriter.java:1257)
at org.apache.pdfbox.pdmodel.PDDocument.save(PDDocument.java:1278)*
我尝试在保存文档之前立即关闭流(我没有看到有人在我阅读的示例中这样做),但随后又出现另一个错误
*java.io.IOException: COSStream has been closed and cannot be read. Perhaps its enclosing PDDocument has been closed?
at org.apache.pdfbox.cos.COSStream.checkClosed(COSStream.java:82)
at org.apache.pdfbox.cos.COSStream.createRawInputStream(COSStream.java:130)
at org.apache.pdfbox.pdfwriter.COSWriter.visitFromStream(COSWriter.java:1203)
at org.apache.pdfbox.cos.COSStream.accept(COSStream.java:388)
at org.apache.pdfbox.pdfwriter.COSWriter.doWriteObject(COSWriter.java:522)
at org.apache.pdfbox.pdfwriter.COSWriter.doWriteObjects(COSWriter.java:460)
at org.apache.pdfbox.pdfwriter.COSWriter.doWriteBody(COSWriter.java:444)
at org.apache.pdfbox.pdfwriter.COSWriter.visitFromDocument(COSWriter.java:1099)
at org.apache.pdfbox.cos.COSDocument.accept(COSDocument.java:419)
at org.apache.pdfbox.pdfwriter.COSWriter.write(COSWriter.java:1370)
at org.apache.pdfbox.pdfwriter.COSWriter.write(COSWriter.java:1257)
at org.apache.pdfbox.pdmodel.PDDocument.save(PDDocument.java:1278)*
非常感谢任何帮助
我用 document.getDocument().createCOSStream()
解决了这个问题,按照 Tilman Hausherr 的建议并在设置 XFA 资源后关闭创建的输出流,代码如下所示
COSStream cs = doc.getDocument().createCOSStream();
OutputStream os = cs.createOutputStream();
Result outputTarget = new StreamResult(os);
Transformer t = TransformerFactory.newInstance().newTransformer();
t.transform(new DOMSource(xmlDoc), outputTarget);
PDXFAResource resout = new PDXFAResource(cs);
aform.setXFA(resout);
os.close();
doc.save( "test.pdf" );