【问题标题】:Convert a PDF with forms to a PDF with text only (preserve data) using iText使用 iText 将带有表单的 PDF 转换为仅带有文本的 PDF(保留数据)
【发布时间】:2015-02-24 10:45:55
【问题描述】:
  • 我有多个使用 acroforms 和 pdfbox 填充多条记录 (a.pdf,b.pdf,c[0-9].pdf,d[0-9].pdf,ez.pdf) 的 PDF。
  • 生成的文件(aflat.pdf、bflat.pdf、c[0-9]flat.pdf、d[0-9]flat.pdf、ezflat.pdf)应该有它们的形式(字典和任何 adobe 使用的)已删除,但填充为原始文本的字段保存在 pdf 中(setReadOnly 不是我想要的!)。

PdfStamper 只能删除字段而不保存其内容,但我发现了一些对 PdfContentByte 的引用作为保存内容的一种方式。唉,文档太简短了,无法理解我应该如何做到这一点。

作为最后的手段,我可​​以使用FieldPosition 直接在 PDF 上书写。有没有人遇到过这样的问题?我该如何解决?

更新保存单页 b.pdf 会生成有效的 bfilled.pdf,但会生成空白的 bflattened.pdf。保存整个文档解决了这个问题。

    populateB();
    try (PDDocument doc = new PDDocument(); FileOutputStream stream = new FileOutputStream("bfilled.pdf")) {
        //importing the page will corrupt the fields
        /*wrong approach*/doc.importPage((PDPage)pdfDocuments.get(0).getDocumentCatalog().getAllPages().get(0));
        /*wrong approach*/doc.save(stream);
        //save the whole document instead
        pdfDocuments.get(0).save(stream);//<---right approach

    }
    try (FileOutputStream stream = new FileOutputStream("bflattened.pdf")) {
        PdfStamper stamper = new PdfStamper(new PdfReader("bfilled.pdf"), stream);
        stamper.setFormFlattening(true);
        stamper.close();
    }

【问题讨论】:

  • 您说您的 PDF 文件是使用 acroforms 和 pdfbox 填充的。 PDFBox 是否为这些字段创建了外观流?如果没有,您可能想阅读布鲁诺的this answer
  • 文档说:设置生成外观的选项。不生成外观将加快表单填写,但在 Acrobat 中结果可能出乎意料。除非您的环境得到很好的控制,否则不要使用它。默认为真。

标签: java pdf itext pdfbox


【解决方案1】:

使用PdfStamper.setFormFlattening(true) 去掉字段并将它们写入内容。

【讨论】:

  • 不保存字段内容。我必须缺少一些步骤。你愿意详细说明吗? :)我应该使用 pdfStamper.getOverContent(pageNum) 来获取内容然后做点什么吗?
  • 你能把pdf发一下吗?
  • pdf 是标准的,将它展平应该没有问题。给我看你的扁平化代码。
  • 我试过了,PdfStampersetFormFlattening(true) 按预期将字段内容展平到页面内容中。如果它不适合您,您应该编辑您的问题以包含足够的代码以允许重新处理问题。
【解决方案2】:

使用 acroforms 时始终使用整个页面

    populateB();
try (PDDocument doc = new PDDocument(); FileOutputStream stream = new FileOutputStream("bfilled.pdf")) {
    //importing the page will corrupt the fields
    doc.importPage((PDPage) pdfDocuments.get(0).getDocumentCatalog().getAllPages().get(0));
    doc.save(stream); 
    //save the whole document instead
    pdfDocuments.get(0).save(stream);

}
try (FileOutputStream stream = new FileOutputStream("bflattened.pdf")) {
    PdfStamper stamper = new PdfStamper(new PdfReader("bfilled.pdf"), stream);
    stamper.setFormFlattening(true);
    stamper.close();
}

【讨论】:

  • 所以这本质上是使用 PDFBox 而不是 iText 的问题,不是吗?顺便说一句,此处显示的代码现在将两个不同的文档保存到同一个输出流中。我假设您在该代码中的 cmets 意味着不使用第一个保存,而是使用第二个保存。但是周围有那么多人不看cmets就复制粘贴代码……
  • 基本上是的。我认为 PDPage 有任何需要的信息。我没有注释错误的说明以使它们更具可读性,我会在旁边添加一点注释以确保。
猜你喜欢
  • 1970-01-01
  • 2015-06-01
  • 2013-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-09
相关资源
最近更新 更多