Using Column headers to parse excel sheets using roo - Ruby

12.2k views Asked by At

Can we use column headers to specify the column number from which we are parsing the excel sheet using roo gem? My current code is like this now:

oo = Openoffice.new("simple_spreadsheet.ods")
oo.default_sheet = oo.sheets.first
(2..oo.last_row).each do |line|
  date       = oo.cell(line,'A')
  start_time = oo.cell(line,'B')
  end_time   = oo.cell(line,'C')
  pause      = oo.cell(line,'D')
  ...
end

I would like to parse from column headers instead of specifying columns as 'A' 'B' 'C' ... Can I acheive this using Roo?

4

There are 4 answers

2
SamuraiJack On BEST ANSWER

You can grab the entire header row as an array and hash the entire row key'd on the header row.

oo = Openoffice.new("simple_spreadsheet.ods") 
oo.default_sheet = oo.sheets.first 
header = oo.row(1) 
2.upto(oo.last_row) do |line|  
  row_data =  Hash[header.zip oo.row(line)]
  ...
end

You could also use row_data[line] to nest the hashes for later use.

0
dabobert On

A cleaner/clearer version of the above is

oo = Openoffice.new("simple_spreadsheet.ods") 
oo.default_sheet = file.sheets.first 
header = oo.first_row 
2.upto(oo.last_row) do |line|  
  row_data =  Hash[*header.zip(row).flatten]
  ...
end

the original took me a bit to understand because especially as i thought hash was a local variable named hash instead of the class Hash

0
Aaron Henderson On

This will use the header row as the keys. The helpful parts are transpose and strip.

def self.excel_to_hash(folder_name, file_name, tab_name)
    # Takes an excel file name and a tab name, and returns an array of stripped, transposed rows
    # Sample call:  my_data = excel_to_hash File.join(Rails.root,'db/data/data_to_import.xlsx'), 'models'
    rows = []
    file = File.open(File.join(folder_name, file_name), mode = 'r')
    excel = Excelx.new(file.path, nil, :ignore)
    excel.default_sheet = excel.sheets.index(tab_name) + 1
    header = excel.row(1)
    (2..excel.last_row).each do |i|
      next unless excel.row(i)[0]
      row = Hash[[header, excel.row(i)].transpose]      
      row.each_key{|x| row[x] = row[x].to_s.strip if row[x]}
      rows << row
    end
    return rows
  end

valid through Roo gem 1.10.2

0
Ahtasham Naeem On

This works for me

 require 'roo'
    # open excel file
    excel_file = Roo::Spreadsheet.open(file_path)
      # iterate on each sheet
      excel_file.each_with_pagename do |name, sheet|
        # iterate on each sheet
        sheet.parse(headers: true, pad_cells: true) do |row|
          # data should be access by column header if we have column header Name we can access like this
          row['Name']
        end
      end
    end