PyPDF2填充法国CERFA PDF表单后更新字段不显示问题求助
PyPDF2填充PDF表单后字段内容不显示问题解决
我需要将数据填充到指定PDF表单中,使用PyPDF2编写了填充代码,但填写完成后PDF页面里的更新字段无法显示。以下是我使用的代码:
原设置函数
def set_need_appearances_writer(writer): # See 12.7.2 and 7.7.2 for more information: http://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/PDF32000_2008.pdf try: catalog = writer._root_object # get the AcroForm tree if "/AcroForm" not in catalog: writer._root_object.update({ NameObject("/AcroForm"): IndirectObject(len(writer._objects), 0, writer) }) need_appearances = NameObject("/NeedAppearances") writer._root_object["/AcroForm"][need_appearances] = BooleanObject(True) # del writer._root_object["/AcroForm"]['NeedAppearances'] return writer except Exception as e: print('set_need_appearances_writer() catch : ', repr(e)) return writer
原填充代码
import PyPDF2 from PyPDF2.generic import BooleanObject, NameObject, IndirectObject # inputFile = "./PDF/DT-DICT-DEMANDE-print.pdf" def change_PdfFile_2(inputFile): """ Change outputFile Content """ print("changeFile2 content function\n\n") # checking the right fields pdf_fields = PyPDF2.PdfReader(inputFile).get_form_text_fields() print(pdf_fields) # creating reader and writer file # first getting a filled pdf file and next changing form values and saving in a writer file pdf_reader = PyPDF2.PdfReader(inputFile) pdf_writer = PyPDF2.PdfWriter() page = pdf_reader.pages[0] # new fields data_dict = { 'Denomination': 'NouveauNom', 'ComplementAdresse': None, 'NoVoie': '123 RUE STE SIMONE', 'LieuditBP': None, 'CodePostal': '33000', 'Commune': 'BORDEAUX', 'Pays': 'FRANCE', } # wishing to resolve the blocking of the pdf formular ... set_need_appearances_writer(pdf_writer) pdf_writer.add_page(page) pdf_writer.update_page_form_field_values(pdf_writer.get_page(0), fields=data_dict) with open('exportRecipice.pdf','wb') as new: pdf_writer.write(new) def set_need_appearances_writer(writer): # See 12.7.2 and 7.7.2 for more information: http://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/PDF32000_2008.pdf try: catalog = writer._root_object # get the AcroForm tree if "/AcroForm" not in catalog: writer._root_object.update({ NameObject("/AcroForm"): IndirectObject(len(writer._objects), 0, writer) }) need_appearances = NameObject("/NeedAppearances") writer._root_object["/AcroForm"][need_appearances] = BooleanObject(True) # del writer._root_object["/AcroForm"]['NeedAppearances'] return writer except Exception as e: print('set_need_appearances_writer() catch : ', repr(e)) return writer
问题原因及解决方法
问题主要出在AcroForm结构处理时机错误和表单字段关联丢失两个点:
- 原代码在添加页面之前调用
set_need_appearances_writer,导致新建的AcroForm无法关联后续添加的页面字段。 - 直接添加页面时,原PDF的表单字段定义未被正确复制到Writer中,导致填充值无法绑定到页面元素。
- 传入
None值会干扰PyPDF2的字段更新逻辑。
修改后的完整代码
import PyPDF2 from PyPDF2.generic import BooleanObject, NameObject, IndirectObject def set_need_appearances_writer(writer): try: catalog = writer._root_object if "/AcroForm" not in catalog: writer._root_object.update({ NameObject("/AcroForm"): IndirectObject(len(writer._objects), 0, writer) }) acro_form = writer._root_object["/AcroForm"] # 设置NeedAppearances让阅读器自动生成字段外观 acro_form[NameObject("/NeedAppearances")] = BooleanObject(True) acro_form[NameObject("/Fields")] = [] return writer except Exception as e: print('set_need_appearances_writer() error: ', repr(e)) return writer def change_PdfFile_2(inputFile): print("changeFile2 content function\n\n") # 查看PDF实际字段名,确保与data_dict中的键匹配 pdf_reader = PyPDF2.PdfReader(inputFile) pdf_fields = pdf_reader.get_form_text_fields() print("PDF表单字段:", pdf_fields) pdf_writer = PyPDF2.PdfWriter() # 复制所有页面到Writer for page in pdf_reader.pages: pdf_writer.add_page(page) # 复制原PDF的AcroForm结构到Writer,保留字段定义 if "/AcroForm" in pdf_reader._root_object: acro_form = pdf_reader._root_object["/AcroForm"] pdf_writer._root_object[NameObject("/AcroForm")] = acro_form # 设置NeedAppearances,确保字段内容可见 set_need_appearances_writer(pdf_writer) # 过滤掉None值的字段,避免处理异常 data_dict = { 'Denomination': 'NouveauNom', 'NoVoie': '123 RUE STE SIMONE', 'CodePostal': '33000', 'Commune': 'BORDEAUX', 'Pays': 'FRANCE', } # 更新所有页面的表单字段 for page_num in range(len(pdf_writer.pages)): pdf_writer.update_page_form_field_values(pdf_writer.get_page(page_num), fields=data_dict) # 保存填充后的PDF with open('exportRecipice.pdf','wb') as new: pdf_writer.write(new) # 调用示例 # change_PdfFile_2("./PDF/DT-DICT-DEMANDE-print.pdf")
关键修改说明
- 复制原AcroForm结构:确保Writer继承原PDF的表单字段定义,避免新建空表单导致字段关联失效。
- 调整调用时机:先添加页面,再设置
NeedAppearances,确保属性作用于已添加的页面。 - 过滤None值:移除值为
None的字段,防止PyPDF2在更新时出现异常。 - 遍历所有页面更新:确保多页PDF的所有表单字段都被正确填充。
内容的提问来源于stack exchange,提问作者jaime sastre
相关产品推荐
相关产品推荐

