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

Django发送压缩XLS文件附件失败问题咨询

我来帮你排查下问题,以及给出修复方案:

问题出在哪?

你在压缩文件时的操作犯了两个关键错误:

  • 复用了存储Excel内容的StringIO对象f:当用zipfile.ZipFile(f, mode='w')打开这个对象时,写模式会直接清空f里原来的Excel数据,后续你再调用f.getvalue()拿到的已经不是你要压缩的Excel内容了。
  • 没有处理StringIO的指针位置:就算你先拿到了Excel内容,写完zip后如果不把指针移到开头,邮件附件可能会读取到空内容(虽然getvalue()不受指针影响,但这是个容易踩的坑)。

修复后的完整代码

正确的做法是用两个独立的StringIO对象分别存储Excel和压缩后的zip数据,避免互相干扰:

import xlwt
import StringIO
import zipfile
from django.core.mail import EmailMessage

work_book = xlwt.Workbook()
# 此处为Excel相关处理逻辑...
report_name = "do_something_%(username)s_%(current_date)s.xls"

# 第一步:把Excel内容写入单独的StringIO
excel_buffer = StringIO.StringIO()
work_book.save(excel_buffer)
excel_content = excel_buffer.getvalue()  # 先把Excel内容存下来,避免后续被覆盖

# 初始化邮件对象
message = EmailMessage(
    subject=u"Sample Title",
    body=u"Sample body",
    to=["test@company.com"])

# 第二步:创建新的StringIO来生成zip文件
zip_buffer = StringIO.StringIO()
with zipfile.ZipFile(zip_buffer, mode='w', compression=zipfile.ZIP_DEFLATED) as zf:
    # 将之前保存的Excel内容写入zip包,用原来的xls文件名
    zf.writestr(report_name, excel_content)

# 写完zip后,把指针移到缓冲区开头(getvalue()其实不受影响,但养成习惯更稳妥)
zip_buffer.seek(0)

# 附加zip文件到邮件,最好指定MIME类型让客户端正确识别
report_name_zip = 'do_something_%(username)s_%(current_date)s.zip'
message.attach(report_name_zip, zip_buffer.getvalue(), 'application/zip')

message.send()

几个关键细节

  • 分离缓冲区:用excel_buffer存Excel数据,zip_buffer存压缩后的数据,彻底避免数据被覆盖的问题。
  • 指定MIME类型:附加zip时加上application/zip类型,邮件客户端能直接识别这是压缩文件,不会出现无法打开的情况。
  • 指针位置处理:写入数据后调用seek(0)是IO操作的常规操作,虽然StringIO.getvalue()会返回全部内容,但如果后续改用read()方法就必须这么做,提前养成习惯能减少踩坑。

这样修改后,你应该就能正常收到带压缩Excel附件的邮件了。

内容的提问来源于stack exchange,提问作者ë..

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:45:37