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

PDFBox:如何将PDAcroForm展平?[重复]

曹旭东
2023-03-14

我正在使用PDFBox库填充PDF表单,但我无法将它们展平。我已经尝试了以下解决方案

 PDAcroForm acroForm = docCatalog.getAcroForm();
 PDField field = acroForm.getField( name );
 field.setReadonly(true); //Solution 1
 field.getDictionary().setInt("Ff",1);//Solution 2

但似乎什么都没用。请提出同样的解决方案。

共有2个答案

夏侯涵映
2023-03-14

正如马鲁安所说,PDAcroForm。可以使用flatte()方法。

尽管字段可能需要一些预处理,最重要的是,必须遍历嵌套字段结构,并检查DV和V的值。

在我们的案例中,有效的是:

private static void flattenPDF(String src, String dst) throws IOException {
    PDDocument doc = PDDocument.load(new File(src));

    PDDocumentCatalog catalog = doc.getDocumentCatalog();
    PDAcroForm acroForm = catalog.getAcroForm();
    PDResources resources = new PDResources();
    acroForm.setDefaultResources(resources);

    List<PDField> fields = new ArrayList<>(acroForm.getFields());
    processFields(fields, resources);
    acroForm.flatten();

    doc.save(dst);
    doc.close();
}

private static void processFields(List<PDField> fields, PDResources resources) {
    fields.stream().forEach(f -> {
        f.setReadOnly(true);
        COSDictionary cosObject = f.getCOSObject();
        String value = cosObject.getString(COSName.DV) == null ?
                       cosObject.getString(COSName.V) : cosObject.getString(COSName.DV);
        System.out.println("Setting " + f.getFullyQualifiedName() + ": " + value);
        try {
            f.setValue(value);
        } catch (IOException e) {
            if (e.getMessage().matches("Could not find font: /.*")) {
                String fontName = e.getMessage().replaceAll("^[^/]*/", "");
                System.out.println("Adding fallback font for: " + fontName);
                resources.put(COSName.getPDFName(fontName), PDType1Font.HELVETICA);
                try {
                    f.setValue(value);
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            } else {
                e.printStackTrace();
            }
        }
        if (f instanceof PDNonTerminalField) {
            processFields(((PDNonTerminalField) f).getChildren(), resources);
        }
    });
}
于意智
2023-03-14

PDFBOX 2.0.0有一个PDAcroForm.flatten()方法

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

  • 我有一个由LiberOffice Draw 4.1.0.4创建的PDF表格。 表单包含文本字段、复选框和单选按钮 在我为字段设置值并使用PDFBox(2.0.21)展平表单后,无法显示字段值 我认为这可能是该字段注释的外观问题,但我不知道如何使其正确 测试PDF

  • 我有一个带有很多acroforms的pdf,我对它进行了一些操作,结果得到了一个新的pdf。所以我有PDF-1(这是原始版本)和PDF-2(只是PDF-1的副本),现在我想合并它们。两个PDF都有一些缩略形式,例如:字段a、字段2。。。 在合并它们之前,我会将PDF-1展平,因为我只想从PDF-2中获取acrofields。当我检查新合并的PDF时,我可以看到PDF-1页面上没有可见字段,PDF-

  • 问题内容: 我做了一个相当大的Docker容器。当我提交容器以创建映像时,该映像大约有7.8 GB。但是,当我将容器(不是映像!)放到压缩包中并重新导入时,映像只有3 GB。当然,历史已经丢失了,但是对我来说这没关系,因为我认为映像已“完成”并准备部署。 如何展平图像/容器而不将其导出到磁盘并再次导入? 并且:这样做是一个明智的主意,还是我错过了一些重要的观点? 问题答案: 从Docker 1.1

  • 我正在使用pdfbox 2.0.21(物理)打印可能有混合页面大小的PDF文件,包括非标准大小,例如8.7“x11.3”,可以在法定大小或更大的纸张上打印,而无需缩放。pdf由许多不同的员工以不同的方式创建(Acrobat DC,从Word保存,打印到pdf,由我们的文档系统生成…)并发送给我的团队打印和邮寄。该卷不允许我们单独检查它们,最终我们将应用程序指向一个文件夹,它将在那里打印所有内容。我