当前位置: 首页 > news >正文

【工具】python汇总发票(含源码)

#创作灵感#

        最近整理发票给财务,发票有点多,自己用excel表格统计的话太费时间,而且容易出错和遗漏。想到之后也会遇到处理发票的事情,索性就做一个批处理的小工具,一劳永逸,这里分享给有需要的小伙伴。

#正文#

情况说明

        这里所说的发票为pdf格式的普通电子发票,专票可以在该方法的基础上进行修改。发票中有许多字段,这里需要的字段有开票日期、开票公司、开票公司的识别号、服务项目以及票额。如果需要其他项目,请根据代码自行调整。另外这里的服务项目只针对单条服务项目的普通发票。

功能说明

        将某个路径下的所有pdf格式普通发票中感兴趣的字段提取出来,并保存到指定的新建excel文件中,最后print出总的发票数量和总金额,方便自己核对。

现有pdf库

        Python有现有的pdf库可以直接使用,这里我们选用的是pdfplumber库:

pdf库
说明
PyMuPDF通用文本读取
pdfplumber表格、结构化数据
PyPDF2不推荐

完整代码

        代码复制,直接可用,可在该代码基础上进行扩展。

import os
import re
import pdfplumber
import pandas as pd# 匹配第一个满足要求的
def re_search(bt, text):result = re.search(bt, text)if result is not None:return re_replace(result[0])return None# 匹配所有满足要求的
def re_findall(bt, text):result = bt.findall(text)# print(result)if result is not None:return re_replace(result[1])return None# 去掉无关字符
def re_replace(text):return text.replace(' ', '').replace(' ', '').replace(')', '').replace(')', '').replace(':', ':')# 获取路径下所有pdf格式的发票文件
def get_files_name(dir_path):files_name = []for root, sub_dir, file_names in os.walk(dir_path):for name in file_names:if name.endswith('.pdf'):filepath = os.path.join(root, name)files_name.append(filepath)return files_name# 读取pdf发票文件中的内容,指定保存的excel文件和发票文件路径
def read_invoice(excel_file, invoice_pdf_path):# 想要读取的字段内容fields_you_need = {"开票日期": [],"开票公司": [],"纳税人识别号": [],"服务项目": [],"票额": [],}filesname = get_files_name(invoice_pdf_path)for filename in filesname:# print(f"正在读取:{filename}")with pdfplumber.open(filename) as pdf:page0 = pdf.pages[0]invoice_text = page0.extract_text()  invoice_date = re_search(re.compile(r'开票日期(.*)'), invoice_text)if invoice_date:fields_you_need["开票日期"].append(invoice_date.replace("开票日期:", ""))seller_name = re_findall(re.compile(r'名\s*称\s*[::]\s*([\u4e00-\u9fa5]+)'), invoice_text)if seller_name:fields_you_need["开票公司"].append(seller_name.replace("名称:", ""))seller_number = re_findall(re.compile(r'纳税人识别号\s*[::]\s*([a-zA-Z0-9]+)'), invoice_text)if seller_number:fields_you_need["纳税人识别号"].append(seller_number.replace("纳税人识别号:", ""))description = re_search(re.compile(r'\*(.*)\*'), invoice_text) # 类别if description:fields_you_need["服务项目"].append(description)total = re_search(re.compile(r'小写.*(.*[0-9.]+)'), invoice_text)if total:fields_you_need["票额"].append(total.replace("小写¥", ""))df = pd.DataFrame(fields_you_need, index = range(len(filesname)))df.index += 1df['票额'] = pd.to_numeric(df['票额'], errors='coerce') # Excel单元格内容转换成数值with pd.ExcelWriter(excel_file) as writer:df.to_excel(writer)all_total = df['票额'].sum()print("一共%d张发票,总额为%.2f元。" %(len(filesname), all_total)) # 打印出所有发票总额returninvoice_pdf_path = r"./INVOICE_PDF"
excel_file = r"./INVOICE_PDF/InvoiceTotal.xlsx"read_invoice(excel_file, invoice_pdf_path)

#总结#

        其他pdf也可以使用该思路读取,可以先读取print出来,寻找规律,然后构建正则表达式来提取关键信息,最后就可以将需要的信息整理,并存储到新建文件中。

        觉得有用的化,可以点个赞和收藏再走!

http://www.lryc.cn/news/601723.html

相关文章:

  • InfluxDB 与 MQTT 协议集成实践(二)
  • Linux网络-------2.应⽤层⾃定义协议与序列化
  • 基于深度学习的图像分割:使用DeepLabv3实现高效分割
  • 【C语言网络编程】HTTP 客户端请求(基于 Socket 的完整实现)
  • 程序代码篇---python向http界面发送数据
  • 【QT入门到晋级】window opencv安装及引入qtcreator(包含两种qt编译器:MSVC和MinGW)
  • 字节前端面试知识点总结
  • 应对反爬机制的具体方法与策略
  • 《 接口日志与异常处理统一设计:AOP与全局异常捕获》
  • Android 调试桥 (adb) 基础知识点
  • 【C 学习】02-究竟什么是C?
  • 【论文阅读】ON THE ROLE OF ATTENTION HEADS IN LARGE LANGUAGE MODEL SAFETY
  • 一文快速了解Docker和命令详解
  • 深度学习中的计算图与自动微分原理:静态图与动态图的实现差异
  • Leetcode力扣解题记录--第136题(查找单数)
  • Springboot+Layui英语单词学习系统的设计与实现
  • MyBatis Plus 分页
  • WiFi Mouse PC端 v1.7.2 官方中文版
  • 《杜甫传》读书笔记与经典摘要(三)流亡与走向人民
  • SPSC无锁环形队列技术(C++)
  • 系统整理Python的循环语句和常用方法
  • CPA青少年编程能力等级测评试卷及答案 Python编程(三级)
  • 详解力扣高频SQL50题之610. 判断三角形【简单】
  • 内存泄漏问题排查
  • idea打开后project窗口未显示项目名称的解决方案
  • 24点数学游戏(穷举法求解表达式)
  • 【计算机网络架构】网状型架构简介
  • Java学习-------序列化与反序列化
  • Windows10+WSL2+Docker相关整理
  • 2025年Agent创业实战指南:从0到1打造高增长AI智能体项目