如何根据Excel人员名单匹配目录文件名批量发送带附件邮件
需求描述
- 存在Excel文件
em.xlsx,包含Name(姓名)、Email(邮箱地址)两列 - 指定目录下存放了若干文件,当文件名(不含后缀)和
Name列的姓名完全匹配时,需要将该文件作为附件,发送到对应行的邮箱地址
原有代码问题
代码运行无返回、无法实现预期效果,是因为存在多处逻辑和语法错误:
- 发邮件逻辑被放在
while name == os.path:判断块中,os.path是Python的路径处理模块,永远不可能等于姓名字符串,整个发邮件代码块从未被执行,这是无任何输出的核心原因 - 文件筛选逻辑矛盾:代码只扫描目录下
.csv后缀的文件,但构造附件时指定的文件子类型是xlsx,后缀不匹配 - 变量名混用:定义的邮件对象是
msg2,后续添加附件、发送邮件时用的是未定义的msg变量,就算判断成立也会抛出变量不存在的错误 - 路径拼接错误:打开附件时只传了文件名,没有拼接目录的完整绝对路径,会触发文件找不到的错误
- 附件头参数缺失:
Content-Disposition头没有指定filename字段,邮箱客户端无法正常识别附件名称 - 依赖导入不全:使用了
MIMEApplication类但没有导入对应模块 - 构造文件名字典时用
ChainMap属于冗余逻辑,可以直接简化
修正后可运行代码
import pandas as pd import smtplib import os from email.mime.multipart import MIMEMultipart from email.mime.application import MIMEApplication # 基础配置 请替换为实际参数 SMTP_HOST = '你的SMTP服务器地址' SMTP_PORT = 465 SENDER_EMAIL = '发件人邮箱地址' SENDER_PASS = '发件人邮箱SMTP授权码/密码' EXCEL_PATH = r'C:\Users\arabw\OneDrive\Bureau\html\em.xlsx' FILE_FOLDER = r'C:\Users\arabw\OneDrive\Bureau\html' # 要匹配的附件后缀,支持多后缀同时匹配,比如('.csv', '.xlsx') MATCH_FILE_SUFFIX = ('.csv', '.xlsx') # 读取Excel中姓名和邮箱的映射关系 email_list = pd.read_excel(EXCEL_PATH) # 扫描目录文件,构造 {无后缀文件名: 文件完整路径} 的映射字典 file_map = {} for file_name in os.listdir(FILE_FOLDER): file_path = os.path.join(FILE_FOLDER, file_name) if os.path.isfile(file_path) and file_name.endswith(MATCH_FILE_SUFFIX): name_without_suffix = os.path.splitext(file_name)[0] file_map[name_without_suffix] = file_path # 遍历每行数据匹配发件 for idx, row in email_list.iterrows(): name = str(row['Name']).strip() receiver_email = str(row['Email']).strip() # 无匹配文件直接跳过 if name not in file_map: print(f"未找到{name}对应文件,跳过") continue match_file_path = file_map[name] match_file_name = os.path.basename(match_file_path) print(f"匹配到{name}对应文件:{match_file_name},准备发送至{receiver_email}") # 构造邮件内容 msg = MIMEMultipart() msg['Subject'] = "您的对应资料附件" msg['From'] = SENDER_EMAIL msg['To'] = receiver_email # 添加附件 with open(match_file_path, 'rb') as f: file_suffix = os.path.splitext(match_file_name)[1].lstrip('.') attach = MIMEApplication(f.read(), _subtype=file_suffix) attach.add_header('Content-Disposition', 'attachment', filename=match_file_name) msg.attach(attach) # 执行发送 try: with smtplib.SMTP_SSL(SMTP_HOST, SMTP_PORT) as smtp: smtp.login(SENDER_EMAIL, SENDER_PASS) smtp.send_message(msg) print(f"给{name}的邮件发送成功") except Exception as e: print(f"给{name}发送邮件失败,错误信息:{str(e)}")
使用说明
- 请将代码开头配置项内的SMTP地址、发件邮箱、授权码替换为实际信息,注意大部分公共邮箱需要单独开启SMTP服务,登录时使用的是SMTP授权码而非邮箱网页登录密码
MATCH_FILE_SUFFIX参数根据实际要发送的附件后缀修改,支持同时匹配多种格式的文件- 代码添加了控制台打印和异常捕获,运行时可以直接看到匹配进度、发送成功/失败的提示,方便定位问题
- 对读取到的姓名、邮箱字段做了字符串转换和首尾空格去除处理,避免Excel单元格存在多余空格导致匹配失败
内容的提问来源于stack exchange,提问作者Yarzooo
相关产品推荐
相关产品推荐

