如何填写PDF表格的例子
实际应用场景中,我们会遇到需要根据会话内容自动填写表格的情况,比如:pdf 表格。假设根据会话内容已经获得相关信息,下面以填写个人信息为例来说明。
个人信息表格.pdf
填写后的效果:
填写代码如下:
from pdfrw import PdfReader, PdfWriter
import tracebackdef fill_personal_info_form(input_path, output_path):# 待填充数据(匹配文档中的字段项)text_data = {"(full_name)": "李四", # 对应文档中“1. 姓名”"(birth_date)": "1985年8月15日", # 对应“3. 出生日期”"(id_card)": "310104198508152345", # 对应“4. 身份证号”"(phone)": "13987654321", # 对应“5. 联系电话”"(email)": "lisi1985@qq.com", # 对应“6. 电子邮箱”"(address)": "上海市徐汇区淮海中路789号2号楼1003室" # 对应“7. 居住地址”}# 性别单选按钮组目标值(对应文档中“2. 性别”的“男”)male_value = "male"try:input_pdf = PdfReader(input_path)print(f"✅ 成功读取文件:{input_path}")print(f"📄 包含 {len(input_pdf.pages)} 页")found_fields = []unnamed_annot_count = 0 # 计数无名字段(性别单选按钮组)gender_male_assigned = False # 标记“男”是否已选中for page_num, page in enumerate(input_pdf.pages, 1):print(f"\n--- 处理第 {page_num} 页 ---")if not page.Annots:print("⚠️ 无表单字段")continuefor annot in page.Annots:# 提取字段名(文本框有明确名称,性别单选按钮可能无名称)raw_field_name = annot.T.strip() if (annot.T and hasattr(annot.T, 'strip')) else None# 处理文本框字段(匹配文档中的姓名、出生日期等)if raw_field_name:if raw_field_name in text_data:annot.V = text_data[raw_field_name] # 文本框用V属性赋值found_fields.append(raw_field_name)print(f"✏️ 已填充 [{raw_field_name}]:{text_data[raw_field_name]}")else:print(f"ℹ️ 跳过字段 [{raw_field_name}]")# 处理无名字段(性别单选按钮组,文档中含“男”“女”)else:unnamed_annot_count += 1print(f"⚠️ 无名字段(序号:{unnamed_annot_count})")# 第1个无名字段设为“男”(选中),用AS属性控制单选按钮状态if not gender_male_assigned and unnamed_annot_count == 1:annot.AS = male_value # 单选按钮用AS属性设置选中状态gender_male_assigned = Trueprint(f"✏️ 已选中第{unnamed_annot_count}个无名字段(男)")# 第2个无名字段设为“女”(未选中)elif unnamed_annot_count == 2:annot.AS = None # 确保“女”未选中print(f"✏️ 第{unnamed_annot_count}个无名字段(女)设为未选中")# 填充结果总结print("\n--- 结果总结 ---")print(f"✅ 成功填充:{found_fields}")print(f"✅ 性别“男”选中状态:{'已选中' if gender_male_assigned else '未选中'}")# 保存文件output_pdf = PdfWriter()output_pdf.addpages(input_pdf.pages)with open(output_path, "wb") as f:output_pdf.write(f)print(f"\n💾 保存至:{output_path}")except Exception as e:print(f"\n❌ 错误:{str(e)}")traceback.print_exc()# 执行填充(输入输出路径可修改)
fill_personal_info_form(input_path="个人信息表.pdf",output_path="填写完成的个人信息表.pdf"
)
个人信息表格.pdf生成代码如下:
from reportlab.pdfgen import canvas
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase import pdfmetrics
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors# 注册Mac系统预装的STHeiti Light字体
# 字体路径为macOS默认路径,无需额外安装
font_path = "/System/Library/Fonts/STHeiti Light.ttc"
font_name = "STHeitiLight" # 自定义字体名称用于引用
pdfmetrics.registerFont(TTFont(font_name, font_path))# 表单字段使用PDF标准字体(避免非标准字体导致的表单错误)
form_font_name = "Helvetica"# 初始化PDF画布
c = canvas.Canvas("个人信息表.pdf", pagesize=A4)
width, height = A4 # A4尺寸:宽595,高842# 绘制标题(使用STHeiti Light字体,中文正常显示)
c.setFont(font_name, 16)
c.drawCentredString(width/2, height-50, "个人信息登记表")
c.setFont(font_name, 12) # 恢复标签字体大小y_position = height - 100 # 起始Y坐标
spacing = 40 # 行间距# 1. 姓名
c.drawString(100, y_position, "1. 姓名:") # 中文标签用STHeiti Light
c.acroForm.textfield(name="full_name",x=200, y=y_position-20,width=200, height=20,borderColor=colors.black,fillColor=colors.white,fontName=form_font_name # 表单字段用标准字体
)
y_position -= spacing# 2. 性别(单选按钮组)
c.drawString(100, y_position, "2. 性别:")
c.acroForm.radio(name="gender",value="male",x=200, y=y_position-10,size=10
)
c.drawString(220, y_position, "男") # 中文选项用STHeiti Lightc.acroForm.radio(name="gender",value="female",x=280, y=y_position-10,size=10
)
c.drawString(300, y_position, "女")
y_position -= spacing# 3. 出生日期
c.drawString(100, y_position, "3. 出生日期:")
c.acroForm.textfield(name="birth_date",x=200, y=y_position-20,width=200, height=20,borderColor=colors.black,fontName=form_font_name
)
y_position -= spacing# 4. 身份证号
c.drawString(100, y_position, "4. 身份证号:")
c.acroForm.textfield(name="id_card",x=200, y=y_position-20,width=300, height=20,borderColor=colors.black,fontName=form_font_name
)
y_position -= spacing# 5. 联系电话
c.drawString(100, y_position, "5. 联系电话:")
c.acroForm.textfield(name="phone",x=200, y=y_position-20,width=200, height=20,borderColor=colors.black,fontName=form_font_name
)
y_position -= spacing# 6. 电子邮箱
c.drawString(100, y_position, "6. 电子邮箱:")
c.acroForm.textfield(name="email",x=200, y=y_position-20,width=300, height=20,borderColor=colors.black,fontName=form_font_name
)
y_position -= spacing# 7. 居住地址
c.drawString(100, y_position, "7. 居住地址:")
c.acroForm.textfield(name="address",x=200, y=y_position-20,width=350, height=20,borderColor=colors.black,fontName=form_font_name
)
y_position -= spacing# 保存PDF
c.save()
print("个人信息表已生成:个人信息表.pdf")
注意:性别竟然找不到对应的(gender),需要特殊处理。
环境为masOS,其它系统字体设置会有所差别。