银行流水PDF是财务对账、个税申报、贷款审批中的常见凭证,但PDF只读、不可编辑,统计汇总效率低。本文将介绍如何用Python脚本将银行流水PDF批量转换为Excel或CSV,并完成数据清洗、格式标准化和准确性校验。
一、转换需求与技术选型
银行流水PDF分两类:一类是原生可复制PDF,文本可以直接选中;另一类是扫描件PDF,本质是图片,必须走OCR识别。对于原生PDF,Python生态有多个表格提取库;对于扫描件,需要额外接入Tesseract OCR引擎。
常用库对比:
- pdfplumber:擅长带复杂结构的文本型PDF表格,无需Java环境,适合精细控制。
- tabula-py:依赖Java环境,适合有清晰边框的标准表格,API简单。
- camelot:支持有边框(lattice)和无边框(stream)两种解析模式,处理扫描件需要Ghostscript和Tesseract。
安装库的命令如下:- pip install pdfplumber pandas openpyxl
- pip install tabula-py
- pip install camelot-py[cv]
- pip install 'camelot-py[ml,ocr]'
复制代码
注意:camelot处理扫描件时,系统需要额外安装Ghostscript和Tesseract OCR引擎。
二、核心批量转换脚本(pdfplumber实现)
以下脚本遍历指定文件夹内的全部PDF,用pdfplumber提取每页表格,过滤空行,再通过pandas去重去空,导出Excel。适用于原生PDF批量处理。- import pdfplumber
- import pandas as pd
- import os
- pdf_folder = '银行流水PDF文件夹'
- output_excel = '银行流水汇总.xlsx'
- all_data = []
- for filename in os.listdir(pdf_folder):
- if filename.endswith('.pdf'):
- pdf_path = os.path.join(pdf_folder, filename)
- with pdfplumber.open(pdf_path) as pdf:
- for page in pdf.pages:
- table = page.extract_table()
- if table:
- all_data.extend([row for row in table if any(cell for cell in row)])
- df = pd.DataFrame(all_data[1:], columns=all_data[0])
- df = df.dropna(how='all').drop_duplicates()
- df.to_excel(output_excel, index=False)
- print(f'转换完成,文件已保存至:{output_excel}')
复制代码
这段代码的关键在page.extract_table()。它返回的列表里,第一个元素通常是表头,后面的元素是数据行。any(cell for cell in row)用于过滤整行为空的情况。如果不同页面的表格结构不一致,需要针对银行样式写额外的清洗逻辑。
对于复杂表格,可以通过table_settings调整提取策略,比如按线条识别列、按文本位置识别行:- custom_settings = {
- 'vertical_strategy': 'lines',
- 'horizontal_strategy': 'text',
- 'snap_tolerance': 5
- }
- table = page.extract_table(table_settings=custom_settings)
复制代码
三、Tabula-py与Camelot的使用
如果PDF表格有清晰边框,用tabula-py更省事。read_pdf直接返回DataFrame,to_csv可以导出CSV。- import tabula
- import pandas as pd
- df = tabula.read_pdf('sample.pdf', pages='all')[0]
- df.to_csv('output.csv', index=False)
复制代码
多页表格写入同一个Excel工作簿:- tables = tabula.read_pdf('sample.pdf', pages='all')
- with pd.ExcelWriter('output.xlsx', engine='openpyxl') as writer:
- for i, table in enumerate(tables):
- table.to_excel(writer, sheet_name=f'Table_{i+1}', index=False)
复制代码
camelot适合无边框表格。lattice模式适合有竖线的表格,stream模式适合靠空白分隔的表格:- import camelot
- tables = camelot.read_pdf('sample.pdf', flavor='lattice')
- tables[0].to_excel('output.xlsx')
复制代码
也可以直接用命令行转换:- camelot lattice --output tables.xlsx sample.pdf
复制代码
四、转换后的数据清洗与格式标准化
转换结果不能直接用,常见问题包括空行乱码、合并单元格、日期格式不一致、金额是文本而非数值。处理思路如下:
- 删除全空行、多余表头、封面和银行说明,只保留交易明细。
- 用pandas处理合并单元格拆分后的数据,或手动填充缺失的余额。
- 日期字段用pd.to_datetime统一成标准日期格式。
- 金额列先去除逗号和空格,再用pd.to_numeric转为数值,确保能求和。
五、准确性校验
转换完成后,至少要做三件事:
- 核对交易笔数:转换后的DataFrame行数要和PDF中实际交易笔数一致。
- 余额校验:用期初余额加每笔交易金额计算最终余额,对比PDF上的期末余额。
- 异常值检查:筛选金额为0、日期为空、摘要缺失的数据,人工确认。
六、常见问题
扫描件转换出来是乱码或空白?因为扫描件本质是图片,普通提取库拿不到文本,必须先用OCR引擎(如Tesseract)识别,或者使用camelot配合OCR模式。
金额无法求和?大概率是文本格式。可以在Excel里用分列功能转成数字,也可以用pandas转换数值类型。
列错位怎么办?重新提取时缩小表格识别范围,或转换后手动调整列顺序,拆分合并单元格。
上百份流水需要批量处理?优先选Python脚本,可循环文件、统一清洗、一次性导出;不懂代码可以用Adobe Acrobat Pro或ABBYY FineReader的批量转换功能。
七、总结
银行流水PDF转Excel没有通用万能方案。原生PDF优先用Python库;扫描件必须上OCR;复杂表格用camelot。新手处理单次文件可以先用Excel原生导入;技术用户追求效率和定制化,建议直接走pdfplumber加pandas脚本。核心原则是以原始数据准确为前提,转换后做好清洗和校验。 |