ruby - 如何在 Roo (Rails) : invalid byte sequence in UTF-8 中编码 csv 文件

标签 ruby ruby-on-rails-3 csv encoding

我正在尝试上传一个 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: '')

另见 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', '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

关于ruby - 如何在 Roo (Rails) : invalid byte sequence in UTF-8 中编码 csv 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22325343/

相关文章:

ruby-on-rails - Model.find_by_sql 与 connection.query,哪个更好?

ruby - 如何判断某个方法是在哪个版本的 Ruby 中首次引入的?

Mac/Linux 和 Windows 上的 Ruby GUI 开发

ruby - 如何将其他 Rack 应用程序(例如 Grape API)挂载到 Padrino 应用程序?

php - CSV 导入大照片时出现 500 内部服务器错误

python - 带有 pandas 的 CSV 副本

c# - 在多值列上写入不带引号的 CSV

Ruby 字符串替换

ruby-on-rails - 从 Controller 请求对象中获取 Authorization header 的正确方法是什么?

ruby-on-rails - ruby rails : Getting an extra record that is nil?