????????實際應用場景中,我們會遇到需要根據會話內容自動填寫表格的情況,比如: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,其它系統字體設置會有所差別。