深度克隆 PDPage 的正确方法是什么?

What is the correct way to deep clone PDPage?

我正在使用 PDFBOX v2,我正在尝试克隆 PDDocument 的第一个 PDPage,以将其保留为新 PDPages 的模板。第一页有一些我需要填写的 acroform 字段。

我尝试了一些方法,但任何人都让我想要实现。

1) 复制第一页内容,当我需要新页面时将其添加到文档中。即复制页面,但 acroform 字段与其他页面字段链接,如果我从第一页修改字段值,则显示在其他页面中。

//Save in variable first page content
COSDictionary pageContent = (COSDictionary)doc.getPage(0).getCOSObject();
...

//when i need insert new page
doc.addPage(new PDPage(pageContent));

2) 克隆第一页内容,然后像第一种方法一样添加到文档中。即复制页面但没有复制字段:/

PDFCloneUtility cloner = new PDFCloneUtility(doc);
COSDictionary pageContent = (COSDictionary)cloner.cloneForNewDocument(doc.getPage(0).getCOSObject());

...

//when i need insert new page
doc.addPage(new PDPage(pageContent));

那么,制作 PDPage 的深层副本以获取独立于第一页的 acroform 字段的正确方法是什么?

谢谢!

我得到了解决方案!

1) 从一个空的 pdf 模板开始,只有 1 页。打开模板文档,填写常用数据,在内存中保存为byte[]。


PDDocument templatedoc = PDDocument.load(new File(path));           
PDDocumentCatalog catalog = templatedoc.getDocumentCatalog();           

PDAcroFrom acroForm = catalog.getAcroForm());

... fill acroForm common data of all pages ...

ByteArrayOutputStream basicTemplate = new ByteArrayOutputStream();          
templatedoc.save(basicTemplate);

byte[] filledBasicTemplate = basicTemplate.toByteArray();

2) 为每个需要的页面生成新文档。


List<PDDocument> documents = new ArrayList<PDDocument>();
PDDocument activeDoc;

for(int i = 0; i < 5; i++) {
  activeDoc = PDDocument.load(filledBasicTemplate);
  documents.add(activeDoc);

  ... fill acroform or you need in each page ...

}

3) 将所有新文档的第一页导入最终文档并保存最终文档。


PDDocument finalDoc = new PDDocument();

for(PDDocument currentDoc : documents) {
   ... fill common things like page numbers ...
   finalDoc.importPage(currentDoc.getPage(0));
}

finalDoc.save(new File(path));


... close all documents after save the final document ...

它可能不是最优化的代码,但它确实有效。