Python读取PDF表格数据转Excel pdfplumber实战
用Python+pdfplumber自动识别PDF中的表格,导出为Excel文件,合并多页表格,告别手动复制单元格。
场景痛点
财报、发票、价目表、统计报表经常以PDF格式下发,里面是密密麻麻的表格。想拿到Excel里做透视或汇总,只能手动一格一格复制,几十行表格复制十分钟还可能错位。用Python+pdfplumber自动识别表格线,把每页表格读成DataFrame,直接导出Excel,准确率比手动高得多。
用到的库
pip install pdfplumber pandas openpyxl
完整代码
# -*- coding: utf-8 -*-
"""
用 pdfplumber 读取 PDF 中的表格并导出为 Excel
"""
import pdfplumber
import pandas as pd
def extract_tables_to_excel(pdf_path: str, out_excel: str) -> None:
"""
提取 PDF 中所有表格,合并后写入 Excel
:param pdf_path: 源 PDF 路径
:param out_excel: 输出 xlsx 路径
"""
all_rows = [] # 存放所有页的表格行
header = None
with pdfplumber.open(pdf_path) as pdf:
for page_no, page in enumerate(pdf.pages, start=1):
# extract_table() 自动识别本页最大的那张表
# 如果一页有多张表,用 extract_tables() 返回列表
table = page.extract_table()
if not table:
print(f"第 {page_no} 页未识别到表格")
continue
print(f"第 {page_no} 页识别到 {len(table)} 行")
# 第一行当表头,后续页如果重复表头就跳过
if header is None:
header = table[0]
rows = table[1:]
else:
# 跳过重复表头行(表头内容和第一页一致)
rows = table[1:] if table[0] == header else table
all_rows.extend(rows)
if not header:
print("未在 PDF 中找到任何表格")
return
# 转成 DataFrame 并导出 Excel
df = pd.DataFrame(all_rows, columns=header)
df.to_excel(out_excel, index=False)
print(f"已导出 {len(df)} 行数据 -> {out_excel}")
if __name__ == "__main__":
extract_tables_to_excel("报表.pdf", "报表.xlsx")
代码讲解
page.extract_table()自动根据表格线和文字位置推断一张表,返回二维列表(行×列)。- 如果一页有多张表,改用
page.extract_tables(),返回的是二维列表的列表。 - 表头只在第一页取一次,后续页若再出现同样的表头行就跳过,避免数据里混入重复表头。
pd.DataFrame(..., columns=header)直接转成表格,to_excel(index=False)不写行号列。- 如果表格有合并单元格、虚线框、跨页断行,可能识别不准,需要调
extract_table(table_settings={...})。
运行结果
控制台打印每页识别到的行数,同目录生成 报表.xlsx。用Excel打开,第一行是表头,下面是干净的数据行,可直接做筛选、透视。
注意事项
- pdfplumber 对线框表识别效果最好;纯文字对齐的"伪表格"(没有实线)可能漏列。
- 跨页表格如果表头被拆到两页,需要手动指定
table_settings的竖线位置。 - 扫描件PDF提取不到表格,必须先OCR。
- 复杂嵌套表建议导出后人工核对一遍。

更新时间:2026-09-14 21:34:32