首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >使用 Python 提取 PDF 的表格数据

使用 Python 提取 PDF 的表格数据

原创
作者头像
用户12495000
修改于 2026-10-09 16:53:26
修改于 2026-10-09 16:53:26
320
举报

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

本文使用 Spire.PDF for Python 的 PdfTableExtractor,演示如何逐页检测 PDF 中的表格,并把每个单元格读取成文本。整体流程只有三步:加载文档 → 逐页提取表格 → 遍历行列读取单元格。

一、环境准备

通过 pip 安装库:

代码语言:javascript
复制
pip install Spire.PDF

如果只是学习或处理小文档,也可以安装免费版本:

代码语言:javascript
复制
pip install Spire.Pdf.Free

需要注意,免费版在加载和处理 PDF 时有页数限制(最多前 10 页),超过 10 页的文档需要自行拆分后再处理,或使用完整版 PyPI。

二、核心代码

代码语言:javascript
复制
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 文档

代码语言:javascript
复制
pdf = PdfDocument()
pdf.LoadFromFile("input.pdf")

PdfDocument 是文档入口对象,LoadFromFile() 传入 PDF 文件路径即可加载。文件路径可以是相对路径或绝对路径。

2. 创建表格提取器

代码语言:javascript
复制
table_extractor = PdfTableExtractor(pdf)

PdfTableExtractor 负责对文档逐页分析版式、检测表格结构,构造时需要传入已加载的 PdfDocument 对象。

3. 逐页提取表格

代码语言:javascript
复制
for i in range(pdf.Pages.Count):
    tables = table_extractor.ExtractTable(i)

pdf.Pages.Count 是文档总页数,ExtractTable(i) 返回第 i 页检测到的所有表格。注意它返回的是一个列表 —— 一页上可能同时存在多个表格;如果该页没有表格,则返回空列表。

4. 遍历表格的行列

代码语言:javascript
复制
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 运行上述代码,输出大致如下:

代码语言:javascript
复制
Table 1 on page 1:
姓名	部门	薪资
张三	技术部	12000
李四	市场部	9800
王五	财务部	10500

每一行对应表格中的一行,各单元格之间以制表符分隔,可以直接粘贴到表格软件中。

五、进阶:把结果保存为 CSV

打印到控制台只适合快速查看。如果要保存下来,可以用 Python 内置的 csv 模块,不需要额外安装库:

代码语言:javascript
复制
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 依赖对页面版式的分析,对带明确边框、结构规整的表格识别效果较好;对于没有可见边框的表格、多行单元格或表头未明确标识的复杂排版,可能出现检测不到或结构不完整的情况。

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 或其他库来配合。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 一、环境准备
  • 二、核心代码
  • 三、代码逐步解析
  • 四、运行效果
  • 五、进阶:把结果保存为 CSV
  • 六、注意事项与局限
  • 七、其他可选的库
  • 八、总结
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档