You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

发送多附件邮件时附件名丢失变为ATT00001.xlsx求助

解决邮件附件文件名变为ATT00001.xlsx的问题

我看到你已经尝试添加邮件正文,但问题依然存在——核心问题出在你把附件的Content-Disposition头加到了整个MIMEMultipart邮件对象上,而不是每个单独的附件对象上。这会导致邮件客户端无法正确识别每个附件的文件名,从而用默认的ATT00001这类名称替代。

错误代码的问题点

在你的循环里,这行代码是错误的:

msg.add_header('Content-Disposition', 'attachment', filename=file_name)

你把附件的 disposition 头加到了整个邮件(msg)上,而不是当前处理的attachment对象。每个附件都需要自己独立的Content-Disposition头来声明文件名。

修正后的完整代码

把设置头的代码移到每个附件对象上,同时优化一些细节(比如文件名的获取、content_type的处理):

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
from email.utils import encode_rfc2231

msg = MIMEMultipart()
msg['Subject'] = subject
msg['To'] = 'abc@sample.com'
msg['From'] = sender

# 添加邮件正文
body_part = MIMEText(body, 'plain')
msg.attach(body_part)

for file_path in file_paths:
    # 更简洁的文件名获取方式
    file_name = file_path.split('/')[-1]
    
    # 打开附件文件
    fp = open(file_path, 'rb')
    # 这里建议根据每个文件的实际类型设置maintype和subtype,而不是统一用一个ctype
    # 如果不确定类型,可以用application/octet-stream作为通用类型
    attachment = MIMEBase('application', 'octet-stream')
    attachment.set_payload(fp.read())
    fp.close()
    
    # 编码附件内容
    encoders.encode_base64(attachment)
    
    # 给当前附件设置Content-Disposition头,处理特殊字符(比如中文)
    attachment.add_header(
        'Content-Disposition',
        'attachment',
        filename=encode_rfc2231(file_name, charset='utf-8')
    )
    
    # 将附件添加到邮件对象
    msg.attach(attachment)

# 发送邮件
smtp_client = smtplib.SMTP(f"{smtp_host}:{smtp_port}")
smtp_client.starttls()
smtp_client.login(sender, smtp_login_password)
smtp_client.sendmail(sender, 'abc@sample.com', msg.as_string())
smtp_client.quit()

额外注意事项

  • 文件名编码:如果文件名包含中文或特殊字符,使用encode_rfc2231可以确保邮件客户端正确解析文件名,避免乱码或无法识别的问题。
  • Content-Type匹配:如果你的附件是特定类型(比如xlsx、pdf),最好根据文件扩展名获取对应的content_type,而不是用通用的application/octet-stream。可以用mimetypes模块自动获取:
    import mimetypes
    ctype, encoding = mimetypes.guess_type(file_path)
    if ctype is None or encoding is not None:
        ctype = 'application/octet-stream'
    maintype, subtype = ctype.split('/', 1)
    attachment = MIMEBase(maintype, subtype)
    
  • 避免重复设置头:不要在MIMEMultipart对象上设置附件相关的头,所有附件的属性都应该绑定到各自的MIMEBase对象上。

内容的提问来源于stack exchange,提问作者abhijit nag

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 12:22:28