当前位置: 首页 > 知识库问答 >
问题:

PDFBOX:如何“扁平化”PDF格式?

鲁淇
2023-03-14
import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDField;

public class PdfBoxTest {
    public void test() throws Exception {
        PDDocument pdDoc = PDDocument.load(new File("E:\\Form-Test.pdf"));
        PDDocumentCatalog pdCatalog = pdDoc.getDocumentCatalog();
        PDAcroForm acroForm = pdCatalog.getAcroForm();

        if (acroForm == null) {
            System.out.println("No form-field --> stop");
            return;
        }

        @SuppressWarnings("unchecked")
        List<PDField> fields = acroForm.getFields();

        // set the text in the form-field <-- does work
        for (PDField field : fields) {
            if (field.getFullyQualifiedName().equals("formfield1")) {
                field.setValue("Test-String");
            }
        }

        // remove form-field but keep text ???
        // acroForm.getFields().clear();         <-- does not work
        // acroForm.setFields(null);             <-- does not work
        // acroForm.setFields(new ArrayList());  <-- does not work
        // ???

        pdDoc.save("E:\\Form-Test-Result.pdf");
        pdDoc.close();
    }
}

共有1个答案

徐昊焜
2023-03-14

使用PDFBox2,现在可以通过调用PDAcroForm对象上的flatten方法轻松地“扁平化”PDF表单。请参见javadoc:pdacroform.flatten()。

使用此方法的示例调用的简化代码:

//Load the document
PDDocument pDDocument = PDDocument.load(new File("E:\\Form-Test.pdf"));    
PDAcroForm pDAcroForm = pDDocument.getDocumentCatalog().getAcroForm();

//Fill the document
...

//Flatten the document
pDAcroForm.flatten();

//Save the document
pDDocument.save("E:\\Form-Test-Result.pdf");
pDDocument.close();

注意:动态XFA表单不能变平。

 类似资料:
  • 如何使用PDFBox“展平”PDF表单(删除表单字段,但保留字段文本)? 这里回答了同样的问题: 一个快速的方法是从acrofrom中删除字段。 为此,您只需要获取文档曲库,然后是acroform,然后从该acroform中删除所有字段。 图形表示与注释链接并保留在文档中。 所以我写了这段代码:

  • 注意:这个问题被简单地标记为这个问题的重复,但它不是完全的重复,因为我是专门询问std::optionals的。如果你关心一般情况,还是一个很好的问题。 假设我有嵌套的选项,如下所示(愚蠢的玩具示例): 还有这个垃圾邮件功能: 什么是压扁这张可选支票的最佳方法?我做了这样的东西,它不是可变的,但我不太关心这个(如果真的需要,我可以再添加一个级别(用),而且超出这个级别的所有东西都是可怕的代码)。

  • 问题内容: 我具有列表的以下元素,并且列表的长度为100个元素。 如何将每个元素转换为如下形式? 问题答案: 元组打包和解包解决了该问题。

  • 我想在指定年份之间的一年做一个季度的笛卡尔积 年度(2105、2016)应返回季度(2015、Q1)、季度(2015、Q2)...季度(2016年第四季度) 我想出的代码如下所示 上面的代码返回,我需要将其扁平化为。

  • 下面的代码演示了一个非常奇怪的错误。一旦"源"文件被关闭"目标"文件不能被保存和关闭,它将抛出"java.io.IOExc0019: COSStream已被关闭,无法读取。也许它的附加文件已经关闭了?" 如果我们注释掉保存源文件,那么目标文件将正确保存并关闭。这似乎清楚地表明源文件包含一个同样存在于目标文件中的costream对象。当我们关闭源文件时,源文件costream似乎被关闭,然后目标文件