自动生成打车报销PDF
前言🥴
公司打车需要报销,需要发票与行程单一一对应并打印,行程少手动问题不大,行程多起来,这个就耗费大量摸鱼时间,所以要想办法解决掉该问题。
常规步骤
- 前往高德找到对应行程开发票
- 邮箱找到邮件(每笔打车对应一个邮件),打开,分别点击下载行程单和发票两个附件
- 将发票和行程单规整,使得一一对应,找到PDF免费合并的在线网站进行合并打印
思考🧐
其实核心就是怎么才能自动化的下载,规整,以及合并。
实现🤪
通过获取邮箱授权码读取邮箱内容
将未读的邮件进行筛选
读取邮件内容进行附件提取
合并PDF
将邮件标记为已读
源码🤩
使用前提一定要保证发票邮件是未读的
import email
import imaplib
import os
from email.header import decode_header
from PyPDF2 import PdfMerger
# 连接到 QQ 邮箱的 IMAP 服务器
imap_server = "imap.qq.com"
user = "xxxx@qq.com"
password = "xxxxx"
# 查找特定主题的邮件
target_subject = '高德打车电子发票'
# 登录到邮箱
mail = imaplib.IMAP4_SSL(imap_server)
mail.login(user, password)
mail.select("inbox")
# 搜索邮件
def save_attachment(part):
# 检查是否有Content-Disposition且为attachment
if part.get("Content-Disposition") is None:
return
disp = part.get("Content-Disposition").split(";")
if disp[0].lower() != "attachment":
return
filename = part.get_filename()
if not filename:
return
# 解码文件名
filename = decode_header(filename)[0][0]
if isinstance(filename, bytes):
filename = filename.decode()
# 解码并保存附件
attachment_data = part.get_payload(decode=True)
filepath = os.path.join("./attachments", filename)
with open(filepath, "wb") as f:
f.write(attachment_data)
print(f"附件已下载到:{filepath}")
merger.append(filepath)
def search_mail():
# 使用SEARCH命令找到所有未读邮件
status, messages = mail.search(None, '(UNSEEN)')
# 邮件ID列表
id_list = messages[0].split() if messages[0] else []
# 遍历每一封邮件
for email_id in id_list:
status, msg_raw = mail.fetch(email_id, "(RFC822)")
for response_part in msg_raw:
if isinstance(response_part, tuple):
msg = email.message_from_bytes(response_part[1])
# 解码邮件主题
subject_header = decode_header(msg["subject"])
if subject_header:
subject, encoding = subject_header[0]
if isinstance(subject, bytes):
subject = subject.decode(encoding or 'utf-8')
# 检查邮件主题是否包含目标主题
if target_subject in subject:
# 遍历邮件的所有部分,查找附件
for part in msg.walk():
save_attachment(part)
# 标记为已读
mail.store(email_id, '+FLAGS', '\Seen')
if __name__ == '__main__':
merger = PdfMerger()
search_mail()
# 关闭连接
mail.close()
mail.logout()
if len(merger.pages) == 0:
print("没有找到附件")
exit(0)
merger.write("merged.pdf")
merger.close()
print("所有附件已合并为 merged.pdf")
效果😎
运行后,所有的发票和行程单都下载在附件下
打开merged.pdf,就是合并后的效果,且能发票行程一一对应
打印时选择一张多页即可
- 感谢你赐予我前进的力量
赞赏者名单
因为你们的支持让我意识到写文章的价值🙏
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 途深
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果