lib/rspreadsheet/cell.rb in rspreadsheet-0.2.3 vs lib/rspreadsheet/cell.rb in rspreadsheet-0.2.4

- old
+ new

@@ -1,15 +1,32 @@ +# @markup markdown +# @author Jakub Tesinsky +# @titel rspreadsheet Cell + require 'andand' require 'rspreadsheet/xml_tied' + + module Rspreadsheet - + +### +# Represents a cell in spreadsheet which has coordinates, contains value, formula and can be formated. +# You can get this object like this (suppose that @worksheet contains {Rspreadsheet::Worksheet} object) +# +# @worksheet.cells(5,2) +# +# Note that when using syntax like `@worksheet[5,2]` or `@worksheet.B5` you won't get this object, but rather the value of the cell. + class Cell < XMLTiedItem attr_accessor :worksheet, :coli, :rowi - def xml_repeated_attribute; 'number-columns-repeated' end - def xml_items_node_name; 'table-cell' end - def xml_options; {:xml_items_node_name => xml_items_node_name, :xml_repeated_attribute => xml_repeated_attribute} end + # `xml_options[:xml_items_node_name]` gives the name of the tag representing cell + # `xml_options[:number-columns-repeated]` gives the name of the previous tag which sais how many times the item is repeated + def xml_options; {:xml_items_node_name => 'table-cell', :xml_repeated_attribute => 'number-columns-repeated'} end + + ## defining abstract methods from XMLTiedItem + # returns parent XMLTiedArray object of myself (XMLTiedItem) def parent; row end def index; @coli end def set_index(value); @coli=value end def set_rowi(arowi); @rowi = arowi end # this should ONLY be used by parent row def initialize(aworksheet,arowi,acoli) @@ -57,25 +74,25 @@ when gt == nil then raise 'This value type is not storable to cell' when gt == Float set_type_attribute('float') remove_all_value_attributes_and_content(xmlnode) Tools.set_ns_attribute(xmlnode,'office','value', avalue.to_s) - xmlnode << Tools.create_ns_node('text','p', avalue.to_f.to_s) + xmlnode << Tools.prepare_ns_node('text','p', avalue.to_f.to_s) when gt == String then set_type_attribute('string') remove_all_value_attributes_and_content(xmlnode) - xmlnode << Tools.create_ns_node('text','p', avalue.to_s) + xmlnode << Tools.prepare_ns_node('text','p', avalue.to_s) when gt == Date then set_type_attribute('date') remove_all_value_attributes_and_content(xmlnode) Tools.set_ns_attribute(xmlnode,'office','date-value', avalue.strftime('%Y-%m-%d')) - xmlnode << Tools.create_ns_node('text','p', avalue.strftime('%Y-%m-%d')) + xmlnode << Tools.prepare_ns_node('text','p', avalue.strftime('%Y-%m-%d')) when gt == :percentage set_type_attribute('percentage') remove_all_value_attributes_and_content(xmlnode) Tools.set_ns_attribute(xmlnode,'office','value', '%0.2d%' % avalue.to_f) - xmlnode << Tools.create_ns_node('text','p', (avalue.to_f*100).round.to_s+'%') + xmlnode << Tools.prepare_ns_node('text','p', (avalue.to_f*100).round.to_s+'%') end else raise "Unknown cell mode #{self.mode}" end end @@ -163,32 +180,83 @@ end end # proxy object to allow cell.format syntax. Also handles all logic for formats. +# @private class CellFormat - attr_reader :bold def initialize(cell) - @bold = false @cell = cell end def cellnode; @cell.xmlnode end - def bold=(value) - Rspreadsheet::Tools.set_ns_attribute(cellnode,'table','style-name','ce99') + + # text style attribute readers + def bold; get_text_style_node_attribute('font-weight') == 'bold' end + def italic; get_text_style_node_attribute('font-style') == 'italic' end + def color; get_text_style_node_attribute('color') end + def font_size; get_text_style_node_attribute('font-size') end + def get_text_style_node_attribute(attribute_name) + text_style_node.nil? ? nil : Tools.get_ns_attribute_value(text_style_node,'fo',attribute_name) end - def bold; Tools.get_ns_attribute_value(text_style_node,'fo','font-weight') == 'bold' end - def italic; Tools.get_ns_attribute_value(text_style_node,'fo','font-style') == 'italic' end - def color; Tools.get_ns_attribute_value(text_style_node,'fo','color') end - def font_size; Tools.get_ns_attribute_value(text_style_node,'fo','font-size') end - def background_color; Tools.get_ns_attribute_value(cell_style_node,'fo','background-color') end - + def background_color; get_cell_style_node_attribute('background-color') end + def get_cell_style_node_attribute(attribute_name) + cell_style_node.nil? ? nil : Tools.get_ns_attribute_value(cell_style_node,'fo',attribute_name) + end + + # text style attribute writers + def bold=(value); set_text_style_node_attribute('font-weight', value ? 'bold' : 'normal') end + def italic=(value); set_text_style_node_attribute('font-style', value ? 'italic' : 'normal') end + def color=(value); set_text_style_node_attribute('color', value) end + def font_size=(value);set_text_style_node_attribute('font-size', value) end + def set_text_style_node_attribute(attribute_name,value) + if text_style_node.nil? + self.create_text_style_node + raise 'Style node was not correctly initialized' if text_style_node.nil? + end + Tools.set_ns_attribute(text_style_node,'fo',attribute_name,value) + end + def background_color=(value); set_cell_style_node_attribute('background-color', value) end + def set_cell_style_node_attribute(attribute_name,value) + if cell_style_node.nil? + self.create_cell_style_node + raise 'Style node was not correctly initialized' if cell_style_node.nil? + end + Tools.set_ns_attribute(cell_style_node,'fo',attribute_name,value) + end + + # @!group initialization of style related nodes, if they do not exist + def create_text_style_node + create_style_node if style_name.nil? or style_node.nil? + raise 'text_style_node already exists' unless text_style_node.nil? + style_node << Tools.prepare_ns_node('style','text-properties') + end + def create_cell_style_node + create_style_node if style_name.nil? or style_node.nil? + raise 'cell_style_node already exists' unless cell_style_node.nil? + style_node << Tools.prepare_ns_node('style','table-cell-properties') + end + def create_style_node + if style_name.nil? + proposed_style_name = unused_cell_style_name + Tools.set_ns_attribute(cellnode,'table','style-name',proposed_style_name) + raise 'Style name was not correctly initialized' if style_name!=proposed_style_name + end + anode = Tools.prepare_ns_node('style','style') + Tools.set_ns_attribute(anode, 'style', 'name', proposed_style_name) + Tools.set_ns_attribute(anode, 'style', 'family', 'table-cell') + Tools.set_ns_attribute(anode, 'style', 'parent-style-name', 'Default') + automatic_styles_node << anode + raise 'Style node was not correctly initialized' if style_node.nil? + end + def unused_cell_style_name last = cellnode.doc.root.find('./office:automatic-styles/style:style'). collect {|node| node['name']}. collect{ |name| /^ce(\d*)$/.match(name); $1.andand.to_i}. compact.max "ce#{last+1}" end + def automatic_styles_node; cellnode.doc.root.find("./office:automatic-styles").first end def style_name; Tools.get_ns_attribute_value(cellnode,'table','style-name') end def style_node; cellnode.doc.root.find("./office:automatic-styles/style:style[@style:name=\"#{style_name}\"]").first end def text_style_node; cellnode.doc.root.find("./office:automatic-styles/style:style[@style:name=\"#{style_name}\"]/style:text-properties").first end def cell_style_node; cellnode.doc.root.find("./office:automatic-styles/style:style[@style:name=\"#{style_name}\"]/style:table-cell-properties").first end end