没有使用 Roo gem / XLS、XLSX、CSV 文件导入将符号隐式转换为整数
no implicit conversion of Symbol into Integer using Roo gem / XLS, XLSX, CSV File imports
我在 rails 5 中使用 Roo Gem 来处理我的数据导入。
我的 CSV 导入工作正常,但我认为使用 XLS 和 XLSLX 效率更高,因为最终用户可以更好地使用它们,我可以提供样式化的导入模板供他们使用。
我尝试导入 sheet 时收到的错误如下:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"X1k7+P2+YQtxJiKzuHZeErDCybH5jjCC1k/Q4OQwVL3hZ+ZEBdkxy8b9vXzGeHXhiMAKbukxvKsVbrQHh4FDFA==", "file"=>#<ActionDispatch::Http::UploadedFile:0x007fadab626f00 @tempfile=#<Tempfile:/var/folders/5z/7q_phgfd14d1cpgcpgwrgrj80000gp/T/RackMultipart20160905-12928-1hbqlew.xlsx>, @original_filename="User_import_excel.xlsx", @content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", @headers="Content-Disposition: form-data; name=\"file\"; filename=\"User_import_excel.xlsx\"\r\nContent-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\r\n">, "commit"=>"Import"}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ORDER BY "users"."id" ASC LIMIT [["id", 1], ["LIMIT", 1]]
Completed 500 Internal Server Error in 16ms (ActiveRecord: 0.3ms)
TypeError (no implicit conversion of Symbol into Integer):
app/models/user.rb:58:in `new'
app/models/user.rb:58:in `open_spreadsheet'
app/models/user.rb:44:in `import'
app/controllers/users_controller.rb:71:in `import'
Rendering /Users/developer/.rvm/gems/ruby-2.3.1/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout
Rendering /Users/developer/.rvm/gems/ruby-2.3.1/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_source.html.erb
Rendered /Users/developer/.rvm/gems/ruby-2.3.1/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_source.html.erb (2.6ms)
Rendering /Users/developer/.rvm/gems/ruby-2.3.1/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb
Rendered /Users/developer/.rvm/gems/ruby-2.3.1/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (1.4ms)
Rendering /Users/developer/.rvm/gems/ruby-2.3.1/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
Rendered /Users/developer/.rvm/gems/ruby-2.3.1/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.1ms)
Rendered /Users/developer/.rvm/gems/ruby-2.3.1/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (49.8ms)
我面临的另一个问题是,当我尝试导入一个包含以前用户的 CSV 文件以批量更新它们时,它只是给我一个错误,提示该电子邮件已被占用。如果我也能得到有关此错误的帮助,那就太好了!
我的用户控制器导入操作:
def import
User.import(params[:file])
redirect_to users_path, notice: "Users successfully imported"
end
我的用户模型
# Accessible Attributes
def accessible_attributes
[:email, :f_name, :l_name, :telephone]
end
# XLSL Importer
def self.import(file)
spreadsheet = open_spreadsheet(file)
header = spreadsheet.row(1)
(2..spreadsheet.last_row).each do |i|
row = Hash[[header, spreadsheet.row(i)].transpose]
product = find_by_id(row["id"]) || new
product.attributes = row.to_hash.slice(*row.to_hash.keys)
product.save!
end
end
def self.open_spreadsheet(file)
case File.extname(file.original_filename)
when ".csv" then Roo::CSV.new(file.path, csv_options: {encoding: "iso-8859-1: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
如果您需要任何其他信息,请告诉我。如有任何帮助,我们将不胜感激!
EDIT # 1
原来我需要改变
when ".xls" then Roo::Excel.new(file.path, nil, :ignore)
到
when ".xlsx" then Roo::Excelx.new(file.path, file_warning: :ignore)
然后我不得不添加
gem 'roo-xls'
为了导入xls文件。
使用最新版本的 Roo,假设 file = params[:uploaded_file].path
在你的控制器中的某处,下面的代码对我有用)
def self.import(file)
spreadsheet = open_spreadsheet(file)
header = spreadsheet.row(1)
(2..spreadsheet.last_row).each do |i|
row = Hash[[header, spreadsheet.row(i)].transpose]
product = find_by_id(row["id"]) || new
product.attributes = row.to_hash.slice(*accessible_attributes)
product.save!
end
end
def self.open_spreadsheet(file)
case File.extname(file)
when ".csv" then Roo::CSV.new(file, headers: true)
when ".xls" then Roo::Excel.new(file, :ignore)
when ".xlsx" then Roo::Excelx.new(file, :ignore)
else raise "Unknown file type: #{file}"
end
end
我在 rails 5 中使用 Roo Gem 来处理我的数据导入。
我的 CSV 导入工作正常,但我认为使用 XLS 和 XLSLX 效率更高,因为最终用户可以更好地使用它们,我可以提供样式化的导入模板供他们使用。
我尝试导入 sheet 时收到的错误如下:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"X1k7+P2+YQtxJiKzuHZeErDCybH5jjCC1k/Q4OQwVL3hZ+ZEBdkxy8b9vXzGeHXhiMAKbukxvKsVbrQHh4FDFA==", "file"=>#<ActionDispatch::Http::UploadedFile:0x007fadab626f00 @tempfile=#<Tempfile:/var/folders/5z/7q_phgfd14d1cpgcpgwrgrj80000gp/T/RackMultipart20160905-12928-1hbqlew.xlsx>, @original_filename="User_import_excel.xlsx", @content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", @headers="Content-Disposition: form-data; name=\"file\"; filename=\"User_import_excel.xlsx\"\r\nContent-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\r\n">, "commit"=>"Import"}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ORDER BY "users"."id" ASC LIMIT [["id", 1], ["LIMIT", 1]]
Completed 500 Internal Server Error in 16ms (ActiveRecord: 0.3ms)
TypeError (no implicit conversion of Symbol into Integer):
app/models/user.rb:58:in `new'
app/models/user.rb:58:in `open_spreadsheet'
app/models/user.rb:44:in `import'
app/controllers/users_controller.rb:71:in `import'
Rendering /Users/developer/.rvm/gems/ruby-2.3.1/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout
Rendering /Users/developer/.rvm/gems/ruby-2.3.1/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_source.html.erb
Rendered /Users/developer/.rvm/gems/ruby-2.3.1/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_source.html.erb (2.6ms)
Rendering /Users/developer/.rvm/gems/ruby-2.3.1/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb
Rendered /Users/developer/.rvm/gems/ruby-2.3.1/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (1.4ms)
Rendering /Users/developer/.rvm/gems/ruby-2.3.1/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
Rendered /Users/developer/.rvm/gems/ruby-2.3.1/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.1ms)
Rendered /Users/developer/.rvm/gems/ruby-2.3.1/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (49.8ms)
我面临的另一个问题是,当我尝试导入一个包含以前用户的 CSV 文件以批量更新它们时,它只是给我一个错误,提示该电子邮件已被占用。如果我也能得到有关此错误的帮助,那就太好了!
我的用户控制器导入操作:
def import
User.import(params[:file])
redirect_to users_path, notice: "Users successfully imported"
end
我的用户模型
# Accessible Attributes
def accessible_attributes
[:email, :f_name, :l_name, :telephone]
end
# XLSL Importer
def self.import(file)
spreadsheet = open_spreadsheet(file)
header = spreadsheet.row(1)
(2..spreadsheet.last_row).each do |i|
row = Hash[[header, spreadsheet.row(i)].transpose]
product = find_by_id(row["id"]) || new
product.attributes = row.to_hash.slice(*row.to_hash.keys)
product.save!
end
end
def self.open_spreadsheet(file)
case File.extname(file.original_filename)
when ".csv" then Roo::CSV.new(file.path, csv_options: {encoding: "iso-8859-1: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
如果您需要任何其他信息,请告诉我。如有任何帮助,我们将不胜感激!
EDIT # 1
原来我需要改变
when ".xls" then Roo::Excel.new(file.path, nil, :ignore)
到
when ".xlsx" then Roo::Excelx.new(file.path, file_warning: :ignore)
然后我不得不添加
gem 'roo-xls'
为了导入xls文件。
使用最新版本的 Roo,假设 file = params[:uploaded_file].path
在你的控制器中的某处,下面的代码对我有用)
def self.import(file)
spreadsheet = open_spreadsheet(file)
header = spreadsheet.row(1)
(2..spreadsheet.last_row).each do |i|
row = Hash[[header, spreadsheet.row(i)].transpose]
product = find_by_id(row["id"]) || new
product.attributes = row.to_hash.slice(*accessible_attributes)
product.save!
end
end
def self.open_spreadsheet(file)
case File.extname(file)
when ".csv" then Roo::CSV.new(file, headers: true)
when ".xls" then Roo::Excel.new(file, :ignore)
when ".xlsx" then Roo::Excelx.new(file, :ignore)
else raise "Unknown file type: #{file}"
end
end