lib/axlsx/workbook/worksheet/cell.rb in axlsx-1.0.16 vs lib/axlsx/workbook/worksheet/cell.rb in axlsx-1.0.17
- old
+ new
@@ -1,6 +1,6 @@
-# -*- coding: utf-8 -*-
+# encoding: UTF-8
module Axlsx
# A cell in a worksheet.
# Cell stores inforamation requried to serialize a single worksheet cell to xml. You must provde the Row that the cell belongs to and the cells value. The data type will automatically be determed if you do not specify the :type option. The default style will be applied if you do not supply the :style option. Changing the cell's type will recast the value to the type specified. Altering the cell's value via the property accessor will also automatically cast the provided value to the cell's type.
# @example Manually creating and manipulating Cell objects
# ws = Workbook.new.add_worksheet
@@ -21,10 +21,18 @@
# @note The recommended way to generate cells is via Worksheet#add_row
#
# @see Worksheet#add_row
class Cell
+
+ # An array of available inline styes.
+ INLINE_STYLES = ['value', 'type', 'font_name', 'charset',
+ 'family', 'b', 'i', 'strike','outline',
+ 'shadow', 'condense', 'extend', 'u',
+ 'vertAlign', 'sz', 'color', 'scheme']
+
+
# The index of the cellXfs item to be applied to this cell.
# @return [Integer]
# @see Axlsx::Styles
attr_reader :style
@@ -184,10 +192,28 @@
@style ||= 0
@type ||= cell_type_from_value(value)
@value = cast_value(value)
end
+ # The Shared Strings Table index for this cell
+ # @return [Integer]
+ attr_reader :ssti
+
+ # equality comparison to test value, type and inline style attributes
+ # this is how we work out if the cell needs to be added or already exists in the shared strings table
+ def shareable(v)
+
+ #using reject becase 1.8.7 select returns an array...
+ v_hash = v.instance_values.reject { |k, v| !INLINE_STYLES.include?(k) }
+ self_hash = self.instance_values.reject { |k, v| !INLINE_STYLES.include?(k) }
+ # required as color is an object, and the comparison will fail even though both use the same color.
+ v_hash['color'] = v_hash['color'].instance_values if v_hash['color']
+ self_hash['color'] = self_hash['color'].instance_values if self_hash['color']
+
+ v_hash == self_hash
+ end
+
# @return [Integer] The index of the cell in the containing row.
def index
@row.cells.index(self)
end
@@ -229,71 +255,83 @@
target.r
end
self.row.worksheet.merge_cells "#{self.r}:#{range_end}" unless range_end.nil?
end
+ # builds an xml text run based on this cells attributes. This is extracted from to_xml so that shared strings can use it.
+ # @param [Nokogiri::XML::Builder] xml The document builder instance this output will be added to.
+ # @return [String] the xml for this cell's text run
+ def run_xml(xml)
+ if (self.instance_values.keys & INLINE_STYLES).size > 0
+ xml.r {
+ xml.rPr {
+ xml.rFont(:val=>@font_name) if @font_name
+ xml.charset(:val=>@charset) if @charset
+ xml.family(:val=>@family) if @family
+ xml.b(:val=>@b) if @b
+ xml.i(:val=>@i) if @i
+ xml.strike(:val=>@strike) if @strike
+ xml.outline(:val=>@outline) if @outline
+ xml.shadow(:val=>@shadow) if @shadow
+ xml.condense(:val=>@condense) if @condense
+ xml.extend(:val=>@extend) if @extend
+ @color.to_xml(xml) if @color
+ xml.sz(:val=>@sz) if @sz
+ xml.u(:val=>@u) if @u
+ # :baseline, :subscript, :superscript
+ xml.vertAlign(:val=>@vertAlign) if @verAlign
+ # :none, major, :minor
+ xml.scheme(:val=>@scheme) if @scheme
+ }
+ xml.t @value.to_s
+ }
+ else
+ xml.t @value.to_s
+ end
+ end
+
# Serializes the cell
# @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
# @return [String] xml text for the cell
- # @note
- # Shared Strings are not used in this library. All values are set directly in the each sheet.
- def to_xml(xml)
-
- # however nokogiri does a nice 'force_encoding' which we shall remove!
+ def to_xml(xml)
if @type == :string
#parse formula
if @value.start_with?('=')
xml.c(:r => r, :t=>:str, :s=>style) {
xml.f @value.to_s.gsub('=', '')
}
else
- #parse standard string
- #xml.c(:r => r, :t=>:inlineStr, :s=>style) {
- # xml.is { xml.t @value.to_s }
- #}
- #parse styled string
- xml.c(:r => r, :s=>style, :t => :inlineStr) {
- xml.is {
- xml.r {
- xml.rPr {
- xml.rFont(:val=>@font_name) if @font_name
- xml.charset(:val=>@charset) if @charset
- xml.family(:val=>@family) if @family
- xml.b(:val=>@b) if @b
- xml.i(:val=>@i) if @i
- xml.strike(:val=>@strike) if @strike
- xml.outline(:val=>@outline) if @outline
- xml.shadow(:val=>@shadow) if @shadow
- xml.condense(:val=>@condense) if @condense
- xml.extend(:val=>@extend) if @extend
- @color.to_xml(xml) if @color
- xml.sz(:val=>@sz) if @sz
- xml.u(:val=>@u) if @u
- # :baseline, :subscript, :superscript
- xml.vertAlign(:val=>@vertAlign) if @verAlign
- # :none, major, :minor
- xml.scheme(:val=>@scheme) if @scheme
- }
- xml.t @value.to_s
+ #parse shared
+ if @ssti
+ xml.c(:r => r, :s=>style, :t => :s) { xml.v ssti }
+ else
+ #parse inline string
+ xml.c(:r => r, :s=>style, :t => :inlineStr) {
+ xml.is {
+ run_xml(xml)
}
}
- }
+ end
end
elsif @type == :time
# Using hardcoded offsets here as some operating systems will not except a 'negative' offset from the ruby epoc.
- # (1970)
epoc1900 = -2209021200 #Time.local(1900, 1, 1)
epoc1904 = -2082877200 #Time.local(1904, 1, 1)
epoc = Workbook.date1904 ? epoc1904 : epoc1900
v = ((@value.localtime.to_f - epoc) /60.0/60.0/24.0).to_f
xml.c(:r => r, :s => style) { xml.v v }
else
xml.c(:r => r, :s => style) { xml.v value }
end
end
-
private
+
+ # @see ssti
+ def ssti=(v)
+ Axlsx::validate_unsigned_int(v)
+ @ssti = v
+ end
# assigns the owning row for this cell.
def row=(v) DataTypeValidator.validate "Cell.row", Row, v; @row=v end
# converts the column index into alphabetical values.