在不少业务里,PDF 不只是'拿来看的文档',它也常被当成数据采集和流转的载体。比起'打印—填写—扫描'这套老办法,交互式 PDF 表单更适合在线收集信息,后续再由程序接着处理。
像问卷、客户登记、入职申请这类场景,只要表单结构设计得还算规整,自动创建和自动填充都能做得比较顺手。这里用 Spire.PDF for Python 走一遍流程:先创建可填写的表单域,再把字段值自动写进去。
安装依赖
这里用到的依赖是:
- Spire.PDF for Python
- plum-dispatch v1.7.4(底层方法分发支持)
安装命令很直接:
pip install Spire.PDF
小型项目也可以直接用免费版:pip install Spire.PDF.Free
如果在 Windows 上安装卡住了,先看官方安装说明,通常问题都出在环境和字体这两类地方。
创建可填写表单域
先把几个基本概念捋清楚:
PdfForm:整个交互式表单PdfField:单个字段- 各类字段对象:不同类型的表单控件
Spire.PDF 支持的字段类型不少,常见的基本就是下面这些:
| 类名 | 说明 | 常用属性 |
|---|---|---|
| PdfTextBoxField | 文本框,用于录入姓名、地址等 | Bounds, Font, Text |
| PdfCheckBoxField | 复选框,用于多选场景 | Checked (True/False) |
| PdfRadioButtonListField | 单选按钮组,互斥选项 | Items, SelectedIndex |
| PdfComboBoxField | 组合框(下拉列表) | Items, Font |
| PdfButtonField | 提交/重置按钮 | Actions.MouseDown |
多数业务表单其实就是这些控件的组合,没必要把问题想得太复杂。
表单创建流程
表单创建的步骤并不绕,核心就是先建文档,再把字段一点点放进去。字段少的时候这样看起来很朴素,但真到后面要改版,结构越清楚,维护越省事。
基本流程如下:
- 创建
PdfDocument - 添加页面
- 创建字段对象
- 设置字段位置(Bounds)
- 添加到
doc.Form.Fields - 保存文档
下面这个示例做了一份员工入职登记表,包含文本输入、材料清单复选、性别单选,以及部门和职位级别的下拉选择。
from spire.pdf.common import *
from spire.pdf import *
# 初始化文档
doc = PdfDocument()
page = doc.Pages.Add()
# 定义布局基准坐标
baseX = 120.0
baseY = 40.0
brush_title = PdfSolidBrush(PdfRGBColor(Color.get_DarkBlue()))
brush_text = PdfSolidBrush(PdfRGBColor(Color.get_Black()))
font = PdfTrueTypeFont(, , PdfFontStyle.Regular, )
page.Canvas.DrawString(, font, brush_title, PointF(, baseY))
txt_name = PdfTextBoxField(page, )
txt_name.Bounds = RectangleF(baseX, baseY, , )
txt_name.Font = font
doc.Form.Fields.Add(txt_name)
baseY +=
page.Canvas.DrawString(, font, brush_title, PointF(, baseY))
cb_id = PdfCheckBoxField(page, )
cb_id.Bounds = RectangleF(baseX, baseY, , )
doc.Form.Fields.Add(cb_id)
page.Canvas.DrawString(, font, brush_text, PointF(baseX + , baseY))
cb_edu = PdfCheckBoxField(page, )
cb_edu.Bounds = RectangleF(baseX + , baseY, , )
doc.Form.Fields.Add(cb_edu)
page.Canvas.DrawString(, font, brush_text, PointF(baseX + , baseY))
baseY +=
page.Canvas.DrawString(, font, brush_title, PointF(, baseY))
rb_gender = PdfRadioButtonListField(page, )
item_m = PdfRadioButtonListItem()
item_m.Bounds = RectangleF(baseX, baseY, , )
page.Canvas.DrawString(, font, brush_text, PointF(baseX + , baseY))
item_f = PdfRadioButtonListItem()
item_f.Bounds = RectangleF(baseX + , baseY, , )
page.Canvas.DrawString(, font, brush_text, PointF(baseX + , baseY))
rb_gender.Items.Add(item_m)
rb_gender.Items.Add(item_f)
doc.Form.Fields.Add(rb_gender)
baseY +=
page.Canvas.DrawString(, font, brush_title, PointF(, baseY))
cmb_dept = PdfComboBoxField(page, )
cmb_dept.Bounds = RectangleF(baseX, baseY, , )
cmb_dept.Items.Add(PdfListFieldItem(, ))
cmb_dept.Items.Add(PdfListFieldItem(, ))
cmb_dept.Items.Add(PdfListFieldItem(, ))
cmb_dept.Font = font
doc.Form.Fields.Add(cmb_dept)
baseY +=
page.Canvas.DrawString(, font, brush_title, PointF(, baseY))
cmb_level = PdfComboBoxField(page, )
cmb_level.Bounds = RectangleF(baseX, baseY, , )
cmb_level.Items.Add(PdfListFieldItem(, ))
cmb_level.Items.Add(PdfListFieldItem(, ))
cmb_level.Items.Add(PdfListFieldItem(, ))
cmb_level.Font = font
doc.Form.Fields.Add(cmb_level)
doc.SaveToFile()
doc.Close()

