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

时间:2014-09-05 21:18:24

标签: python django csv unicode

我的网站上有一个报告功能,可以通过电子邮件发送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包含重音时,他们的系统会在我的CSV上添加额外的换行符......

2 个答案:

答案 0 :(得分:5)

根据评论者的要求,我将添加一个涉及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对象作为附件可能会解决问题。不过,我会给你留下实验。

答案 1 :(得分:2)

对于那些使用Sendgrid作为SMTP提供商向您发送电子邮件的人,如果您发现了类似的问题,我通过不使用SMTP而不是使用Sendgrid的Web API(通过https://github.com/elbuo8/sendgrid-django)解决了我的问题。

我的CSV报告中不再有额外的行了!