How to fill and flatten PDF forms
Filling writes values into the AcroForm and leaves the document interactive. Flattening draws the field appearances into the page content stream and deletes the fields. Most completed-form workflows do both, in that order.
fdata, err := fjson.LoadFromJSONFile("fill.json")
if err != nil {
return err
}
fieldAppearance := annotator.FieldAppearance{
OnlyIfMissing: true,
RegenerateTextFields: true,
}
if err := pdfReader.AcroForm.Fill(fdata); err != nil {
return err
}
if err := pdfReader.FlattenFields(true, fieldAppearance); err != nil {
return err
}
pdfWriter, err := pdfReader.ToWriter(&model.ReaderToWriterOpts{SkipAcroForm: true})
if err != nil {
return err
}
return pdfWriter.WriteToFile("output.pdf")The JSON is an array of {"name": ..., "value": ...} objects. fjson also goes
the other way: fjson.LoadFromPDFFile produces the field list from a document,
which is how you get the names right.
The appearance generator is the part that trips people up. A field holds its
value in V, but a viewer draws the widget annotation’s appearance stream, not
V. Fill does not generate appearances, so flattening a programmatically
filled form with nil as the generator draws nothing and you get blank space
where the values should be. OnlyIfMissing generates one for fields that lack
it and leaves the rest alone; RegenerateTextFields overrides that for text
fields, which is what you want after a fill, since any appearance already in the
file was generated for the old value.
FillWithAppearance takes the same generator and does both steps at once, for
when the output has to stay interactive rather than being flattened.
Flattening is destructive and cannot be undone within the same document: no values to read back, no export, no editing. Run it on a copy.
FlattenFields(true, ...) flattens every annotation on every page, not just
form widgets. Pass false to leave the others alone, or use
FlattenFieldsWithOpts with a FilterFunc to select fields by name. And
flattening a signed document invalidates the signature, so flatten first, sign
second.
See fill form fields, flatten form and fill and flatten with appearance.