Rails中压缩CSV文件并邮件附件发送失败问题求助
兄弟,我之前踩过完全一样的坑!你遇到的乱码问题,本质是没给邮件附件做对「身份标识」,还有压缩数据的处理细节没到位——跟要不要生成物理文件没关系,内存里就能搞定。
问题出在哪?
1. 文件名和MIME类型没匹配压缩格式
你压缩后的内容本质是gzip包,但还是用了.csv后缀、没改MIME类型,邮件客户端会把它当成普通CSV解析,自然读出来是乱码!正确的做法是给附件加上.gz后缀,MIME类型设为application/gzip,这样客户端才知道这是个压缩包。
2. 压缩数据的编码没处理好
压缩后的内容是二进制流,直接塞给邮件附件可能会被当成文本编码处理,导致数据损坏。最好用StringIO包装一下,明确设置二进制编码。
正确的实现代码
假设你已经生成了正常的CSV文本内容,存在csv_content变量里:
# 1. 用ActiveSupport::Gzip压缩CSV内容 gzipped_data = ActiveSupport::Gzip.compress(csv_content) # 2. 用StringIO包装二进制数据,避免编码混乱 gzip_stream = StringIO.new(gzipped_data) gzip_stream.set_encoding('BINARY') # 3. 添加到邮件附件,注意文件名后缀和MIME类型 mail.attachments["user_data.csv.gz"] = { mime_type: 'application/gzip', content: gzip_stream.string }
现在发送的附件是user_data.csv.gz,现代邮件客户端会自动识别并解压,打开就是正常的CSV内容。
如果你非要用.csv后缀(不推荐)
如果因为业务需求必须保留.csv后缀,那得给附件加上gzip编码标识,但这种方式兼容性较差(比如老版本Outlook可能仍会乱码):
mail.attachments["user_data.csv"] = { mime_type: 'text/csv', content: gzipped_data, encoding: 'gzip' }
总结一下:核心是告诉邮件客户端“这是个压缩包”,不需要生成物理文件,用StringIO在内存处理压缩流就足够了。
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

