簡體   English   中英

pdfbox:如何克隆頁面

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM