CSV文件中包含随机的新行/拆分。为什么会这样?

时间:2015-08-18 06:17:04

标签: ruby-on-rails ruby csv

我正在使用Rails并生成每周一次的CSV电子邮件。

module CSVData
  class Report
    HEADER = ["url", "description", "title", "logo_url", "created_at"]

    attr_reader :start_date, :end_date, :file_name, :posts

    def initialize(time)
      @start_date = time - 7.days
      @end_date = time
      @file_name = "post_data_#{@end_date.strftime("%-m_%-d_%Y")}"
      @posts = Post.where(created_at: @start_date..@end_date)
    end

    def create_csv
      file = File.new(File.join(Dir.pwd, "/tmp/#{@file_name}.csv"), "w+")
      CSV.open(file, "wb") { |csv| write_data(csv) }
      file
    end

    def write_data(csv)
      csv << HEADER
      @posts.each do |post|
        csv << data_row(post)
      end
      csv
    end

    def data_row(post)
      description = post.description || ""
      description = "\"" + description.gsub("\"", "\"\"") + "\""
      description = description.squish

      ["http://#{ENV['HOST']}/#{post.slug}",
      description,
      post.title,
      "http://#{ENV['HOST']}#{post.author.logo.url(:thumb)}",
      post.created_at.strftime("%m/%d/%Y %H:%M")]
    end
  end
end

邮件程序

  def post_data_email
    time = Time.now
    @file = CSVData::Report.new(time).create_csv
    attachments["Post_Data_#{time.strftime("%m_%d_%Y")}.csv"] = {
      :content => @file.read
    }

    ## Mail details
  end

当我在开发中运行它时效果很好,CSV文件很好。然而,生产中的自动化(带有“每当宝石”)电子邮件有一些奇怪的错误,其中数据被分割到换行符。通常在“url”,“description”或“logo_url”

有时在描述的中间它会跳转到一个新的行

http://...,"""Here is a description that will be fine and then just 

 jump to a new line.""",Post Title,http://...thumb.jpg?1,08/14/2015 16:27

这个跳跃在logo_url

的中间
"Everything fine until here",http://example.com/logos/1441/thumb.png?143

 9262835,08/11/2015 10:17

一行在开头缺少“ht”。

tp://example.com/post,## the rest of the line is fine

这让我很困惑。知道什么可能导致这样的事情吗?

编辑:我已根据评论进行了更改,但仍然出现相同的错误。 Here is an image.

邮件程序

  def post_data_email
    time = Time.now
    @file = CSVData::Report.new(time).create_csv
    attachments["Post_Data_#{time.strftime("%m_%d_%Y")}.csv"] = {
      :content => File.read(@file.path)
    }

    ## Mail details
  end

create_csv和write_data方法已更改

def create_csv
  csv_string = CSV.generate(write_headers: true, headers: HEADER) { |csv| write_data(csv) }
  file = File.new(File.join(Dir.pwd, "/tmp/#{@file_name}.csv"), "w+")
  file.write(csv_string)
  file.close
  file
end

def write_data(csv)
  @posts.each do |post|
    csv << data_row(post)
  end
  csv
end

1 个答案:

答案 0 :(得分:0)

根据RFC 821: SMTP,电子邮件附件将被剪切为1000个字符。

  

文字行

     

包含文本行的最大总长度       是1000个字符(但不包括领先      点复制透明度。)

解决方案是将附件编码为base64:

#BtnResubmit

How to send a csv attachment with lines longer than 990 characters?

无耻地复制