繁体   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