如何使用 iText/XFA Worker 将 XFA xml 数据移动到符合 PDF/A-2 的文件中

How to move XFA xml data into PDF/A-2 conforming File with iText/XFA Worker

在 PDF/A 的 Adob​​e ISO 32000 规范中,它声明 XFA 数据可以存储在 PDF/A-2 确认 PDF 中的一个特殊位置。这是该部分的文本。

Incorporation of XFA Datasets into a PDF/A-2 Conforming File To support PDF/A-2 conforming files, ExtensionLevel 3 adds support for XML form data (XFA datasets) through the XFAResources name tree, which is part of the name dictionary of the document catalog.

(See “TABLE 3.28 Entries in the name dictionary” on page 23.) While Acrobat forms (and form data) are permitted in a PDF/A-2 conforming file, XML forms are not. Such XML forms are specified as XDP streams referenced from interactive form dictionaries. XDP streams can contain XFA datasets.

For applications that convert PDF documents to PDF/A-2, the XFAResources name tree supports relocation of XML form data from XDP streams in a PDF document into the XFAResources name tree.

The XFAResources name tree consists of a string name and an indirect reference to a stream. The string name is created at the time the document is converted to a PDF/A-2 conforming file. The stream contains the element of the XFA, comprised of elements.

In addition to data values for XML form fields, the elements enable the storage and retrieval of other types of information that may be useful for other workflows, including data that is not bound to form fields, and one or more XML signature(s).

See the XML Architecture, XML Forms Architecture (XFA) Specification, version 2.6 in the Bibliography

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

我们目前正在测试 XFA Worker 以查看它是否允许我们执行此操作,我一直无法找到可以为我们执行此操作的 XFA Worker 示例。

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

如何将 XFA xml 数据放入 Adob​​e 所说的用 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 的字节数组。

请允许我从一些慈父般的建议开始。 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 告诉您必须向文档目录的 Names 词典添加一个条目。不幸的是,iText 5 不允许您在创建文件时将自己的条目添加到此名称字典中,因此您将不得不 post-process 文档。

假设你有一个位于filePath的文件,那么你可以像这样得到Catalog条目和Catalog条目的Names条目:

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();
}

结果如下所示:

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

注意:我在Stack Overflow上提供的所有代码都可以在CC-BY-SA as defined in the Stack Exchange Network Terms of Service. If you do not like the CC-BY-SA, I also provide this code under the same license as used for iText, more specifically the AGPL.

下使用