如何使用iText填充XFA,使Foxit Reader兼容

时间:2015-11-01 16:18:00

标签: forms pdf itext xfa foxit-reader

我使用Web上提供的示例来创建一个能够获取XFA表单xml结构的应用程序,然后将其设置回填充。重要代码如下所示:

public void readData(String src, String dest)
        throws IOException, ParserConfigurationException, SAXException,
        TransformerFactoryConfigurationError, TransformerException {
    FileOutputStream os = new FileOutputStream(dest);
    PdfReader reader = new PdfReader(src);
    XfaForm xfa = new XfaForm(reader);
    Node node = xfa.getDatasetsNode();
    NodeList list = node.getChildNodes();
    for (int i = 0; i < list.getLength(); i++) {
        if ("data".equals(list.item(i).getLocalName())) {
            node = list.item(i);
            break;
        }
    }

    Transformer tf = TransformerFactory.newInstance().newTransformer();
    tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
    tf.setOutputProperty(OutputKeys.INDENT, "yes");
    tf.transform(new DOMSource(node), new StreamResult(os));
    reader.close();
}

public void fillPdfWithXmlData(String src, String xml, String dest)
        throws IOException, DocumentException {

    PdfReader.unethicalreading = true;
    PdfReader reader = new PdfReader(src);
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest), '\0', true);
    AcroFields form = stamper.getAcroFields();
    XfaForm xfa = form.getXfa();
    xfa.fillXfaForm(new FileInputStream(xml));
    stamper.close();
    reader.close();
}

当我使用它填写此表单时:http://www.vzp.cz/uploads/document/tiskopisy-pro-zamestnavatele-hromadne-oznameni-zamestnavatele-verze-2-pdf-56-kb.pdf它工作正常,我可以在Acrobat Reader中看到填充的表单。但是,如果我在Foxit Reader中打开文档,我会看到一个空白表单(在最新版本和5.x版本中测试)。

我尝试使用它并获得这些XfaForm(...).getDomDocument()数据:

由Acrobat Reader填写:http://pastebin.com/kXKyh9EM
填写福昕阅读器:http://pastebin.com/tiZ7EmfE
由iText填写:http://pastebin.com/tTKLMERC
由iText填写后填写福昕阅读器:http://pastebin.com/Uuq0jS4b

填充的字段是。是否可以使用iText,即使使用Foxit Reader也可以使用它(并保留XFA签名?)

1 个答案:

答案 0 :(得分:1)

在您的填写iText 示例中,有一个多余的<xfa:data>元素:

<xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">
  <xfa:data>
    <xfa:data>
      <HOZ>
        <!-- rest of your data here -->
      </HOZ>
    </xfa:data>
  </xfa:data>
  <!-- data description -->
</xfa:datasets>

这是因为fillXfaForm()的{​​{1}}方法期望没有XfaForm的XML数据作为根元素。因此,您的XML数据应如下所示:

<xfa:data>

我看到您提取现有表单数据的<HOZ> <!-- rest of your data here --> </HOZ> 方法,包括readData()元素:

<xfa:data>

剥离外部元素应该可以解决您的问题。例如:

<xfa:data>
  <HOZ>
    <!-- rest of your data here -->
  </HOZ>
</xfa:data>