class Roo::Excelx::SheetDoc

Public Class Methods

new(path, relationships, styles, shared_strings, workbook, options = {}) click to toggle source
Calls superclass method Roo::Excelx::Extractor::new
# File lib/roo/excelx/sheet_doc.rb, line 5
def initialize(path, relationships, styles, shared_strings, workbook, options = {})
  super(path)
  @options = options
  @relationships = relationships
  @styles = styles
  @shared_strings = shared_strings
  @workbook = workbook
end

Public Instance Methods

cells(relationships) click to toggle source
# File lib/roo/excelx/sheet_doc.rb, line 14
def cells(relationships)
  @cells ||= extract_cells(relationships)
end
dimensions() click to toggle source

Get the dimensions for the sheet. This is the upper bound of cells that might be parsed. (the document may be sparse so cell count is only upper bound)

# File lib/roo/excelx/sheet_doc.rb, line 25
def dimensions
  @dimensions ||= extract_dimensions
end
each_cell(row_xml) { |cell_from_xml(cell_element, hyperlinks(relationships)[key])| ... } click to toggle source

Yield each cell as Excelx::Cell to caller for given row xml

# File lib/roo/excelx/sheet_doc.rb, line 36
def each_cell(row_xml)
  return [] unless row_xml
  row_xml.children.each do |cell_element|
    key = ::Roo::Utils.ref_to_key(cell_element['r'])
    yield cell_from_xml(cell_element, hyperlinks(@relationships)[key])
  end
end
each_row_streaming(&block) click to toggle source

Yield each row xml element to caller

# File lib/roo/excelx/sheet_doc.rb, line 30
def each_row_streaming(&block)
  Roo::Utils.each_element(@path, 'row', &block)
end

Private Instance Methods

cell_from_xml(cell_xml, hyperlink) click to toggle source
# File lib/roo/excelx/sheet_doc.rb, line 46
def cell_from_xml(cell_xml, hyperlink)
  # This is error prone, to_i will silently turn a nil into a 0
  # and it works by coincidence that Format[0] is general
  style = cell_xml['s'].to_i   # should be here
  # c: <c r="A5" s="2">
  # <v>22606</v>
  # </c>, format: , tmp_type: float
  value_type =
    case cell_xml['t']
    when 's'
      :shared
    when 'b'
      :boolean
    # 2011-02-25 BEGIN
    when 'str'
      :string
    # 2011-02-25 END
    # 2011-09-15 BEGIN
    when 'inlineStr'
      :inlinestr
    # 2011-09-15 END
    else
      format = @styles.style_format(style)
      Excelx::Format.to_type(format)
    end
  formula = nil
  row, column = ::Roo::Utils.split_coordinate(cell_xml['r'])
  cell_xml.children.each do |cell|
    case cell.name
    when 'is'
      cell.children.each do |inline_str|
        if inline_str.name == 't'
          return Excelx::Cell.new(inline_str.content,:string,formula,:string,inline_str.content,style, hyperlink, @workbook.base_date, Excelx::Cell::Coordinate.new(row, column))
        end
      end
    when 'f'
      formula = cell.content
    when 'v'
      if [:time, :datetime].include?(value_type) && cell.content.to_f >= 1.0
        value_type =
          if (cell.content.to_f - cell.content.to_f.floor).abs > 0.000001
            :datetime
          else
            :date
          end
      end
      excelx_type = [:numeric_or_formula,format.to_s]
      value =
        case value_type
        when :shared
          value_type = :string
          excelx_type = :string
          @shared_strings[cell.content.to_i]
        when :boolean
          (cell.content.to_i == 1 ? 'TRUE' : 'FALSE')
        when :date, :time, :datetime
          cell.content
        when :formula
          cell.content.to_f
        when :string
          excelx_type = :string
          cell.content
        else
          value_type = :float
          cell.content
        end
      return Excelx::Cell.new(value,value_type,formula,excelx_type,cell.content,style, hyperlink, @workbook.base_date, Excelx::Cell::Coordinate.new(row, column))
    end
  end
  Excelx::Cell.new(nil, nil, nil, nil, nil, nil, nil, nil, Excelx::Cell::Coordinate.new(row, column))
end
expand_merged_ranges(cells) click to toggle source
# File lib/roo/excelx/sheet_doc.rb, line 126
def expand_merged_ranges(cells)
  # Extract merged ranges from xml
  merges = {}
  doc.xpath("/worksheet/mergeCells/mergeCell").each do |mergecell_xml|
    tl, br = mergecell_xml['ref'].split(/:/).map {|ref| ::Roo::Utils.ref_to_key(ref)}
    for row in tl[0]..br[0] do
      for col in tl[1]..br[1] do
        next if row == tl[0] && col == tl[1]
        merges[[row,col]] = tl
      end
    end
  end
  # Duplicate value into all cells in merged range
  merges.each do |dst, src|
    cells[dst] = cells[src]
  end
end
extract_cells(relationships) click to toggle source
# File lib/roo/excelx/sheet_doc.rb, line 144
def extract_cells(relationships)
  extracted_cells = Hash[doc.xpath("/worksheet/sheetData/row/c").map do |cell_xml|
    key = ::Roo::Utils.ref_to_key(cell_xml['r'])
    [key, cell_from_xml(cell_xml, hyperlinks(relationships)[key])]
  end]
  if @options[:expand_merged_ranges]
    expand_merged_ranges(extracted_cells)
  end
  extracted_cells
end
extract_dimensions() click to toggle source
# File lib/roo/excelx/sheet_doc.rb, line 155
def extract_dimensions
  Roo::Utils.each_element(@path, 'dimension') do |dimension|
    return dimension.attributes["ref"].value
  end
end