简体   繁体   中英

Reading and saving data from Excel file- How to parse a file - undefined method `to_f' for #<Array:0x1579b6a8>

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM