class Crek::Sheet
Attributes
Public Class Methods
# File lib/crek/sheet.rb, line 17 def initialize book, name, sheetid, state, visible, rid, sheetfile @book = book @name = name @sheetid = sheetid @visible = visible @rid = rid @state = state @sheetfile = sheetfile @images_present = false end
Public Instance Methods
Extracts images for a cell to a temporary folder. Returns array of Pathnames for the cell. Returns nil if images asre not found for the cell or images were not preloaded with with_images
.
# File lib/crek/sheet.rb, line 45 def images_at(cell) @drawing.images_at(cell) if @images_present end
Provides an Enumerator that returns a hash representing each row. The key of the hash is the Cell id and the value is the value of the cell.
# File lib/crek/sheet.rb, line 60 def rows rows_generator false, false end
Provides an Enumerator that returns a hash representing each row. The hash contains meta data of the row and a 'cells' embended hash which contains the cell contents.
# File lib/crek/sheet.rb, line 67 def rows_with_meta_data rows_generator true, false end
Provides an Enumerator that returns a hash representing each row. The key of the hash is the column ID and the value is the value of the cell.
# File lib/crek/sheet.rb, line 53 def simple_rows rows_generator false, true end
Provides an Enumerator that returns a hash representing each row. The hash contains meta data of the row and a 'cells' embended hash which contains the cell contents.
# File lib/crek/sheet.rb, line 74 def simple_rows_with_meta_data rows_generator true, true end
Preloads images info (coordinates and paths) from related drawing.xml and drawing rels. Must be called before rows
method if you want to have images included. Returns self so you can chain the calls (sheet.with_images.rows).
# File lib/crek/sheet.rb, line 32 def with_images @drawingfile = extract_drawing_filepath if @drawingfile @drawing = Crek::Drawing.new(@book, @drawingfile.sub('..', 'xl')) @images_present = @drawing.has_images? end self end
Private Instance Methods
# File lib/crek/sheet.rb, line 128 def convert(value, type, style_idx) style = @book.style_types[style_idx.to_i] Crek::Styles::Converter.call(value, type, style, converter_options) end
# File lib/crek/sheet.rb, line 133 def converter_options @converter_options ||= { shared_strings: @book.shared_strings.dictionary, base_date: @book.base_date } end
Find drawing filepath for the current sheet. Sheet
xml contains drawing relationship ID. Sheet
relationships xml contains drawing file's location.
# File lib/crek/sheet.rb, line 162 def extract_drawing_filepath # Read drawing relationship ID from the sheet. sheet_filepath = "xl/#{@sheetfile}" drawing = parse_xml(sheet_filepath).css('drawing').first return if drawing.nil? drawing_rid = drawing.attributes['id'].value # Read sheet rels to find drawing file's location. sheet_rels_filepath = expand_to_rels_path(sheet_filepath) parse_xml(sheet_rels_filepath).css("Relationship[@Id='#{drawing_rid}']").first.attributes['Target'].value end
The unzipped XML file does not contain any node for empty cells. Empty cells are being padded in using this function
# File lib/crek/sheet.rb, line 143 def fill_in_empty_cells(cells, row_number, last_col, use_simple_rows_format) new_cells = Hash.new unless cells.empty? last_col = last_col.gsub(row_number, '') ("A"..last_col).to_a.each do |column| id = use_simple_rows_format ? "#{column}" : "#{column}#{row_number}" new_cells[id] = cells[id] end end new_cells end
Returns a hash per row that includes the cell ids and values. Empty cells will be also included in the hash with a nil value.
# File lib/crek/sheet.rb, line 83 def rows_generator include_meta_data=false, use_simple_rows_format=false path = if @sheetfile.start_with? "/xl/" or @sheetfile.start_with? "xl/" then @sheetfile else "xl/#{@sheetfile}" end if @book.files.file.exist?(path) # SAX parsing, Each element in the stream comes through as two events: # one to open the element and one to close it. opener = Nokogiri::XML::Reader::TYPE_ELEMENT closer = Nokogiri::XML::Reader::TYPE_END_ELEMENT Enumerator.new do |y| row, cells, cell = nil, {}, nil cell_type = nil cell_style_idx = nil @book.files.file.open(path) do |xml| Nokogiri::XML::Reader.from_io(xml).each do |node| if (node.name.eql? 'row') and (node.node_type.eql? opener) row = node.attributes row['cells'] = Hash.new cells = Hash.new y << (include_meta_data ? row : cells) if node.self_closing? elsif (node.name.eql? 'row') and (node.node_type.eql? closer) processed_cells = fill_in_empty_cells(cells, row['r'], cell, use_simple_rows_format) if @images_present processed_cells.each do |cell_name, cell_value| next unless cell_value.nil? processed_cells[cell_name] = images_at(cell_name) end end row['cells'] = processed_cells y << (include_meta_data ? row : processed_cells) elsif (node.name.eql? 'c') and (node.node_type.eql? opener) cell_type = node.attributes['t'] cell_style_idx = node.attributes['s'] cell = node.attributes['r'] elsif (['v', 't'].include? node.name) and (node.node_type.eql? opener) unless cell.nil? cells[(use_simple_rows_format ? cell.tr("0-9", "") : cell)] = convert(node.inner_xml, cell_type, cell_style_idx) end end end end end end end