使用 Python 扁平化 PDF 文档 【附代码示例】

在处理 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 时,还需要留意以下几点:

  1. 提前备份原始文件。 扁平化会改变 PDF 的对象结构,通常无法直接恢复。建议将处理结果另存为新文件,避免覆盖原始文档。
  2. 区分扁平化和只读设置。 将表单字段设置为只读(ReadOnly = True)只是限制字段编辑,并没有移除字段对象。扁平化则会将字段转换为静态页面内容,两者的处理结果不同。
  3. 留意免费版的页数限制。 使用免费版时,需要注意其处理页数限制,超出限制的部分可能受到水印或其他功能限制的影响。具体以当前版本的产品说明为准。
  4. 及时释放资源。 文件处理完成后,调用 Close() 关闭 PDF 文档,避免占用不必要的资源。
  5. 结合循环实现批量处理。 如果需要处理多个 PDF 文件,可以遍历文件列表,逐个加载、扁平化并保存处理结果。

总结

使用 Spire.PDF for Python 可以灵活地扁平化 PDF 表单字段,无论是将整份文档中的表单字段统一转换为静态内容,还是只处理指定字段,都能根据实际需求选择合适的方式。如果需要生成最终版 PDF 表单,建议先完成字段填写,再进行扁平化并保存为新文件。将表单填写、数据导入导出与扁平化结合起来,还可以进一步实现从模板生成、自动填写到最终归档的完整处理流程。

相关推荐
Java后端的Ai之路35 分钟前
Java并发编程07-等待通知机制优化循环等待
java·数据库·python
小小张说故事37 分钟前
Python 的 async def 为什么能同时跑几千个任务?拆开协程对象、await 与事件循环那次让出
后端·python
ZZHow10241 小时前
神经网络与深度学习笔记_Day1
人工智能·pytorch·笔记·python·深度学习·神经网络·机器学习
北城笑笑1 小时前
Vue 106 ,上篇:前端桌面端应用实现方案( Electron 框架详细介绍,Vue + Electron )
前端·javascript·vue.js·python·electron
青少儿编程课堂2 小时前
蓝桥杯·全国青少年信息素养大赛·电子学会C/C++考级:分层图最短路解析
c++·python·算法·bfs·信息学竞赛
全栈练习生2 小时前
大模型原理之自适应推理
python·ai
实名上网宋凯宣11 小时前
Django
后端·python·django
如若12312 小时前
【论文复现】CoFailMed:从零复现医学图像分割的共享失败审计,含完整代码流程与科研绘图
人工智能·python
砚底藏山河13 小时前
python量化自定义周期 K 线合成
java·开发语言·数据库·python·金融