使用 iText 复制带有注释的 PDF

Mic*_*lYu 4 java pdf itext pdf-annotations

我们需要将现有的多个 PDF 导入到一个新的 PDF 中。部分代码与iText in Action 第二版6.2.1 节中的示例代码类似:

Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(
    document, new FileOutputStream(RESULT));
document.open();
PdfPTable table = new PdfPTable(2);
PdfReader reader = new PdfReader(MovieTemplates.RESULT);
int n = reader.getNumberOfPages();
PdfImportedPage page;
for (int i = 1; i <= n; i++) {
    page = writer.getImportedPage(reader, i);
    table.addCell(Image.getInstance(page));
}
document.add(table);
document.close();
Run Code Online (Sandbox Code Playgroud)

然而,我们刚刚意识到,在处理带有注释的可填充 PDF 时(在我们的例子中,这些 PDF 已经填充了数据),所有填充的数据都会在新 PDF 中丢失。

我们在书中的同一部分找到了答案:

了解呈现页面内容所需的资源与页面的交互功能之间的区别非常重要。一般来说,这些功能称为注释。它们包括链接、文本注释和表单字段。注释不是内容流的一部分。它们没有列在页面的资源字典中,而是列在注释字典中。使用 时不会复制这些交互功能PdfImportedPage,这意味着使用该类的getImportedPage()方法复制页面时,所有交互性都会丢失PdfWriter

但是保留这些注释的解决方案是什么?

Bru*_*gie 6

作为您提到的这本书的作者,我想指出书中的示例有些过时了。本书将建议您使用PdfCopyFields合并表单,但该类在 iText 的最新版本中已被弃用。

请看一下新的示例:

换句话说:现在可以使用该类复制/合并PdfCopy表单,但导入该类是为了告诉PdfCopy需要合并字段,如以下代码片段所示:

public void createPdf(String filename) throws IOException, DocumentException {
    PdfReader[] readers = {
        new PdfReader(getFile1()),
        new PdfReader(getFile2())
    };
    createPdf(filename, readers);
}

public void createPdf(String filename, PdfReader[] readers)
    throws IOException, DocumentException {
    Document document = new Document();
    PdfCopy copy = new PdfCopy(document, new FileOutputStream(filename));
    copy.setMergeFields();
    document.open();
    for (PdfReader reader : readers) {
        copy.addDocument(reader);
    }
    document.close();
    for (PdfReader reader : readers) {
        reader.close();
    }
}
Run Code Online (Sandbox Code Playgroud)

方法setMergeFields()就是你需要记住的方法。