如何使用Python的pdfplumber从PDF多页提取并合并为单个表格
如何使用Python的pdfplumber从PDF多页提取并合并为单个表格
嗨,我来帮你解决这个问题!你的代码现在的问题很明显——每次处理完一页就直接把数据存成Excel了,而且文件名都是同一个PDF的名字,最后自然只有最后一页的数据被保留下来。咱们要做的是把一个PDF里所有页面的表格数据先收集起来,合并成一个完整的DataFrame,再一次性导出成Excel文件。
先说说原代码里的几个小问题
- 变量名有点混乱,比如你把当前页的表格命名为
first_page,但其实这是每一页的表,容易误导自己 - 每次循环页面时直接导出Excel,后面的页会覆盖前面的结果(因为文件名相同)
- 没有把多页的数据整合到一起,而是每页单独处理了
咱们来一步步改代码
下面是修改后的完整代码,我已经帮你把所有问题都修复了,还加了一些实用的细节:
import pdfplumber import pandas as pd import glob import os # 设置PDF文件路径和输出路径 pdf_folder_path = r"C:\Users\path_where_I_have_my_pdf_files" output_folder = r"C:/Temp/test/" # 确保输出文件夹存在,不存在就自动创建 os.makedirs(output_folder, exist_ok=True) # 获取文件夹里所有的PDF文件 all_files = glob.glob(pdf_folder_path + "/*.pdf") for pdf_file in all_files: # 用一个列表存当前PDF所有页面的表格数据 page_dfs = [] # 提取原PDF的文件名,用来命名后续的Excel pdf_filename = os.path.basename(pdf_file) with pdfplumber.open(pdf_file) as pdf: for page_num, page in enumerate(pdf.pages, start=1): print(f"正在处理{pdf_filename}的第{page_num}页...") # 提取当前页的表格,保持你原来的提取规则 table = page.extract_table(table_settings={ "vertical_strategy": "lines", "horizontal_strategy": "text" }) if table: # 和你原代码逻辑一致:用第一行做列名,从第三行开始取数据 df = pd.DataFrame(table[2:], columns=table[0]) # 把当前页的DataFrame加入列表暂存 page_dfs.append(df) # 所有页处理完后,合并所有页面的DataFrame if page_dfs: merged_df = pd.concat(page_dfs, ignore_index=True) # 拼接输出的Excel路径 excel_path = os.path.join(output_folder, f"{pdf_filename}.xlsx") merged_df.to_excel(excel_path, index=False) print(f"{pdf_filename}处理完成,已保存到{excel_path}") else: print(f"{pdf_filename}中未提取到任何表格数据,跳过处理")
关键改动说明
- 新增了
page_dfs列表,专门用来存每个页面的表格数据,这样就不会把之前页的数据覆盖了 - 把导出Excel的操作移到了整个PDF所有页处理完之后,用
pd.concat()把所有页的表格合并成一个完整的DataFrame - 修复了变量名混乱的问题,比如把
first_page改成table,更贴合实际含义 - 加了打印提示,方便你跟踪处理进度,知道现在在处理哪个PDF的哪一页
- 新增了
os.makedirs(),确保输出文件夹一定存在,避免因为文件夹不存在报错
一些实用的注意事项
- 要确保你所有PDF页面的表格列结构是一致的哦,如果有的页面列名或列数不一样,合并的时候会出现列名不匹配的问题,这时候你得先检查PDF的排版,或者根据实际情况调整列的映射
- 可以根据你PDF的实际排版,调整
table_settings里的参数,比如vertical_strategy和horizontal_strategy,确保表格提取的准确性 - 如果有的页面没有表格,代码会自动跳过,不会影响其他页面的处理,还会给你打印提示告诉你这个PDF没提取到数据




