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

PDFBox:如何“展平”PDF表单?

鲜于致远
2023-03-14

如何使用PDFBox“展平”PDF表单(删除表单字段,但保留字段文本)?

这里回答了同样的问题:

一个快速的方法是从acrofrom中删除字段。

为此,您只需要获取文档曲库,然后是acroform,然后从该acroform中删除所有字段。

图形表示与注释链接并保留在文档中。

所以我写了这段代码:

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();
    }
}

共有3个答案

李星辰
2023-03-14

setReadOnly为我工作,如下所示-

   @SuppressWarnings("unchecked")
    List<PDField> fields = acroForm.getFields();
    for (PDField field : fields) {
        if (field.getFullyQualifiedName().equals("formfield1")) {
            field.setReadOnly(true);
        }
    }
潘衡
2023-03-14

这是可以肯定的——我遇到了这个问题,调试了一整晚,但最终找到了解决方法:)

这是假设你有能力以某种方式编辑PDF/对PDF有一些控制。

首先,使用Acrobat Pro编辑表单。将它们隐藏并只读。

然后需要使用两个库:PDFBox和PDFClown。

PDFBox删除了告诉Adobe Reader这是一个表单的东西;PDFClown删除实际字段。必须先执行PDFClown,然后执行PDFBox(按此顺序执行。另一种方法不起作用)。

单字段示例代码:

// PDF Clown code
File file = new File("Some file path"); 
Document document = file.getDocument();
Form form = file.getDocument.getForm();
Fields fields = form.getFields();
Field field = fields.get("some_field_name");

PageStamper stamper = new PageStamper(); 
FieldWidgets widgets = field.getWidgets();
Widget widget = widgets.get(0); // Generally is 0.. experiment to figure out
stamper.setPage(widget.getPage());

// Write text using text form field position as pivot.
PrimitiveComposer composer = stamper.getForeground();
Font font = font.get(document, "some_path"); 
composer.setFont(font, 10); 
double xCoordinate = widget.getBox().getX();
double yCoordinate = widget.getBox().getY(); 
composer.showText("text i want to display", new Point2D.Double(xCoordinate, yCoordinate)); 

// Actually delete the form field!
field.delete();
stamper.flush(); 

// Create new buffer to output to... 
Buffer buffer = new Buffer();
file.save(buffer, SerializationModeEnum.Standard); 
byte[] bytes = buffer.toByteArray(); 

// PDFBox code
InputStream pdfInput = new ByteArrayInputStream(bytes);
PDDocument pdfDocument = PDDocument.load(pdfInput);

// Tell Adobe we don't have forms anymore.
PDDocumentCatalog pdCatalog = pdfDocument.getDocumentCatalog();
PDAcroForm acroForm = pdCatalog.getAcroForm();
COSDictionary acroFormDict = acroForm.getDictionary();
COSArray cosFields = (COSArray) acroFormDict.getDictionaryObject("Fields");
cosFields.clear();

// Phew. Finally.
pdfDocument.save("Some file path");

可能有一些错别字在这里和那里,但这应该足以得到要点:)

邢晗日
2023-03-14

使用PDFBox 2,现在可以通过调用PDAcroForm对象上的flatte方法轻松“展平”PDF表单。参见Javadoc:PDAcroForm。展平()。

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

//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 1.*到2.0的迁移,请查看官方迁移指南。

 类似资料:
  • 我正在使用PDFBox库填充PDF表单,但我无法将它们展平。我已经尝试了以下解决方案: 但似乎什么都没用。请提出同样的解决方案。

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

  • 当我使用这个长字段名时,我没有得到任何错误,但是得到的PDF不包含我放在字段中的值。我想可能字段名有问题,所以我使用了Pdftk工具,它只给出了作为字段名。但是当我仅仅使用它时,我会得到error。救命?

  • 问题内容: 我正在使用Apache PDFBox处理Java应用程序中的PDF文件。我想在每个页面上分割一个PDF文档。 是否有可能做到这一点Apache PDFBox?如果是这样,怎么办? 问题答案: 可以使用来实现。 这是一个示例代码,它将在每个页面上拆分文档: 您可以使用来控制每个拆分的PDF的页数。

  • 我正在迁移一些代码(最初使用iText)来使用PdfBox进行PDF合并。除了创建PDF包或文件夹,一切都很好。我不得不承认,直到现在我才意识到它的存在。 这是我的代码片段(使用iText): 我需要这个,但与PdfBox。 我正在研究两者的 API 和文档,但找不到解决方案。任何帮助都会很棒。 附言。如果我给人留下印象,我需要在iText中解决方案,我需要它在PdfBox中,因为迁移是从iTex