处理 PDF 表单PDF Form是办公自动化中一个比较高级的需求——批量填写合同模板、生成大量报表、提取表单数据。这篇用两个完整案例讲清楚。一、案例一批量填写 PDF 表单假设你有一份 PDF 合同模板里面有表单字段姓名、金额、日期等需要根据 Excel 数据批量填写并生成合同。1. 准备工作pipinstallpdfplumber PyPDF22. 查看 PDF 表单字段importpdfplumberdefinspect_form_fields(pdf_path):查看 PDF 中的表单字段信息withpdfplumber.open(pdf_path)aspdf:fori,pageinenumerate(pdf.pages):# 获取注释包括表单字段annotationspage.annotsifannotations:print(f第{i1}页表单字段:)foranninannotations:print(f -{ann.get(name,未命名)}: f类型{ann.get(subtype,)})3. 批量填写fromPyPDF2importPdfReader,PdfWriterimportpandasaspddeffill_pdf_form(template_path,output_path,data_dict): 填写 PDF 表单 template_path: 模板 PDF output_path: 输出 PDF data_dict: 字段名→值的字典 readerPdfReader(template_path)writerPdfWriter()pagereader.pages[0]# 更新表单字段writer.add_page(page)# 设置表单字段值writer.update_page_form_field_values(writer.pages[0],data_dict)# 保存withopen(output_path,wb)asf:writer.write(f)defbatch_fill_forms(template_path,excel_path,output_dir):根据 Excel 数据批量生成 PDF 合同importos os.makedirs(output_dir,exist_okTrue)dfpd.read_excel(excel_path)for_,rowindf.iterrows():# 构建字段数据data{name:row[客户名称],amount:str(row[金额]),date:str(row[签订日期]),contract_no:row[合同编号],}outputos.path.join(output_dir,f合同_{row[客户名称]}.pdf)fill_pdf_form(template_path,output,data)print(f已生成:{output})二、案例二提取 PDF 表单数据1. 提取已填写的表单defextract_form_data(pdf_path):提取 PDF 表单中的填写数据readerPdfReader(pdf_path)fieldsreader.get_form_text_fields()print(表单字段提取结果:)forfield_name,valueinfields.items():print(f{field_name}:{value})returnfieldsdefbatch_extract(pdf_dir,output_excel):批量提取多个 PDF 表单到 Excelimportos all_data[]forfinos.listdir(pdf_dir):iff.endswith(.pdf):fieldsextract_form_data(os.path.join(pdf_dir,f))fields[来源文件]f all_data.append(fields)ifall_data:dfpd.DataFrame(all_data)df.to_excel(output_excel,indexFalse)print(f共提取{len(all_data)}份表单:{output_excel})2. 提取不可填写的表格数据defextract_table_from_scanned(pdf_path): 从扫描件或不可填写的 PDF 中提取表格 适用于文字型 PDF 中的表格数据 importpdfplumberimportpandasaspdwithpdfplumber.open(pdf_path)aspdf:all_tables[]fori,pageinenumerate(pdf.pages):tablespage.extract_tables()fortableintables:iftableandlen(table)1:# 第一行为表头dfpd.DataFrame(table[1:],columnstable[0])all_tables.append(df)print(f第{i1}页找到表格:{len(table)}行)ifall_tables:resultpd.concat(all_tables,ignore_indexTrue)returnresultreturnNone3. 完整工作流defdaily_pdf_pipeline():每日 PDF 处理流水线print(开始 PDF 处理...)# 1. 提取表单数据form_dataextract_form_data(日报表.pdf)print(f提取到{len(form_data)}个字段)# 2. 提取表格数据table_dfextract_table_from_scanned(明细.pdf)iftable_dfisnotNone:table_df.to_excel(提取数据.xlsx,indexFalse)print(f导出{len(table_df)}行数据)# 3. 生成汇总报告# ...print(处理完成!)三、注意事项1. PDF 表单需要是 AcroForm 格式不是扫描件 2. 拍照/扫描件需要先 OCR 识别 3. 批量处理前先测试一个样本 4. 中文字体在 PDF 中需要嵌入否则显示方框 觉得有用的话点赞 关注【张老师技术栈】吧每周更新 Java/Python/爬虫 实战干货不让你白来。