如何将XFA xml数据转换为符合PDF / A-2标准的文件与iText / XFA Worker

时间:2016-11-03 20:54:33

标签: pdf itext xfa xmlworker

在Adobe的PDF / A ISO 32000规范中,它声明XFA数据可以存储在PDF / A-2确认PDF中的特殊位置。以下是该部分的文字。

  

将XFA数据集合并到PDF / A-2符合文件中   为了支持PDF / A-2符合文件,ExtensionLevel 3增加了对XML表单数据(XFA数据集)的支持   通过XFAResources名称树,它是文档目录的名称字典的一部分。

     

(请参阅第23页上的“表3.28名称词典中的条目”。)Acrobat表单(和表单数据)是   在PDF / A-2符合文件中允许,XML表单不允许。这种XML表单被指定为XDP流   从交互式表单词典中引用。 XDP流可以包含XFA数据集。

     

对于将PDF文档转换为PDF / A-2的应用程序,XFAResources名称树支持   将XML表单数据从PDF文档中的XDP流重新定位到 XFAResources 名称树中。

     

XFAResources 名称树由字符串名称和对流的间接引用组成。字符串   在将文档转换为符合PDF / A-2的文件时创建名称。该流包含   XFA的元素,由元素组成。

     

除了XML表单字段的数据值之外,这些元素还支持存储和检索   可能对其他工作流程有用的其他类型信息,包括未绑定的数据   表单字段和一个或多个XML签名。

     

参见参考书目

中的XML体系结构,XML表单体系结构(XFA)规范,2.6版

我们有一个XFA表单,我们将xml传递给现在需要将该文档转换为PDF / A-2。

我们目前正在测试XFA工作人员,看看是否允许我们这样做,我一直无法找到将为我们这样做的XFA工作者样本。

我首先尝试使用XFA Worker进行展平,但这样可以完全删除数据并且无法再提取数据。

如何将XFA xml数据放入Adobe说要将其放入XFA Worker的位置?

更新:感谢Bruno,我的代码不允许我将XFA表格转换为PDF / A-2。这是我使用的代码。

    xfa.fillXfaForm(new ByteArrayInputStream(xmlSchemaStream.toByteArray()));

    stamper.close();
    reader.close();

    try (ByteArrayOutputStream outputStreamDest = new ByteArrayOutputStream()) {
        PdfReader pdfAReader = new PdfReader(output.toByteArray());

        PdfAStamper pdfAStamper = new PdfAStamper(pdfAReader, outputStreamDest, PdfAConformanceLevel.PDF_A_2A);
....

我收到错误com.itextpdf.text.pdf.PdfAConformanceException:只能在PdfAStamper中打开PDF / A文档。

所以我现在假设新的PdfAStamper不是转换器,只是读取XFA PDF的字节数组。

1 个答案:

答案 0 :(得分:0)

请允许我从一些父亲的建议开始。 XFA将在ISO-32000-2(PDF 2.0)中弃用,您将XFA文档转换为PDF / A文档非常棒。但是,为什么选择PDF / A-2? PDF / A-3与PDF / A-2 完全相同,但有一个例外:在PDF / A-3中,您可以嵌入XML文件。您甚至可以指示附加的XML和PDF之间的关系。创建PDF / A-3文件并将原始数据(不是XFA文件)附加为附件会不会更聪明?

假设你忽略了这个父亲的建议,你能做什么?

ISO-19005-2(和-3)的附录D告诉您,您必须在文档目录的名称字典中添加一个条目。不幸的是,iText 5不允许您在创建文件时将自己的条目添加到此名称字典中,因此您必须对文档进行后处理。

假设您有一个位于filePath的文件,那么您可以获得Catalog条目和Names条目的Catalog条目,如下所示:

PdfReader reader = new PdfReader(filePath);
PdfDictionary catalog = reader.getCatalog();
PdfDictionary names = catalog.getAsDict(PdfName.NAMES);

您可以向此names词典添加条目。例如:假设我想添加内容为some bytes的流作为自定义条目,我会使用此代码:

public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
    PdfReader reader = new PdfReader(src);
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
    PdfDictionary catalog = reader.getCatalog();
    PdfDictionary names = catalog.getAsDict(PdfName.NAMES);
    if (names == null) {
        names = new PdfDictionary();
    }
    PdfStream stream = new PdfStream("Some bytes".getBytes());
    PdfIndirectObject objref = stamper.getWriter().addToBody(stream);
    names.put(new PdfName("ITXT_Custom"), objref.getIndirectReference());
    catalog.put(PdfName.NAMES, names);
    stamper.close();
    reader.close();
}

结果如下:

enter image description here

在您的情况下,您不希望输入名为ITXT_Custom的条目。您想要添加名为XFAResources的条目,该条目的值应该是名称树,其中包含字符串名称和对流的间接引用。应该很容易调整我的例子来实现这一目标。

注意:我在Stack Overflow上提供的所有代码都可以在CC-BY-SA中定义的Stack Exchange Network Terms of Service下使用。如果您不喜欢CC-BY-SA,我也会使用与iText相同的许可证提供此代码,更具体地说是AGPL