使用Tabula提取PDF表格为CSV:解决单元格文本跨行拆分问题
解决PDF表格提取时单元格文本拆分问题的方案
针对你用tabula提取PDF表格时,同一单元格文本被拆分为多行的问题,以下是几个纯文本处理的解决方案:
1. 优化tabula参数,精准识别列边界
默认的lattice模式依赖表格边框识别,若PDF边框不清晰就会出错,改用stream模式结合指定列坐标,能更准确识别单元格范围:
步骤:
- 先用tabula的GUI工具(通过
tabula命令行启动)打开PDF,手动标记列的分隔位置,获取坐标值(比如示例中的100, 500, 800) - 用以下代码提取:
import tabula import pandas as pd # stream模式基于文本布局识别,columns指定列分隔坐标,guess=False禁用自动猜测 df = tabula.read_pdf( '045632_2023.pdf', pages='all', stream=True, guess=False, columns=[100, 500, 800] # 替换为你实际的列坐标 ) # 合并所有页的表格(如果有多页) combined_df = pd.concat(df, ignore_index=True) combined_df.to_csv('result.csv', index=False)
2. 提取后合并同一单元格的多行文本
如果调整参数后仍有部分单元格拆分,可通过pandas对提取后的DataFrame进行后处理,合并同一单元格的零散行:
import tabula import pandas as pd df = tabula.read_pdf('045632_2023.pdf', pages='all', lattice=True) combined_df = pd.concat(df, ignore_index=True) # 处理每一列:填充空值并合并连续行的文本 for col in combined_df.columns: # 用前一行的值填充空单元格(适用于单元格跨行的情况) combined_df[col] = combined_df[col].fillna(method='ffill') # 按非空单元格的分组,合并同一单元格的多行文本 combined_df[col] = combined_df.groupby(combined_df[col].notna().cumsum())[col].transform( lambda x: '\n'.join(x.dropna().astype(str)) ) # 去重(因为分组后会重复) combined_df = combined_df.drop_duplicates().reset_index(drop=True) combined_df.to_csv('result.csv', index=False)
3. 使用tabula命令行工具(更稳定)
有时候Python API的参数限制较多,直接用tabula-java的命令行工具能获得更灵活的控制:
# stream模式提取,指定列坐标,输出为CSV tabula --pages all --stream --columns 100,500,800 --output result.csv 045632_2023.pdf
4. 尝试camelot库(替代tabula的文本提取工具)
camelot同样基于文本处理,对复杂表格的识别能力更强:
import camelot # flavor='stream'适用于无严格边框的表格,split_text=False避免拆分单元格内文本 tables = camelot.read_pdf( '045632_2023.pdf', pages='all', flavor='stream', split_text=False ) # 合并所有表格并保存 combined_df = pd.concat([table.df for table in tables], ignore_index=True) combined_df.to_csv('result.csv', index=False)
内容的提问来源于stack exchange,提问作者R. Carrillo
相关产品推荐
相关产品推荐

