Python 读取电子发票PDF 转成Excel
Python 读取电子发票PDF 转成Excel
目录
0.前提
1.python相关的处理PDF的库
2.实际好用的
3.实际代码
4.思考
0.前提
只识别普通电子发票PDF,提取其中某些关键内容到excel中。
1.python相关的处理PDF的库
如下4个库是经常更新维护的!
pyPDF/pyPDF2、pdfplumber、PyMuPDF、Camelot等4个库。
2.实际好用的
个人推荐pdfplumber,它有extract_tables函数
3.实际代码
import pdfplumber
import re
import os
import pandas as pd
'''处理 普通发票电子PDF 提取关键字段内容信息写入excel中其它类的发票 自己参考对应规律 更改代码即可参考:pdfplumber官网、以及:https://blog.csdn.net/Burannnn/article/details/129393295
'''
def re_text(bt, text):# re 搜索正则匹配 包含re.compile包含的文字内容m1 = re.search(bt, text)if m1 is not None:return re_block(m1[0])return Nonedef re_block(text):# 去掉空格、中英文小括号、中文冒号变英文冒号;去掉中文全角空格return text.replace(' ', '').replace(' ', '').replace(')', '').replace(')', '').replace(':', ':')def get_pdf(dir_path):pdf_file = []for root, sub_dirs, file_names in os.walk(dir_path):for name in file_names:if name.endswith('.pdf'):filepath = os.path.join(root, name)pdf_file.append(filepath)return pdf_filedef read(xlsx_path, pdf_root):# 构建excel writer 写入器writer = pd.ExcelWriter(xlsx_path)# 如果字段不通用 则需要单独拎出来判断,这里我全部拎出来做了if判断all_fields = {"开票日期": [],"名称": [],"纳税人识别号": [],"价税合计(小写)": [],"货物或应税劳务、服务名称": [],"规格型号": [],"单位": [],"数量": [],"单价": [],"金额": [],"税率": [],"税额": [],}filenames = get_pdf(pdf_root)for filename in filenames:print(f"正在读取:{filename}")with pdfplumber.open(filename) as pdf:first_page = pdf.pages[0]pdf_text = first_page.extract_text()# print(pdf_text)kaipiao = re_text(re.compile(r'开票日期(.*)'), pdf_text)if kaipiao:all_fields["开票日期"].append(kaipiao.replace("开票日期:", ""))mingcheng = re_text(re.compile(r'名\s*称\s*[::]\s*([\u4e00-\u9fa5]+)'), pdf_text)if mingcheng:all_fields["名称"].append(mingcheng.replace("名称:", ""))# nashuiren = re_text(re.compile(r'纳税人识别号\s*[::]\s*([a-zA-Z0-9]+)'), pdf_text)# if nashuiren:# all_fields["纳税人识别号"].append(nashuiren.replace("纳税人识别号:", ""))jine = re_text(re.compile(r'小写.*(.*[0-9.]+)'), pdf_text)if jine:all_fields["价税合计(小写)"].append(jine.replace("小写¥", ""))table = first_page.extract_tables()[0]# 纳税人识别号 购买方for t in table[0]:t_ = str(t).replace(" ", "")nashuiren = re_text(re.compile(r'纳税人识别号\s*[::]\s*([a-zA-Z0-9]+)'), t_)if nashuiren:all_fields["纳税人识别号"].append(nashuiren.replace("纳税人识别号:", ""))# 这里根据pdfplumber提取table来依次输出,查看规律(适合普通发票,其它发票打印输出看规律即可)for t in table[1]:if not t:continuet_ = str(t).replace(" ", "") # 去掉空格ts = t_.split("\n")if "货物或应税劳务、服务名称" in t_:if len(ts) > 1:all_fields["货物或应税劳务、服务名称"].append(ts[1])else:all_fields["货物或应税劳务、服务名称"].append("")if "规格型号" in t_:if len(ts) > 1:all_fields["规格型号"].append(ts[1])else:all_fields["规格型号"].append("")if "单位" in t_:if len(ts) > 1:all_fields["单位"].append(ts[1])else:all_fields["单位"].append("")if "数量" in t_:if len(ts) > 1:all_fields["数量"].append(ts[1])else:all_fields["数量"].append("")if "单价" in t_:if len(ts) > 1:all_fields["单价"].append(ts[1])else:all_fields["单价"].append("")if "税率" in t_:if len(ts) > 1:all_fields["税率"].append(ts[1])else:all_fields["税率"].append("")if "金额" in t_:if len(ts) > 1:all_fields["金额"].append(ts[1])else:all_fields["金额"].append("")if "税额" in t_:if len(ts) > 1:all_fields["税额"].append(ts[1])else:all_fields["税额"].append("")# print('--------------------------------------------------------')# print(re_text(re.compile(r'[\u4e00-\u9fa5]+电子普通发票.*?'), pdf_text))# # print(re_text(re.compile(r'发票代码(.*\d+)'), pdf_text))# print(re_text(re.compile(r'发票号码(.*\d+)'), pdf_text))# print(re_text(re.compile(r'开票日期(.*)'), pdf_text))# print(re_text(re.compile(r'名\s*称\s*[::]\s*([\u4e00-\u9fa5]+)'), pdf_text))# print(re_text(re.compile(r'纳税人识别号\s*[::]\s*([a-zA-Z0-9]+)'), pdf_text))# price = re_text(re.compile(r'小写.*(.*[0-9.]+)'), pdf_text)# print(price)# company = re.findall(re.compile(r'名.*称\s*[::]\s*([\u4e00-\u9fa5]+)'), pdf_text)# if company:# print(re_block(company[len(company)-1]))# print('--------------------------------------------------------')print(all_fields)df = pd.DataFrame(all_fields)df.to_excel(writer)writer.save()returnpdf_root = r"G:\PDF"
xlsx_path = r"G:\PDF\all_fields.xlsx"read(xlsx_path, pdf_root)
4.思考
对于专用发票,找到对应的规律即可。这里最好用的是extract_tables函数,打印出来,找规律即可!
相关文章:
Python 读取电子发票PDF 转成Excel
Python 读取电子发票PDF 转成Excel 目录 0.前提 1.python相关的处理PDF的库 2.实际好用的 3.实际代码 4.思考 0.前提 只识别普通电子发票PDF,提取其中某些关键内容到excel中。 1.python相关的处理PDF的库 如下4个库是经常更新维护的! pyP…...
我的项目问题
1.一点缩放和旋转就消失,需要再次平移才出现 解决方案:在显示当前图形时,显示已有图形。 2.每次点击平移,图形移动到上次点击的位置。 ho_RegionUnion.Dispose(); ho_RegionUnion ExpTmpOutVar_0;这两段代码放到显示之后的&am…...
【c】杨辉三角
下面介绍两种方法 1.利用上面性质的第五条,我们可以求各行各列的组合数 2.利用上面性质的第7条,我们可以用数组完成 下面附上代码 1. #include<stdio.h> void fact(int n ,int m )//求组合数 {long long int sum11;long long int sum21;int a…...
算法刷题之数组篇
题目一:两数之和 给出一个整型数组 numbers 和一个目标值 target,请在数组中找出两个加起来等于目标值的数的下标,返回的下标按升序排列。 (注:返回的数组下标从1开始算起,保证target一定可以由数组里面2…...
TR转发路由器测评—云企业网实现跨地域跨VPC的网络互通测评实战【阿里云产品测评】
文章目录 一.转发路由器 Transit Router 测评1.1 准备阶段1.2 本文测评收获1.3 什么是云企业网实例、转发路由器实例和云数据传输服务 二.使用云企业网实现跨地域跨VPC的网络互通2.2 **测试连通性**2.3 网络拓扑如下: 心得:总结: 声明&#x…...
1.1美术理论基础
一、光影 物体呈现在人们眼前的时候,不同的受光面其明暗变化以及物体的影子。 1.什么是黑白灰 在美术中黑白灰指亮面、灰面、暗面,属于素描的三大面,主要体验一个物体的整体寿光过程。普遍存在于各种艺术和设计领域。黑白灰作品的出现&#x…...
【Java 基础】21 多线程同步与锁
文章目录 1.存在的问题2.使用同步解决问题1) synchronized2) volatile3) 锁 总结 用多线程过程中,有可能出现 多个线程同时处理(获取或修改等)同一个数据,这个时候就 会发生数据不同步的问题, 因此出现了同步和锁来…...
Python语言基础知识(一)
文章目录 1、Python内置对象介绍2、标识符与变量3、数据类型—数字4、数据类型—字符串与字节串5、数据类型—列表、元组、字典、集合6、运算符和表达式7、运算符和表达式—算术运算符8、运算符和表达式—关系运算符9.1、运算符和表达式— 成员测试运算符in9.2、运算符和表达式…...
Xilinx FPGA平台DDR3设计详解(三):DDR3 介绍
本文介绍一下常用的存储芯片DDR3,包括DDR3的芯片型号识别、DDR3芯片命名、DDR3的基本结构等知识,为后续掌握FPGA DDR3的读写控制打下坚实基础。 一、DDR3芯片型号 电路板上的镁光DDR3芯片上没有具体的型号名。 如果想知道具体的DDR3芯片型号&#…...
字典的遍历
字典不是有序的集合,就不能通过index来遍历了,那如何遍历字典呢? 方法一:直接用字典 for key in a_dict: print a_dict[key] 通过这样的结构可以的。 d {"liming" : 98, "wangli":95, "mali":90, "liping&q…...
Linux环境下的MySQL安装
文章目录 前提说明1.卸载内置环境2.检查系统安装包3.卸载这些默认安装包4.获取MySQL官方yum源5.安装MySQLyum源,对比前后yum源6.查看yum源是否生效7.安装MySQL服务8.查看相对应的配置文件9.启动服务10.查看启动服务11.登录方法一12.登录方法二13.登录方法三14.设置开…...
梦想与魔法:编程之路的挑战与荣耀
在年少轻狂的岁月里,我们都有过一些不切实际的梦想,渴望成为某种神奇的存在。我的梦想是成为一名神奇的码农,用键盘编织魔法,创造出炫酷的虚拟世界。然而,现实是残酷的,当我刚入门计算机领域时,…...
qt 5.15.2 主窗体菜单工具栏树控件功能
qt 5.15.2 主窗体菜单工具栏树控件功能 显示主窗体效果: mainwindow.h文件内容: #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include <QFileDialog> #include <QString> #include <QMessageBox>#inc…...
Day15——File类与IO流
1.java.io.File类的使用 1.1 File类的理解 File 类及本章下的各种流,都定义在 java.io 包下。一个 File 对象代表硬盘或网络中可能存在的一个文件或者文件目录(俗称文件夹),与平台无关。(体会万事万物皆对象…...
【Qt】QLineEdit显示输入十六进制,位数不足时按照规则填充显示及每两个字符以空格填充
问题 在实际开发中,有时候需要对输入进行限制,一是更加合理,二是防止出现误操作。 比如: 使用Qt进行应用程序开发时,对单行编辑框QLineEdit控件,设置只可输入十六进制。 限制输入的方式常用且经典的是使用…...
GPT 中文提示词技巧:参照 OpenAI 官方教程
前言 搜了半天什么 prompt engineering 的课,最后会发现 gpt 官方其实是有 prompt 教程的。因此本文主要是学习这篇教程。 概述 - OpenAI API 部分案例是参考:根据吴恩达老师教程总结出中文版prompt教程_哔哩哔哩_bilibili up主的内容。 一、尽可能清…...
原生微信小程序将字符串生成二维码图片
weapp-qrcode.js再最后 inde.ts中的内容 // pages/qrCode/index.ts // 引入weapp-qrcode.js文件 var QRCode require(../../utils/weapp-qrcode) Page({/*** 页面的初始数据*/data: {orderNo:"",imagePath:},/*** 生命周期函数--监听页面加载*/onLoad(options:any)…...
深入理解HTTPS加密协议
在现代网络环境中,数据安全和隐私保护至关重要。HTTPS(全称为HyperText Transfer Protocol Secure)是一种用于保障互联网通信安全的加密协议,它通过在HTTP协议的基础上添加SSL/TLS层来实现对数据的加密传输。本文将详细介绍HTTPS的…...
路径规划之PRM算法
系列文章目录 路径规划之Dijkstra算法 路径规划之Best-First Search算法 路径规划之A *算法 路径规划之D *算法 路径规划之PRM算法 路径规划之PRM算法 系列文章目录前言一、前期准备1.栅格地图2.采样3.路标 二、PRM算法1.起源2.流程3. 优缺点4. 实际效果 前言 之前提到的几种…...
深入理解数据在内存中是如何存储的,位移操作符如何使用(能看懂文字就能明白系列)文章超长,慢慢品尝
系列文章目录 C语言笔记专栏 能看懂文字就能明白系列 🌟 个人主页:古德猫宁- 🌈 信念如阳光,照亮前行的每一步 文章目录 系列文章目录🌈 *信念如阳光,照亮前行的每一步* 前言引子一、2进制和进制转化为什么…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...
《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...
处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的
修改bug思路: 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑:async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...
