CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pypdf

A pure-python PDF library capable of splitting, merging, cropping, and transforming PDF files

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

form-fields.mddocs/

Form Fields and Interactive Elements

Comprehensive form field manipulation capabilities for reading, updating, and managing interactive PDF forms. pypdf provides robust support for working with form fields, annotations, and interactive elements in PDF documents.

Capabilities

Form Field Value Updates

Update form field values across pages with support for different field types and automatic appearance generation.

def update_page_form_field_values(
    self,
    page: PageObject | list[PageObject] | None,
    fields: dict[str, str | list[str] | tuple[str, str, float]],
    flags: int = 0,
    auto_regenerate: bool = True,
    flatten: bool = False
) -> None:
    """
    Update form field values for given page(s) from a fields dictionary.
    
    Args:
        page: Page(s) to update, or None for all pages
        fields: Dictionary mapping field names to values
            - str: Simple text value
            - list[str]: Multiple values for choice fields
            - tuple[str, str, float]: (value, export_value, font_size)
        flags: Form field flags for appearance
        auto_regenerate: Whether to regenerate field appearances automatically
        flatten: Whether to flatten fields after updating (make non-editable)
    """

Form Field Appearance Control

Control how form fields are rendered and displayed in PDF viewers.

def set_need_appearances_writer(self, state: bool = True) -> None:
    """
    Set the NeedAppearances flag for form fields.
    
    The NeedAppearances flag indicates whether the PDF viewer should
    automatically generate appearances for form fields or use embedded
    appearances.
    
    Args:
        state: Whether to enable automatic appearance generation
    """

Form Field Structure Management

Manage the hierarchical structure of form fields and handle orphaned field elements.

def reattach_fields(self, page: PageObject | None = None) -> list[DictionaryObject]:
    """
    Parse page annotations to find orphan fields and reattach them
    to the document's form field structure.
    
    Args:
        page: Page to analyze, or None to analyze all pages
        
    Returns:
        List of reattached field dictionary objects
    """

Usage Examples

Basic Form Field Updates

from pypdf import PdfReader, PdfWriter

# Read PDF with form fields
reader = PdfReader("form.pdf")
writer = PdfWriter()

# Copy pages to writer
for page in reader.pages:
    writer.add_page(page)

# Update form field values
field_updates = {
    "FirstName": "John",
    "LastName": "Doe", 
    "Email": "john.doe@example.com",
    "Age": "30",
    "Subscription": "Premium"  # Checkbox or choice field
}

# Update all pages with form fields
writer.update_page_form_field_values(None, field_updates)

# Save updated PDF
with open("filled_form.pdf", "wb") as output:
    writer.write(output)

Advanced Form Field Operations

from pypdf import PdfReader, PdfWriter

reader = PdfReader("complex_form.pdf")
writer = PdfWriter()
writer.append_pages_from_reader(reader)

# Complex field values with formatting
advanced_fields = {
    # Simple text field
    "name": "Alice Smith",
    
    # Choice field with multiple selections
    "interests": ["Technology", "Science", "Art"],
    
    # Field with custom font size and export value
    "salary": ("75000", "75k", 10.0),  # (display_value, export_value, font_size)
    
    # Boolean/checkbox field
    "agree_terms": "Yes"
}

# Update with custom flags and flattening
writer.update_page_form_field_values(
    page=None,  # All pages
    fields=advanced_fields,
    flags=0,
    auto_regenerate=True,  # Generate field appearances
    flatten=True  # Make fields non-editable
)

with open("processed_form.pdf", "wb") as output:
    writer.write(output)

Form Field Structure Repair

from pypdf import PdfReader, PdfWriter

reader = PdfReader("damaged_form.pdf")
writer = PdfWriter()
writer.append_pages_from_reader(reader)

# Repair orphaned form fields
for page in writer.pages:
    orphaned_fields = writer.reattach_fields(page)
    if orphaned_fields:
        print(f"Reattached {len(orphaned_fields)} orphaned fields")

# Ensure appearances are properly generated
writer.set_need_appearances_writer(True)

with open("repaired_form.pdf", "wb") as output:
    writer.write(output)

Batch Form Processing

from pypdf import PdfReader, PdfWriter
import json

def process_form_batch(template_path: str, data_file: str, output_dir: str):
    """Process multiple form submissions from JSON data."""
    
    # Load form data
    with open(data_file, 'r') as f:
        submissions = json.load(f)
    
    template_reader = PdfReader(template_path)
    
    for i, submission in enumerate(submissions):
        # Create new writer for each submission
        writer = PdfWriter()
        writer.append_pages_from_reader(template_reader)
        
        # Update form fields
        writer.update_page_form_field_values(
            page=None,
            fields=submission,
            auto_regenerate=True
        )
        
        # Save individual form
        output_path = f"{output_dir}/form_{i+1:03d}.pdf"
        with open(output_path, "wb") as output:
            writer.write(output)
        
        print(f"Generated form {i+1}: {output_path}")

# Use batch processor
process_form_batch(
    "application_template.pdf",
    "submissions.json", 
    "completed_forms/"
)

Reading Existing Form Field Values

from pypdf import PdfReader

def extract_form_data(pdf_path: str) -> dict:
    """Extract all form field values from a PDF."""
    
    reader = PdfReader(pdf_path)
    form_data = {}
    
    # Check if PDF has form fields
    if reader.is_encrypted:
        print("PDF is encrypted - decrypt first")
        return form_data
    
    try:
        # Access form fields through document structure
        if hasattr(reader, 'root_object') and '/AcroForm' in reader.root_object:
            acroform = reader.root_object['/AcroForm']
            if '/Fields' in acroform:
                fields = acroform['/Fields']
                for field_ref in fields:
                    field = field_ref.get_object()
                    if '/T' in field:  # Field name
                        field_name = field['/T']
                        field_value = field.get('/V', '')  # Field value
                        form_data[field_name] = field_value
    
    except Exception as e:
        print(f"Error extracting form data: {e}")
    
    return form_data

# Extract form data
data = extract_form_data("filled_form.pdf")
print("Form field values:", data)

Install with Tessl CLI

npx tessl i tessl/pypi-pypdf

docs

annotations.md

form-fields.md

index.md

metadata.md

page-operations.md

reading-writing.md

text-extraction.md

utilities.md

tile.json