ruby – 如何在Roo(Rails)中编码csv文件:UTF-8中的无效字节序列

我试图上传一个csv文件,但在UTF-8错误中获得无效的字节序列.我正在使用’roo’宝石.

我的代码是这样的:

def upload_results_csv file

    spreadsheet = MyFileUtil.open_file(file)
    header = spreadsheet.row(1) # THIS LINE RAISES THE ERROR

    (2..spreadsheet.last_row).each do |i|
      row = Hash[[header,spreadsheet.row(i)].transpose]
      ...
      ...
end

class MyFileUtil

  def self.open_file(file)
    case File.extname(file.original_filename)
      when ".csv" then
        Roo::Csv.new(file.path,csv_options: {encoding: Encoding::UTF_8})
      when ".xls" then
        Roo::Excel.new(file.path,nil,:ignore)
      when ".xlsx" then
        Roo::Excelx.new(file.path,:ignore)
      else
        raise "UnkNown file type: #{file.original_filename}"
    end
  end

end.

我不知道如何编码csv文件.请帮忙!

谢谢

解决方法

要将字符串安全地转换为utf-8,您可以:
str.encode('utf-8','binary',invalid: :replace,undef: :replace,replace: '')

另见this blog post.

由于roo gem只将文件名作为构造函数参数,而不是普通IO对象,我能想到的唯一解决方案是将一个已清理的版本写入临时文件并将其传递给roo,

require 'tempfile'

def upload_results_csv file
    tmpfile = Tempfile.new(file.path)
    tmpfile.write(File.read(file.path).encode('utf-8',replace: ''))
    tmpfile.rewind

    spreadsheet = MyFileUtil.open_file(tmpfile,file.original_filename)
    header = spreadsheet.row(1) # THIS LINE RAISES THE ERROR

    # ...
ensure
    tmpfile.close
    tmpfile.unlink
end

您还需要更改MyFileUtil,因为需要传递原始文件名:

class MyFileUtil
  def self.open_file(file,original_filename)
    case File.extname(original_filename)
      when ".csv" then
        Roo::Csv.new(file.path,:ignore)
      else
        raise "UnkNown file type: #{original_filename}"
    end
  end
end

相关文章

validates:conclusion,:presence=>true,:inclusion=>{...
一、redis集群搭建redis3.0以前,提供了Sentinel工具来监控各...
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣...
上一篇博文 ruby传参之引用类型 里边定义了一个方法名 mo...
一编程与编程语言 什么是编程语言? 能够被计算机所识别的表...
Ruby类和对象Ruby是一种完美的面向对象编程语言。面向对象编...