[英]pdfbox: how to clone a page
使用 Apache PDFBox,我正在編輯一個現有文檔,我想從該文檔中取出一頁並簡單地克隆它,復制它包含的任何元素。 作為額外的轉折,我想獲得對這個新克隆頁面中任何表單字段的所有PDField
的引用。 這是我到目前為止嘗試過的代碼:
PDPage newPage = new PDPage(lastPage.getCOSDictionary());
PDFCloneUtility cloner = new PDFCloneUtility(pdfDoc);
pdfDoc.addPage(newPage);
cloner.cloneMerge(lastPage, newPage);
// there doesn't seem to be an API to read the fields from the page, need to filter them out from the document.
List<PDField> newFields = readPdfFields(pdfDoc);
Iterator<PDField> i = newFields.iterator();
while (i.hasNext()) {
if (i.next().getWidget().getPage() != newPage)
i.remove();
}
readPdfFields
是我編寫的一個輔助方法,用於使用 AcroForm 獲取文檔中的所有字段。
但是這段代碼似乎導致我的 JVM 中出現某種崩潰/掛起狀態 - 我無法准確調試正在發生的事情,但我猜這實際上並不是克隆頁面的正確方法。 什么是?
克隆頁面最不占用資源的方式是對應字典的淺拷貝:
PDDocument doc = PDDocument.load( file );
List<PDPage> allPages = doc.getDocumentCatalog().getAllPages();
PDPage page = allPages.get(0);
COSDictionary pageDict = page.getCOSDictionary();
COSDictionary newPageDict = new COSDictionary(pageDict);
newPageDict.removeItem(COSName.ANNOTS);
PDPage newPage = new PDPage(newPageDict);
doc.addPage(newPage);
doc.save( outfile );
我明確刪除了副本的注釋(表單字段等),因為注釋有一個指向其頁面的引用,這在復制的頁面中顯然是錯誤的。
因此,如果您希望注釋以干凈的方式出現,您必須創建注釋數組和所有包含的注釋字典的淺拷貝,並替換其中的頁面引用。
但是,如果頁面引用不正確,大多數 PDF 閱讀器不會介意。 因此,對於骯臟的解決方案,您可以簡單地將注釋留在頁面字典中。 但是誰想變臟...;)
如果您想額外更改新頁面或舊頁面的某些部分,您顯然還必須在操作之前復制相應的 PDF 對象。
其他一些注意事項:
你的原始頁面克隆給我看起來很奇怪。 畢竟,您再次將相同的頁面字典添加到文檔中(我認為頁面樹中的重復條目將被忽略),然后在這些相同的頁面對象之間進行一些合並。
我認為PDFCloneUtility
用於在不同文檔之間進行克隆,而不是在同一文檔內進行克隆,但不需要將字典合並到自身中。
我想獲得對這個新克隆頁面中任何表單字段的所有 PDField 的引用
由於字段具有相同的名稱,因此它們是相同的!
PDF 中的字段是抽象字段,可以在文檔中分布多個外觀。 同名意味着同一個領域。
某個頁面上出現的字段意味着頁面上有一個表示該字段的注釋。 為了使事情變得更復雜,對於只有一種外觀的字段,可以合並字段字典和注釋字典。
因此,根據您的要求,您首先必須決定是要使用字段還是使用字段注釋。
我發現了如何正確克隆頁面。 但是目錄中的鏈接不起作用,如果這對您很重要。
private static void createDocument(File outputFile) {
try {
PDDocument outputDoc = new PDDocument();
outputDoc = new PDDocument();
outputDoc.getDocument().setVersion(originalDocument.getDocument().getVersion());
outputDoc.setDocumentInformation(originalDocument.getDocumentInformation());
outputDoc.getDocumentCatalog().setViewerPreferences(originalDocument.getDocumentCatalog().getViewerPreferences());
PDFCloneUtility cloner = new PDFCloneUtility(outputDoc);
for (PDPage originalPage : originalDocument.getPages()) {
COSDictionary pageDictionary = (COSDictionary) cloner.cloneForNewDocument(originalPage);
PDPage page = new PDPage(pageDictionary);
outputDoc.addPage(page);
}
outputFile.delete();
outputDoc.save(outputFile);
outputDoc.close();
} catch (IOException e) {
e.printStackTrace();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.