class Shoji::ODS::Reader

Attributes

skip_empty_row[RW]

Public Class Methods

new(filename) click to toggle source
# File lib/shoji/ods/reader.rb, line 14
def initialize(filename)
  @filename = filename
end
open(filename, sheet_name = nil, &block) click to toggle source
# File lib/shoji/ods/reader.rb, line 8
def self.open(filename, sheet_name = nil, &block)
  reader = new(filename)
  reader.skip_empty_row = false
  reader.process_book(sheet_name, &block)
end
valid_file?(filename) click to toggle source
# File lib/shoji/ods/reader.rb, line 44
def self.valid_file?(filename)
  new(filename).valid_file?
end

Public Instance Methods

process_book(sheet_name = nil, &block) click to toggle source
# File lib/shoji/ods/reader.rb, line 18
def process_book(sheet_name = nil, &block)
  docbytes = read_from_zip_content_xml(@filename)

  doc = Nokogiri::XML(docbytes)
  path = "//table:table"
  path += "[@table:name='#{sheet_name}']" if sheet_name
  ws = doc.at_xpath path
  process_sheet(ws, &block)
end
process_row(rowreps, row, &block) click to toggle source
# File lib/shoji/ods/reader.rb, line 56
def process_row(rowreps, row, &block)
  cols = []
  index = 0
  has_value = false
  row.xpath('table:table-cell').each do |cell|
    tv = typed_value cell
    if tv && tv != ''
      cols[index] = tv
      has_value = true
    else
      cols[index] = ''
    end
    colreps = cell['number-columns-repeated']
    if colreps
      colreps.to_i.times do |num|
        cols[index + num] = cols[index]
      end
      index = index + colreps.to_i
    else
      index = index + 1
    end
  end
  cols = regulate_trailing_blank_cols(cols)
  rowreps.times do |num|
    if has_value
      block.call(cols)
    elsif !skip_empty_row
      block.call(cols)
    end
  end
end
process_sheet(sheet, &block) click to toggle source
# File lib/shoji/ods/reader.rb, line 48
def process_sheet(sheet, &block)
  sheet.xpath('table:table-row').each do |row|
    rowreps = row['table:number-rows-repeated'] || '1'
    rowreps = rowreps.to_i
    process_row(rowreps, row, &block)
  end
end
rows(opts = {}) click to toggle source
# File lib/shoji/ods/reader.rb, line 37
def rows(opts = {})
  result = []
  process_book(opts[:sheet]) do |row|
    result << row
  end
  result
end
valid_file?() click to toggle source
# File lib/shoji/ods/reader.rb, line 28
def valid_file?
  valid = true
  begin
    read_from_zip_content_xml(@filename, true)
  rescue
    valid = false
  end
  valid
end

Private Instance Methods

read_from_zip_content_xml(filename, verify_only = false) click to toggle source
# File lib/shoji/ods/reader.rb, line 98
def read_from_zip_content_xml(filename, verify_only = false)
  raise "File:#{filename} doesn't exist." unless File.exist? filename
  docbytes = nil
  Zip::Archive.open(filename) do |ar|
    raise "content.xml doesn't exist in #{filename}" unless ar.get_stat 'content.xml' # raise unless exist.
    unless verify_only
      f = ar.fopen('content.xml')
      docbytes = f.read
      f.close
    end
  end
  docbytes
end
regulate_trailing_blank_cols(cols) click to toggle source
# File lib/shoji/ods/reader.rb, line 112
def regulate_trailing_blank_cols(cols)
  while cols.size > 0 && (cols[cols.size-1] == nil || cols[cols.size-1] == '')
    cols.pop
  end
  cols
end
typed_value(cell) click to toggle source
# File lib/shoji/ods/reader.rb, line 89
def typed_value(cell)
  case cell['value-type']
  when nil then nil
  when 'date' then Date.parse cell['date-value']
  when 'currency', 'float' then cell['value'].to_f
  else cell.text
  end
end