You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python pypdf模块填写PDF表单:填充无效与下拉框处理求助

Solution for pypdf Form Filling & Dropdown Conversion Issues

Fixing Form Field Filling Without Duplicate Pages

The core problem is that PdfWriter wasn't inheriting the original PDF's AcroForm dictionary—this structure is mandatory for recognizing and editing form fields. Instead of using both page-adding methods, use one to add pages, then explicitly copy the AcroForm to the writer:

from pypdf import PdfReader, PdfWriter
from pypdf import generic as pypdf_generic

reader = PdfReader("form.pdf")
writer = PdfWriter()

# Add all pages from the original PDF to the writer
writer.append_pages_from_reader(reader)

# Copy the AcroForm dictionary (critical for form field functionality)
if "/AcroForm" in reader._root_object:
    acroform = reader._root_object["/AcroForm"].get_object()
    writer._root_object[pypdf_generic.NameObject("/AcroForm")] = acroform

# Update your form fields as usual
writer.update_page_form_field_values(
    writer.pages[0],
    {"fieldname": "some filled in text"},
    auto_regenerate=False
)

with open("filled-out.pdf", "wb") as output_stream:
    writer.write(output_stream)

This keeps a single copy of each page while retaining the form structure needed to populate fields.

Converting Dropdown (Choice) Fields to Text Fields

Changing a dropdown's type requires modifying both the page annotation and the corresponding entry in the AcroForm dictionary—your original code only updated the annotation. Here's the complete workflow:

from pypdf import PdfReader, PdfWriter
from pypdf import generic as pypdf_generic

reader = PdfReader("form.pdf")
page = reader.pages[0]

### Step 1: Modify the page annotation for the dropdown
annots = page.get("/Annots")
if annots:
    # Target the 5th annotation (index 5) - adjust the index for your specific field
    field_annot = annots.get_object()[5].get_object()
    
    # Switch field type from Choice (/Ch) to Text (/Tx)
    field_annot[pypdf_generic.NameObject("/FT")] = pypdf_generic.NameObject("/Tx")
    
    # Remove dropdown-specific properties (like options list)
    if "/Opt" in field_annot:
        del field_annot["/Opt"]

### Step 2: Update the matching field in the AcroForm
fields = reader.get_fields()
for field_name, field_obj in fields.items():
    # Replace with your dropdown's actual field name (use reader.get_fields().keys() to list names)
    if field_name == "your_dropdown_field_name":
        field_obj[pypdf_generic.NameObject("/FT")] = pypdf_generic.NameObject("/Tx")
        if "/Opt" in field_obj:
            del field_obj["/Opt"]

### Step 3: Write the modified PDF
writer = PdfWriter()
writer.append_pages_from_reader(reader)

# Copy the updated AcroForm to the writer
if "/AcroForm" in reader._root_object:
    acroform = reader._root_object["/AcroForm"].get_object()
    writer._root_object[pypdf_generic.NameObject("/AcroForm")] = acroform

# Fill the converted text field
writer.update_page_form_field_values(
    writer.pages[0],
    {"your_dropdown_field_name": "custom text here"},
    auto_regenerate=False
)

with open("modified_form.pdf", "wb") as output_stream:
    writer.write(output_stream)

Notes:

  • Repeat the annotation modification step for each dropdown you need to convert (adjust the index in annots.get_object()[5] as needed).
  • Use print(reader.get_fields().keys()) to get the exact names of your form fields if you're unsure.

内容的提问来源于stack exchange,提问作者Annabanana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 16:23:15