Understanding PDF form filling
AcroForm, XFA, and just plain pixels.
The three flavours of PDF form, why government and bank forms are different, and the trick to "filling" a form that has no fields.
AcroForm — the standard kind.
The dominant PDF form format. Form fields are declared as PDF objects with names, types (text, checkbox, dropdown, radio, signature), and positions. Filling means setting the value of each named field; the PDF renderer paints the value on top of the page at the field's coordinates. AcroForm fields are interactive in any conforming PDF viewer — Acrobat, Preview, Chrome's built-in viewer all let you click and type.
XFA — the dying kind.
Adobe's pre-2017 alternative, an XML-based form system layered on top of PDF. Used heavily by government agencies (US IRS, Canada Revenue Agency, EU member states) before the standardisation effort moved everyone to AcroForm. Most modern viewers (Chrome, Safari, modern Acrobat Reader) can't fill XFA forms — they just render a static preview. The fix is Adobe Acrobat (paid), an XFA-aware tool, or downloading and opening with the agency's own PDF.
"Forms" that aren't forms.
A printed form scanned to PDF has visible blanks but no interactive fields. From the PDF's perspective it's just pixels. "Filling" requires overlaying text on top of the page at the right coordinates — same drawing operation as a watermark. Tools that claim to "fill any PDF" detect blank spaces by image analysis (or let you click where to place text) and add a text annotation. The output PDF is filled but the underlying form isn't; the next user has to add their own overlays.
A worked example.
A two-page tax form with 32 AcroForm fields. A filler tool enumerates the fields by name — name_first, name_last, ssn, income_w2_box1, etc. — populates each from a data source (form input, CSV row, API call), then saves. The result is a PDF with the same fields, now carrying values. Subsequent opens show the values; the underlying field structure remains.
Field enumeration + value set
getFields() → setText / setCheck / setSelected
One function call per field; library writes the PDF.
form.getFields() then setText('name_first','Q') for each
= Filled PDF saved out
Flattening — the irreversible step.
A filled-but-unflattened PDF carries the field structure plus the values; opening it shows the values and lets the user edit them. A flattened PDF rasters the field values into the page content stream — they become permanent visual marks, no longer editable. Choose unflattened for "form to be reviewed and signed, changes possible" and flattened for "form submitted, can't be modified, archival copy". The flatten step is one library call but it's one-way.
Signatures aren't form fields.
A PDF signature field is special. Filling it requires a cryptographic key and a certificate; the signature is computed over the document hash and embedded as a PKCS#7 blob. Plain form fillers can populate the visual appearance but not the cryptographic content. For real signatures, use DocuSign / Adobe Sign / a PKI-aware library; "type your name into the signature box" is a UI convention, not a signature in the legal-cryptographic sense.