PDF 文档解析提取表格数据

FreeGuideOnline 最新 2026-07-10

bash pip install camelot-py[cv]


**核心代码**
```python
import camelot

# 读取 PDF 文件,默认使用 Lattice 模式(基于线条)
tables = camelot.read_pdf('财报表格.pdf', pages='1-3', flavor='lattice')

# 输出第一个表格的数据
print(tables[0].df)

# 将表格导出为 CSV
tables.export('output.csv', f='csv')

# 查看提取准确度报告(非常推荐)
print(tables[0].parsing_report)

适用场景:财务报表、银行流水等具有明显栏线和框线的表格。

2. Tabula:无框表格的利器

如果表格没有竖线和横线,仅靠空白对齐,Tabula 会通过分析文本的空间排列来推测列边界。它的 Java 核心同样在 Python 中可用。

安装

pip install tabula-py

核心代码

import tabula

# 从文件中自动探测表格区域,stream 模式适用于无框表
df_list = tabula.read_pdf('无框数据表.pdf', pages='all', multiple_tables=True, stream=True)

# 将第一个表格保存为 Excel
if df_list:
    df_list[0].to_excel('output.xlsx', index=False)

关键参数

  • multiple_tables=True 允许单页检测多个独立表格。
  • stream=True 告诉引擎使用文本流模式,忽略线条。
  • 若区域识别不准,可手动添加 area 参数指定 [top,left,bottom,right] 坐标。

3. Pdfplumber:提供底层控制的全能型选手

Pdfplumber 能获取每个字符的精确坐标、字体和大小,你可以基于它构建自定义的提取逻辑,处理极端不规则的布局。

安装

pip install pdfplumber

通用提取代码(结合内置表格探测器)

import pdfplumber

with pdfplumber.open('复杂报表.pdf') as pdf:
    page = pdf.pages[0]
    
    # 自动提取表格(基于文本位置和隐形线条)
    tables = page.extract_tables()
    
    for table in tables:
        for row in table:
            print(row)

高级用法:手动合并多列头 当自动提取的列边界错误时,你可以打印所有字符的坐标,然后显式指定垂直分隔线:

with pdfplumber.open('复杂报表.pdf') as pdf:
    page = pdf.pages[0]
    # 设置自定义列分割线 x 坐标
    custom_lines = [50, 160, 280, 420, 550]
    tables = page.extract_table({
        "vertical_strategy": "explicit",
        "explicit_vertical_lines": custom_lines
    })

实战方案二:扫描件与 OCR 解决方案

当面对纸质表格的扫描件时,常规解析库会完全失效。此时需要引入 OCR 引擎。当前工业级开源方案首推 PaddleOCR,因其对中英文表格结构识别非常出色。

1. 安装 PaddleOCR 与依赖

pip install paddlepaddle paddleocr

2. 将 PDF 页面转为图像并进行结构识别

PaddleOCR 的表格识别模型可以端到端地输出 HTML 结构或单元格坐标。

from paddleocr import PPStructure, save_structure_res

# 初始化表格结构识别引擎
engine = PPStructure(show_log=True, lang='ch')  # 支持 'ch', 'en' 等

# 图像路径,你需要先将 PDF 转换为图像(可使用 pdf2image 库)
img_path = 'page_1.png'

result = engine(img_path)

# 保存结果,包括识别后的表格和 HTML 版本
save_structure_res(result, 'output_folder', 'page_1')

# 遍历结果,提取每个表格的纯文本矩阵
for line in result:
    if line['type'] == 'table':
        # 单元格文本存储在 table_cells 中
        for cell in line['res']['cells']:
            print(cell['text'])

将 PDF 转为图像的辅助步骤:

from pdf2image import convert_from_path

images = convert_from_path('扫描版.pdf', dpi=300)  # dpi 越高 OCR 越准
for i, img in enumerate(images):
    img.save(f'page_{i+1}.png', 'PNG')