You wrote a script to fill a PDF, it runs cleanly, but the saved file looks exactly like the blank original. No error, no filled data. This is one of the most common PDF automation gotchas, and the cause is almost always the same.
The cause: the PDF has no form fields
Libraries like pypdf and pdftk fill AcroForm fields, the interactive boxes embedded in a PDF. A flat PDF (scanned, printed to PDF, or exported from a design tool) has no such fields, so there is nothing to fill and the call silently does nothing. Check whether your file has fields before anything else:
from pypdf import PdfReader
reader = PdfReader("form.pdf")
fields = reader.get_fields()
if not fields:
print("No form fields. This is a flat PDF.")
else:
print(f"{len(fields)} fillable fields found")If get_fields() returns None or an empty result, the document is flat. You cannot fill fields that do not exist, so no fill library will help until you put text on the page another way.
The fix: draw text onto the page at coordinates
For a flat PDF, build an overlay with the text positioned where it needs to go, then merge that overlay onto the original page. reportlab draws the overlay and pypdf merges it:
from io import BytesIO
from reportlab.pdfgen import canvas
from pypdf import PdfReader, PdfWriter
# 1. Draw the value where it needs to appear
buffer = BytesIO()
overlay_canvas = canvas.Canvas(buffer)
overlay_canvas.drawString(72, 700, "Jane Smith")
overlay_canvas.save()
buffer.seek(0)
# 2. Merge the overlay onto the flat page
overlay = PdfReader(buffer).pages[0]
base = PdfReader("form.pdf")
writer = PdfWriter()
page = base.pages[0]
page.merge_page(overlay)
writer.add_page(page)
with open("filled.pdf", "wb") as out:
writer.write(out)Coordinates start at the bottom-left of the page and are measured in points (72 points per inch). You will need to find the x and y for each value once per template.
When the layout changes
Hard-coded coordinates break the moment a template shifts, so this approach is best for stable, unchanging forms. For flat PDFs that change often or arrive in many formats, a service that detects field positions for you is less brittle. Anvil's PDF Filling API tags flat PDFs by detecting lines and boxes, then fills values at those coordinates from JSON, which avoids maintaining pixel positions by hand.
Back to All Questions