在处理 PDF 表单时,有时需要将填写好的内容固定下来,避免接收者再次修改。例如,入职登记表填写完成、审批单盖章或票据生成二维码后,通常都需要将最终内容保存为不可编辑的版本。
PDF 中的表单字段、批注和图层等对象通常独立于页面内容存在,因此可以单独编辑或删除。PDF 扁平化就是将这些对象转换为页面上的静态内容,同时移除原有的独立对象。 扁平化后,文档中的相关内容不再能够像原来一样单独编辑。
本文以 Spire.PDF for Python 为例,介绍 PDF 扁平化的基本原理,以及如何通过 Python 扁平化整个文档或指定的表单字段。
为什么要扁平化 PDF?
PDF 扁平化在表单处理、文档归档和文件分发等场景中都很实用,主要有以下几个用途:
- 防止表单内容被修改: 将填写完成的表单字段转换为静态内容,避免接收者直接修改原有字段。
- 保持文档显示效果: 将表单字段等交互对象转换为页面内容,减少不同 PDF 阅读器之间的显示差异。
- 方便打印和归档: 将交互式内容固定下来,便于保存和分发最终版本。
- 简化后续处理: 移除不再需要的交互对象,让 PDF 更适合后续的打印、共享或归档流程。
需要注意,扁平化并不是压缩 PDF 或合并页面,而是将原本可以独立操作的对象转换为静态页面内容。
环境准备
开始之前,需要安装 Spire.PDF for Python。打开终端或命令提示符,执行以下命令:
bash
pip install Spire.PDF
安装完成后,在 Python 脚本中导入相关模块:
python
from spire.pdf.common import *
from spire.pdf import *
理解 PDF 扁平化的基本原理
PDF 页面中的内容大致可以分为两类:
- 静态内容: 例如普通文本、图片和矢量图形。这些内容通常直接绘制在页面上。
- 交互对象: 例如表单字段、批注、图层和链接。这些对象可以独立于页面内容进行操作。
扁平化的基本思路,就是将需要处理的交互对象渲染为页面上的静态内容,再移除原有的独立对象。完成后,原本可以单独编辑的字段或批注就不再具有相同的交互能力。
需要注意,扁平化通常无法直接恢复。因此,建议在操作前保留原始 PDF 文件。
本文接下来主要介绍 Spire.PDF for Python 对 PDF 表单字段的扁平化处理。
方法一:扁平化整个 PDF 文档的表单字段
如果需要将 PDF 中所有表单字段一次性转换为静态内容,可以使用 doc.Form.IsFlatten 属性。
具体代码如下:
python
from spire.pdf.common import *
from spire.pdf import *
inputFile = "FormField.pdf"
outputFile = "FlattenAll_out.pdf"
doc = PdfDocument()
doc.LoadFromFile(inputFile)
# 开启表单扁平化
doc.Form.IsFlatten = True
doc.SaveToFile(outputFile)
doc.Close()
这里通过 doc.Form.IsFlatten = True 开启整个文档的表单扁平化。设置完成后,调用 SaveToFile() 保存文件,表单字段就会被转换为静态页面内容。
这种方式适合处理整份 PDF 中的所有表单字段,不需要逐个指定目标字段。
方法二:只扁平化指定的表单字段
如果只想固定某些表单字段,同时保留其他字段的编辑能力,可以遍历 PDF 中的表单字段,根据字段名称选择需要处理的对象。
具体代码如下:
python
from spire.pdf.common import *
from spire.pdf import *
inputFile = "FormField.pdf"
outputFile = "FlattenSingle_out.pdf"
doc = PdfDocument()
doc.LoadFromFile(inputFile)
pdfform = doc.Form
formWidget = PdfFormWidget(pdfform)
# 遍历表单字段,找到指定字段并进行扁平化
for i in range(formWidget.FieldsWidget.Count):
field = formWidget.FieldsWidget.get_Item(i)
if field.Name == "TextBox1":
field.Flatten = True
doc.SaveToFile(outputFile)
doc.Close()
这段代码首先通过 doc.Form 获取 PDF 表单对象,再使用 PdfFormWidget 访问其中的字段集合 FieldsWidget。
随后,遍历字段集合,通过 field.Name 判断字段名称。当找到名为 TextBox1 的字段时,将其 Flatten 属性设为 True。
这样就只会扁平化指定字段,其他表单字段仍然可以正常编辑。
完整工作流:先填写表单,再进行扁平化
在实际项目中,通常需要先填写 PDF 表单,再将填写结果固定下来。例如,使用模板生成多份登记表、申请表或订单文件时,可以先通过代码填入数据,最后统一扁平化。
下面的示例展示了如何先填写指定文本字段,再扁平化整个文档中的表单字段:
python
from spire.pdf.common import *
from spire.pdf import *
inputFile = "FillFormField.pdf"
outputFile = "FillThenFlatten_out.pdf"
doc = PdfDocument()
doc.LoadFromFile(inputFile)
pdfform = doc.Form
formWidget = PdfFormWidget(pdfform)
# 第一步:填写表单字段
for i in range(formWidget.FieldsWidget.Count):
field = formWidget.FieldsWidget.get_Item(i)
if isinstance(field, PdfTextBoxFieldWidget):
if field.Name == "username":
field.Text = "E-iceblue"
# 第二步:扁平化整个文档的表单字段
doc.Form.IsFlatten = True
doc.SaveToFile(outputFile)
doc.Close()
在这个示例中,代码首先遍历表单字段,找到名称为 username 的文本框,并将其内容设置为 E-iceblue。完成填写后,再通过 doc.Form.IsFlatten = True 扁平化整份文档。
这里需要注意操作顺序:先填写表单,再执行扁平化。 因为扁平化会移除原有的表单字段结构,如果先扁平化,就无法再按照原来的方式修改字段值。
如果还需要处理表单数据的导入和导出,可以参考系列文章《在 PDF 中导入或导出表单数据》。
验证 PDF 扁平化是否成功
完成扁平化后,可以重新加载生成的 PDF,检查其中还剩下多少个表单字段。
以下代码通过 FieldsWidget.Count 获取文档中剩余的表单字段数量:
python
from spire.pdf.common import *
from spire.pdf import *
outputFile = "FlattenAll_out.pdf"
doc = PdfDocument()
doc.LoadFromFile(outputFile)
pdfform = doc.Form
formWidget = PdfFormWidget(pdfform)
# 检查剩余表单字段数量
print("剩余可编辑字段数:", formWidget.FieldsWidget.Count)
doc.Close()
如果整份文档中的表单字段都已成功扁平化,检查结果中的字段数量应为 0。
这种方式也可以用于批量处理流程,在保存文件后检查字段数量,确认表单扁平化是否达到预期效果。
延伸:PDF 中还有哪些对象可以扁平化?
除了表单字段,PDF 中还有一些常见的交互对象,例如批注和图层。它们也可能需要转换为静态内容,但具体处理方式取决于对象类型,不能直接套用表单字段的扁平化方法。
- 批注(Annotation): PDF 批注包括高亮、下划线、自由文本和图章等。处理这类对象时,需要根据具体批注类型选择相应的 API。Spire.PDF 的
05_Annotations/示例目录中提供了批注的增删查改示例。 - 图层(Layer / OCG): 一些 PDF 文件包含多个可单独显示或隐藏的图层,例如 CAD 图纸和多语言文档。Spire.PDF 的
14_Document/示例目录中提供了图层相关示例。 - 数字签名及透明内容: 这类内容涉及不同的 PDF 对象和处理机制,需要根据实际需求选择合适的方法,不能简单地等同于普通表单字段扁平化。
本文的代码主要针对 PDF 表单字段。如果需要处理批注或图层,建议进一步查阅对应对象的 API 和官方示例。
实用技巧与注意事项
使用 Python 扁平化 PDF 时,还需要留意以下几点:
- 提前备份原始文件。 扁平化会改变 PDF 的对象结构,通常无法直接恢复。建议将处理结果另存为新文件,避免覆盖原始文档。
- 区分扁平化和只读设置。 将表单字段设置为只读(
ReadOnly = True)只是限制字段编辑,并没有移除字段对象。扁平化则会将字段转换为静态页面内容,两者的处理结果不同。 - 留意免费版的页数限制。 使用免费版时,需要注意其处理页数限制,超出限制的部分可能受到水印或其他功能限制的影响。具体以当前版本的产品说明为准。
- 及时释放资源。 文件处理完成后,调用
Close()关闭 PDF 文档,避免占用不必要的资源。 - 结合循环实现批量处理。 如果需要处理多个 PDF 文件,可以遍历文件列表,逐个加载、扁平化并保存处理结果。
总结
使用 Spire.PDF for Python 可以灵活地扁平化 PDF 表单字段,无论是将整份文档中的表单字段统一转换为静态内容,还是只处理指定字段,都能根据实际需求选择合适的方式。如果需要生成最终版 PDF 表单,建议先完成字段填写,再进行扁平化并保存为新文件。将表单填写、数据导入导出与扁平化结合起来,还可以进一步实现从模板生成、自动填写到最终归档的完整处理流程。