PDFBox: How to “flatten” a PDF-form?

后端 未结 11 2201
难免孤独
难免孤独 2020-12-09 06:32

How do I \"flatten\" a PDF-form (remove the form-field but keep the text of the field) with PDFBox?

Same question was answered here:

a quick

11条回答
  •  不知归路
    2020-12-09 07:00

    This works for sure - I've ran into this problem, debugged all-night, but finally figured out how to do this :)

    This is assuming that you have capability to edit the PDF in some way/have some control over the PDF.

    First, edit the forms using Acrobat Pro. Make them hidden and read-only.

    Then you need to use two libraries: PDFBox and PDFClown.

    PDFBox removes the thing that tells Adobe Reader that it's a form; PDFClown removes the actual field. PDFClown must be done first, then PDFBox (in that order. The other way around doesn't work).

    Single field example code:

    // 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");
    

    Probably some typos here and there, but this should be enough to get the gist :)

提交回复
热议问题