我试图上传一个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: '')
由于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