
本文介绍如何在基于win32com的outlook邮件发送脚本中,以最小侵入方式集成pdf等文件附件功能,同时保留原有csv解析逻辑和html签名嵌入机制。
本文介绍如何在基于win32com的outlook邮件发送脚本中,以最小侵入方式集成pdf等文件附件功能,同时保留原有csv解析逻辑和html签名嵌入机制。
在使用 win32com.client 调用 Outlook 发送批量邮件时,为每封邮件附加 PDF 文件(如合同、通知单或展会指南)是一项常见需求。关键在于:不破坏现有 CSV 解析与条件筛选逻辑,仅扩展邮件构造环节。以下提供一套稳健、可复用的实现方案。
✅ 核心改进:增强 send_email() 函数
我们将原函数升级为支持可选附件路径,并加入存在性校验与错误防护:
import os
import win32com.client as win32
import pandas as pd
import datetime
def send_email(to, body, subject, attachment_path=None):
mail = outlook.CreateItem(0)
mail.To = to
mail.Subject = subject
# 1. 嵌入签名Logo(保持原有逻辑)
logo_path = "C:/Users/User/AppData/Local/Programs/Python/Python311/my_sig_files/logo.png"
if os.path.exists(logo_path):
logo_attachment = mail.Attachments.Add(logo_path)
logo_attachment.PropertyAccessor.SetProperty(
"http://schemas.microsoft.com/mapi/proptag/0x3712001FFS", "my_sig"
)
else:
raise FileNotFoundError(f"Logo file not found: {logo_path}")
# 2. 动态添加PDF或其他附件(新增逻辑)
if attachment_path:
if os.path.exists(attachment_path):
mail.Attachments.Add(attachment_path)
else:
print(f"[WARN] Attachment not found: {attachment_path} — skipping.")
# 3. 组装HTML正文(含内联图片)
mail.HTMLBody = body + "@@##@@"
mail.Send()
? 注意:
0x3712001FFS是 Outlook 的 CID 属性标识符(实际应为0x3712001F,原文中的FFS系笔误),正确写法如下:"http://schemas.microsoft.com/mapi/proptag/0x3712001F"
? 调用示例(无缝接入原流程)
在主循环中,只需传入附件路径即可——其余逻辑完全不变:
# 示例:统一附加同一份PDF
pdf_path = "C:/Users/User/Documents/exhibitor_guide.pdf"
for index, row in df.iterrows():
if row['check_on'] == today and row['designation'] == "auto" and row['action'] == "send":
to = row['email_address']
body = email_template # 可在此处动态插入客户姓名等变量
subject = "Exhibitor Email"
# ✅ 一行调用,支持附件
send_email(to, body, subject, pdf_path)
# 更新CSV状态
df.at[index, 'check_on'] = (datetime.datetime.today() + datetime.timedelta(days=28)).strftime('%m/%d/%Y')
df.at[index, 'action'] = 'sent'
df.to_csv('exhibitorlist.csv', index=False)
⚠️ 重要注意事项
- 路径安全性:确保附件路径为绝对路径,且 Python 进程有读取权限;避免使用用户输入直传路径,防止路径遍历风险。
-
大文件限制:Outlook 默认附件上限通常为 20MB,超限将静默失败。建议在调用前检查文件大小:
if attachment_path and os.path.getsize(attachment_path) > 20 * 1024 * 1024: print(f"[SKIP] File too large: {os.path.basename(attachment_path)}") continue -
异常处理增强(推荐):生产环境建议包裹
mail.Send()并捕获pywintypes.com_error,记录失败邮箱与原因。 -
替代方案提示:若需跨平台(非Windows)或规避Outlook依赖,可改用
smtplib+email.mime构建 MIME 邮件,但需配置SMTP服务器及认证。
通过以上改造,您在零改动 CSV 解析、条件过滤与状态更新逻辑的前提下,成功赋予脚本灵活的附件能力——兼顾简洁性、健壮性与可维护性。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











