帮财务小姐姐写了几个 Python 自动化脚本,结果...
平平无奇的一个下午,我正摸鱼刷手机,突然财务小姐姐拍了下我肩膀,一脸无奈地说:“救救我吧,我每周都要点鼠标点到怀疑人生。”我还以为又是报销啥复杂流程,结果她说她要的其实是:监控文件夹,自动处理PDF,补充业务信息,最后生成个报告发给领导。我一听乐了,这不正是Python的主场嘛。
第一步就是文件夹监控。她那个目录每天都会丢各种文件进去,发票PDF、Excel、甚至JPG,简直像个垃圾桶。我就写了个watchdog脚本,监听到有新文件就处理,非PDF直接忽略。那天她在旁边看,看到日志里打印“❌ 忽略文件: photo.jpg”,立刻知道是谁乱丢东西,当场笑出声。
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
import time, osclassHandler(FileSystemEventHandler):
defon_created(self, event):
ifnot event.is_directory:
if event.src_path.endswith(".pdf"):
print("✅ 处理文件:", event.src_path)
else:
print("❌ 忽略文件:", event.src_path)
observer = Observer()
observer.schedule(Handler(), path="invoices", recursive=False)
observer.start()
try:
whileTrue:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
监控有了,接下来就是解析PDF。她之前每周都得手工把发票金额抄到Excel,整整一个小时。我直接用pdfplumber扒数据,再用pandas聚合。结果Excel一导出,她激动得喊“卧槽这太爽了”。
import pdfplumber, pandas as pd, globrecords = []
for pdf_file in glob.glob("invoices/*.pdf"):
with pdfplumber.open(pdf_file) as pdf:
for page in pdf.pages:
table = page.extract_table()
if table:
for row in table[1:]: # 跳过表头
date, amount = row[0], float(row[1])
records.append({"日期": date, "金额": amount})
df = pd.DataFrame(records)
daily = df.groupby("日期").sum().reset_index()
daily.to_excel("output/每日汇总.xlsx", index=False)
有一次更复杂,她说发票里只有客户号,领导要的报告必须带客户全名。我一开始写了个字典映射,后来嫌麻烦,干脆让她自己维护个Excel。代码跑的时候自动去查,空的就标“未知”。她看完直接拍桌子说:“这比我抄快一百倍。”
customers = pd.read_excel("客户信息.xlsx") # 两列:客户号、客户名
cust_map = dict(zip(customers["客户号"], customers["客户名"]))df["客户名"] = df["客户号"].map(cust_map).fillna("未知")
最后一步就是生成周报并发邮件。她原来打算用U盘拷给领导,我直接写了个邮件发送。第一次她不敢点,怕炸了老板邮箱,笑死。
import smtplib
from email.message import EmailMessagemsg = EmailMessage()
msg["Subject"] = "周报"
msg["From"] = "[email protected]"
msg["To"] = "[email protected]"
msg.set_content("领导好,附件是最新周报。")
with open("output/周报.xlsx", "rb") as f:
msg.add_attachment(f.read(), maintype="application", subtype="octet-stream", filename="周报.xlsx")
with smtplib.SMTP("smtp.example.com", 587) as server:
server.login("[email protected]", "password")
server.send_message(msg)
不过也不是没翻过车。有次PDF里日期格式不对,脚本直接崩。她当场吓得不敢再用。我就加了个异常处理,坏数据跳过,还顺便写个日志。
bad_rows = []
for row in table[1:]:
try:
date, amount = row[0], float(row[1])
records.append({"日期": date, "金额": amount})
except Exception as e:
bad_rows.append({"row": row, "error": str(e)})if bad_rows:
pd.DataFrame(bad_rows).to_csv("output/错误日志.csv", index=False)
这样她再跑的时候,就算遇到问题也只是生成一个“错误日志.csv”,心里就安稳多了。她说:“这才靠谱嘛。”
更搞笑的是,小姐姐第一次尝到甜头之后就上瘾了,隔三岔五跑来加需求:能不能自动对账?能不能发现异常数据就直接短信提醒?我笑着说,再这么搞下去,你这就是在养一个“财务机器人”啊。她还特别认真点头:“那不是更好嘛!”
说实话,这些代码在我们眼里都挺基础的,但真能帮到别人,成就感爆棚。印象最深的一次,她周一上午十点才来找我,说十点半要把数据交给领导。我脚本一跑,十分钟搞定,她当场感叹“你是神”。我说别神不神的,下次请我喝咖啡就行。
写到最后我才发现,这些小脚本其实比大项目更能让我开心。因为它们真的改变了一个人的工作方式,让一个原本每周都要熬夜加班的人,能提早去喝奶茶。而且顺带也让我体会到,写代码不光是给服务器跑性能测试,很多时候就是帮身边人解决最琐碎的痛点。
-END-
我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html
虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB,点击下方公众号回复关键字 python 全部免费领