class Roo::Base
Attributes
partial_match[RW]
changes:
-
added option :partial_match to allow to use headers that only partially match the query
-
added option :required_headers to force the result to have at least these columns
-
allow option :headers to contain an array with header labels that will be forced when no header row is found
-
improved proper range scanning (first_row->last_row and first_column->last_column)
Public Instance Methods
each(options = {}) { |row(line)| ... }
click to toggle source
# File lib/libis/tools/extend/roo.rb, line 18 def each(options = {}) return to_enum(:each, options) unless block_given? @partial_match = options.delete(:partial_match) if options.has_key?(:partial_match) required_headers = options.delete(:required_headers) if options.has_key?(:required_headers) if options.empty? first_row.upto(last_row) do |line| yield row(line) end else clean_sheet_if_need(options) @headers = search_or_set_header(options) if required_headers raise Roo::HeaderRowIncompleteError unless headers.keys & required_headers == required_headers end header_line.upto(last_row) do |line| yield(headers.each_with_object({}) { |(k, v), hash| hash[k] = cell(line, v) }) end end end
Private Instance Methods
row_with(query)
click to toggle source
# File lib/libis/tools/extend/roo.rb, line 43 def row_with(query) line_no = first_row each do |row| headers = query.map { |q| row.grep(q)[0] }.compact if headers.length == query.length @header_line = line_no return headers elsif line_no > 100 raise Roo::HeaderRowNotFoundError elsif headers.length > 0 # partial match @header_line = line_no raise Roo::HeaderRowIncompleteError unless partial_match return headers end line_no += 1 end raise Roo::HeaderRowNotFoundError end
search_or_set_header(options)
click to toggle source
# File lib/libis/tools/extend/roo.rb, line 64 def search_or_set_header(options) force_headers = options.delete(:headers) if options[:header_search] row_with(options[:header_search]) elsif [:first_row, true].include?(force_headers) @header_line = first_row else return set_headers(options) end return Hash[row(header_line).map { |x| [x, header_index(x)] }] rescue Roo::HeaderRowNotFoundError => e # Not OK unless a list of headers is supplied raise e unless force_headers.is_a?(Array) # Force the headers in the order they are given, but up to the last column @header_line = first_row - 1 return Hash[force_headers.zip(first_column..last_column)].cleanup end
set_headers(hash)
click to toggle source
# File lib/libis/tools/extend/roo.rb, line 82 def set_headers(hash) # try to find header row with all values or give an error # then create new hash by indexing strings and keeping integers for header array row_with(hash.values) positions = Hash[row(header_line).map { |x| [x, header_index(x)] }] Hash[positions.map { |k, v| [hash.invert[k] || k, v] }] end