I followed a tutorial on RailsCast about how to import data from Excel.
I would like to read my excel file and to tell him which information to read and save indicating the row to pick up. So I wrote something like that in my model (.rb) file:
def self.to_csv(options = {})
CSV.generate(options) do |csv|
csv<<column_names
all.each do |repartition|
csv<<repartition.attributes.values_at(*column_names)
end
end
end
def self.import(file)
#Ouverture du fichier
spreadsheet = open_spreadsheet(file)
#Lecture du fichier, lignes par lignes, en aveugle
(1..spreadsheet.last_row).each do |i|
@repartition=Repartition.new
@repartition.fond_repartition_id=spreadsheet.row(4)
@repartition.date_repartition=spreadsheet.row(3)
@repartition.AssetAllocCash=spreadsheet.row(5)
@repartition.AssetAllocEquity=spreadsheet.row(6)
@repartition.AssetAllocBond=spreadsheet.row(7)
@repartition.AssetAllocOther=spreadsheet.row(8)
#Sauvegarde de la ligne qui vient d'être lu
repartition.save!
#Depart prochaine ligne ou fin
end
end
def self.open_spreadsheet(file)
case File.extname(file.original_filename)
when ".csv" then Roo::Csv.new(file.path, options={})
when ".xls" then Roo::Excel.new(file.path, options={})
when ".xlsx" then Roo::Excelx.new(file.path, options={})
else raise "Unknown file type: #{file.original_filename}"
end
end
And I wrote this code in my controller
def import
Repartition.import(params[:file])
redirect_to upload_path, notice: "Répartition effectuée avec succès"
end
I have the error message :
NoMethodError in RepartitionsController#import
undefined method `to_f' for #<Array:0x1579b6a8>
All my data are float attributes. Why do I have this error ?
This is what worked for me. To parse my excel file I did the following steps.
I am using the gem roo. So in my GemFile is the line:
gem 'roo', '~>2.1.0'
Then I ran the command line:
bundle install
In my controller :
def import Repartition.import(params[:file]) redirect_to resultat_path, notice: "Répartition effectuée avec succès" end
Then in my model:
def self.open_file(file) case File.extname(file.original_filename) when ".csv" then Roo::Csv.new(file.path, options={}) when ".xls" then Roo::Excel.new(file.path, options={}) when ".xlsx" then Roo::Excelx.new(file.path, options={}) else raise "Unknown file type: #{file.original_filename}" end end def self.import(file_path) #Ouverture du fichier file = open_file(file_path) #Lecture du fichier (1..file.last_row).each do |i| row = file.row(i) @repartition=Repartition.new @repartition.fond_repartition_id=row[4] @repartition.date_repartition=row[3] @repartition.save! end end
Then to call the method, on the web page on which I want to interact, I wrote this:
<%= form_tag import_repartitions_path, multipart: true do %> <%= file_field_tag :file %> <%= submit_tag "Importer", class: "btn btn-primary" %> <% end %>
The mistake was that I forgot to write (first of all)
row = file.row(i)
Then what I tried to read had the wrong name. In the schema of my database I had migrate my table with attribute "date_repartitio" instead of "date_repartitio n " And the error to_f was saying that instead of reading "date_repartition" which is a float (not a datetime I know) it was reading "date_repartitio" which is actually nothing existing.
But with this I do not yet have the code to avoid creating an entity each time I run the import method.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.