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



我试图上传csv文件,但在UTF-8错误中获得无效字节序列。我使用'roo' gem.

我的代码是这样的:
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, nil, :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: '')

也可以看这篇博文。

由于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', 'binary', invalid: :replace, undef: :replace, 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,csv_options: {encoding: Encoding::UTF_8})
      when ".xls" then
        Roo::Excel.new(file.path, nil, :ignore)
      when ".xlsx" then
        Roo::Excelx.new(file.path, nil, :ignore)
      else
        raise "Unknown file type: #{original_filename}"
    end
  end
end

相关内容

  • 没有找到相关文章

最新更新