如何发送行长超过 990 个字符的 csv 附件?

Posted

技术标签:

【中文标题】如何发送行长超过 990 个字符的 csv 附件?【英文标题】:How to send a csv attachment with lines longer than 990 characters? 【发布时间】:2012-05-11 05:25:09 【问题描述】:

好的。我认为这个问题与我的 rails 应用程序有关,但似乎与电子邮件附件的更深层次的工作有关。

我必须将一个 csv 文件从我的 rails 应用程序发送到一个仓库,该仓库负责履行我商店中的订单。仓库有CSV的格式,讽刺的是CSV文件的标题行超长(1000+个字符)。

当我收到测试电子邮件时,我在 csv 文件的标题行中发现了一个换行符,但我无法弄清楚它放在那里的内容。但是,一些谷歌搜索终于找到了原因:附件的行字符限制为 1000。为什么?我不知道。这看起来很荒谬,但我还是得以某种方式发送这个 csv 文件。

我尝试手动将附件的 MIME 类型设置为 text/csv,但这没有帮助。有人知道如何解决这个问题吗?

一些相关的谷歌搜索结果:http://www.google.com/search?client=safari&rls=en&q=csv+wrapped+990&ie=UTF-8&oe=UTF-8

更新

我尝试过像这样在 base64 中编码附件:

    attachments['205.csv'] = :data=> ActiveSupport::Base64.encode64(@string), :encoding => 'base64', :mime_type => 'text/csv'

这似乎没有什么不同。我通过 Mac 版 Sparrow 收到带有 me.com 帐户的电子邮件。我会尝试使用 gmail 的网络界面。

【问题讨论】:

您能否发布 ActionMailer 的代码(以及 CSV 数据生成)?我尝试使用CSV.generate 构建大于 1000 个字符的行,将生成的数据添加到 ActionMailer 的 attachments 部分并发送,但它没有重现您的问题。 不幸的是,即使使用您的代码,我仍然无法重现该问题。如果您只是保存 CSV 而不是通过电子邮件发送,那么换行符仍然存在吗?另外,您使用的是什么邮件服务器、邮件客户端和 CSV 查看器? 我正在通过 Heroku 使用 SendGrid 服务。在查看 csv 文件方面,我使用了 Numbers 以及简单的文本编辑器。文件中肯定有换行符。 如果我直接从本地 Rails 控制台将 csv 写入文件,则输出很好。所以看起来 CSV 生成本身没有问题。 【参考方案1】:

这似乎是因为 SendGrid 邮件服务器正在修改附件内容。如果您发送带有纯文本存储 mime 类型(例如 text/csv)的附件,它将每 990 个字符包装一次内容,如您所见。我认为这与RFC 2045/821有关:

    Content-Transfer-Encoding 头域

    许多可以通过电子邮件有效传输的媒体类型是 以“自然”格式表示为 8 位字符或二进制 数据。此类数据无法通过某些传输协议传输。 例如,RFC 821 (SMTP) 将邮件消息限制为 7 位 US-ASCII 行数不超过 1000 个字符的数据,包括任何尾随 CRLF 行分隔符。

    因此,有必要为定义一个标准机制 将此类数据编码为 7 位短线格式。适当的标签 以较少限制格式直接使用的未编码材料 限制较少的传输也是可取的。本文档 指定此类编码将由新的“Content- Transfer-Encoding”头域。该域尚未被定义 任何以前的标准。

如果您使用 base64 编码而不是默认的 7 位发送附件,则附件保持不变(不添加换行符):

attachments['file.csv']=  :data=> ActiveSupport::Base64.encode64(@string), :encoding => 'base64' 

【讨论】:

对,我确实遇到了那个文档。让我试试你的解决方案…… 我已使用您建议添加附件的行,但结果文件在我收到时未解码 - 它仍然是一系列 base64 值。 您发送到哪个电子邮件服务器,您是否使用 OSX mail.app 来阅读电子邮件?听起来 mail.app 在解码一些 base64 附件时有问题,但我目前无法访问 OSX 来测试它。在发布之前,我测试了使用 ActionMailer 通过 heroku/SendGrid 将附件发送到 gmail/hotmail/yahoo/smartermail 帐户,他们都正确解码了附件。您是在电子邮件中发送文本还是仅发送附件?另外,您确定添加了:encoding => 'base64' 部分吗? 不要添加:mime_type => 'text/csv'(正如您在问题更新中所做的那样),这会将:encoding 值设置回7 位,因此附件不会被解码。 好了,宝贝。谢谢!附件现在很好! (一旦达到时间限制,我将奖励赏金。从现在起 3 小时后)【参考方案2】:

您的数据中是否包含会导致这种情况的换行符?看看有没有

csv_for_orders(orders).lines.count == orders.count

如果是这样,一个快速/骇人听闻的修复可能会将您调用 values_for_line_item(item) 的位置更改为 values_for_line_item(item).map|c| c.gsub(/(\r|\n)/, '')(其他 line_item 调用也是如此)。

【讨论】:

我已经尝试过这些方面的东西,但让我试试你的具体例子,看看他们是否想出了任何东西。谢谢! 是的,看起来 csv 检查结果很好。行数正确。

以上是关于如何发送行长超过 990 个字符的 csv 附件?的主要内容,如果未能解决你的问题,请参考以下文章

将超过 255 个字符从 excel 导入到 sql server(上一个问题 - 如何使用 ssis 将文本限定 CSV 动态加载到 sql server)

android导出到csv并作为电子邮件附件发送

在 Javascript 中使用 GMAIL API 发送带有附件文件(超过 10 MB)的电子邮件

发送带有显示 base64 格式的附件 CSV 的邮件

包含扩展字符的 MIME 附件名称失败

从 html 表单发送带有 csv 附件的电子邮件