Python 自动化之批量处理 PDF 合同与发票——实战案例 之前讲了很多 PDF 的基础操作这次用两个完整的实战案例把知识串起来——批量处理 PDF 合同和批量提取发票信息。一、实战案例一批量生成 PDF 合同把 Excel 里的客户数据批量生成合同 PDF这是办公自动化里最高频的需求。1. 准备数据importpandasaspd# 模拟客户数据data{客户编号:[KH001,KH002,KH003],客户名称:[北京科技有限公司,上海信息有限公司,广州贸易有限公司],合同金额:[150000,98000,210000],签订日期:[2026-07-01,2026-07-05,2026-07-10],项目内容:[数据分析系统开发,爬虫数据采集服务,可视化平台搭建],}dfpd.DataFrame(data)df.to_excel(客户数据.xlsx,indexFalse)2. 安装依赖pipinstallpython-docx docx2pdf# 先生成 Word再转 PDF3. 生成合同fromdocximportDocumentfromdocx.sharedimportPt,Cm,Inches,RGBColorfromdocx.enum.textimportWD_ALIGN_PARAGRAPHimportpandasaspdfromdatetimeimportdatetimeimportosclassContractGenerator:合同批量生成器def__init__(self,template_path):self.template_pathtemplate_pathdefgenerate_contract(self,customer):为单个客户生成合同docDocument(self.template_path)# 替换占位符replacements{{{客户编号}}:customer[客户编号],{{客户名称}}:customer[客户名称],{{合同金额}}:f{customer[合同金额]:,.0f},{{大写金额}}:self._num_to_cn(customer[合同金额]),{{签订日期}}:customer[签订日期],{{项目内容}}:customer[项目内容],}forpindoc.paragraphs:forkey,valinreplacements.items():ifkeyinp.text:forruninp.runs:ifkeyinrun.text:run.textrun.text.replace(key,val)# 保存filenamef合同_{customer[客户编号]}_{customer[客户名称]}.docxfilepathos.path.join(生成合同,filename)os.makedirs(生成合同,exist_okTrue)doc.save(filepath)returnfilepathdef_num_to_cn(self,num):金额转大写简化版c_num零壹贰叁肆伍陆柒捌玖c_unit分角元拾佰仟万拾佰仟亿# 实际项目需要完善的大写金额转换returnf{num}元整defbatch_generate(self,excel_path):批量生成dfpd.read_excel(excel_path)files[]for_,rowindf.iterrows():pathself.generate_contract(row)files.append(path)print(f已生成:{os.path.basename(path)})returnfiles# 使用generatorContractGenerator(合同模板.docx)filesgenerator.batch_generate(客户数据.xlsx)4. Word 转 PDFfromdocx2pdfimportconvertdefbatch_docx_to_pdf(docx_dir生成合同,pdf_dir生成PDF):批量把 Word 合同转成 PDFos.makedirs(pdf_dir,exist_okTrue)forfinos.listdir(docx_dir):iff.endswith(.docx):docx_pathos.path.join(docx_dir,f)pdf_pathos.path.join(pdf_dir,f.replace(.docx,.pdf))convert(docx_path,pdf_path)print(f已转换:{f}→{os.path.basename(pdf_path)})# 使用batch_docx_to_pdf()二、实战案例二批量提取发票信息从一堆 PDF 发票中自动提取关键字段导出到 Excel。1. 文字型发票提取importpdfplumberimportpandasaspdimportreimportosclassInvoiceExtractor:发票信息提取器def__init__(self):self.fields[发票号码,开票日期,金额,税额,价税合计,销售方名称,购买方名称,货物名称]defextract_from_text(self,pdf_path):从文字型 PDF 发票中提取信息info{文件:os.path.basename(pdf_path)}textwithpdfplumber.open(pdf_path)aspdf:forpageinpdf.pages:textpage.extract_text()or# 发票号码matchre.search(r发票号码[:]\s*(\d),text)ifmatch:info[发票号码]match.group(1)# 开票日期matchre.search(r开票日期[:]\s*(\d{4}[\-\年]\d{1,2}[\-\月]\d{1,2}),text)ifmatch:info[开票日期]match.group(1).replace(年,-).replace(月,-)# 金额价税合计matchre.search(r价税合计[(]大写[)][^0-9]*([\d,]\.\d{2}),text)ifmatch:info[价税合计]match.group(1).replace(,,)# 销售方名称matchre.search(r销售方[名称]?[:]\s*(.?)(?:\n|$),text)ifmatch:info[销售方名称]match.group(1).strip()# 购买方名称matchre.search(r购买方[名称]?[:]\s*(.?)(?:\n|$),text)ifmatch:info[购买方名称]match.group(1).strip()returninfodefextract_from_table(self,pdf_path):从发票 PDF 的表格中提取商品明细items[]withpdfplumber.open(pdf_path)aspdf:forpageinpdf.pages:tablespage.extract_tables()fortableintables:forrowintable[1:]:# 跳过表头ifrowandrow[0]andlen(row)4:items.append({货物名称:row[0],数量:row[1]iflen(row)1else,单价:row[2]iflen(row)2else,金额:row[3]iflen(row)3else,})returnitemsdefbatch_extract(self,pdf_dir):批量提取all_data[]forfinos.listdir(pdf_dir):iff.endswith(.pdf):infoself.extract_from_text(os.path.join(pdf_dir,f))all_data.append(info)print(f已提取:{f})dfpd.DataFrame(all_data)df.to_excel(发票信息汇总.xlsx,indexFalse)print(f\n共提取{len(all_data)}张发票已导出到 发票信息汇总.xlsx)returndf# 使用extractorInvoiceExtractor()extractor.batch_extract(发票PDF)2. 扫描件发票OCRimportpytesseractfromPILimportImageimportpdfplumberimportiodefocr_invoice(pdf_path):OCR 识别扫描件发票withpdfplumber.open(pdf_path)aspdf:fori,pageinenumerate(pdf.pages):# 转图片imgpage.to_image(resolution300)img_pathftemp_page_{i}.pngimg.save(img_path)# OCR 识别textpytesseract.image_to_string(Image.open(img_path),langchi_simeng,# 中文 英文)# 提取关键信息invoice_nore.search(r发票号码[:]\s*(\d),text)totalre.search(r价税合计[:]?\s*[¥]?([\d,]\.\d{2}),text)print(f发票号码:{invoice_no.group(1)ifinvoice_noelse未识别})print(f价税合计:{total.group(1)iftotalelse未识别})# 使用需要安装 Tesseract-OCR 引擎# ocr_invoice(扫描发票.pdf)三、实战案例三合并多个 PDFfromPyPDF2importPdfMerger,PdfReader,PdfWriterimportosdefmerge_invoices(pdf_dir,output合并发票.pdf):合并多个发票 PDF 为一个文件mergerPdfMerger()filessorted([fforfinos.listdir(pdf_dir)iff.endswith(.pdf)])forfinfiles:merger.append(os.path.join(pdf_dir,f))merger.write(output)merger.close()print(f合并完成共{len(files)}个文件 →{output})defsplit_into_single_pages(pdf_path,output_dir拆分明细):将合并的 PDF 按页拆分为单张os.makedirs(output_dir,exist_okTrue)readerPdfReader(pdf_path)foriinrange(len(reader.pages)):writerPdfWriter()writer.add_page(reader.pages[i])outputos.path.join(output_dir,f第{i1}页.pdf)withopen(output,wb)asf:writer.write(f)print(f已拆分{len(reader.pages)}页到{output_dir})四、完整工作流defdaily_invoice_pipeline(input_dir):每日发票处理流水线print(开始发票处理流水线...)# 1. 提取信息extractorInvoiceExtractor()dfextractor.batch_extract(input_dir)# 2. 合并 PDFmerge_invoices(input_dir,f发票汇总_{datetime.now().strftime(%Y%m%d)}.pdf)# 3. 生成统计报表ifnotdf.emptyand价税合计indf.columns:totaldf[价税合计].sum()countlen(df)print(f\n统计共{count}张发票总金额{total:,.2f}元)print(处理完成)# 使用daily_invoice_pipeline(发票PDF)五、各场景注意事项场景注意事项合同模板占位符不要用 {name} 要用 {{name}}避免正则冲突发票提取不同公司的发票格式不同需要针对性调整正则扫描件 OCR必须安装 Tesseract 引擎和中文语言包PDF 合并按文件名排序保证顺序建议文件名加日期前缀批量处理先处理一个样本调通再批量全跑 觉得有用的话点赞 关注【张老师技术栈】吧每周更新 Java/Python/爬虫 实战干货不让你白来。

相关新闻

最新新闻

计算机毕业设计之基于大数据的抖音音乐播放数据分析可视化

计算机毕业设计之基于大数据的抖音音乐播放数据分析可视化

基于大数据的抖音音乐播放数据分析可视化利用海量数据资源为用户提供个性化音乐推荐的服务平台。通过分析用户的听歌历史、喜好偏好、社交网络互动等多个维度数据,运用机器学习和数据挖掘技术,为用户提供精准、高效的音乐推荐。收集用户在抖音平台上的听…

2026/7/7 2:01:30
STM32 裸机 Blink 的坑 你确定你的向量表能跑起来

STM32 裸机 Blink 的坑 你确定你的向量表能跑起来

一句话:从零写一个 STM32F103 的裸机 Blink 很简单,但 binary 里的向量表字节顺序错了,你的芯片根本不会跑。 前言 很多嵌入式开发入门都是从 HAL 库或者标准外设库开始的 —— 点个灯,调个时钟,看个寄存器。这些都没问题,但如果你像我一样曾经好奇过"不用库,纯裸…

2026/7/7 2:01:30
Agent 工程化新底座:用 CLI 契约层打通 HTTP 接口与业务能力

Agent 工程化新底座:用 CLI 契约层打通 HTTP 接口与业务能力

变化分层:Agent 基建应该压在哪一层如果把 AI 应用的技术栈按变化速度拆开,会发现它不是一条直线,而是一组稳定性差异很大的层。图:越往底层越适合承载长期业务契约。模型和 Agent 框架适合快速试错,不适合作为业务基础…

2026/7/7 2:01:30
研发工程师现场演算:Pixel2Geo 像素转三维坐标核心数学模型

研发工程师现场演算:Pixel2Geo 像素转三维坐标核心数学模型

研发工程师现场演算:Pixel2Geo 像素转三维坐标核心数学模型 前置说明 Pixel2Geo™ 为镜像视界自研纯视觉无源定位核心演算引擎,依托多视几何联立方程组实现二维图像像素(u,v)→CGCS2000大地三维坐标\boldsymbol{P}(X,Y,Z) 刚性映射,全程不…

2026/7/7 2:01:30
UltraStar Deluxe:完全免费的开源卡拉OK唱歌游戏入门指南

UltraStar Deluxe:完全免费的开源卡拉OK唱歌游戏入门指南

UltraStar Deluxe:完全免费的开源卡拉OK唱歌游戏入门指南 【免费下载链接】USDX The free and open source karaoke singing game UltraStar Deluxe, inspired by Sony SingStar™ 项目地址: https://gitcode.com/gh_mirrors/us/USDX UltraStar Deluxe是一款…

2026/7/7 2:01:30
UL 1069-2024新版护士呼叫设备安全标准,这些技术更新必须吃透

UL 1069-2024新版护士呼叫设备安全标准,这些技术更新必须吃透

重磅解读|UL 1069-2024新版护士呼叫设备安全标准,这些技术更新必须吃透 在医疗建筑智能化、医护设备数字化高速迭代的当下,护士呼叫系统(NCS)作为医院医患沟通、应急救助的核心基础设施,其安全可靠性、兼容…

2026/7/7 1:56:30

月新闻