axlsx 1.0.11 → 1.0.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (145) hide show
  1. data/.yardopts +4 -0
  2. data/README.md +7 -4
  3. data/examples/example.rb +6 -4
  4. data/examples/example.rb~ +112 -0
  5. data/lib/schema/dc.xsd~ +118 -0
  6. data/lib/schema/dcterms.xsd~ +331 -0
  7. data/lib/schema/opc-coreProperties.xsd~ +50 -0
  8. metadata +43 -193
  9. data/Gemfile +0 -3
  10. data/Gemfile.lock +0 -29
  11. data/axlsx.gemspec +0 -42
  12. data/doc/Axlsx.html +0 -2718
  13. data/doc/Axlsx/App.html +0 -2640
  14. data/doc/Axlsx/Axis.html +0 -1075
  15. data/doc/Axlsx/Bar3DChart.html +0 -1182
  16. data/doc/Axlsx/BarSeries.html +0 -711
  17. data/doc/Axlsx/Border.html +0 -779
  18. data/doc/Axlsx/BorderPr.html +0 -709
  19. data/doc/Axlsx/CatAxis.html +0 -769
  20. data/doc/Axlsx/CatAxisData.html +0 -397
  21. data/doc/Axlsx/Cell.html +0 -3187
  22. data/doc/Axlsx/CellAlignment.html +0 -1247
  23. data/doc/Axlsx/CellProtection.html +0 -565
  24. data/doc/Axlsx/CellStyle.html +0 -949
  25. data/doc/Axlsx/Chart.html +0 -1692
  26. data/doc/Axlsx/Color.html +0 -670
  27. data/doc/Axlsx/ContentType.html +0 -335
  28. data/doc/Axlsx/Core.html +0 -465
  29. data/doc/Axlsx/DataTypeValidator.html +0 -324
  30. data/doc/Axlsx/Default.html +0 -565
  31. data/doc/Axlsx/Drawing.html +0 -1264
  32. data/doc/Axlsx/Fill.html +0 -460
  33. data/doc/Axlsx/Font.html +0 -1554
  34. data/doc/Axlsx/GradientFill.html +0 -1026
  35. data/doc/Axlsx/GradientStop.html +0 -526
  36. data/doc/Axlsx/GraphicFrame.html +0 -642
  37. data/doc/Axlsx/Line3DChart.html +0 -1004
  38. data/doc/Axlsx/LineSeries.html +0 -605
  39. data/doc/Axlsx/Marker.html +0 -857
  40. data/doc/Axlsx/NumFmt.html +0 -562
  41. data/doc/Axlsx/OneCellAnchor.html +0 -982
  42. data/doc/Axlsx/Override.html +0 -552
  43. data/doc/Axlsx/Package.html +0 -825
  44. data/doc/Axlsx/Parser.html +0 -549
  45. data/doc/Axlsx/PatternFill.html +0 -681
  46. data/doc/Axlsx/Pic.html +0 -1701
  47. data/doc/Axlsx/PictureLocking.html +0 -1159
  48. data/doc/Axlsx/Pie3DChart.html +0 -489
  49. data/doc/Axlsx/PieSeries.html +0 -710
  50. data/doc/Axlsx/RegexValidator.html +0 -268
  51. data/doc/Axlsx/Relationship.html +0 -554
  52. data/doc/Axlsx/Relationships.html +0 -338
  53. data/doc/Axlsx/RestrictionValidator.html +0 -300
  54. data/doc/Axlsx/Row.html +0 -916
  55. data/doc/Axlsx/Scaling.html +0 -742
  56. data/doc/Axlsx/SerAxis.html +0 -641
  57. data/doc/Axlsx/Series.html +0 -813
  58. data/doc/Axlsx/SeriesTitle.html +0 -290
  59. data/doc/Axlsx/Styles.html +0 -1754
  60. data/doc/Axlsx/TableStyle.html +0 -705
  61. data/doc/Axlsx/TableStyleElement.html +0 -677
  62. data/doc/Axlsx/TableStyles.html +0 -594
  63. data/doc/Axlsx/Title.html +0 -543
  64. data/doc/Axlsx/TwoCellAnchor.html +0 -973
  65. data/doc/Axlsx/ValAxis.html +0 -538
  66. data/doc/Axlsx/ValAxisData.html +0 -321
  67. data/doc/Axlsx/View3D.html +0 -973
  68. data/doc/Axlsx/Workbook.html +0 -1630
  69. data/doc/Axlsx/Worksheet.html +0 -2682
  70. data/doc/Axlsx/Xf.html +0 -1780
  71. data/doc/_index.html +0 -649
  72. data/doc/class_list.html +0 -47
  73. data/doc/css/common.css +0 -1
  74. data/doc/css/full_list.css +0 -55
  75. data/doc/css/style.css +0 -322
  76. data/doc/file.LICENSE.html +0 -91
  77. data/doc/file.README.html +0 -338
  78. data/doc/file_list.html +0 -52
  79. data/doc/frames.html +0 -13
  80. data/doc/index.html +0 -338
  81. data/doc/js/app.js +0 -205
  82. data/doc/js/full_list.js +0 -167
  83. data/doc/js/jquery.js +0 -16
  84. data/doc/method_list.html +0 -3502
  85. data/doc/top-level-namespace.html +0 -103
  86. data/lib/axlsx.rb +0 -54
  87. data/lib/axlsx/content_type/content_type.rb +0 -23
  88. data/lib/axlsx/content_type/default.rb +0 -37
  89. data/lib/axlsx/content_type/override.rb +0 -37
  90. data/lib/axlsx/doc_props/app.rb +0 -178
  91. data/lib/axlsx/doc_props/core.rb +0 -34
  92. data/lib/axlsx/drawing/axis.rb +0 -90
  93. data/lib/axlsx/drawing/bar_3D_chart.rb +0 -128
  94. data/lib/axlsx/drawing/bar_series.rb +0 -64
  95. data/lib/axlsx/drawing/cat_axis.rb +0 -63
  96. data/lib/axlsx/drawing/cat_axis_data.rb +0 -35
  97. data/lib/axlsx/drawing/chart.rb +0 -179
  98. data/lib/axlsx/drawing/drawing.rb +0 -137
  99. data/lib/axlsx/drawing/graphic_frame.rb +0 -52
  100. data/lib/axlsx/drawing/line_3D_chart.rb +0 -106
  101. data/lib/axlsx/drawing/line_series.rb +0 -46
  102. data/lib/axlsx/drawing/marker.rb +0 -61
  103. data/lib/axlsx/drawing/one_cell_anchor.rb +0 -89
  104. data/lib/axlsx/drawing/pic.rb +0 -153
  105. data/lib/axlsx/drawing/picture_locking.rb +0 -72
  106. data/lib/axlsx/drawing/pie_3D_chart.rb +0 -41
  107. data/lib/axlsx/drawing/pie_series.rb +0 -56
  108. data/lib/axlsx/drawing/scaling.rb +0 -59
  109. data/lib/axlsx/drawing/ser_axis.rb +0 -45
  110. data/lib/axlsx/drawing/series.rb +0 -71
  111. data/lib/axlsx/drawing/series_title.rb +0 -22
  112. data/lib/axlsx/drawing/title.rb +0 -61
  113. data/lib/axlsx/drawing/two_cell_anchor.rb +0 -76
  114. data/lib/axlsx/drawing/val_axis.rb +0 -34
  115. data/lib/axlsx/drawing/val_axis_data.rb +0 -28
  116. data/lib/axlsx/drawing/view_3D.rb +0 -85
  117. data/lib/axlsx/package.rb +0 -214
  118. data/lib/axlsx/rels/relationship.rb +0 -44
  119. data/lib/axlsx/rels/relationships.rb +0 -25
  120. data/lib/axlsx/stylesheet/border.rb +0 -57
  121. data/lib/axlsx/stylesheet/border_pr.rb +0 -68
  122. data/lib/axlsx/stylesheet/cell_alignment.rb +0 -105
  123. data/lib/axlsx/stylesheet/cell_protection.rb +0 -36
  124. data/lib/axlsx/stylesheet/cell_style.rb +0 -65
  125. data/lib/axlsx/stylesheet/color.rb +0 -69
  126. data/lib/axlsx/stylesheet/fill.rb +0 -32
  127. data/lib/axlsx/stylesheet/font.rb +0 -139
  128. data/lib/axlsx/stylesheet/gradient_fill.rb +0 -76
  129. data/lib/axlsx/stylesheet/gradient_stop.rb +0 -33
  130. data/lib/axlsx/stylesheet/num_fmt.rb +0 -63
  131. data/lib/axlsx/stylesheet/pattern_fill.rb +0 -66
  132. data/lib/axlsx/stylesheet/styles.rb +0 -298
  133. data/lib/axlsx/stylesheet/table_style.rb +0 -47
  134. data/lib/axlsx/stylesheet/table_style_element.rb +0 -71
  135. data/lib/axlsx/stylesheet/table_styles.rb +0 -39
  136. data/lib/axlsx/stylesheet/xf.rb +0 -138
  137. data/lib/axlsx/util/constants.rb +0 -216
  138. data/lib/axlsx/util/parser.rb +0 -43
  139. data/lib/axlsx/util/simple_typed_list.rb +0 -160
  140. data/lib/axlsx/util/validators.rb +0 -132
  141. data/lib/axlsx/version.rb +0 -4
  142. data/lib/axlsx/workbook/workbook.rb +0 -160
  143. data/lib/axlsx/workbook/worksheet/cell.rb +0 -340
  144. data/lib/axlsx/workbook/worksheet/row.rb +0 -107
  145. data/lib/axlsx/workbook/worksheet/worksheet.rb +0 -278
@@ -1,340 +0,0 @@
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
- # Both 1.8 and 1.9 return the same 'fast_xf'
229
- # &#12491;&#12507;&#12531;&#12468;
230
- # &#12491;&#12507;&#12531;&#12468;
231
-
232
- # however nokogiri does a nice 'force_encoding' which we shall remove!
233
- if @type == :string
234
- #parse formula
235
- if @value.start_with?('=')
236
- xml.c(:r => r, :s=>style) {
237
- xml.f @value.to_s.gsub('=', '')
238
- }
239
- else
240
- #parse standard string
241
- #xml.c(:r => r, :t=>:inlineStr, :s=>style) {
242
- # xml.is { xml.t @value.to_s }
243
- #}
244
- #parse styled string
245
- xml.c(:r => r, :s=>style) {
246
- xml.is {
247
- xml.r {
248
- xml.rPr {
249
- xml.rFont(:val=>@font_name) if @font_name
250
- xml.charset(:val=>@charset) if @charset
251
- xml.family(:val=>@family) if @family
252
- xml.b(:val=>@b) if @b
253
- xml.i(:val=>@i) if @i
254
- xml.strike(:val=>@strike) if @strike
255
- xml.outline(:val=>@outline) if @outline
256
- xml.shadow(:val=>@shadow) if @shadow
257
- xml.condense(:val=>@condense) if @condense
258
- xml.extend(:val=>@extend) if @extend
259
- @color.to_xml(xml) if @color
260
- xml.sz(:val=>@sz) if @sz
261
- xml.u(:val=>@u) if @u
262
- # :baseline, :subscript, :superscript
263
- xml.vertAlign(:val=>@vertAlign) if @verAlign
264
- # :none, major, :minor
265
- xml.scheme(:val=>@scheme) if @scheme
266
- }
267
- xml.t @value.to_s
268
- }
269
- }
270
- }
271
- end
272
-
273
- else
274
- xml.c(:r => r, :s => style) { xml.v value }
275
- end
276
- end
277
-
278
-
279
- private
280
-
281
- # assigns the owning row for this cell.
282
- def row=(v) DataTypeValidator.validate "Cell.row", Row, v; @row=v end
283
-
284
- # converts the column index into alphabetical values.
285
- # @note This follows the standard spreadsheet convention of naming columns A to Z, followed by AA to AZ etc.
286
- # @return [String]
287
- def col_ref
288
- chars = []
289
- index = self.index
290
- while index >= 26 do
291
- chars << ((index % 26) + 65).chr
292
- index /= 26
293
- end
294
- chars << ((chars.empty? ? index : index-1) + 65).chr
295
- chars.reverse.join
296
- end
297
-
298
- # Determines the cell type based on the cell value.
299
- # @note This is only used when a cell is created but no :type option is specified, the following rules apply:
300
- # 1. If the value is an instance of Time, the type is set to :time
301
- # 2. :float and :integer types are determined by regular expression matching.
302
- # 3. Anything that does not meet either of the above is determined to be :string.
303
- # @return [Symbol] The determined type
304
- def cell_type_from_value(v)
305
- if v.is_a? Time
306
- :time
307
- elsif v.to_s.match(/\A[+-]?\d+?\Z/) #numeric
308
- :integer
309
- elsif v.to_s.match(/\A[+-]?\d+\.\d+?\Z/) #float
310
- :float
311
- else
312
- :string
313
- end
314
- end
315
-
316
- # Cast the value into this cells data type.
317
- # @note
318
- # 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.
319
- # @see Axlsx#date1904
320
- def cast_value(v)
321
- if (@type == :time && v.is_a?(Time)) || (@type == :time && v.respond_to?(:to_time))
322
- v = v.respond_to?(:to_time) ? v.to_time : v
323
- self.style = STYLE_DATE if self.style == 0
324
- # Using hardcoded offsets here as some operating systems will not except a 'negative' offset from the ruby epoc.
325
- # (1970)
326
- epoc1900 = -2209021200 #Time.local(1900, 1, 1)
327
- epoc1904 = -2082877200 #Time.local(1904, 1, 1)
328
- epoc = Workbook.date1904 ? epoc1904 : epoc1900
329
- ((v.localtime.to_f - epoc) /60.0/60.0/24.0).to_f
330
- elsif @type == :float
331
- v.to_f
332
- elsif @type == :integer
333
- v.to_i
334
- else
335
- @type = :string
336
- v.to_s
337
- end
338
- end
339
- end
340
- end
@@ -1,107 +0,0 @@
1
- module Axlsx
2
- # A Row is a single row in a worksheet.
3
- # @note The recommended way to manage rows and cells is to use Worksheet#add_row
4
- # @see Worksheet#add_row
5
- class Row
6
-
7
- # The worksheet this row belongs to
8
- # @return [Worksheet]
9
- attr_reader :worksheet
10
-
11
- # The cells this row holds
12
- # @return [SimpleTypedList]
13
- attr_reader :cells
14
-
15
- # Creates a new row. New Cell objects are created based on the values, types and style options.
16
- # A new cell is created for each item in the values array. style and types options are applied as follows:
17
- # If the types option is defined and is a symbol it is applied to all the cells created.
18
- # If the types option is an array, cell types are applied by index for each cell
19
- # If the types option is not set, the cell will automatically determine its type.
20
- # If the style option is defined and is an Integer, it is applied to all cells created.
21
- # If the style option is an array, style is applied by index for each cell.
22
- # If the style option is not defined, the default style (0) is applied to each cell.
23
- # @param [Worksheet] worksheet
24
- # @option options [Array] values
25
- # @option options [Array, Symbol] types
26
- # @option options [Array, Integer] style
27
- # @see Row#array_to_cells
28
- # @see Cell
29
- def initialize(worksheet, values=[], options={})
30
- self.worksheet = worksheet
31
- @cells = SimpleTypedList.new Cell
32
- @worksheet.rows << self
33
- array_to_cells(values, options)
34
- end
35
-
36
- # The index of this row in the worksheet
37
- # @return [Integer]
38
- def index
39
- worksheet.rows.index(self)
40
- end
41
-
42
- # Serializes the row
43
- # @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
44
- # @return [String]
45
- def to_xml(xml)
46
- xml.row(:r => index+1) { @cells.each { |cell| cell.to_xml(xml) } }
47
- end
48
-
49
- # Adds a singel sell to the row based on the data provided and updates the worksheet's autofit data.
50
- # @return [Cell]
51
- def add_cell(value="", options={})
52
- c = Cell.new(self, value, options)
53
- update_auto_fit_data
54
- c
55
- end
56
-
57
- # sets the style for every cell in this row
58
- def style=(style)
59
- cells.each_with_index do | cell, index |
60
- s = style.is_a?(Array) ? style[index] : style
61
- cell.style = s
62
- end
63
- end
64
-
65
- # returns the cells in this row as an array
66
- # This lets us transpose the rows into columns
67
- # @return [Array]
68
- def to_ary
69
- @cells.to_ary
70
- end
71
-
72
- private
73
-
74
- # assigns the owning worksheet for this row
75
- def worksheet=(v) DataTypeValidator.validate "Row.worksheet", Worksheet, v; @worksheet=v; end
76
-
77
- # Tell the worksheet to update autofit data for the columns based on this row's cells.
78
- # @return [SimpleTypedList]
79
- def update_auto_fit_data
80
- worksheet.send(:update_auto_fit_data, self.cells)
81
- end
82
-
83
-
84
- # Converts values, types, and style options into cells and associates them with this row.
85
- # A new cell is created for each item in the values array.
86
- # If value option is defined and is a symbol it is applied to all the cells created.
87
- # If the value option is an array, cell types are applied by index for each cell
88
- # If the style option is defined and is an Integer, it is applied to all cells created.
89
- # If the style option is an array, style is applied by index for each cell.
90
- # @option options [Array] values
91
- # @option options [Array, Symbol] types
92
- # @option options [Array, Integer] style
93
- def array_to_cells(values, options={})
94
- values = values
95
- DataTypeValidator.validate 'Row.array_to_cells', Array, values
96
- types, style = options.delete(:types), options.delete(:style)
97
- values.each_with_index do |value, index|
98
- cell_style = style.is_a?(Array) ? style[index] : style
99
- options[:style] = cell_style if cell_style
100
- cell_type = types.is_a?(Array)? types[index] : types
101
- options[:type] = cell_type if cell_type
102
- Cell.new(self, value, options)
103
- end
104
- end
105
- end
106
-
107
- end
@@ -1,278 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- module Axlsx
3
-
4
- # The Worksheet class represents a worksheet in the workbook.
5
- class Worksheet
6
-
7
- # The name of the worksheet
8
- # @return [String]
9
- attr_reader :name
10
-
11
- # The workbook that owns this worksheet
12
- # @return [Workbook]
13
- attr_reader :workbook
14
-
15
-
16
- # The rows in this worksheet
17
- # @note The recommended way to manage rows is Worksheet#add_row
18
- # @return [SimpleTypedList]
19
- # @see Worksheet#add_row
20
- attr_reader :rows
21
-
22
- # An array of content based calculated column widths.
23
- # @note a single auto fit data item is a hash with :longest => [String] and :sz=> [Integer] members.
24
- # @return [Array] of Hash
25
- attr_reader :auto_fit_data
26
-
27
- # TODO Merge Cells
28
- # attr_reader :merge_cells
29
-
30
- # Creates a new worksheet.
31
- # @note the recommended way to manage worksheets is Workbook#add_worksheet
32
- # @see Workbook#add_worksheet
33
- # @option options [String] name The name of this sheet.
34
- def initialize(wb, options={})
35
- @drawing = nil
36
- @rows = SimpleTypedList.new Row
37
- self.workbook = wb
38
- @workbook.worksheets << self
39
- @auto_fit_data = []
40
- self.name = options[:name] || "Sheet" + (index+1).to_s
41
- @magick_draw = Magick::Draw.new
42
- @cols = SimpleTypedList.new Cell
43
- end
44
-
45
- # Returns the cell or cells defined using excel style A1:B3 references.
46
- # @param [String] cell_def the string defining the cell or range of cells
47
- # @return [Cell, Array]
48
- def [](cell_def)
49
- parts = cell_def.split(':')
50
- first = name_to_cell parts[0]
51
-
52
- if parts.size == 1
53
- first
54
- else
55
- cells = []
56
- last = name_to_cell(parts[1])
57
- rows[(first.row.index..last.row.index)].each do |r|
58
- r.cells[(first.index..last.index)].each do |c|
59
- cells << c
60
- end
61
- end
62
- cells
63
- end
64
- end
65
-
66
- # returns the column and row index for a named based cell
67
- # @param [String] name The cell or cell range to return. "A1" will return the first cell of the first row.
68
- # @return [Cell]
69
- def name_to_cell(name)
70
- col_index, row_index = *Axlsx::name_to_indices(name)
71
- r = rows[row_index]
72
- r.cells[col_index] if r
73
- end
74
-
75
- # The name of the worksheet
76
- # @param [String] v
77
- def name=(v)
78
- DataTypeValidator.validate "Worksheet.name", String, v
79
- sheet_names = @workbook.worksheets.map { |s| s.name }
80
- raise ArgumentError, (ERR_DUPLICATE_SHEET_NAME % v) if sheet_names.include?(v)
81
- @name=v
82
- end
83
-
84
- # The part name of this worksheet
85
- # @return [String]
86
- def pn
87
- "#{WORKSHEET_PN % (index+1)}"
88
- end
89
-
90
- # The relationship part name of this worksheet
91
- # @return [String]
92
- def rels_pn
93
- "#{WORKSHEET_RELS_PN % (index+1)}"
94
- end
95
-
96
- # The relationship Id of thiw worksheet
97
- # @return [String]
98
- def rId
99
- "rId#{index+1}"
100
- end
101
-
102
- # The index of this worksheet in the owning Workbook's worksheets list.
103
- # @return [Integer]
104
- def index
105
- @workbook.worksheets.index(self)
106
- end
107
-
108
- # The drawing associated with this worksheet.
109
- # @note the recommended way to work with drawings and charts is Worksheet#add_chart
110
- # @return [Drawing]
111
- # @see Worksheet#add_chart
112
- def drawing
113
- @drawing || @drawing = Axlsx::Drawing.new(self)
114
- end
115
-
116
- # Adds a row to the worksheet and updates auto fit data
117
- # @return [Row]
118
- # @option options [Array] values
119
- # @option options [Array, Symbol] types
120
- # @option options [Array, Integer] style
121
- def add_row(values=[], options={})
122
- Row.new(self, values, options)
123
- update_auto_fit_data @rows.last.cells
124
- yield @rows.last if block_given?
125
- @rows.last
126
- end
127
-
128
- # Set the style for cells in a specific row
129
- # @param [Integer] index or range of indexes in the table
130
- # @param [Integer] the cellXfs index
131
- # @option options [Integer] col_offset only cells after this column will be updated.
132
- # @note You can also specify the style in the add_row call
133
- # @see Worksheet#add_row
134
- # @see README.md for an example
135
- def row_style(index, style, options={})
136
- offset = options.delete(:col_offset) || 0
137
- rs = @rows[index]
138
- if rs.is_a?(Array)
139
- rs.each { |r| r.cells[(offset..-1)].each { |c| c.style = style } }
140
- else
141
- rs.cells[(offset..-1)].each { |c| c.style = style }
142
- end
143
- end
144
-
145
- # returns the sheet data as columnw
146
- def cols
147
- @rows.transpose
148
- end
149
-
150
-
151
- # Set the style for cells in a specific column
152
- # @param [Integer] index the index of the column
153
- # @param [Integer] the cellXfs index
154
- # @option options [Integer] row_offset only cells after this column will be updated.
155
- # @note You can also specify the style for specific columns in the call to add_row by using an array for the :styles option
156
- # @see Worksheet#add_row
157
- # @see README.md for an example
158
- def col_style(index, style, options={})
159
- offset = options.delete(:row_offset) || 0
160
- @rows[(offset..-1)].each do |r|
161
- cells = r.cells[index]
162
- if cells.is_a?(Array)
163
- cells.each { |c| c.style = style }
164
- else
165
- cells.style = style
166
- end
167
- end
168
- end
169
-
170
- # Adds a chart to this worksheets drawing. This is the recommended way to create charts for your worksheet. This method wraps the complexity of dealing with ooxml drawing, anchors, markers graphic frames chart objects and all the other dirty details.
171
- # @param [Class] chart_type
172
- # @option options [Array] start_at
173
- # @option options [Array] end_at
174
- # @option options [Cell, String] title
175
- # @option options [Boolean] show_legend
176
- # @option options [Integer] style
177
- # @note each chart type also specifies additional options
178
- # @see Chart
179
- # @see Pie3DChart
180
- # @see Bar3DChart
181
- # @see Line3DChart
182
- # @see README for examples
183
- def add_chart(chart_type, options={})
184
- chart = drawing.add_chart(chart_type, options)
185
- yield chart if block_given?
186
- chart
187
- end
188
-
189
- # Adds a media item to the worksheets drawing
190
- # @param [Class] media_type
191
- # @option options [] unknown
192
- def add_image(options={})
193
- image = drawing.add_image(options)
194
- yield image if block_given?
195
- image
196
- end
197
-
198
- # Serializes the worksheet document
199
- # @return [String]
200
- def to_xml
201
- builder = Nokogiri::XML::Builder.new(:encoding => ENCODING) do |xml|
202
- xml.worksheet(:xmlns => XML_NS, :'xmlns:r' => XML_NS_R) {
203
- if @auto_fit_data.size > 0
204
- xml.cols {
205
- @auto_fit_data.each_with_index do |col, index|
206
- min_max = index+1
207
- xml.col(:min=>min_max, :max=>min_max, :width => auto_width(col), :customWidth=>"true")
208
- end
209
- }
210
- end
211
- xml.sheetData {
212
- @rows.each do |row|
213
- row.to_xml(xml)
214
- end
215
- }
216
- xml.drawing :"r:id"=>"rId1" if @drawing
217
- }
218
- end
219
- builder.to_xml
220
- end
221
-
222
- # The worksheet relationships. This is managed automatically by the worksheet
223
- # @return [Relationships]
224
- def relationships
225
- r = Relationships.new
226
- r << Relationship.new(DRAWING_R, "../#{@drawing.pn}") if @drawing
227
- r
228
- end
229
-
230
- private
231
-
232
- # assigns the owner workbook for this worksheet
233
- def workbook=(v) DataTypeValidator.validate "Worksheet.workbook", Workbook, v; @workbook = v; end
234
-
235
- # Updates auto fit data.
236
- # Autofit data attempts to determine the cell in a column that has the greatest width by comparing the length of the text multiplied by the size of the font.
237
- # @return [Array] of Cell objects
238
- # @param [Array] cells an array of cells
239
- def update_auto_fit_data(cells)
240
- styles = self.workbook.styles
241
- cellXfs, fonts = styles.cellXfs, styles.fonts
242
- sz = fonts[0].sz
243
- cells.each_with_index do |item, index|
244
- next if item.value.is_a?(String) && item.value.start_with?('=')
245
- col = @auto_fit_data[index] || {:longest=>"", :sz=>sz}
246
- cell_xf = cellXfs[item.style]
247
- font = fonts[cell_xf.fontId || 0]
248
- sz = item.sz || font.sz || fonts[0].sz
249
- if (col[:longest].scan(/./mu).size * col[:sz]) < (item.value.to_s.scan(/./mu).size * sz)
250
- col[:sz] = sz
251
- col[:longest] = item.value.to_s
252
- end
253
- @auto_fit_data[index] = col
254
- end
255
- cells
256
- end
257
-
258
- # Determines the proper width for a column based on content.
259
- # @note
260
- # From ECMA docs
261
- # Column width measured as the number of characters of the maximum digit width of the numbers 0 .. 9 as
262
- # rendered in the normal style's font. There are 4 pixels of margin padding (two on each side), plus 1 pixel padding for the gridlines.
263
- # width = Truncate([!{Number of Characters} * !{Maximum Digit Width} + !{5 pixel padding}]/{Maximum Digit Width}*256)/256
264
- # @return [Float]
265
- # @param [Hash] A hash of auto_fit_data
266
- def auto_width(col)
267
- mdw = 6.0 # maximum digit with is always 6.0 with RMagick's default font
268
- mdw_count = 0
269
- best_guess = 1.5 #direct testing shows the results of the documented formula to be a bit too small. This is a best guess scaling
270
- font_scale = col[:sz].to_f / (self.workbook.styles.fonts[0].sz.to_f || 11.0)
271
-
272
- col[:longest].scan(/./mu).each do |i|
273
- mdw_count +=1 if @magick_draw.get_type_metrics(i).width >= mdw
274
- end
275
- ((mdw_count * mdw + 5) / mdw * 256) / 256.0 * best_guess * font_scale
276
- end
277
- end
278
- end