【问题标题】:CSV file has random new lines / splits in it. Why is this happening?CSV 文件中有随机的新行/拆分。为什么会这样?
【发布时间】:2015-08-18 06:17:04
【问题描述】:

我正在使用 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 文件也很好。但是,生产中的自动化(使用“每当 gem”)电子邮件在数据被拆分到换行符时存在一些奇怪的错误。通常在“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

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

编辑:我已经根据 cmets 进行了更改,但仍然出现相同的错误。

邮递员

  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

【问题讨论】:

  • 不要将CSV.open 与打开的File 一起使用。将它与字符串 filename 一起使用。并重构一切。
  • @pguardiario 我尝试更改它以使其无法打开已打开的文件(请参阅编辑),但仍然无法正常工作。
  • 你能提供更多关于自动化的细节吗?它是一个cronjob吗?如果是这样,您使用的是哪种服务器?

标签: ruby-on-rails ruby csv


【解决方案1】:

根据RFC 821: SMTP,邮件附件在1000个字符处被截断。

文本行

文本行的最大总长度,包括 是 1000 个字符(但不包括前导 点复制以提高透明度)。

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

attachments["Post_Data_#{time.strftime("%m_%d_%Y")}.csv"] = {
  :data=> ActiveSupport::Base64.encode64(File.read(@file.path)),
  :encoding => 'base64'
}

无耻抄袭How to send a csv attachment with lines longer than 990 characters?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-26
    • 1970-01-01
    • 2013-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多