pdf 是日常工作中最常见的文档格式之一,但它的 "表格" 和 excel 里的表格是两回事:pdf 文件本身并不保存结构化的表格数据,页面上的表格只是由文字和线条按位置关系呈现出来的视觉效果。因此,用程序读取 pdf 表格,本质上是让库去分析页面版式、识别行与列的结构。

一、环境准备
通过 pip 安装库:
pip install spire.pdf
如果只是学习或处理小文档,也可以安装免费版本:
pip install spire.pdf.free
需要注意,免费版在加载和处理 pdf 时有页数限制(最多前 10 页),超过 10 页的文档需要自行拆分后再处理,或使用完整版 pypi 。
二、核心代码
from spire.pdf import pdfdocument, pdftableextractor
# load pdf document
pdf = pdfdocument()
pdf.loadfromfile("input.pdf")
# create a pdftableextractor object
table_extractor = pdftableextractor(pdf)
# extract tables from each page
for i in range(pdf.pages.count):
tables = table_extractor.extracttable(i)
for table_index, table in enumerate(tables):
print(f"table {table_index + 1} on page {i + 1}:")
for row in range(table.getrowcount()):
row_data = []
for col in range(table.getcolumncount()):
text = table.gettext(row, col).replace("\n", " ")
row_data.append(text.strip())
print("\t".join(row_data))三、代码逐步解析
1. 加载 pdf 文档
pdf = pdfdocument()
pdf.loadfromfile("input.pdf")pdfdocument 是文档入口对象,loadfromfile() 传入 pdf 文件路径即可加载。文件路径可以是相对路径或绝对路径。
2. 创建表格提取器
table_extractor = pdftableextractor(pdf)
pdftableextractor 负责对文档逐页分析版式、检测表格结构,构造时需要传入已加载的 pdfdocument 对象。
3. 逐页提取表格
for i in range(pdf.pages.count):
tables = table_extractor.extracttable(i)pdf.pages.count 是文档总页数,extracttable(i) 返回第 i 页检测到的所有表格。注意它返回的是一个列表 —— 一页上可能同时存在多个表格;如果该页没有表格,则返回空列表。
4. 遍历表格的行列
for row in range(table.getrowcount()):
row_data = []
for col in range(table.getcolumncount()):
text = table.gettext(row, col).replace("\n", " ")
row_data.append(text.strip())
print("\t".join(row_data))getrowcount() / getcolumncount() 获取表格的行数和列数;
gettext(row, col) 读取指定单元格的文本。单元格内可能存在换行,这里把 \n 替换成空格,再 strip() 去掉首尾空白,避免输出时产生多余的空行;
最后用 \t(制表符)把一行单元格拼接起来输出,便于复制到 excel 或作为 tsv 使用。
四、运行效果
对一份包含简单表格的 pdf 运行上述代码,输出大致如下:
table 1 on page 1:
姓名 部门 薪资
张三 技术部 12000
李四 市场部 9800
王五 财务部 10500
每一行对应表格中的一行,各单元格之间以制表符分隔,可以直接粘贴到表格软件中。
五、进阶:把结果保存为 csv
打印到控制台只适合快速查看。如果要保存下来,可以用 python 内置的 csv 模块,不需要额外安装库:
import csv
from spire.pdf import pdfdocument, pdftableextractor
pdf = pdfdocument()
pdf.loadfromfile("input.pdf")
extractor = pdftableextractor(pdf)
with open("output.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
for i in range(pdf.pages.count):
for table in extractor.extracttable(i):
for row in range(table.getrowcount()):
row_data = [
table.gettext(row, col).replace("\n", " ").strip()
for col in range(table.getcolumncount())
]
writer.writerow(row_data)
pdf.close()用 csv.writer 写入时,程序会自动处理单元格中包含逗号、引号等特殊字符的情况,比手动拼接字符串 更可靠。
六、注意事项与局限
1. 适合有清晰边框的表格。 pdftableextractor 依赖对页面版式的分析,对带明确边框、结构规整的表格识别效果较好;对于没有可见边框的表格、多行单元格或表头未明确标识的复杂排版,可能出现检测不到或结构不完整的情况 e-iceblue。
2. 扫描件需要先 ocr。 如果 pdf 是扫描图片(没有文本层),任何文本类工具都无法直接读取内容,需要先用 ocr 把图片转成文字,本库不提供 ocr 功能 博客园。
3. 免费版页数限制。 免费版最多处理前 10 页,处理长文档时建议在循环里加上 min(pdf.pages.count, 10) 限制,或把文档按页拆分 博客园。
4. 用完释放资源。 批量处理大量文件时,记得在最后调用 pdf.close() 释放资源。
七、其他可选的库
如果遇到 spire.pdf 处理不了的复杂表格,可以尝试以下开源 库作为补充:
- pdfplumber :基于 pdfminer.six,提供较细粒度的页面对象访问,适合处理复杂排版;
- camelot :通过检测表格线来识别结构,对有线表格效果较好;
- tabula-py :封装了 java 的 tabula,输出与 pandas dataframe 直接兼容。
实际项目里可以根据表格类型组合使用:结构规整的表格用任一个库都能处理,复杂的先做小样本测试再选型。
八、总结
用 spire.pdf for python 提取 pdf 表格的流程非常直接:加载文档 → 创建 pdftableextractor → 逐页调用 extracttable() → 遍历行列读取单元格。它适合处理带边框、结构清晰的表格,配合 csv 模块就能把结果落盘。对于无边框、扫描件等特殊情况,则需要 ocr 或其他库来配合。
发表评论