require 'rubyXL/objects/ooxml_object' require 'rubyXL/objects/simple_types' require 'rubyXL/objects/text' require 'rubyXL/objects/formula' require 'rubyXL/cell' require 'rubyXL/convenience_methods' module RubyXL # http://www.schemacentral.com/sc/ooxml/e-ssml_v-1.html class CellValue < OOXMLObject define_attribute(:_, :string, :accessor => :value) define_attribute(:'xml:space', %w{ preserve }) define_element_name 'v' def before_write_xml preserve_whitespace true end end # http://www.schemacentral.com/sc/ooxml/e-ssml_c-2.html class Cell < OOXMLObject define_attribute(:r, :ref) define_attribute(:s, :int, :default => 0, :accessor => :style_index) define_attribute(:t, RubyXL::ST_CellType, :accessor => :datatype, :default => 'n' ) define_attribute(:cm, :int, :default => 0) define_attribute(:vm, :int, :default => 0) define_attribute(:ph, :bool, :default => false) define_child_node(RubyXL::Formula, :accessor => :formula) define_child_node(RubyXL::CellValue, :accessor => :value_container) define_child_node(RubyXL::RichText) # is define_element_name 'c' def index_in_collection r.col_range.begin end def row r && r.first_row end def row=(v) self.r = RubyXL::Reference.new(v, column || 0) end def column r && r.first_col end def column=(v) self.r = RubyXL::Reference.new(row || 0, v) end def raw_value value_container && value_container.value end def raw_value=(v) self.value_container ||= RubyXL::CellValue.new value_container.value = v end def number_format workbook.stylesheet.get_number_format_by_id(get_cell_xf.num_fmt_id) end def is_date? return false unless raw_value =~ /\A\d+(?:\.\d+)?\Z/ # Only fully numeric values can be dates num_fmt = self.number_format num_fmt && num_fmt.is_date_format? end # Gets massaged value of the cell, converting datatypes to those known to Ruby (that includes # stripping any special formatting from RichText). def value(args = {}) if args[:raw] then warn "[DEPRECATION] option :raw to `#{__method__}` is deprecated. Please use `raw_value` instead." raw_value elsif datatype == RubyXL::DataType::SHARED_STRING then workbook.shared_strings_container[raw_value.to_i].to_s elsif is_date? then workbook.num_to_date(raw_value.to_f) elsif raw_value.is_a?(String) && (raw_value =~ /\A-?\d+(\.\d+(?:e[+-]\d+)?)?\Z/i) # Numeric if $1 then raw_value.to_f else raw_value.to_i end else raw_value end end def inspect str = "#<#{self.class}(#{row},#{column}): #{raw_value.inspect}" str += " =#{self.formula.expression}" if self.formula str += ", datatype=#{self.datatype.inspect}, style_index=#{self.style_index.inspect}>" return str end include LegacyCell include CellConvenienceMethods end #TODO# # http://www.schemacentral.com/sc/ooxml/e-ssml_row-1.html class Row < OOXMLObject define_attribute(:r, :int) define_attribute(:spans, :string) define_attribute(:s, :int, :default => 0, :accessor => :style_index) define_attribute(:customFormat, :bool, :default => false) define_attribute(:ht, :double) define_attribute(:hidden, :bool, :default => false) define_attribute(:customHeight, :bool, :default => false) define_attribute(:outlineLevel, :int, :default => 0) define_attribute(:collapsed, :bool, :default => false) define_attribute(:thickTop, :bool, :default => false) define_attribute(:thickBot, :bool, :default => false) define_attribute(:ph, :bool, :default => false) define_child_node(RubyXL::Cell, :collection => true, :accessor => :cells) define_element_name 'row' attr_accessor :worksheet def index_in_collection r - 1 end def [](ind) cells[ind] end def size cells.size end def insert_cell_shift_right(c, col_index) cells.insert(col_index, c) update_cell_coords(col_index) end def delete_cell_shift_left(col_index) cells.delete_at(col_index) update_cell_coords(col_index) end def update_cell_coords(start_from_index) cells.drop(start_from_index).each_with_index { |cell, i| next if cell.nil? cell.column = start_from_index + i } end private :update_cell_coords def xf @worksheet.workbook.cell_xfs[self.style_index || 0] end def get_fill_color @worksheet.workbook.get_fill_color(xf) end def get_font @worksheet.workbook.fonts[xf.font_id] end end # http://www.schemacentral.com/sc/ooxml/e-ssml_sheetData-1.html class SheetData < OOXMLObject define_child_node(RubyXL::Row, :collection => true, :accessor => :rows) define_element_name 'sheetData' def [](ind) rows[ind] end def size rows.size end end end