【问题标题】:PDFBox how to import acrofield from another pdfPDFBox如何从另一个pdf导入acrofield
【发布时间】:2018-01-25 11:46:39
【问题描述】:

我在将现有 acrofield 从 pdf 导入另一个 pdf 时遇到问题。 这两个pdf是相似的。我尝试导入并保存文件(下面的代码)。如果我从文件系统打开它,我看不到更改,但如果我用 pdfbox 打开它,我会看到之前插入的 acrofile。 我注意到文件大小增加了,但是当我打开它时,我没有看到可填写的字段。

提前谢谢你

        PDDocument documentSrc = PDDocument.load(new File(SRC));
        PDAcroForm acroFormSrc = documentSrc.getDocumentCatalog().getAcroForm();

        PDDocument documentDest = PDDocument.load(new File(DEST));
        PDAcroForm acroFormDest = new PDAcroForm(documentDest);

        System.out.println("\n\n\n----------> FIELDS OF DOC SOURCE");
        for(PDField field : acroFormSrc.getFields()) {
            System.out.println(field);
        }

        acroFormDest.setCacheFields(true);
        acroFormDest.setFields(acroFormSrc.getFields());
        documentDest.getDocumentCatalog().setAcroForm(acroFormDest);

        documentDest.save(DEST_MERGED);
        documentDest.close();
        documentSrc.close();

        PDDocument documentMERGED = PDDocument.load(new File(DEST_MERGED));
        PDAcroForm acroFormMERGED = documentMERGED.getDocumentCatalog().getAcroForm();

        System.out.println("\n\n\n----------> FIELDS OF DOC MERGED");
        for(PDField field : acroFormMERGED.getFields()) {
            System.out.println(field);
        }

        documentMERGED.close();

【问题讨论】:

  • 您还需要复制注释,并修复页面引用。
  • 您不小心用itext 标记了您的问题。我将删除标签。
  • 感谢您的干预。当您谈论引用时,意图 COSObject?
  • 小部件注解有 getPage / setPage 方法。我认为最简单的方法是浏览您的页面,获取注释,然后使用相应的“新”页面更新每个页面。可能还有更多我想念的东西......例如acroform 的默认资源。
  • 它可以工作,但是当我插入文本时,它看起来不像原始文本。可能是你说的资源。可能?您还有其他建议吗?

标签: java pdf import pdfbox acrofields


【解决方案1】:

我是这样解决的:

    try
    {

        PDDocument documentSrc = PDDocument.load(new File(SRC));
        PDAcroForm acroFormSrc = documentSrc.getDocumentCatalog().getAcroForm();

        PDDocument documentDest = PDDocument.load(new File(DEST));
        PDAcroForm acroFormDest = new PDAcroForm(documentDest);

        acroFormDest.setCacheFields(true);
        acroFormDest.setFields(acroFormSrc.getFields());
        documentDest.getDocumentCatalog().setAcroForm(acroFormDest);

        int pageIndex = 0;
        for(PDPage page: documentSrc.getPages()){
            documentDest.getPage(pageIndex).setAnnotations(page.getAnnotations());
            documentDest.getPage(pageIndex).setResources(page.getResources());
            pageIndex++;
        }

        documentDest.save(DEST_MERGED);
        documentDest.close();
        documentSrc.close();
    }
    catch (IOException e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

感谢您的支持:)

【讨论】:

  • documentDest.getPage(pageIndex).setResources(page.getResources()); 可能会带来麻烦,因为这意味着您正在丢弃目标文档的页面资源。 setAcroForm(acroFormDest); 可以,但前提是目标文件没有任何 Acroform 内容。请注意,我提到了“acroform 的默认资源”,而不是页面资源。如果两个文件来自同一来源,您的解决方案可能仍然有效,例如群发邮件。
  • 我在此document source 上尝试了您的代码输出 pdf acroform 稍微移到页面外。不同之处在于我如何创建 destFile:PDDocument documentDest = new PDDocument(); for (PDPage page : documentSrc.getPages()) { documentDest.addPage(new PDPage(PDRectangle.A4)); } result result pdf @TilmanHausherr 如果您也可以在这里提供您的专业知识,请
  • 最后我发现我用 setCropBox 和 setMediaBox 从源文件页面创建了 destfile
  • 除了复制错误的资源(页面而不是表单默认)之外,上面的代码还有另一个问题:注释按原样复制,保留所有属性。但是注解的一个属性是对其页面的引用。对于大多数注释,这是可选的,但如果使用它,则复制注释的原始页面会被拖到目标文件中,使其大于所需的大小。
【解决方案2】:

我已将您的代码更新为:

    public static void copyAcroForm(
            String acroFormPathfile,
            String inPathfile,
            String outPathfile) 
        throws IOException {

        try (
            PDDocument acroFormDocument = PDDocument.load(new File(acroFormPathfile));
            PDDocument outDocument = PDDocument.load(new File(inPathfile));) 
        {
            PDAcroForm templateAcroForm = acroFormDocument.getDocumentCatalog().getAcroForm();
            PDAcroForm outAcroForm = new PDAcroForm(outDocument);
            
            outAcroForm.setCacheFields(true);
            outAcroForm.setFields(templateAcroForm.getFields());
            outDocument.getDocumentCatalog().setAcroForm(outAcroForm);
            
            int pageIndex = 0;
            for (PDPage page: acroFormDocument.getPages()) {
                outDocument.getPage(pageIndex).setAnnotations(page.getAnnotations());
                outDocument.getPage(pageIndex).setResources(page.getResources());
                pageIndex++;
            }

            outDocument.save(outPathfile);
        }
    }

并在这里提出一个使用它的简单 Swing 应用程序 https://github.com/DavidRobertKeller/pdf-acroform-utils

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-14
    • 1970-01-01
    • 1970-01-01
    • 2013-11-03
    • 2014-12-03
    相关资源
    最近更新 更多