Jun*_*aid 8 ruby csv encoding ruby-on-rails-3
我试图上传一个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, nil, :ignore)
else
raise "Unknown file type: #{file.original_filename}"
end
end
end.
Run Code Online (Sandbox Code Playgroud)
我不知道如何编码csv文件.请帮忙!
谢谢
要将字符串安全地转换为utf-8,您可以执行以下操作:
str.encode('utf-8', 'binary', invalid: :replace, undef: :replace, replace: '')
Run Code Online (Sandbox Code Playgroud)
也看到这篇博文.
由于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
Run Code Online (Sandbox Code Playgroud)
您还需要更改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
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3406 次 |
最近记录: |