pdfbox:如何克隆页面

Dan*_*Dan 5 java pdfbox

使用Apache PDFBox,我正在编辑现有文档,我想从该文档中获取一个页面并简单地克隆它,复制它包含的任何元素.作为一个额外的转折,我想获得对PDField这个新克隆页面中任何表单字段的所有s 的引用.这是我到目前为止尝试的代码:

            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();
            }
Run Code Online (Sandbox Code Playgroud)

readPdfFields 我写的一个帮助方法是使用AcroForm获取文档中的所有字段.

但是这段代码似乎导致了我的JVM中的某种崩溃/挂起状态 - 我无法完全调试正在发生的事情,但我猜这实际上并不是克隆页面的正确方法.什么是?

mkl*_*mkl 11

克隆页面的资源最少的方法是相应字典的浅表副本:

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 );
Run Code Online (Sandbox Code Playgroud)

我明确删除了副本的注释(表单字段等),因为注释有一个指向其页面的引用,在复制页面中显然是错误的.

因此,如果您希望注释以干净的方式出现,则必须创建注释数组的浅表副本以及所有包含注释字典的副本,并替换其中的页面引用.

但是,如果页面引用不正确,大多数PDF阅读器都不会介意.因此,对于脏解决方案,您只需将注释保留在页面字典中即可.但谁想要变脏...;)

如果要另外更改新页面或旧页面的某些部分,显然还需要在操作它们之前复制相应的PDF对象.

其他一些评论:

克隆给我的原始页面看起来很奇怪.毕竟你再次将相同的页面字典添加到文档中(我认为页面树中的重复条目被忽略),然后在这些相同的页面对象之间进行一些合并.

我认为它PDFCloneUtility是用于在不同文档之间进行克隆,而不是在同一文档内部进行克隆,但是将字典合并到自身中并不需要工作.

我想获得对这个新克隆页面中任何表单字段的所有PDField的引用

由于字段名称相同,因此它们完全相同!

PDF中的字段是抽象字段,可以在文档上分布许多外观.同名字表示相同的字段.

出现在某个页面上的字段表示在页面上有一个表示该字段的注释.为了使事情更复杂,可以仅为具有一个外观的字段合并字段字典和注释字典.

因此,根据您的要求,您首先必须决定是使用字段还是使用字段注释.