我的网站上有一个报告功能,可以通过电子邮件发送CSV附件.我最近注意到,如果其中一个字符串包含重音字符,我附加的CSV有额外的换行符.奇怪的是,如果字符串不包含任何重音,我看不到任何这些额外的换行符.
代码看起来有点像这样:
# -*- coding: utf8 -*-
import unicodecsv
from StringIO import StringIO
from django.core.mail import EmailMultiAlternatives
# Generating the CSV
csvfile = StringIO()
writer = unicodecsv.writer(csvfile, encoding='utf-8')
writer.writerow([u'Test', u'Linebreak è'])
writer.writerow([u'Another', u'line'])
# Email
msg = EmailMultiAlternatives(
'csv report',
'Here is your attached report',
'email@from.com',
'email@to.com'
)
msg.attach('your_report.csv', csvfile.getvalue(), 'text/csv')
msg.send()
用VIM打开文件向我展示了类似的东西:
Test,Linebreak è^M
Another,line
相比之下,如果CSV行包括:
writer.writerow([u'Test', u'Linebreak'])
writer.writerow([u'Another', u'line'])
附加的CSV将如下所示:
Test,Linebreak
Another,line
getvalue()似乎输出了正确的EOL格式化程序,但是一旦附加了文件,似乎就会出现这种情况.别人注意到了类似的问题吗?
(在Python 2.7上运行Django 1.6)
编辑:我找到了问题的根源.事实证明我正在使用sendgrid发送我的电子邮件,并且出于某种原因,当这个包含重音时,他们的系统会在我的CSV上添加额外的换行符……
最佳答案 根据评论者的要求,我将添加一个涉及Python的stamdard SMTP库而不是SendGrid的解决方案.
与OP的代码一样,我们使用unicode的CSV数据.在准备消息时,我们明确地将数据添加为UTF-8编码的文本附件,并构造消息对象,如下所示:
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
# Write CSV data ...
msg = MIMEMultipart()
msg['Subject'] = subject
msg['From'] = sender
msg['To'] = recipients
msg.preamble = subject + '\n'
# Message body
body = MIMEText(body, 'plain', 'utf-8')
# CSV data
csv = MIMEText(csvfile.getvalue(), 'csv', 'utf-8')
csv.add_header("Content-Disposition", "attachment",
filename=report_filename)
# Add body and attachment to message
msg.attach(body)
msg.attach(csv)
您可以在Python library documentation中阅读有关MIMEText的更多信息.我发现传递unicode字符串(而不是str / bytes)只要有正确的delcared字符集就可以工作.
此外,我必须指出,我不确定是否通过使用MIMEText附件或编码来解决换行问题.在OP的代码中使用MIMEText对象作为附件可能会解决问题.不过,我给你留下了实验.