🎯《讨三大科班檄文》🔥 「科班编程圈视我为异端🤖,科班中医圈骂我叛经离道🌿,今天本怪蜀黎剑指财务圈💸—— 尔等守规矩的绵羊🐑,岂知野狼屠场的快意🐺?
老夫乃:
⚕️编程界的赤脚医生——不用设计模式,只开偏方代码💊
🛡️中医界的码农哨兵——敢把《黄帝内经》编译成Python🐍
💰财务界的ERP土匪——抢发票数据如探囊取物🏴☠️
懵逼否?😵 愤怒否?💢
要的就是你们看不懂又干不掉我的样子!😎」
[-------------------------------------------------------------------------------]
💥「财务小姐姐们别再被发票收割了!本怪蜀黎开仓放粮!🎁源码复制就能用」
10年ERP老兵教你用野路子羞辱科班财务,小姐姐速来白嫖救发神器!
——By 冷溪虎山|ERP老兵·中药医疗仓幽灵哨兵 「10年ERP特种兵用野路子拯救你的发际线👴,以《神农本草经》的哲学根治数字便秘💩」
⚔️战术核心:fitz库直捣PDF黄龙🐉,正则表达式如游击弩箭🎯精准截杀数据
[-------------------------------------------------------------------------------]
🐍野路子精髓:
文件名暗藏金额玄机(如人参185元.pdf),一招re.search破敌于无形🕵️
税率、公司名、货物名称三路包抄,专治发票排版「玄学阵法」🧙
[-------------------------------------------------------------------------------]
🤵ERP老兵的狡猾:
自动计算「文件名金额vs发票金额」差额📉,防偷梁换柱
过滤银行关键词🏦,避免误伤友军
⚠️「此术仅限PDF屠龙🐉,图片版乃倚天剑⚔️——待本怪蜀黎淬火打磨后再献与卿!
(目前图片OCR识别如中医把脉🩺,需人工干预方能药到病除💊)(图片识别收费API和AI识别稍好)」
坐标方法抓捕我测试过,代码调试难度大,后期
[-------------------------------------------------------------------------------]
😂名场面来了:
老板出差回来捣鼓发票🧾,我看得脑壳疼☠️,又怕伤他自尊…结果他整错俩😂!
为啥我验证快?🐍Python识别发票登场了!
Python源码 我的Python版本3.12.7
import fitz
import re
import pandas as pd
import glob
from pathlib import Path
def extract_amount_from_filename(filename):
"""从文件名中提取金额(如'人参185元.pdf'返回185)"""
match = re.search(r'(\d+(?:\.\d+)?)元', filename)
return float(match.group(1)) if match else None
def process_single_pdf(pdf_path):
"""处理单个PDF文件"""
# 初始化列表
dates = []
company_names1 = [] # 包含银行
goods_services = []
prices = []
tax_rates = []
# 从文件名提取金额
filename_amount = extract_amount_from_filename(Path(pdf_path).name)
doc = fitz.open(pdf_path)
for page in doc:
text = page.get_text()
# 1. 提取日期 逻辑可以自己拓展
date_match = re.search(r"开票日期[::]\s*(\d{4}[年\-/]\d{1,2}[月\-/]\d{1,2}日?)", text) or \
re.search(r"\s*(\d{4}[年\-/]\d{1,2}[月\-/]\d{1,2}日?)", text)
if date_match:
dates.append(date_match.group(1))
# 2. 提取公司名称(保持不变) 逻辑可以自己拓展
companies = re.findall(r"([^\n::]*[公司经营部][^\n::]*)", text) or \
re.findall(r"名\s*称[::]\s*([^\n]+)", text)
if companies:
company_names1.extend([c.strip() for c in companies if len(c) > 2])
# 3. 提取货物或服务名称(保持不变)逻辑可以自己拓展
goods = re.findall(r"\*[\w\u4e00-\u9fa5]+\*[\w\u4e00-\u9fa5]+", text) or \
re.findall(r"\s*([^\n]+)", text)
if goods:
goods_services.extend(goods)
# 4. 提取价格(获取发票中最大的金额作为对比基准)逻辑可以自己拓展
amount_matches = re.finditer(r"[$¥¥]\s*(\d+\.?\d*)", text) or \
re.finditer(r"¥\s*(\d+\.?\d*)", text)
if amount_matches:
for match in amount_matches:
amount = float(match.group(1))
if amount > 1: # 过滤掉小于等于1的金额
prices.append(amount)
# 5. 提取税率(保持不变)逻辑可以自己拓展
taxes = re.findall(r"\s*(\d+\.?\d*)%", text) or \
re.findall(r"税额[::]\s*¥?\d+\.?\d*\s*\((\d+)%\)", text)
if taxes:
tax_rates.extend([f"{tax}%" for tax in taxes])
doc.close()
# 数据清洗(保持不变) 逻辑可以自己拓展
company_names = list(filter(lambda x: "银行" not in x and "其他" not in x, company_names1))
company_names = list(set(company_names)) # 去重
prices = sorted(prices, reverse=True) # 金额从大到小排序
# 计算差额(文件名金额 - 发票最大金额) 逻辑可以自己拓展
price_diff = None
if filename_amount and prices:
price_diff = round(filename_amount - max(prices), 2)
# 转换为DataFrame 逻辑可以自己拓展
max_len = max(len(dates), len(company_names), len(goods_services), len(prices), len(tax_rates))
data = {
"文件路径": str(pdf_path),
"发票命名金额提取": [filename_amount] + [None] * (max_len - 1),
"差额验证": [price_diff] + [None] * (max_len - 1),
"日期": dates + [None] * (max_len - len(dates)),
"公司名称": company_names + [None] * (max_len - len(company_names)),
"货物或服务名称": goods_services + [None] * (max_len - len(goods_services)),
"价格": prices + [None] * (max_len - len(prices)),
"税率": tax_rates + [None] * (max_len - len(tax_rates))
}
return pd.DataFrame(data)
# 主程序 逻辑可以自己拓展
if __name__ == "__main__":
pdf_files = glob.glob("./BOSS7月出差/7月发票/*.pdf") #PDF路径设置改这行,这里用显式相对路径,你们可改成绝对路径
if not pdf_files:
print("未找到PDF文件!")
exit()
base_df = process_single_pdf(pdf_files[0])
print(f"已处理: {Path(pdf_files[0]).name}")
for pdf_file in pdf_files[1:]:
try:
new_df = process_single_pdf(pdf_file)
base_df = pd.concat([base_df, new_df], ignore_index=True)
print(f"已处理: {Path(pdf_file).name}")
except Exception as e:
print(f"处理失败: {pdf_file} - {str(e)}")
# 保存结果 输出路径 改成自己路径单反斜杆\记得加r,否则必加双反斜杆\\,我这里为了省事用了相对路径
base_df.to_excel("批量提取BOSS出差发票数据.xlsx", index=False)
print(f"\n处理完成!共处理 {len(pdf_files)} 个PDF")
[--------------------------------------------------------------]以下是运行截图
文件名扫描金额提取,其他发票项目提取
💥关键错的那个还是人参😂!老板气虚买药材,莫名撞我野路子领域🌿… (老板买的什么药,我反向快速推断🔍…这里不展开了,老板自尊心受30倍暴击💔) ——本怪蜀黎凭借《神农本草经》野路子,一眼看穿他买的啥药方子🧪 (但我不敢说,怕他下次给我穿小鞋👞)」
⛑️温馨提示: AI写的复杂正则准确率不高❌,建议自己夯实基础📚! (普通正则➡️国际正则,末尾有我的正则文章📖👇)
🏢实力晒图: 以下是我亲自操刀做账的公司💼,学会精髓后10几家量大账随便扛🦾! (但建议挑账不混乱的公司接✅,太乱的纠错费时间⏳)
👩💼财务小姐姐需特别注意的亮点👇:
price_diff = round(filename_amount - max(prices), 2) # 金额差额自检,防财务失血🩸
company_names = list(filter(lambda x: "银行" not in x, company_names1)) # 剔除银行干扰🏦
[------------------------------------------------------------------]
⚠️重要提示一:Python坐标抓捕法实测劝退
「本人亲测:用坐标定位提取发票数据(如page.search_for()+矩形框抓捕)🧭
——代码调试难度极大🔧,肉眼对齐像素点看到头晕👁️,且发票格式一变直接崩盘💥
结论:正则虽野,但专治各种排版花里胡哨!」
[------------------------------------------------------------------]
📊重要提示二:Excel终极懒人包
「本脚本已实现:
✅ 文件名自动解析(如人参185元.pdf → 提取185)
✅ 文件名金额 vs 发票金额自动比对(防错差)
✅ 价税分离(税率单独提取)
✅ 公司名+货物名清洗(过滤银行干扰项)
👉输出Excel后——筛选即可用!零手工操作!」
👉若遇复杂发票,优先用文件名金额+最大金额双校验,人工兜底!
💡终极建议: 「财务人先用本脚本跑批量✅,再人工抽查关键大额发票🔍 ——效率提升90%!发际线保住了!💇♀️」 [------------------------------------------------------------------]
🎯嘲讽梗三连击:
对科班编程圈:「你们用设计模式,我用偏方代码——但老板只认结果✅」
对科班财务圈:「证书堆成山,不如我代码跑一遍⏰」
对科班中医圈:「把脉看气虚?我直接看发票就知道老板买了人参枸杞😂」
🚀「本怪蜀黎野生野长🌱,专治各种『科班不服』🎓」 (欢迎跨界追杀🏃,横竖你们也追不上我的发际线👴)」
[------------------------------------------------------------------]
🌟本蜀黎功德量化报告(走心加料版):
✅ 拯救发际线:100+条(每避免手动录入1张发票=挽救0.01根头发💇♀️,按此推算已守护一片黑森林🌳)
✅老肝能量释放:200+小时 (财务圈集体提前下班⏰,陪对象/娃/猫时间++,家庭和谐度直接拉满🏡)
✅拯救职场爱情:N对 (程序猿借代码秀操作撩动财务妹❤️,成就“发票姻缘”佳话—— “那年报销季,TA用Python帮我验票…”)
✅欢乐普渡:功德无量
(各位打工人看完本座故事,欢乐指数++++📈,摸鱼时间笑声溢出屏幕😂,
建议HR纳入员工心理健康福利方案)
————————————————
⚠️ 免责声明(附因果律警告)
本代码已注入中医玄学能量,请谨慎使用:
- ✅ 允许白嫖,但白嫖不点赞可能导致:
- 下次面试官恰好问到这个算法
- 键盘自动打出
//这里感谢冷溪虎山老中医 - 奶茶精准洒在刚写好的代码上
- ✅ 允许商用,但商用不注明出处可能触发:
- 产品上线前夜突然出现递归栈溢出
- 数据库莫名存储君臣佐使字段
- ✅ 允许吐槽,但吐槽不带改进建议可能引发:
- 终生与边界条件相爱相杀
🚀 现在立即行动:
- 点赞 → 吸收本篇算法精华+怪蜀黎脑洞思维
- 收藏 → 避免日后求医无门
- 关注 → 接收更多「中医+代码」脑洞
- 评论区留言 → 领取你的专属「算法药方」
如有不对之处,欢迎评论区批评指出或者留言给我!✅✅
如果这份文章帮到了你,请点赞、收藏、关注三连!你们的支持,就是我继续‘炼丹’的动力🏆🏆!
✨碰到 其他卡顿问题| 其他数据抓取"正则"匹配问题? JetBrains 全家桶性能优化 ,点击以下链接👇👇直达其他爆款指南:
从ASCII到Unicode:"国际正则"|"表达式"跨国界实战指南(附四大语言支持对比+中医HIS类比映射表) - 掘金
"正则"|"表达式"?面试题必考的转义符/量词大全!这张表让我告别面试翻车(附记忆口诀->映射表)正则转义符映射表 “每 - 掘金
[---------------------------------------------------------------------------------------] ✨碰到其他卡顿问题? JetBrains 全家桶性能优化共 6 篇,点击以下链接👇👇直达其他爆款指南
IDEA 性能炸裂!手把手拆解我的 9GB 堆内存+G1GC 调参表(附详细注释,小白慎改)类别 参数 值 作用解析 适 - 掘金
PyCharm 卡成 PPT?Python 开发者必藏的 vmoptions 调优表(9GB 堆内存+JVM 终极配置,效率翻倍) - 掘金
WebStorm 卡成幻灯片?前端大佬都在偷学的 vmoptions 调优表(续集来了!IDEA/PyCharm 飞升后,轮到它起飞) - 掘金
GoLand 卡成幻灯片?Gopher 必藏的 vmoptions 调优表(续集:WebStorm 飞升后,轮到 Go 开发神器起飞) - 掘金
CLion 卡成幻灯片?C/C++ 开发者必看的 vmoptions 调优表(续集:GoLand 飞升后,轮到它起飞) - 掘金
DataGrip 用久了又卡又慢?JetBrains 家的数据库 IDE 怎么调优?看这篇就够了⚠⚠⚠根据电脑配置调整 - 掘金