python – Django:包含Unicode字符的电子邮件附件中的CSV会导致额外的换行符

我的网站上有一个报告功能,可以通过电子邮件发送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对象作为附件可能会解决问题.不过,我给你留下了实验.

点赞