axlsx 1.0.12 → 1.0.13
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +7 -3
- data/lib/axlsx.rb +57 -0
- data/lib/axlsx/content_type/content_type.rb +23 -0
- data/lib/axlsx/content_type/default.rb +37 -0
- data/lib/axlsx/content_type/override.rb +37 -0
- data/lib/axlsx/doc_props/app.rb +178 -0
- data/lib/axlsx/doc_props/core.rb +34 -0
- data/lib/axlsx/drawing/axis.rb +90 -0
- data/lib/axlsx/drawing/bar_3D_chart.rb +128 -0
- data/lib/axlsx/drawing/bar_series.rb +64 -0
- data/lib/axlsx/drawing/cat_axis.rb +63 -0
- data/lib/axlsx/drawing/cat_axis_data.rb +35 -0
- data/lib/axlsx/drawing/chart.rb +179 -0
- data/lib/axlsx/drawing/drawing.rb +137 -0
- data/lib/axlsx/drawing/graphic_frame.rb +52 -0
- data/lib/axlsx/drawing/line_3D_chart.rb +106 -0
- data/lib/axlsx/drawing/line_series.rb +46 -0
- data/lib/axlsx/drawing/marker.rb +61 -0
- data/lib/axlsx/drawing/one_cell_anchor.rb +89 -0
- data/lib/axlsx/drawing/pic.rb +153 -0
- data/lib/axlsx/drawing/picture_locking.rb +72 -0
- data/lib/axlsx/drawing/picture_locking.rb~ +36 -0
- data/lib/axlsx/drawing/pie_3D_chart.rb +41 -0
- data/lib/axlsx/drawing/pie_series.rb +56 -0
- data/lib/axlsx/drawing/scaling.rb +59 -0
- data/lib/axlsx/drawing/ser_axis.rb +45 -0
- data/lib/axlsx/drawing/series.rb +71 -0
- data/lib/axlsx/drawing/series_title.rb +22 -0
- data/lib/axlsx/drawing/title.rb +61 -0
- data/lib/axlsx/drawing/two_cell_anchor.rb +76 -0
- data/lib/axlsx/drawing/val_axis.rb +34 -0
- data/lib/axlsx/drawing/val_axis_data.rb +28 -0
- data/lib/axlsx/drawing/view_3D.rb +85 -0
- data/lib/axlsx/package.rb +215 -0
- data/lib/axlsx/rels/relationship.rb +44 -0
- data/lib/axlsx/rels/relationships.rb +25 -0
- data/lib/axlsx/stylesheet/border.rb +57 -0
- data/lib/axlsx/stylesheet/border_pr.rb +68 -0
- data/lib/axlsx/stylesheet/cell_alignment.rb +105 -0
- data/lib/axlsx/stylesheet/cell_protection.rb +36 -0
- data/lib/axlsx/stylesheet/cell_style.rb +65 -0
- data/lib/axlsx/stylesheet/color.rb +69 -0
- data/lib/axlsx/stylesheet/fill.rb +32 -0
- data/lib/axlsx/stylesheet/font.rb +139 -0
- data/lib/axlsx/stylesheet/gradient_fill.rb +76 -0
- data/lib/axlsx/stylesheet/gradient_stop.rb +33 -0
- data/lib/axlsx/stylesheet/num_fmt.rb +63 -0
- data/lib/axlsx/stylesheet/pattern_fill.rb +66 -0
- data/lib/axlsx/stylesheet/styles.rb +298 -0
- data/lib/axlsx/stylesheet/table_style.rb +47 -0
- data/lib/axlsx/stylesheet/table_style_element.rb +71 -0
- data/lib/axlsx/stylesheet/table_styles.rb +39 -0
- data/lib/axlsx/stylesheet/xf.rb +138 -0
- data/lib/axlsx/util/constants.rb +220 -0
- data/lib/axlsx/util/parser.rb +43 -0
- data/lib/axlsx/util/parser.rb~ +6 -0
- data/lib/axlsx/util/simple_typed_list.rb +160 -0
- data/lib/axlsx/util/validators.rb +132 -0
- data/lib/axlsx/version.rb +4 -0
- data/lib/axlsx/workbook/#workbook.rb# +165 -0
- data/lib/axlsx/workbook/workbook.rb +160 -0
- data/lib/axlsx/workbook/worksheet/cell.rb +337 -0
- data/lib/axlsx/workbook/worksheet/row.rb +107 -0
- data/lib/axlsx/workbook/worksheet/worksheet.rb +279 -0
- metadata +93 -141
- data/examples/follow_20111202.xlsx +0 -0
- data/test/content_type/tc_content_type.rb +0 -81
- data/test/content_type/tc_default.rb +0 -40
- data/test/content_type/tc_override.rb +0 -40
- data/test/doc_props/tc_app.rb +0 -19
- data/test/doc_props/tc_core.rb +0 -34
- data/test/drawing/tc_axis.rb +0 -40
- data/test/drawing/tc_bar_3D_chart.rb +0 -66
- data/test/drawing/tc_bar_series.rb +0 -34
- data/test/drawing/tc_cat_axis.rb +0 -32
- data/test/drawing/tc_cat_axis_data.rb +0 -18
- data/test/drawing/tc_chart.rb +0 -73
- data/test/drawing/tc_drawing.rb +0 -80
- data/test/drawing/tc_graphic_frame.rb +0 -26
- data/test/drawing/tc_line_3d_chart.rb +0 -48
- data/test/drawing/tc_line_series.rb +0 -27
- data/test/drawing/tc_marker.rb +0 -45
- data/test/drawing/tc_one_cell_anchor.rb +0 -67
- data/test/drawing/tc_pic.rb +0 -71
- data/test/drawing/tc_picture_locking.rb +0 -73
- data/test/drawing/tc_pie_3D_chart.rb +0 -33
- data/test/drawing/tc_pie_series.rb +0 -35
- data/test/drawing/tc_scaling.rb +0 -37
- data/test/drawing/tc_ser_axis.rb +0 -31
- data/test/drawing/tc_series.rb +0 -24
- data/test/drawing/tc_series_title.rb +0 -34
- data/test/drawing/tc_title.rb +0 -34
- data/test/drawing/tc_two_cell_anchor.rb +0 -38
- data/test/drawing/tc_val_axis.rb +0 -25
- data/test/drawing/tc_val_axis_data.rb +0 -18
- data/test/drawing/tc_view_3D.rb +0 -55
- data/test/rels/tc_relationship.rb +0 -16
- data/test/rels/tc_relationships.rb +0 -27
- data/test/stylesheet/tc_border.rb +0 -38
- data/test/stylesheet/tc_border_pr.rb +0 -33
- data/test/stylesheet/tc_cell_alignment.rb +0 -77
- data/test/stylesheet/tc_cell_protection.rb +0 -30
- data/test/stylesheet/tc_cell_style.rb +0 -58
- data/test/stylesheet/tc_color.rb +0 -38
- data/test/stylesheet/tc_fill.rb +0 -19
- data/test/stylesheet/tc_font.rb +0 -114
- data/test/stylesheet/tc_gradient_fill.rb +0 -65
- data/test/stylesheet/tc_gradient_stop.rb +0 -32
- data/test/stylesheet/tc_num_fmt.rb +0 -31
- data/test/stylesheet/tc_pattern_fill.rb +0 -38
- data/test/stylesheet/tc_styles.rb +0 -52
- data/test/stylesheet/tc_table_style.rb +0 -37
- data/test/stylesheet/tc_table_style_element.rb +0 -37
- data/test/stylesheet/tc_table_styles.rb +0 -30
- data/test/stylesheet/tc_xf.rb +0 -121
- data/test/tc_package.rb +0 -68
- data/test/util/tc_simple_typed_list.rb +0 -66
- data/test/util/tc_validators.rb +0 -76
- data/test/workbook/tc_workbook.rb +0 -60
- data/test/workbook/worksheet/tc_cell.rb +0 -179
- data/test/workbook/worksheet/tc_row.rb +0 -36
- data/test/workbook/worksheet/tc_worksheet.rb +0 -138
@@ -0,0 +1,160 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module Axlsx
|
3
|
+
|
4
|
+
require 'axlsx/workbook/worksheet/cell.rb'
|
5
|
+
require 'axlsx/workbook/worksheet/row.rb'
|
6
|
+
require 'axlsx/workbook/worksheet/worksheet.rb'
|
7
|
+
|
8
|
+
# The Workbook class is an xlsx workbook that manages worksheets, charts, drawings and styles.
|
9
|
+
# The following parts of the Office Open XML spreadsheet specification are not implimented in this version.
|
10
|
+
#
|
11
|
+
# bookViews
|
12
|
+
# calcPr
|
13
|
+
# customWorkbookViews
|
14
|
+
# definedNames
|
15
|
+
# externalReferences
|
16
|
+
# extLst
|
17
|
+
# fileRecoveryPr
|
18
|
+
# fileSharing
|
19
|
+
# fileVersion
|
20
|
+
# functionGroups
|
21
|
+
# oleSize
|
22
|
+
# pivotCaches
|
23
|
+
# smartTagPr
|
24
|
+
# smartTagTypes
|
25
|
+
# webPublishing
|
26
|
+
# webPublishObjects
|
27
|
+
# workbookProtection
|
28
|
+
# workbookPr*
|
29
|
+
#
|
30
|
+
# *workbookPr is only supported to the extend of date1904
|
31
|
+
class Workbook
|
32
|
+
|
33
|
+
# A collection of worksheets associated with this workbook.
|
34
|
+
# @note The recommended way to manage worksheets is add_worksheet
|
35
|
+
# @see Workbook#add_worksheet
|
36
|
+
# @see Worksheet
|
37
|
+
# @return [SimpleTypedList]
|
38
|
+
attr_reader :worksheets
|
39
|
+
|
40
|
+
# A colllection of charts associated with this workbook
|
41
|
+
# @note The recommended way to manage charts is Worksheet#add_chart
|
42
|
+
# @see Worksheet#add_chart
|
43
|
+
# @see Chart
|
44
|
+
# @return [SimpleTypedList]
|
45
|
+
attr_reader :charts
|
46
|
+
|
47
|
+
# A colllection of images associated with this workbook
|
48
|
+
# @note The recommended way to manage images is Worksheet#add_image
|
49
|
+
# @see Worksheet#add_image
|
50
|
+
# @see Pic
|
51
|
+
# @return [SimpleTypedList]
|
52
|
+
attr_reader :images
|
53
|
+
|
54
|
+
# A colllection of drawings associated with this workbook
|
55
|
+
# @note The recommended way to manage drawings is Worksheet#add_chart
|
56
|
+
# @see Worksheet#add_chart
|
57
|
+
# @see Drawing
|
58
|
+
# @return [SimpleTypedList]
|
59
|
+
attr_reader :drawings
|
60
|
+
|
61
|
+
# The styles associated with this workbook
|
62
|
+
# @note The recommended way to manage styles is Styles#add_style
|
63
|
+
# @see Style#add_style
|
64
|
+
# @see Style
|
65
|
+
# @return [Styles]
|
66
|
+
def styles
|
67
|
+
yield @styles if block_given?
|
68
|
+
@styles
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
# Indicates if the epoc date for serialization should be 1904. If false, 1900 is used.
|
73
|
+
@@date1904 = false
|
74
|
+
|
75
|
+
# lets come back to this later when we are ready for parsing.
|
76
|
+
#def self.parse entry
|
77
|
+
# io = entry.get_input_stream
|
78
|
+
# w = self.new
|
79
|
+
# w.parser_xml = Nokogiri::XML(io.read)
|
80
|
+
# w.parse_string :date1904, "//xmlns:workbookPr/@date1904"
|
81
|
+
# w
|
82
|
+
#end
|
83
|
+
|
84
|
+
# Creates a new Workbook
|
85
|
+
# @option options [Boolean] date1904
|
86
|
+
def initialize(options={})
|
87
|
+
@styles = Styles.new
|
88
|
+
@worksheets = SimpleTypedList.new Worksheet
|
89
|
+
@drawings = SimpleTypedList.new Drawing
|
90
|
+
@charts = SimpleTypedList.new Chart
|
91
|
+
@images = SimpleTypedList.new Pic
|
92
|
+
self.date1904= options[:date1904] unless options[:date1904].nil?
|
93
|
+
yield self if block_given?
|
94
|
+
end
|
95
|
+
|
96
|
+
# Instance level access to the class variable 1904
|
97
|
+
# @return [Boolean]
|
98
|
+
def date1904() @@date1904; end
|
99
|
+
|
100
|
+
# see @date1904
|
101
|
+
def date1904=(v) Axlsx::validate_boolean v; @@date1904 = v; end
|
102
|
+
|
103
|
+
# Sets the date1904 attribute to the provided boolean
|
104
|
+
# @return [Boolean]
|
105
|
+
def self.date1904=(v) Axlsx::validate_boolean v; @@date1904 = v; end
|
106
|
+
|
107
|
+
# retrieves the date1904 attribute
|
108
|
+
# @return [Boolean]
|
109
|
+
def self.date1904() @@date1904; end
|
110
|
+
|
111
|
+
# Adds a worksheet to this workbook
|
112
|
+
# @return [Worksheet]
|
113
|
+
# @option options [String] name The name of the worksheet.
|
114
|
+
# @see Worksheet#initialize
|
115
|
+
def add_worksheet(options={})
|
116
|
+
worksheet = Worksheet.new(self, options)
|
117
|
+
yield worksheet if block_given?
|
118
|
+
worksheet
|
119
|
+
end
|
120
|
+
|
121
|
+
# The workbook relationships. This is managed automatically by the workbook
|
122
|
+
# @return [Relationships]
|
123
|
+
def relationships
|
124
|
+
r = Relationships.new
|
125
|
+
@worksheets.each do |sheet|
|
126
|
+
r << Relationship.new(WORKSHEET_R, WORKSHEET_PN % (r.size+1))
|
127
|
+
end
|
128
|
+
r << Relationship.new(STYLES_R, STYLES_PN)
|
129
|
+
r
|
130
|
+
end
|
131
|
+
|
132
|
+
# returns a range of cells in a worksheet
|
133
|
+
# @param [String] cell_def The excel style reference defining the worksheet and cells. The range must specify the sheet to
|
134
|
+
# retrieve the cells from. e.g. range('Sheet1!A1:B2') will return an array of four cells [A1, A2, B1, B2] while range('Sheet1!A1') will return a single Cell.
|
135
|
+
# @return [Cell, Array]
|
136
|
+
def [](cell_def)
|
137
|
+
sheet_name = cell_def.split('!')[0] if cell_def.match('!')
|
138
|
+
worksheet = self.worksheets.select { |s| s.name == sheet_name }.first
|
139
|
+
raise ArgumentError, 'Unknown Sheet' unless sheet_name && worksheet.is_a?(Worksheet)
|
140
|
+
worksheet[cell_def.gsub(/.+!/,"")]
|
141
|
+
end
|
142
|
+
|
143
|
+
# Serializes the workbook document
|
144
|
+
# @return [String]
|
145
|
+
def to_xml()
|
146
|
+
add_worksheet unless worksheets.size > 0
|
147
|
+
builder = Nokogiri::XML::Builder.new(:encoding => ENCODING) do |xml|
|
148
|
+
xml.workbook(:xmlns => XML_NS, :'xmlns:r' => XML_NS_R) {
|
149
|
+
xml.workbookPr(:date1904=>@@date1904)
|
150
|
+
xml.sheets {
|
151
|
+
@worksheets.each_with_index do |sheet, index|
|
152
|
+
xml.sheet(:name=>sheet.name, :sheetId=>index+1, :"r:id"=>sheet.rId)
|
153
|
+
end
|
154
|
+
}
|
155
|
+
}
|
156
|
+
end
|
157
|
+
builder.to_xml(:indent=>0)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,337 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module Axlsx
|
3
|
+
# A cell in a worksheet.
|
4
|
+
# 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.
|
5
|
+
# @example Manually creating and manipulating Cell objects
|
6
|
+
# ws = Workbook.new.add_worksheet
|
7
|
+
# # This is the simple, and recommended way to create cells. Data types will automatically be determined for you.
|
8
|
+
# ws.add_row :values => [1,"fish",Time.now]
|
9
|
+
#
|
10
|
+
# # but you can also do this
|
11
|
+
# r = ws.add_row
|
12
|
+
# r.add_cell 1
|
13
|
+
#
|
14
|
+
# # or even this
|
15
|
+
# r = ws.add_row
|
16
|
+
# c = Cell.new row, 1, :value=>integer
|
17
|
+
#
|
18
|
+
# # cells can also be accessed via Row#cells. The example here changes the cells type, which will automatically updated the value from 1 to 1.0
|
19
|
+
# r.cells.last.type = :float
|
20
|
+
#
|
21
|
+
# @note The recommended way to generate cells is via Worksheet#add_row
|
22
|
+
#
|
23
|
+
# @see Worksheet#add_row
|
24
|
+
class Cell
|
25
|
+
|
26
|
+
# The index of the cellXfs item to be applied to this cell.
|
27
|
+
# @return [Integer]
|
28
|
+
# @see Axlsx::Styles
|
29
|
+
attr_reader :style
|
30
|
+
|
31
|
+
# The row this cell belongs to.
|
32
|
+
# @return [Row]
|
33
|
+
attr_reader :row
|
34
|
+
|
35
|
+
# The cell's data type. Currently only four types are supported, :time, :float, :integer and :string.
|
36
|
+
# Changing the type for a cell will recast the value into that type. If no type option is specified in the constructor, the type is
|
37
|
+
# automatically determed.
|
38
|
+
# @see Cell#cell_type_from_value
|
39
|
+
# @return [Symbol] The type of data this cell's value is cast to.
|
40
|
+
# @raise [ArgumentExeption] Cell.type must be one of [:time, :float, :integer, :string]
|
41
|
+
# @note
|
42
|
+
# If the value provided cannot be cast into the type specified, type is changed to :string and the following logic is applied.
|
43
|
+
# :string to :integer or :float, type coversions always return 0 or 0.0
|
44
|
+
# :string, :integer, or :float to :time conversions always return the original value as a string and set the cells type to :string.
|
45
|
+
# No support is currently implemented for parsing time strings.
|
46
|
+
attr_reader :type
|
47
|
+
# @see type
|
48
|
+
def type=(v)
|
49
|
+
RestrictionValidator.validate "Cell.type", [:time, :float, :integer, :string], v
|
50
|
+
@type=v
|
51
|
+
self.value = @value
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
# The value of this cell.
|
56
|
+
# @return [String, Integer, Float, Time] casted value based on cell's type attribute.
|
57
|
+
attr_reader :value
|
58
|
+
# @see value
|
59
|
+
def value=(v)
|
60
|
+
#TODO: consider doing value based type determination first?
|
61
|
+
@value = cast_value(v)
|
62
|
+
end
|
63
|
+
|
64
|
+
# The inline font_name property for the cell
|
65
|
+
# @return [String]
|
66
|
+
attr_reader :font_name
|
67
|
+
# @see font_name
|
68
|
+
def font_name=(v) Axlsx::validate_string(v); @font_name = v; end
|
69
|
+
|
70
|
+
# The inline charset property for the cell
|
71
|
+
# @return [String]
|
72
|
+
attr_reader :charset
|
73
|
+
# @see charset
|
74
|
+
def charset=(v) Axlsx::validate_unsigned_int(v); @charset = v; end
|
75
|
+
|
76
|
+
# The inline family property for the cell
|
77
|
+
# @return [String]
|
78
|
+
attr_reader :family
|
79
|
+
# @see family
|
80
|
+
def family=(v) Axlsx::validate_string(v); @family = v; end
|
81
|
+
|
82
|
+
# The inline bold property for the cell
|
83
|
+
# @return [Boolean]
|
84
|
+
attr_reader :b
|
85
|
+
# @see b
|
86
|
+
def b=(v) Axlsx::validate_boolean(v); @b = v; end
|
87
|
+
|
88
|
+
# The inline italic property for the cell
|
89
|
+
# @return [Boolean]
|
90
|
+
attr_reader :i
|
91
|
+
# @see i
|
92
|
+
def i=(v) Axlsx::validate_boolean(v); @i = v; end
|
93
|
+
|
94
|
+
# The inline strike property for the cell
|
95
|
+
# @return [Boolean]
|
96
|
+
attr_reader :strike
|
97
|
+
# @see strike
|
98
|
+
def strike=(v) Axlsx::validate_boolean(v); @strike = v; end
|
99
|
+
|
100
|
+
# The inline outline property for the cell
|
101
|
+
# @return [Boolean]
|
102
|
+
attr_reader :outline
|
103
|
+
# @see outline
|
104
|
+
def outline=(v) Axlsx::validate_boolean(v); @outline = v; end
|
105
|
+
|
106
|
+
# The inline shadow property for the cell
|
107
|
+
# @return [Boolean]
|
108
|
+
attr_reader :shadow
|
109
|
+
# @see shadow
|
110
|
+
def shadow=(v) Axlsx::validate_boolean(v); @shadow = v; end
|
111
|
+
|
112
|
+
# The inline condense property for the cell
|
113
|
+
# @return [Boolean]
|
114
|
+
attr_reader :condense
|
115
|
+
# @see condense
|
116
|
+
def condense=(v) Axlsx::validate_boolean(v); @condense = v; end
|
117
|
+
|
118
|
+
# The inline extend property for the cell
|
119
|
+
# @return [Boolean]
|
120
|
+
attr_reader :extend
|
121
|
+
# @see extend
|
122
|
+
def extend=(v) Axlsx::validate_boolean(v); @extend = v; end
|
123
|
+
|
124
|
+
# The inline underline property for the cell
|
125
|
+
# @return [Boolean]
|
126
|
+
attr_reader :u
|
127
|
+
# @see u
|
128
|
+
def u=(v) Axlsx::validate_boolean(v); @u = v; end
|
129
|
+
|
130
|
+
# The inline color property for the cell
|
131
|
+
# @return [Color]
|
132
|
+
attr_reader :color
|
133
|
+
# @param [String] The 8 character representation for an rgb color #FFFFFFFF"
|
134
|
+
def color=(v)
|
135
|
+
@color = v.is_a?(Color) ? v : Color.new(:rgb=>v)
|
136
|
+
end
|
137
|
+
|
138
|
+
# The inline sz property for the cell
|
139
|
+
# @return [Boolean]
|
140
|
+
attr_reader :sz
|
141
|
+
# @see sz
|
142
|
+
def sz=(v) Axlsx::validate_unsigned_int(v); @sz = v; end
|
143
|
+
|
144
|
+
# The inline vertical alignment property for the cell
|
145
|
+
# this must be one of [:baseline, :subscript, :superscript]
|
146
|
+
# @return [Symbol]
|
147
|
+
attr_reader :vertAlign
|
148
|
+
# @see vertAlign
|
149
|
+
def vertAlign=(v) RestrictionValidator.validate "Cell.vertAlign", [:baseline, :subscript, :superscript], v; @vertAlign = v; end
|
150
|
+
|
151
|
+
# The inline scheme property for the cell
|
152
|
+
# this must be one of [:none, major, minor]
|
153
|
+
# @return [Symbol]
|
154
|
+
attr_reader :scheme
|
155
|
+
# @see scheme
|
156
|
+
def scheme=(v) RestrictionValidator.validate "Cell.schema", [:none, :major, :minor], v; @scheme = v; end
|
157
|
+
|
158
|
+
# @param [Row] row The row this cell belongs to.
|
159
|
+
# @param [Any] value The value associated with this cell.
|
160
|
+
# @option options [Symbol] type The intended data type for this cell. If not specified the data type will be determined internally based on the vlue provided.
|
161
|
+
# @option options [Integer] style The index of the cellXfs item to be applied to this cell. If not specified, the default style (0) will be applied.
|
162
|
+
# @option options [String] font_name
|
163
|
+
# @option options [Integer] charset
|
164
|
+
# @option options [String] family
|
165
|
+
# @option options [Boolean] b
|
166
|
+
# @option options [Boolean] i
|
167
|
+
# @option options [Boolean] strike
|
168
|
+
# @option options [Boolean] outline
|
169
|
+
# @option options [Boolean] shadow
|
170
|
+
# @option options [Boolean] condense
|
171
|
+
# @option options [Boolean] extend
|
172
|
+
# @option options [Boolean] u
|
173
|
+
# @option options [Symbol] vertAlign must be one of :baseline, :subscript, :superscript
|
174
|
+
# @option options [Integer] sz
|
175
|
+
# @option options [String] color an 8 letter rgb specification
|
176
|
+
# @option options [Symbol] scheme must be one of :none, major, :minor
|
177
|
+
def initialize(row, value="", options={})
|
178
|
+
self.row=row
|
179
|
+
@styles = row.worksheet.workbook.styles
|
180
|
+
@style = 0
|
181
|
+
@type = cell_type_from_value(value)
|
182
|
+
@row.cells << self
|
183
|
+
options.each do |o|
|
184
|
+
self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
|
185
|
+
end
|
186
|
+
@value = cast_value(value)
|
187
|
+
end
|
188
|
+
|
189
|
+
# @return [Integer] The index of the cell in the containing row.
|
190
|
+
def index
|
191
|
+
@row.cells.index(self)
|
192
|
+
end
|
193
|
+
|
194
|
+
# @return [String] The alpha(column)numeric(row) reference for this sell.
|
195
|
+
# @example Relative Cell Reference
|
196
|
+
# ws.rows.first.cells.first.r #=> "A1"
|
197
|
+
def r
|
198
|
+
"#{col_ref}#{@row.index+1}"
|
199
|
+
end
|
200
|
+
|
201
|
+
# @return [String] The absolute alpha(column)numeric(row) reference for this sell.
|
202
|
+
# @example Absolute Cell Reference
|
203
|
+
# ws.rows.first.cells.first.r #=> "$A$1"
|
204
|
+
def r_abs
|
205
|
+
"$#{r.split('').join('$')}"
|
206
|
+
end
|
207
|
+
|
208
|
+
# @return [Integer] The cellXfs item index applied to this cell.
|
209
|
+
# @raise [ArgumentError] Invalid cellXfs id if the value provided is not within cellXfs items range.
|
210
|
+
def style=(v)
|
211
|
+
Axlsx::validate_unsigned_int(v)
|
212
|
+
count = @styles.cellXfs.size
|
213
|
+
raise ArgumentError, "Invalid cellXfs id" unless v < count
|
214
|
+
@style = v
|
215
|
+
end
|
216
|
+
|
217
|
+
# @return [Array] of x/y coordinates in the cheet for this cell.
|
218
|
+
def pos
|
219
|
+
[index, row.index]
|
220
|
+
end
|
221
|
+
|
222
|
+
# Serializes the cell
|
223
|
+
# @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
|
224
|
+
# @return [String] xml text for the cell
|
225
|
+
# @note
|
226
|
+
# Shared Strings are not used in this library. All values are set directly in the each sheet.
|
227
|
+
def to_xml(xml)
|
228
|
+
|
229
|
+
# however nokogiri does a nice 'force_encoding' which we shall remove!
|
230
|
+
if @type == :string
|
231
|
+
#parse formula
|
232
|
+
if @value.start_with?('=')
|
233
|
+
xml.c(:r => r, :t=>:str, :s=>style) {
|
234
|
+
xml.f @value.to_s.gsub('=', '')
|
235
|
+
}
|
236
|
+
else
|
237
|
+
#parse standard string
|
238
|
+
#xml.c(:r => r, :t=>:inlineStr, :s=>style) {
|
239
|
+
# xml.is { xml.t @value.to_s }
|
240
|
+
#}
|
241
|
+
#parse styled string
|
242
|
+
xml.c(:r => r, :s=>style, :t => :inlineStr) {
|
243
|
+
xml.is {
|
244
|
+
xml.r {
|
245
|
+
xml.rPr {
|
246
|
+
xml.rFont(:val=>@font_name) if @font_name
|
247
|
+
xml.charset(:val=>@charset) if @charset
|
248
|
+
xml.family(:val=>@family) if @family
|
249
|
+
xml.b(:val=>@b) if @b
|
250
|
+
xml.i(:val=>@i) if @i
|
251
|
+
xml.strike(:val=>@strike) if @strike
|
252
|
+
xml.outline(:val=>@outline) if @outline
|
253
|
+
xml.shadow(:val=>@shadow) if @shadow
|
254
|
+
xml.condense(:val=>@condense) if @condense
|
255
|
+
xml.extend(:val=>@extend) if @extend
|
256
|
+
@color.to_xml(xml) if @color
|
257
|
+
xml.sz(:val=>@sz) if @sz
|
258
|
+
xml.u(:val=>@u) if @u
|
259
|
+
# :baseline, :subscript, :superscript
|
260
|
+
xml.vertAlign(:val=>@vertAlign) if @verAlign
|
261
|
+
# :none, major, :minor
|
262
|
+
xml.scheme(:val=>@scheme) if @scheme
|
263
|
+
}
|
264
|
+
xml.t @value.to_s
|
265
|
+
}
|
266
|
+
}
|
267
|
+
}
|
268
|
+
end
|
269
|
+
else
|
270
|
+
xml.c(:r => r, :s => style) { xml.v value }
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
|
275
|
+
private
|
276
|
+
|
277
|
+
# assigns the owning row for this cell.
|
278
|
+
def row=(v) DataTypeValidator.validate "Cell.row", Row, v; @row=v end
|
279
|
+
|
280
|
+
# converts the column index into alphabetical values.
|
281
|
+
# @note This follows the standard spreadsheet convention of naming columns A to Z, followed by AA to AZ etc.
|
282
|
+
# @return [String]
|
283
|
+
def col_ref
|
284
|
+
chars = []
|
285
|
+
index = self.index
|
286
|
+
while index >= 26 do
|
287
|
+
chars << ((index % 26) + 65).chr
|
288
|
+
index /= 26
|
289
|
+
end
|
290
|
+
chars << ((chars.empty? ? index : index-1) + 65).chr
|
291
|
+
chars.reverse.join
|
292
|
+
end
|
293
|
+
|
294
|
+
# Determines the cell type based on the cell value.
|
295
|
+
# @note This is only used when a cell is created but no :type option is specified, the following rules apply:
|
296
|
+
# 1. If the value is an instance of Time, the type is set to :time
|
297
|
+
# 2. :float and :integer types are determined by regular expression matching.
|
298
|
+
# 3. Anything that does not meet either of the above is determined to be :string.
|
299
|
+
# @return [Symbol] The determined type
|
300
|
+
def cell_type_from_value(v)
|
301
|
+
if v.is_a? Time
|
302
|
+
:time
|
303
|
+
elsif v.to_s.match(/\A[+-]?\d+?\Z/) #numeric
|
304
|
+
:integer
|
305
|
+
elsif v.to_s.match(/\A[+-]?\d+\.\d+?\Z/) #float
|
306
|
+
:float
|
307
|
+
else
|
308
|
+
:string
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
# Cast the value into this cells data type.
|
313
|
+
# @note
|
314
|
+
# About Time - Time in OOXML is *different* from what you might expect. The history as to why is interesting, but you can safely assume that if you are generating docs on a mac, you will want to specify Workbook.1904 as true when using time typed values.
|
315
|
+
# @see Axlsx#date1904
|
316
|
+
def cast_value(v)
|
317
|
+
if (@type == :time && v.is_a?(Time)) || (@type == :time && v.respond_to?(:to_time))
|
318
|
+
v = v.respond_to?(:to_time) ? v.to_time : v
|
319
|
+
self.style = STYLE_DATE if self.style == 0
|
320
|
+
# Using hardcoded offsets here as some operating systems will not except a 'negative' offset from the ruby epoc.
|
321
|
+
# (1970)
|
322
|
+
epoc1900 = -2209021200 #Time.local(1900, 1, 1)
|
323
|
+
epoc1904 = -2082877200 #Time.local(1904, 1, 1)
|
324
|
+
epoc = Workbook.date1904 ? epoc1904 : epoc1900
|
325
|
+
v = ((v.localtime.to_f - epoc) /60.0/60.0/24.0).to_f
|
326
|
+
((v * 10**11).round.to_f / 10**11)
|
327
|
+
elsif @type == :float
|
328
|
+
v.to_f
|
329
|
+
elsif @type == :integer
|
330
|
+
v.to_i
|
331
|
+
else
|
332
|
+
@type = :string
|
333
|
+
v.to_s
|
334
|
+
end
|
335
|
+
end
|
336
|
+
end
|
337
|
+
end
|