Search code examples
javapdfpdfbox

Fill out field for pdf revision when signing with PDFbox


I am trying to add input to my existing field in a pdf that should be signed at the end. I used the library from swisscom (https://github.com/SwisscomTrustServices/pdfbox-ais-client/blob/8d52c759ade267b0c443fcd6f15bc9635c745d72/src/main/java/com/swisscom/ais/client/impl/PdfDocument.java#L97) with PDFbox (v2.0.24) and added these lines

try {
    PDAcroForm acroForm = pdDocument.getDocumentCatalog().getAcroForm();
    acroForm.setSignaturesExist(true);
    acroForm.setAppendOnly(true);
    acroForm.getCOSObject().setDirect(true);
    acroForm.getCOSObject().setNeedToBeUpdated(true);
    FieldInput[] fields = new FieldInput[1];
    COSObject pdfFields = acroForm.getCOSObject().getCOSObject(COSName.FIELDS);
    if (pdfFields != null) {
        pdfFields.setNeedToBeUpdated(true);
    }
    fields[0] = new FieldInput("1", "foobar");
    for (int i = 0; i < fields.length; i++) {
        PDField field = acroForm.getField(fields[0].id);
        if (field != null) {
            field.setValue(fields[0].value);
            Log.info("set field: " + field.getFullyQualifiedName());
        }
    }
    pdDocument.getDocumentCatalog().getCOSObject().setNeedToBeUpdated(true);
} catch (Exception e) {
    Log.warn(e);
}

I get the log output that the field was set, but in the final document the field is still empty. Using this answer from PDFBox 2.0 create signature field and save incremental with already signed document was no luck for me, I think I messed up the form handling since pdfFields is null.

Update: I added the suggestion from Tilman, now the entry gets set with field.getCOSObject().setNeedToBeUpdated(true); But when looking at the signature I have no information which fields are filled out:

enter image description here

Is it possible with pdfbox to achieve the same output as AdobeSign like where you can store more detailed information in the revision metadata? I am not able to open the file with itext rups because the pdf gets locked with a password at the end....

enter image description here

And what would be the best way to look the fields when everyone is done (so the fields are not shown as editable fields anymore):

  • setting a lock like in Adobe
  • setting some protection after the field was filled

Solution

  • The update flag must be set on the field itself

    field.getCOSObject().setNeedToBeUpdated(true);
    

    and on the appearance of the widget of the field

    field.getWidgets().get(0).getAppearance().getCOSObject().setNeedToBeUpdated(true);
    

    (this assumes that the field is its own widget and that there is only one)

    It might still work if the second code part is missing because Adobe Reader updates the appearance when displaying.