A lot of forms still arrive as PDFs with a note that says "print, fill, scan, and send back". Most of the time you don't need the printer. Here's how to tell what kind of form you have, fill it with free tools, and decide whether the copy you send should still be editable.
Three things that look like a form
- An AcroForm. The PDF stores a list of named fields (text boxes, checkboxes, radio groups, dropdowns), and each one has a widget on the page that draws its value. This is the kind almost every viewer can fill.
- An XFA form. An older Adobe format where the form is described in XML inside the PDF. Most viewers outside Adobe's own apps can't render it.
- A flat scan or export. Boxes and lines drawn on the page, with no fields at all. It only looks like a form.
pdfinfo (from poppler-utils) tells you which one you have on its Form: line:
$ pdfinfo form.pdf | grep Form
Form: AcroForm
It prints AcroForm, XFA, or none.
The XFA gotcha
If you open a PDF and see only a page that starts with "Please wait... If this message is not eventually replaced by the proper contents of the document, your PDF viewer may not be able to display this type of document", that's an XFA form. Waiting won't help. Browsers and most free viewers show that placeholder page instead of the form. The realistic options are Adobe Acrobat Reader, which still fills XFA, or asking the sender for an AcroForm or Word version.
Filling an AcroForm without extra software
Chrome, Edge, Firefox and macOS Preview all fill AcroForm fields: open the file, click into a field, type, tick, and save. The saved file is still a form. Your answers sit in the fields, and anyone who opens it can change them.
If you get none, there's nothing to fill. You can still type on top using a viewer's text or annotation tool, but that's adding text to the page, not filling fields.
Filling from a script
For a form you fill often, a short pypdf script is handy. First list the field names, because they're whatever the form's author called them, not the labels you see:
import sys
from pypdf import PdfReader
for name, field in (PdfReader(sys.argv[1]).get_fields() or {}).items():
print(name, field.get("/FT"), field.get("/_States_", ""))
On my test form:
full_name /Tx
agree /Btn ['/Off', '/Yes']
/Tx is a text field and /Btn is a checkbox or radio. The states in brackets are the exact values a checkbox accepts. Here it's /Yes, but some forms use /On or /1, so read them instead of guessing.
Then fill:
import sys
from pypdf import PdfReader, PdfWriter
src, out = sys.argv[1], sys.argv[2]
flatten = "--flatten" in sys.argv
reader = PdfReader(src)
writer = PdfWriter()
writer.append(reader)
values = {"full_name": "Test Person", "agree": "/Yes"}
for page in writer.pages:
writer.update_page_form_field_values(page, values, auto_regenerate=False, flatten=flatten)
if flatten:
writer.remove_annotations(subtypes="/Widget")
del writer.root_object["/AcroForm"]
writer.write(out)
I tested this with pypdf 6.21. Without --flatten, the output is still a form with the values in the fields.
Why I flatten the copy I send
Flattening draws each field's appearance into the page content and removes the fields. The answers still show, but they're page content now, not a form someone can edit by accident (or on purpose) and send on.
With --flatten, my test file went from Form: AcroForm to Form: none, the field list came back empty, and pdftotext still printed "Test Person". Rendering the page with pdftoppm showed the name and the ticked box.
qpdf can flatten a file you already filled in a viewer:
qpdf --generate-appearances --flatten-annotations=all filled.pdf flat.pdf
--generate-appearances makes qpdf draw fields whose viewer didn't save an appearance, and --flatten-annotations=all burns them into the page. On my filled test file this gave the same result: Form: none and the values visible on the page. Note that all also flattens comments and other annotations, which is usually what you want for a final copy.
Two cautions. Keep an unflattened copy if you might need to change an answer, because flattening is one-way. And don't flatten a form the receiver asked for as a fillable file, since some offices read the field data straight out of it.
Signature fields
A signature field is a placeholder for a digital signature, not a text box. None of the methods above signs anything. If the form wants a drawn signature, add an image on the page; if it wants a real digital signature, that's a separate step with a certificate.
A browser option
I built ToolOcean, and it has a page that lists a PDF's AcroForm fields, lets you fill them, and downloads the result with flattening off by default. It runs in the browser without uploading the file, skips signature fields, and doesn't fill XFA forms: toolocean.co/pdf-form-fill.
Drafted with AI help, tested and checked by me.
Top comments (0)