-
Notifications
You must be signed in to change notification settings - Fork 329
implement interactive PDF form fields (AcroForms) #1706
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
- Added support for TextField and Checkbox with appearance stream generation. - Introduced FieldFlag IntFlag enum for form field properties. - Added text_field() and checkbox() methods to FPDF class. - Implemented automatic AcroForm dictionary generation in PDF catalog. - Ensured cross-reader compatibility by providing pre-rendered appearance XObjects.
- Created docs/Forms.md with comprehensive usage examples and API details. - Updated docs/indexdocs: add documentation and changelog for interactive forms - Created docs/Forms.md with comprehensive usage examples and API details. - Updated docs/index
|
hey @Lucas-C i have tried to resolve this issue with this PR. Sorry it took time. here is sample output that i am getting right now |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR implements basic support for interactive PDF form fields (AcroForms), enabling users to create fillable forms with text fields and checkboxes. The implementation includes appearance stream generation to ensure cross-viewer compatibility without requiring dynamic appearance generation by the PDF reader.
Key changes:
- Added
text_field()andcheckbox()methods to the FPDF class for creating interactive form fields - Implemented a new internal module
fpdf/forms.pywithTextFieldandCheckboxclasses that generate their own appearance streams - Extended the
FieldFlagenum infpdf/enums.pyto support form field properties like read-only, required, multiline, and password masking - Updated
fpdf/output.pyto automatically build the AcroForm dictionary and manage default resources for standard fonts
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| test/forms/test_forms.py | Test/demo script for form fields (contains hardcoded paths and doesn't follow test conventions) |
| fpdf/forms.py | New internal module implementing FormField, TextField, and Checkbox classes with appearance stream generation |
| fpdf/fpdf.py | Added public API methods text_field() and checkbox() for creating interactive form fields |
| fpdf/output.py | Extended AcroForm class and modified _finalize_catalog() to build form dictionary with default resources |
| fpdf/enums.py | Added FieldFlag enum with flags for common field properties and type-specific behaviors |
| docs/Forms.md | New documentation page explaining how to use interactive forms with examples |
| docs/index.md | Added link to Forms documentation |
| CHANGELOG.md | Added entry documenting the new AcroForms feature |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "/ZaDb <</Type /Font /Subtype /Type1 /BaseFont /ZapfDingbats>>" | ||
| ">>>>" | ||
| ) | ||
| default_appearance = "(/Helv 0 Tf 0 g)" |
Copilot
AI
Dec 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default_appearance string has a syntax error: it includes an opening parenthesis ( at the start but this should not be there. According to PDF specification, the default appearance string (DA) should be a valid PDF content stream fragment, typically something like /Helv 0 Tf 0 g. The parenthesis makes this invalid PDF syntax. This should be changed to just "/Helv 0 Tf 0 g" without the parenthesis.
| default_appearance = "(/Helv 0 Tf 0 g)" | |
| default_appearance = "/Helv 0 Tf 0 g" |
- Remove unused imports (PDFObject, AnnotationFlag, DEFAULT_ANNOT_FLAGS) in fpdf/forms.py.
- Remove hardcoded font object reference "2 0 R" in TextField appearance streams to rely on global AcroForm resources.
- Document bit-flag sharing between RICH_TEXT and RADIOS_IN_UNISON in FieldFlag per PDF specification.
- Completely refactor test/forms/test_forms.py to follow pytest conventions:
- Use tmprefactor: cleanup AcroForms implementation and improve test suite
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Add documentation for d_a (default appearance) property in TextField and Checkbox classes explaining the PDF content stream fragment format. - Add clarifying comments for default_appearance in output.py explaining that parentheses are required per PDF spec 12.7.3.3. - Document why hasattr checks are used for appearance XObjects in _add_annotations_as_objects (different field types have different attrs). - Update test_forms.py to use assert_pdf_equal for proper regression testing instead of simple file existence checks. - Add 7 reference PDFs for form field tests: - text_field_basic.pdf - text_field_multiline.pdf - text_field_readonly.pdf - checkbox_unchecked.pdf - checkbox_checked.pdf - checkbox_readonly.pdf - form_multiple_fields.pdf
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you planning on also implementing other field types (push buttons, choice...)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes i do!
For the initial PR i wanted to push basic changes to gather feedback and see if i am going in the right direction
| "/Helv <</Type /Font /Subtype /Type1 /BaseFont /Helvetica /Encoding /WinAnsiEncoding>> " | ||
| "/ZaDb <</Type /Font /Subtype /Type1 /BaseFont /ZapfDingbats>>" | ||
| ">>>>" | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure having a hardcoded resource dictionary with /Helv /ZaDb is the best approach - tapping into the main FPDF resources (or at least the ResourceCatalog) will give you much more choices and flexibility, including user added/TTF fonts.
|
Hi @Kaos599 , |
|
@andersonhc thanks for the review! I would also be a little busy this weekend but i will try to implement the feedback and more functionality whenever i get time |
This PR implements basic support for interactive PDF form fields (AcroForms), specifically
TextFieldandCheckbox.Key changes:
text_field()andcheckbox()methods to theFPDFclass.fpdf/forms.pyto handle form field logic and XObject appearance streams.FieldFlaginfpdf/enums.pyfor managing field properties likeReadOnly,Required,Multiline, etc.fpdf/output.pyto automatically construct the globalAcroFormdictionary and manage default resources (/DR) for standard fonts.Fixes #257
Checklist:
A unit test is covering the code added / modified by this PR
In case of a new feature, docstrings have been added, with also some documentation in the
docs/folderA mention of the change is present in
CHANGELOG.mdThis PR is ready to be merged
By submitting this pull request, I confirm that my contribution is made under the terms of the GNU LGPL 3.0 license.