lib/roo/xls/excel_2003_xml.rb in roo-xls-1.1.0 vs lib/roo/xls/excel_2003_xml.rb in roo-xls-1.2.0
- old
+ new
@@ -19,11 +19,11 @@
unless File.file?(@filename)
raise IOError, "file #{@filename} does not exist"
end
@doc = ::Roo::Utils.load_xml(@filename)
end
- namespace = @doc.namespaces.select{|xmlns, urn| urn == 'urn:schemas-microsoft-com:office:spreadsheet'}.keys.last
+ namespace = @doc.namespaces.select { |_, urn| urn == 'urn:schemas-microsoft-com:office:spreadsheet' }.keys.last
@namespace = (namespace.nil? || namespace.empty?) ? 'ss' : namespace.split(':').last
super(filename, options)
@formula = {}
@style = {}
@style_defaults = Hash.new { |h, k| h[k] = [] }
@@ -56,11 +56,11 @@
@formula[sheet][[row, col]] && @formula[sheet][[row, col]]['oooc:'.length..-1]
end
alias_method :formula?, :formula
class Font
- attr_accessor :bold, :italic, :underline
+ attr_accessor :bold, :italic, :underline, :color, :name, :size
def bold?
@bold == '1'
end
@@ -189,35 +189,53 @@
def read_cells(sheet = nil)
sheet ||= @default_sheet
validate_sheet!(sheet)
return if @cells_read[sheet]
sheet_found = false
+
@doc.xpath("/#{@namespace}:Workbook/#{@namespace}:Worksheet[@#{@namespace}:Name='#{sheet}']").each do |ws|
sheet_found = true
- row = 1
+ column_styles = {}
+
+ # Column Styles
col = 1
- column_attributes = {}
- idx = 0
ws.xpath("./#{@namespace}:Table/#{@namespace}:Column").each do |c|
- column_attributes[(idx += 1).to_s] = c['StyleID']
+ skip_to_col = c["#{@namespace}:Index"].to_i
+ col = skip_to_col if skip_to_col > 0
+ col_style_name = c["#{@namespace}:StyleID"]
+ column_styles[col] = col_style_name unless col_style_name.nil?
+ col += 1
end
+
+ # Rows
+ row = 1
ws.xpath("./#{@namespace}:Table/#{@namespace}:Row").each do |r|
- skip_to_row = r['Index'].to_i
+ skip_to_row = r["#{@namespace}:Index"].to_i
row = skip_to_row if skip_to_row > 0
- style_name = r['StyleID'] if r['StyleID']
+
+ # Excel uses a 'Span' attribute on a 'Row' to indicate the presence of
+ # empty rows to skip.
+ skip_next_rows = r["#{@namespace}:Span"].to_i
+
+ row_style_name = r["#{@namespace}:StyleID"]
+
+ # Cells
+ col = 1
r.xpath("./#{@namespace}:Cell").each do |c|
- skip_to_col = c['Index'].to_i
+ skip_to_col = c["#{@namespace}:Index"].to_i
col = skip_to_col if skip_to_col > 0
- if c['StyleID']
- style_name = c['StyleID']
- elsif
- style_name ||= column_attributes[c['Index']]
- end
+
+ skip_next_cols = c["#{@namespace}:MergeAcross"].to_i
+
+ cell_style_name = c["#{@namespace}:StyleID"]
+ style_name = cell_style_name || row_style_name || column_styles[col]
+
+ # Cell Data
c.xpath("./#{@namespace}:Data").each do |cell|
formula = cell['Formula']
value_type = cell["#{@namespace}:Type"].downcase.to_sym
- v = cell.content
+ v = cell.content
str_v = v
case value_type
when :number
v = v.to_f
value_type = :float
@@ -232,29 +250,32 @@
when :boolean
v = cell['boolean-value']
end
set_cell_values(sheet, col, row, 0, v, value_type, formula, cell, str_v, style_name)
end
- col += 1
+ col += (skip_next_cols + 1)
end
- row += 1
- col = 1
+ row += (skip_next_rows + 1)
end
end
unless sheet_found
raise RangeError, "Unable to find sheet #{sheet} for reading"
end
@cells_read[sheet] = true
end
def read_styles
@doc.xpath("/#{@namespace}:Workbook/#{@namespace}:Styles/#{@namespace}:Style").each do |style|
- style_id = style['ID']
- @style_definitions[style_id] = Roo::Excel2003XML::Font.new
- if font = style.at_xpath("./#{@namespace}:Font")
- @style_definitions[style_id].bold = font['Bold']
- @style_definitions[style_id].italic = font['Italic']
- @style_definitions[style_id].underline = font['Underline']
+ style_id = style["#{@namespace}:ID"]
+ font = style.at_xpath("./#{@namespace}:Font")
+ unless font.nil?
+ @style_definitions[style_id] = Roo::Excel2003XML::Font.new
+ @style_definitions[style_id].bold = font["#{@namespace}:Bold"]
+ @style_definitions[style_id].italic = font["#{@namespace}:Italic"]
+ @style_definitions[style_id].underline = font["#{@namespace}:Underline"]
+ @style_definitions[style_id].color = font["#{@namespace}:Color"]
+ @style_definitions[style_id].name = font["#{@namespace}:FontName"]
+ @style_definitions[style_id].size = font["#{@namespace}:Size"]
end
end
end
A_ROO_TYPE = {