axlsx 1.0.17 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. data/CHANGELOG.md +11 -3
  2. data/README.md +159 -51
  3. data/examples/example.csv +1000 -0
  4. data/examples/example.rb +255 -150
  5. data/examples/example.xlsx +0 -0
  6. data/examples/example_streamed.xlsx +0 -0
  7. data/examples/no-use_autowidth.xlsx +0 -0
  8. data/examples/shared_strings_example.xlsx +0 -0
  9. data/lib/axlsx/content_type/content_type.rb +12 -12
  10. data/lib/axlsx/content_type/default.rb +9 -6
  11. data/lib/axlsx/content_type/override.rb +12 -8
  12. data/lib/axlsx/doc_props/app.rb +37 -40
  13. data/lib/axlsx/doc_props/core.rb +12 -17
  14. data/lib/axlsx/drawing/axis.rb +38 -19
  15. data/lib/axlsx/drawing/bar_3D_chart.rb +33 -32
  16. data/lib/axlsx/drawing/bar_series.rb +13 -14
  17. data/lib/axlsx/drawing/cat_axis.rb +15 -14
  18. data/lib/axlsx/drawing/cat_axis_data.rb +16 -18
  19. data/lib/axlsx/drawing/chart.rb +39 -40
  20. data/lib/axlsx/drawing/drawing.rb +15 -12
  21. data/lib/axlsx/drawing/graphic_frame.rb +21 -21
  22. data/lib/axlsx/drawing/hyperlink.rb +12 -11
  23. data/lib/axlsx/drawing/line_3D_chart.rb +30 -28
  24. data/lib/axlsx/drawing/line_series.rb +11 -11
  25. data/lib/axlsx/drawing/marker.rb +10 -8
  26. data/lib/axlsx/drawing/named_axis_data.rb +36 -0
  27. data/lib/axlsx/drawing/one_cell_anchor.rb +17 -16
  28. data/lib/axlsx/drawing/pic.rb +25 -37
  29. data/lib/axlsx/drawing/picture_locking.rb +21 -18
  30. data/lib/axlsx/drawing/pie_3D_chart.rb +10 -8
  31. data/lib/axlsx/drawing/pie_series.rb +15 -12
  32. data/lib/axlsx/drawing/scaling.rb +10 -10
  33. data/lib/axlsx/drawing/scatter_chart.rb +69 -0
  34. data/lib/axlsx/drawing/scatter_series.rb +39 -0
  35. data/lib/axlsx/drawing/ser_axis.rb +10 -10
  36. data/lib/axlsx/drawing/series.rb +15 -15
  37. data/lib/axlsx/drawing/series_title.rb +14 -14
  38. data/lib/axlsx/drawing/title.rb +26 -26
  39. data/lib/axlsx/drawing/two_cell_anchor.rb +18 -20
  40. data/lib/axlsx/drawing/val_axis.rb +8 -7
  41. data/lib/axlsx/drawing/val_axis_data.rb +17 -17
  42. data/lib/axlsx/drawing/view_3D.rb +22 -20
  43. data/lib/axlsx/package.rb +60 -43
  44. data/lib/axlsx/rels/relationship.rb +11 -8
  45. data/lib/axlsx/rels/relationships.rb +7 -1
  46. data/lib/axlsx/stylesheet/#num_fmt.rb# +69 -0
  47. data/lib/axlsx/stylesheet/border.rb +27 -23
  48. data/lib/axlsx/stylesheet/border_pr.rb +16 -15
  49. data/lib/axlsx/stylesheet/cell_alignment.rb +23 -21
  50. data/lib/axlsx/stylesheet/cell_protection.rb +10 -7
  51. data/lib/axlsx/stylesheet/cell_style.rb +8 -5
  52. data/lib/axlsx/stylesheet/color.rb +20 -14
  53. data/lib/axlsx/stylesheet/fill.rb +7 -5
  54. data/lib/axlsx/stylesheet/font.rb +21 -14
  55. data/lib/axlsx/stylesheet/gradient_fill.rb +19 -16
  56. data/lib/axlsx/stylesheet/gradient_stop.rb +9 -5
  57. data/lib/axlsx/stylesheet/num_fmt.rb +12 -6
  58. data/lib/axlsx/stylesheet/pattern_fill.rb +25 -10
  59. data/lib/axlsx/stylesheet/styles.rb +47 -35
  60. data/lib/axlsx/stylesheet/table_style.rb +9 -4
  61. data/lib/axlsx/stylesheet/table_style_element.rb +10 -7
  62. data/lib/axlsx/stylesheet/table_styles.rb +11 -8
  63. data/lib/axlsx/stylesheet/xf.rb +29 -25
  64. data/lib/axlsx/util/constants.rb +20 -14
  65. data/lib/axlsx/util/simple_typed_list.rb +18 -9
  66. data/lib/axlsx/util/validators.rb +13 -6
  67. data/lib/axlsx/version.rb +1 -1
  68. data/lib/axlsx/workbook/shared_strings_table.rb +19 -21
  69. data/lib/axlsx/workbook/workbook.rb +58 -34
  70. data/lib/axlsx/workbook/worksheet/cell.rb +149 -132
  71. data/lib/axlsx/workbook/worksheet/col.rb +114 -0
  72. data/lib/axlsx/workbook/worksheet/col.rb~ +0 -0
  73. data/lib/axlsx/workbook/worksheet/date_time_converter.rb +29 -0
  74. data/lib/axlsx/workbook/worksheet/page_margins.rb +97 -0
  75. data/lib/axlsx/workbook/worksheet/row.rb +40 -23
  76. data/lib/axlsx/workbook/worksheet/table.rb +96 -0
  77. data/lib/axlsx/workbook/worksheet/table.rb~ +97 -0
  78. data/lib/axlsx/workbook/worksheet/worksheet.rb +243 -127
  79. data/lib/axlsx.rb +30 -9
  80. data/lib/schema/dc.xsd +5 -5
  81. data/lib/schema/dcmitype.xsd +5 -3
  82. data/lib/schema/dcterms.xsd +15 -15
  83. data/lib/schema/opc-coreProperties.xsd +6 -2
  84. data/lib/schema/xml.xsd +7 -8
  85. data/test/#benchmark.txt# +7 -0
  86. data/test/#tc_helper.rb# +3 -0
  87. data/test/benchmark.rb +81 -0
  88. data/test/benchmark.rb~ +0 -0
  89. data/test/benchmark.txt +6 -0
  90. data/test/benchmark.txt~ +6 -0
  91. data/test/content_type/tc_content_type.rb +30 -32
  92. data/test/content_type/tc_default.rb +8 -23
  93. data/test/content_type/tc_override.rb +7 -21
  94. data/test/doc_props/tc_app.rb +2 -8
  95. data/test/doc_props/tc_core.rb +6 -7
  96. data/test/drawing/tc_axis.rb +7 -3
  97. data/test/drawing/tc_bar_3D_chart.rb +6 -7
  98. data/test/drawing/tc_bar_series.rb +4 -5
  99. data/test/drawing/tc_cat_axis.rb +2 -3
  100. data/test/drawing/tc_cat_axis_data.rb +2 -3
  101. data/test/drawing/tc_chart.rb +13 -14
  102. data/test/drawing/tc_drawing.rb +7 -8
  103. data/test/drawing/tc_graphic_frame.rb +3 -4
  104. data/test/drawing/tc_hyperlink.rb +2 -3
  105. data/test/drawing/tc_line_3d_chart.rb +5 -6
  106. data/test/drawing/tc_line_series.rb +3 -4
  107. data/test/drawing/tc_marker.rb +3 -4
  108. data/test/drawing/tc_one_cell_anchor.rb +6 -7
  109. data/test/drawing/tc_pic.rb +8 -9
  110. data/test/drawing/tc_picture_locking.rb +2 -3
  111. data/test/drawing/tc_pie_3D_chart.rb +5 -6
  112. data/test/drawing/tc_pie_series.rb +4 -5
  113. data/test/drawing/tc_scaling.rb +3 -4
  114. data/test/drawing/tc_scatter_chart.rb +43 -0
  115. data/test/drawing/tc_scatter_series.rb +20 -0
  116. data/test/drawing/tc_ser_axis.rb +2 -3
  117. data/test/drawing/tc_series.rb +4 -5
  118. data/test/drawing/tc_series_title.rb +4 -5
  119. data/test/drawing/tc_title.rb +4 -5
  120. data/test/drawing/tc_two_cell_anchor.rb +4 -5
  121. data/test/drawing/tc_val_axis.rb +2 -3
  122. data/test/drawing/tc_val_axis_data.rb +2 -3
  123. data/test/drawing/tc_view_3D.rb +6 -7
  124. data/test/example.csv +1000 -0
  125. data/test/example.xlsx +0 -0
  126. data/test/example_streamed.xlsx +0 -0
  127. data/test/profile.rb +33 -0
  128. data/test/rels/tc_relationship.rb +5 -6
  129. data/test/rels/tc_relationships.rb +4 -5
  130. data/test/stylesheet/tc_border.rb +3 -4
  131. data/test/stylesheet/tc_border_pr.rb +3 -4
  132. data/test/stylesheet/tc_cell_alignment.rb +10 -6
  133. data/test/stylesheet/tc_cell_protection.rb +2 -3
  134. data/test/stylesheet/tc_cell_style.rb +2 -3
  135. data/test/stylesheet/tc_color.rb +2 -3
  136. data/test/stylesheet/tc_fill.rb +1 -2
  137. data/test/stylesheet/tc_font.rb +12 -5
  138. data/test/stylesheet/tc_gradient_fill.rb +1 -2
  139. data/test/stylesheet/tc_gradient_stop.rb +1 -2
  140. data/test/stylesheet/tc_num_fmt.rb +1 -2
  141. data/test/stylesheet/tc_pattern_fill.rb +3 -4
  142. data/test/stylesheet/tc_styles.rb +16 -6
  143. data/test/stylesheet/tc_table_style.rb +2 -3
  144. data/test/stylesheet/tc_table_style_element.rb +2 -3
  145. data/test/stylesheet/tc_table_styles.rb +3 -4
  146. data/test/stylesheet/tc_xf.rb +16 -17
  147. data/test/tc_axlsx.rb +39 -0
  148. data/test/tc_axlsx.rb~ +0 -0
  149. data/test/tc_helper.rb +3 -0
  150. data/test/tc_helper.rb~ +3 -0
  151. data/test/tc_package.rb +13 -10
  152. data/test/util/tc_simple_typed_list.rb +8 -9
  153. data/test/util/tc_validators.rb +7 -8
  154. data/test/workbook/tc_shared_strings_table.rb +5 -6
  155. data/test/workbook/tc_workbook.rb +24 -6
  156. data/test/workbook/worksheet/table/tc_table.rb +71 -0
  157. data/test/workbook/worksheet/table/tc_table.rb~ +72 -0
  158. data/test/workbook/worksheet/tc_cell.rb +62 -18
  159. data/test/workbook/worksheet/tc_col.rb +59 -0
  160. data/test/workbook/worksheet/tc_col.rb~ +10 -0
  161. data/test/workbook/worksheet/tc_date_time_converter.rb +126 -0
  162. data/test/workbook/worksheet/tc_page_margins.rb +97 -0
  163. data/test/workbook/worksheet/tc_row.rb +54 -4
  164. data/test/workbook/worksheet/tc_worksheet.rb +177 -34
  165. metadata +69 -41
  166. data/test/drawing/tc_hyperlink.rb~ +0 -71
  167. data/test/workbook/tc_shared_strings_table.rb~ +0 -8
@@ -120,25 +120,26 @@ module Axlsx
120
120
  end
121
121
 
122
122
  # Drastically simplifies style creation and management.
123
- # @return [Integer]
123
+ # @return [Integer]
124
124
  # @option options [String] fg_color The text color
125
125
  # @option options [Integer] sz The text size
126
126
  # @option options [Boolean] b Indicates if the text should be bold
127
127
  # @option options [Boolean] i Indicates if the text should be italicised
128
+ # @option options [Boolean] u Indicates if the text should be underlined
128
129
  # @option options [Boolean] strike Indicates if the text should be rendered with a strikethrough
129
130
  # @option options [Boolean] strike Indicates if the text should be rendered with a shadow
130
131
  # @option options [Integer] charset The character set to use.
131
132
  # @option options [Integer] family The font family to use.
132
- # @option options [String] name The name of the font to use
133
+ # @option options [String] font_name The name of the font to use
133
134
  # @option options [Integer] num_fmt The number format to apply
134
135
  # @option options [String] format_code The formatting to apply. If this is specified, num_fmt is ignored.
135
- # @option options [Integer] border The border style to use.
136
+ # @option options [Integer] border The border style to use.
136
137
  # @option options [String] bg_color The background color to apply to the cell
137
138
  # @option options [Boolean] hidden Indicates if the cell should be hidden
138
139
  # @option options [Boolean] locked Indicates if the cell should be locked
139
140
  # @option options [Hash] alignment A hash defining any of the attributes used in CellAlignment
140
141
  # @see CellAlignment
141
- #
142
+ #
142
143
  # @example You Got Style
143
144
  # require "rubygems" # if that is your preferred way to manage gems!
144
145
  # require "axlsx"
@@ -147,7 +148,7 @@ module Axlsx
147
148
  # ws = p.workbook.add_worksheet
148
149
  #
149
150
  # # black text on a white background at 14pt with thin borders!
150
- # title = ws.style.add_style(:bg_color => "FFFF0000", :fg_color=>"#FF000000", :sz=>14, :border=>Axlsx::STYLE_THIN_BORDER
151
+ # title = ws.style.add_style(:bg_color => "FFFF0000", :fg_color=>"#FF000000", :sz=>14, :border=> {:style => :thin, :color => "FFFF0000"}
151
152
  #
152
153
  # ws.add_row :values => ["Least Popular Pets"]
153
154
  # ws.add_row :values => ["", "Dry Skinned Reptiles", "Bald Cats", "Violent Parrots"], :style=>title
@@ -164,15 +165,15 @@ module Axlsx
164
165
  # ws = p.workbook.add_worksheet
165
166
  #
166
167
  # # define your styles
167
- # title = ws.style.add_style(:bg_color => "FFFF0000",
168
+ # title = ws.style.add_style(:bg_color => "FFFF0000",
168
169
  # :fg_color=>"#FF000000",
169
- # :border=>Axlsx::STYLE_THIN_BORDER,
170
+ # :border=>Axlsx::STYLE_THIN_BORDER,
170
171
  # :alignment=>{:horizontal => :center})
171
172
  #
172
173
  # date_time = ws.style.add_style(:num_fmt => Axlsx::NUM_FMT_YYYYMMDDHHMMSS,
173
174
  # :border=>Axlsx::STYLE_THIN_BORDER)
174
175
  #
175
- # percent = ws.style.add_style(:num_fmt => Axlsx::NUM_FMT_PERCENT,
176
+ # percent = ws.style.add_style(:num_fmt => Axlsx::NUM_FMT_PERCENT,
176
177
  # :border=>Axlsx::STYLE_THIN_BORDER)
177
178
  #
178
179
  # currency = ws.style.add_style(:format_code=>"¥#,##0;[Red]¥-#,##0",
@@ -189,7 +190,7 @@ module Axlsx
189
190
  # f = File.open('example_you_got_style.xlsx', 'w')
190
191
  # p.serialize(f)
191
192
  def add_style(options={})
192
-
193
+
193
194
  numFmtId = if options[:format_code]
194
195
  n = @numFmts.map{ |f| f.numFmtId }.max + 1
195
196
  numFmts << NumFmt.new(:numFmtId => n, :formatCode=> options[:format_code])
@@ -197,60 +198,71 @@ module Axlsx
197
198
  else
198
199
  options[:num_fmt] || 0
199
200
  end
200
-
201
+
201
202
  borderId = options[:border] || 0
203
+
204
+ if borderId.is_a?(Hash)
205
+ raise ArgumentError, "border hash definitions must include both style and color" unless borderId.keys.include?(:style) && borderId.keys.include?(:color)
206
+
207
+ s = borderId.delete :style
208
+ c = borderId.delete :color
209
+ border = Border.new
210
+ [:left, :right, :top, :bottom].each {|pr| border.prs << BorderPr.new(:name => pr, :style=>s, :color => Color.new(:rgb => c))}
211
+ borderId = self.borders << border
212
+ end
213
+
202
214
  raise ArgumentError, "Invalid borderId" unless borderId < borders.size
203
-
215
+
204
216
  fill = if options[:bg_color]
205
217
  color = Color.new(:rgb=>options[:bg_color])
206
218
  pattern = PatternFill.new(:patternType =>:solid, :fgColor=>color)
207
- fills << Fill.new(pattern)
219
+ fills << Fill.new(pattern)
208
220
  else
209
221
  0
210
222
  end
211
-
212
- fontId = if (options.values_at(:fg_color, :sz, :b, :i, :strike, :outline, :shadow, :charset, :family, :font_name).length)
223
+
224
+ fontId = if (options.values_at(:fg_color, :sz, :b, :i, :u, :strike, :outline, :shadow, :charset, :family, :font_name).length)
213
225
  font = Font.new()
214
- [:b, :i, :strike, :outline, :shadow, :charset, :family, :sz].each { |k| font.send("#{k}=", options[k]) unless options[k].nil? }
226
+ [:b, :i, :u, :strike, :outline, :shadow, :charset, :family, :sz].each { |k| font.send("#{k}=", options[k]) unless options[k].nil? }
215
227
  font.color = Color.new(:rgb => options[:fg_color]) unless options[:fg_color].nil?
216
228
  font.name = options[:font_name] unless options[:font_name].nil?
217
229
  fonts << font
218
230
  else
219
- 0
231
+ 0
220
232
  end
221
-
233
+
222
234
  applyProtection = (options[:hidden] || options[:locked]) ? 1 : 0
223
-
235
+
224
236
  xf = Xf.new(:fillId => fill, :fontId=>fontId, :applyFill=>1, :applyFont=>1, :numFmtId=>numFmtId, :borderId=>borderId, :applyProtection=>applyProtection)
225
237
 
226
238
  xf.applyNumberFormat = true if xf.numFmtId > 0
227
-
239
+ xf.applyBorder = true if borderId > 0
240
+
228
241
  if options[:alignment]
229
242
  xf.alignment = CellAlignment.new(options[:alignment])
243
+ xf.applyAlignment = true
230
244
  end
231
-
245
+
232
246
  if applyProtection
233
247
  xf.protection = CellProtection.new(options)
234
248
  end
235
-
249
+
236
250
  cellXfs << xf
237
251
  end
238
-
239
- # Serializes the styles document
252
+
253
+ # Serializes the object
254
+ # @param [String] str
240
255
  # @return [String]
241
- def to_xml()
242
- builder = Nokogiri::XML::Builder.new(:encoding => ENCODING) do |xml|
243
- xml.styleSheet(:xmlns => XML_NS) {
244
- [:numFmts, :fonts, :fills, :borders, :cellStyleXfs, :cellXfs, :cellStyles, :dxfs, :tableStyles].each do |key|
245
- self.instance_values[key.to_s].to_xml(xml) unless self.instance_values[key.to_s].nil?
246
- end
247
- }
256
+ def to_xml_string(str = '')
257
+ str << '<styleSheet xmlns="' << XML_NS << '">'
258
+ [:numFmts, :fonts, :fills, :borders, :cellStyleXfs, :cellXfs, :cellStyles, :dxfs, :tableStyles].each do |key|
259
+ self.instance_values[key.to_s].to_xml_string(str) unless self.instance_values[key.to_s].nil?
248
260
  end
249
- builder.to_xml(:save_with => 0)
261
+ str << '</styleSheet>'
250
262
  end
251
263
 
252
264
  private
253
- # Creates the default set of styles the exel requires to be valid as well as setting up the
265
+ # Creates the default set of styles the exel requires to be valid as well as setting up the
254
266
  # Axlsx::STYLE_THIN_BORDER
255
267
  def load_default_styles
256
268
  @numFmts = SimpleTypedList.new NumFmt, 'numFmts'
@@ -271,8 +283,8 @@ module Axlsx
271
283
  @borders = SimpleTypedList.new Border, 'borders'
272
284
  @borders << Border.new
273
285
  black_border = Border.new
274
- [:left, :right, :top, :bottom].each do |item|
275
- black_border.prs << BorderPr.new(:name=>item, :style=>:thin, :color=>Color.new(:rgb=>"FF000000"))
286
+ [:left, :right, :top, :bottom].each do |item|
287
+ black_border.prs << BorderPr.new(:name=>item, :style=>:thin, :color=>Color.new(:rgb=>"FF000000"))
276
288
  end
277
289
  @borders << black_border
278
290
  @borders.lock
@@ -297,4 +309,4 @@ module Axlsx
297
309
  end
298
310
  end
299
311
  end
300
-
312
+
@@ -36,13 +36,18 @@ module Axlsx
36
36
  # @see table
37
37
  def table=(v) Axlsx::validate_boolean v; @table=v end
38
38
 
39
- # Serializes the table style
40
- # @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
39
+ # Serializes the object
40
+ # @param [String] str
41
41
  # @return [String]
42
- def to_xml(xml)
42
+ def to_xml_string(str = '')
43
43
  attr = self.instance_values.select { |k, v| [:name, :pivot, :table].include? k }
44
44
  attr[:count] = self.size
45
- xml.tableStyle(attr) { self.each { |table_style_el| table_style_el.to_xml(xml) } }
45
+ str << '<tableStyle '
46
+ str << attr.map { |key, value| '' << key.to_s << '="' << value.to_s << '"' }.join(' ')
47
+ str << '>'
48
+ each { |table_style_el| table_style_el.to_xml_string(str) }
49
+ str << '</tableStyle>'
46
50
  end
51
+
47
52
  end
48
53
  end
@@ -1,7 +1,7 @@
1
1
  # encoding: UTF-8
2
2
  module Axlsx
3
- # an element of style that belongs to a table style.
4
- # @note tables and table styles are not supported in this version. This class exists in preparation for that support.
3
+ # an element of style that belongs to a table style.
4
+ # @note tables and table styles are not supported in this version. This class exists in preparation for that support.
5
5
  class TableStyleElement
6
6
  # The type of style element. The following type are allowed
7
7
  # :wholeTable
@@ -39,7 +39,7 @@ module Axlsx
39
39
  # @return [Integer]
40
40
  attr_reader :size
41
41
 
42
- # The dxfId this style element points to
42
+ # The dxfId this style element points to
43
43
  # @return [Integer]
44
44
  attr_reader :dxfId
45
45
 
@@ -62,11 +62,14 @@ module Axlsx
62
62
  # @see dxfId
63
63
  def dxfId=(v) Axlsx::validate_unsigned_int v; @dxfId = v end
64
64
 
65
- # Serializes the table style element
66
- # @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
65
+ # Serializes the object
66
+ # @param [String] str
67
67
  # @return [String]
68
- def to_xml(xml)
69
- xml.tableStyleElement self.instance_values
68
+ def to_xml_string(str = '')
69
+ str << '<tableStyleElement '
70
+ str << instance_values.map { |key, value| '' << key.to_s << '="' << value.to_s << '"' }.join(' ')
71
+ str << '/>'
70
72
  end
73
+
71
74
  end
72
75
  end
@@ -11,13 +11,13 @@ module Axlsx
11
11
  # The default pivot table style. The default value is 'PivotStyleLight6'
12
12
  # @return [String]
13
13
  attr_reader :defaultPivotStyle
14
-
14
+
15
15
  # Creates a new TableStyles object that is a container for TableStyle objects
16
16
  # @option options [String] defaultTableStyle
17
17
  # @option options [String] defaultPivotStyle
18
18
  def initialize(options={})
19
19
  @defaultTableStyle = options[:defaultTableStyle] || "TableStyleMedium9"
20
- @defaultPivotStyle = options[:defaultPivotStyle] || "PivotStyleLight16"
20
+ @defaultPivotStyle = options[:defaultPivotStyle] || "PivotStyleLight16"
21
21
  super TableStyle
22
22
  end
23
23
  # @see defaultTableStyle
@@ -25,16 +25,19 @@ module Axlsx
25
25
  # @see defaultPivotStyle
26
26
  def defaultPivotStyle=(v) Axlsx::validate_string(v); @defaultPivotStyle = v; end
27
27
 
28
- # Serializes the table styles element
29
- # @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
28
+ # Serializes the object
29
+ # @param [String] str
30
30
  # @return [String]
31
- def to_xml(xml)
31
+ def to_xml_string(str = '')
32
32
  attr = self.instance_values.reject {|k, v| ![:defaultTableStyle, :defaultPivotStyle].include?(k.to_sym) }
33
33
  attr[:count] = self.size
34
- xml.tableStyles(attr) {
35
- self.each { |table_style| table_style.to_xml(xml) }
36
- }
34
+ str << '<tableStyles '
35
+ str << attr.map { |key, value| '' << key.to_s << '="' << value.to_s << '"' }.join(' ')
36
+ str << '>'
37
+ each { |table_style| table_style.to_xml_string(str) }
38
+ str << '</tableStyles>'
37
39
  end
40
+
38
41
  end
39
42
 
40
43
  end
@@ -22,7 +22,7 @@ module Axlsx
22
22
  # index (0 based) of the font to be used in this style
23
23
  # @return [Integer]
24
24
  attr_reader :fontId
25
-
25
+
26
26
  # index (0 based) of the fill to be used in this style
27
27
  # @return [Integer]
28
28
  attr_reader :fillId
@@ -50,7 +50,7 @@ module Axlsx
50
50
  # indicates if the fontId should be applied
51
51
  # @return [Boolean]
52
52
  attr_reader :applyFont
53
-
53
+
54
54
  # indicates if the fillId should be applied
55
55
  # @return [Boolean]
56
56
  attr_reader :applyFill
@@ -75,7 +75,7 @@ module Axlsx
75
75
  # @option options [Integer] xfId
76
76
  # @option options [Boolean] quotePrefix
77
77
  # @option options [Boolean] pivotButton
78
- # @option options [Boolean] applyNumberFormat
78
+ # @option options [Boolean] applyNumberFormat
79
79
  # @option options [Boolean] applyFont
80
80
  # @option options [Boolean] applyFill
81
81
  # @option options [Boolean] applyBorder
@@ -87,8 +87,8 @@ module Axlsx
87
87
  options.each do |o|
88
88
  self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
89
89
  end
90
- end
91
-
90
+ end
91
+
92
92
  # @see Xf#alignment
93
93
  def alignment=(v) DataTypeValidator.validate "Xf.alignment", CellAlignment, v; @alignment = v end
94
94
 
@@ -96,44 +96,48 @@ module Axlsx
96
96
  def protection=(v) DataTypeValidator.validate "Xf.protection", CellProtection, v; @protection = v end
97
97
 
98
98
  # @see numFmtId
99
- def numFmtId=(v) Axlsx::validate_unsigned_int v; @numFmtId = v end
99
+ def numFmtId=(v) Axlsx::validate_unsigned_int v; @numFmtId = v end
100
100
 
101
101
  # @see fontId
102
- def fontId=(v) Axlsx::validate_unsigned_int v; @fontId = v end
102
+ def fontId=(v) Axlsx::validate_unsigned_int v; @fontId = v end
103
103
  # @see fillId
104
- def fillId=(v) Axlsx::validate_unsigned_int v; @fillId = v end
104
+ def fillId=(v) Axlsx::validate_unsigned_int v; @fillId = v end
105
105
  # @see borderId
106
- def borderId=(v) Axlsx::validate_unsigned_int v; @borderId = v end
106
+ def borderId=(v) Axlsx::validate_unsigned_int v; @borderId = v end
107
107
  # @see xfId
108
- def xfId=(v) Axlsx::validate_unsigned_int v; @xfId = v end
108
+ def xfId=(v) Axlsx::validate_unsigned_int v; @xfId = v end
109
109
  # @see quotePrefix
110
- def quotePrefix=(v) Axlsx::validate_boolean v; @quotePrefix = v end
110
+ def quotePrefix=(v) Axlsx::validate_boolean v; @quotePrefix = v end
111
111
  # @see pivotButton
112
- def pivotButton=(v) Axlsx::validate_boolean v; @pivotButton = v end
112
+ def pivotButton=(v) Axlsx::validate_boolean v; @pivotButton = v end
113
113
  # @see applyNumberFormat
114
- def applyNumberFormat=(v) Axlsx::validate_boolean v; @applyNumberFormat = v end
114
+ def applyNumberFormat=(v) Axlsx::validate_boolean v; @applyNumberFormat = v end
115
115
  # @see applyFont
116
- def applyFont=(v) Axlsx::validate_boolean v; @applyFont = v end
116
+ def applyFont=(v) Axlsx::validate_boolean v; @applyFont = v end
117
117
  # @see applyFill
118
- def applyFill=(v) Axlsx::validate_boolean v; @applyFill = v end
118
+ def applyFill=(v) Axlsx::validate_boolean v; @applyFill = v end
119
119
 
120
120
  # @see applyBorder
121
- def applyBorder=(v) Axlsx::validate_boolean v; @applyBorder = v end
121
+ def applyBorder=(v) Axlsx::validate_boolean v; @applyBorder = v end
122
122
 
123
123
  # @see applyAlignment
124
- def applyAlignment=(v) Axlsx::validate_boolean v; @applyAlignment = v end
124
+ def applyAlignment=(v) Axlsx::validate_boolean v; @applyAlignment = v end
125
125
 
126
126
  # @see applyProtection
127
- def applyProtection=(v) Axlsx::validate_boolean v; @applyProtection = v end
127
+ def applyProtection=(v) Axlsx::validate_boolean v; @applyProtection = v end
128
128
 
129
- # Serializes the xf elemen
130
- # @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
129
+ # Serializes the object
130
+ # @param [String] str
131
131
  # @return [String]
132
- def to_xml(xml)
133
- xml.xf(self.instance_values.reject { |k, v| [:alignment, :protection, :extList, :name].include? k.to_sym}) {
134
- alignment.to_xml(xml) if self.alignment
135
- protection.to_xml(xml) if self.protection
136
- }
132
+ def to_xml_string(str = '')
133
+ str << '<xf '
134
+ h = instance_values.reject { |k, v| [:alignment, :protection, :extList, :name].include? k.to_sym}
135
+ str << h.map { |key, value| '' << key.to_s << '="' << value.to_s << '"' }.join(' ')
136
+ str << '>'
137
+ alignment.to_xml_string(str) if self.alignment
138
+ protection.to_xml_string(str) if self.protection
139
+ str << '</xf>'
137
140
  end
141
+
138
142
  end
139
143
  end
@@ -21,7 +21,7 @@ module Axlsx
21
21
 
22
22
  # dc elements (core) namespace
23
23
  CORE_NS_DC = "http://purl.org/dc/elements/1.1/"
24
-
24
+
25
25
  # dcmit (core) namespcace
26
26
  CORE_NS_DCMIT = "http://purl.org/dc/dcmitype/"
27
27
 
@@ -30,10 +30,10 @@ module Axlsx
30
30
 
31
31
  # xml schema namespace
32
32
  CORE_NS_XSI = "http://www.w3.org/2001/XMLSchema-instance"
33
-
33
+
34
34
  # spreadsheet drawing namespace
35
35
  XML_NS_XDR = "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"
36
-
36
+
37
37
  # drawing namespace
38
38
  XML_NS_A = "http://schemas.openxmlformats.org/drawingml/2006/main"
39
39
 
@@ -43,13 +43,12 @@ module Axlsx
43
43
  # relationships namespace
44
44
  XML_NS_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships"
45
45
 
46
-
47
46
  # relationships name space
48
47
  RELS_R = "http://schemas.openxmlformats.org/package/2006/relationships"
49
48
 
50
49
  # table rels namespace
51
50
  TABLE_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/table"
52
-
51
+
53
52
  # workbook rels namespace
54
53
  WORKBOOK_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"
55
54
 
@@ -80,7 +79,7 @@ module Axlsx
80
79
  # image rels namespace
81
80
  HYPERLINK_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"
82
81
 
83
- # table content type
82
+ # table content type
84
83
  TABLE_CT = "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml"
85
84
 
86
85
  # workbook content type
@@ -90,14 +89,14 @@ module Axlsx
90
89
  APP_CT = "application/vnd.openxmlformats-officedocument.extended-properties+xml"
91
90
 
92
91
  # rels content type
93
- RELS_CT = "application/vnd.openxmlformats-package.relationships+xml"
92
+ RELS_CT = "application/vnd.openxmlformats-package.relationships+xml"
94
93
 
95
94
  # styles content type
96
95
  STYLES_CT = "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"
97
96
 
98
97
  # xml content type
99
98
  XML_CT = "application/xml"
100
-
99
+
101
100
  # worksheet content type
102
101
  WORKSHEET_CT = "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"
103
102
 
@@ -127,7 +126,7 @@ module Axlsx
127
126
 
128
127
  # jpeg extension
129
128
  JPEG_EX = "jpeg"
130
-
129
+
131
130
  # gif extension
132
131
  GIF_EX = "gif"
133
132
 
@@ -145,10 +144,10 @@ module Axlsx
145
144
 
146
145
  # shared_strings part
147
146
  SHARED_STRINGS_PN = "sharedStrings.xml"
148
-
147
+
149
148
  # app part
150
149
  APP_PN = "docProps/app.xml"
151
-
150
+
152
151
  # core part
153
152
  CORE_PN = "docProps/core.xml"
154
153
 
@@ -173,6 +172,9 @@ module Axlsx
173
172
  # drawing rels part
174
173
  DRAWING_RELS_PN = "drawings/_rels/drawing%d.xml.rels"
175
174
 
175
+ # drawing part
176
+ TABLE_PN = "tables/table%d.xml"
177
+
176
178
  # chart part
177
179
  CHART_PN = "charts/chart%d.xml"
178
180
 
@@ -196,12 +198,12 @@ module Axlsx
196
198
 
197
199
  # spreadsheetML validation schema
198
200
  SML_XSD = SCHEMA_BASE + "sml.xsd"
199
-
201
+
200
202
  # drawing validation schema
201
203
  DRAWING_XSD = SCHEMA_BASE + "dml-spreadsheetDrawing.xsd"
202
204
 
203
205
  # number format id for pecentage formatting using the default formatting id.
204
- NUM_FMT_PERCENT = 9
206
+ NUM_FMT_PERCENT = 9
205
207
 
206
208
  # number format id for date format like 2011/11/13
207
209
  NUM_FMT_YYYYMMDD = 100
@@ -216,7 +218,7 @@ module Axlsx
216
218
  STYLE_DATE = 2
217
219
 
218
220
  # error messages RestrictionValidor
219
- ERR_RESTRICTION = "Invalid Data: %s. %s must be one of %s."
221
+ ERR_RESTRICTION = "Invalid Data: %s. %s must be one of %s."
220
222
 
221
223
  # error message DataTypeValidator
222
224
  ERR_TYPE = "Invalid Data %s for %s. must be %s."
@@ -224,6 +226,10 @@ module Axlsx
224
226
  # error message for RegexValidator
225
227
  ERR_REGEX = "Invalid Data. %s does not match %s."
226
228
 
229
+ # error message for sheets that use a name which is longer than 31 bytes
230
+ ERR_SHEET_NAME_TOO_LONG = "Your worksheet name '%s' is too long. Worksheet names must be 31 characters (bytes) or less"
231
+
227
232
  # error message for duplicate sheet names
228
233
  ERR_DUPLICATE_SHEET_NAME = "There is already a worksheet in this workbook named '%s'. Please use a unique name"
234
+
229
235
  end
@@ -1,6 +1,6 @@
1
1
  # encoding: UTF-8
2
2
  module Axlsx
3
- # A SimpleTypedList is a type restrictive collection that allows some of the methods from Array and supports basic xml serialization.
3
+ # A SimpleTypedList is a type restrictive collection that allows some of the methods from Array and supports basic xml serialization.
4
4
  # @private
5
5
  class SimpleTypedList
6
6
  # The class constants of allowed types
@@ -12,14 +12,14 @@ module Axlsx
12
12
  attr_reader :locked_at
13
13
 
14
14
  # The tag name to use when serializing this object
15
- # by default the parent node for all items in the list is the classname of the first allowed type with the first letter in lowercase.
15
+ # by default the parent node for all items in the list is the classname of the first allowed type with the first letter in lowercase.
16
16
  # @return [String]
17
17
  attr_reader :serialize_as
18
18
 
19
19
  # Creats a new typed list
20
20
  # @param [Array, Class] type An array of Class objects or a single Class object
21
21
  # @param [String] serialize The tag name to use in serialization
22
- # @raise [ArgumentError] if all members of type are not Class objects
22
+ # @raise [ArgumentError] if all members of type are not Class objects
23
23
  def initialize type, serialize_as=nil
24
24
  if type.is_a? Array
25
25
  type.each { |item| raise ArgumentError, "All members of type must be Class objects" unless item.is_a? Class }
@@ -39,7 +39,7 @@ module Axlsx
39
39
  @locked_at = @list.size
40
40
  self
41
41
  end
42
-
42
+
43
43
  def to_ary
44
44
  @list
45
45
  end
@@ -58,7 +58,7 @@ module Axlsx
58
58
  def <<(v)
59
59
  DataTypeValidator.validate "SimpleTypedList.<<", @allowed_types, v
60
60
  @list << v
61
- @list.size - 1
61
+ @list.size - 1
62
62
  end
63
63
 
64
64
  # alternate of << method
@@ -104,14 +104,14 @@ module Axlsx
104
104
  return false unless @locked_at.is_a? Fixnum
105
105
  index < @locked_at
106
106
  end
107
-
107
+
108
108
  # override the equality method so that this object can be compared to a simple array.
109
109
  # if this object's list is equal to the specifiec array, we return true.
110
110
  def ==(v)
111
111
  v == @list
112
112
  end
113
113
  # method_mission override to pass allowed methods to the list.
114
- # @note
114
+ # @note
115
115
  # the following methods are not allowed
116
116
  # :replace
117
117
  # :insert
@@ -140,15 +140,23 @@ module Axlsx
140
140
  DELEGATES = Array.instance_methods - self.instance_methods - DESTRUCTIVE
141
141
 
142
142
  DELEGATES.each do |method|
143
- class_eval %{
143
+ class_eval %{
144
144
  def #{method}(*args, &block)
145
145
  @list.send(:#{method}, *args, &block)
146
146
  end
147
147
  }
148
148
  end
149
149
 
150
+ def to_xml_string(str = '')
151
+ classname = @allowed_types[0].name.split('::').last
152
+ el_name = serialize_as || (classname[0,1].downcase + classname[1..-1])
153
+ str << '<' << el_name << ' count="' << @list.size.to_s << '">'
154
+ @list.each { |item| item.to_xml_string(str) }
155
+ str << '</' << el_name << '>'
156
+ end
157
+
150
158
  # Serializes the list
151
- # If the serialize_as property is set, it is used as the parent node name.
159
+ # If the serialize_as property is set, it is used as the parent node name.
152
160
  # If the serialize_as property is nil, the first item in the list of allowed_types will be used, having the first letter of the class changed to lower case.
153
161
  # @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
154
162
  # @return [String]
@@ -159,6 +167,7 @@ module Axlsx
159
167
  @list.each { |item| item.to_xml(xml) }
160
168
  }
161
169
  end
170
+
162
171
  end
163
172
 
164
173
 
@@ -5,11 +5,11 @@ module Axlsx
5
5
  # Perform validation
6
6
  # @param [String] name The name of what is being validatied. This is included in the error message
7
7
  # @param [Array] choices The list of choices to validate against
8
- # @param [Any] v The value to be validated
8
+ # @param [Any] v The value to be validated
9
9
  # @raise [ArgumentError] Raised if the value provided is not in the list of choices.
10
10
  # @return [Boolean] true if validation succeeds.
11
11
  def self.validate(name, choices, v)
12
- raise ArgumentError, (ERR_RESTRICTION % [v.to_s, name, choices.inspect]) unless choices.include?(v)
12
+ raise ArgumentError, (ERR_RESTRICTION % [v.to_s, name, choices.inspect]) unless choices.include?(v)
13
13
  true
14
14
  end
15
15
  end
@@ -55,7 +55,7 @@ module Axlsx
55
55
 
56
56
  # Requires that the value is a Fixnum Integer or Float and is greater or equal to 0
57
57
  # @param [Any] v The value validated
58
- # @raise [ArgumentError] raised if the value is not a Fixnum or Integer value greater or equal to 0
58
+ # @raise [ArgumentError] raised if the value is not a Fixnun, Integer, Float value greater or equal to 0
59
59
  # @return [Boolean] true if the data is valid
60
60
  def self.validate_unsigned_numeric(v)
61
61
  DataTypeValidator.validate("Invalid column width", [Fixnum, Integer, Float], v, lambda { |arg| arg.respond_to?(:>=) && arg >= 0 })
@@ -68,7 +68,7 @@ module Axlsx
68
68
  end
69
69
 
70
70
  # Requires that the value is a form that can be evaluated as a boolean in an xml document.
71
- # The value must be an instance of Fixnum, String, Integer, Symbol, TrueClass or FalseClass and
71
+ # The value must be an instance of Fixnum, String, Integer, Symbol, TrueClass or FalseClass and
72
72
  # it must be one of 0, 1, "true", "false", :true, :false, true, false, "0", or "1"
73
73
  # @param [Any] v The value validated
74
74
  def self.validate_boolean(v)
@@ -79,13 +79,13 @@ module Axlsx
79
79
  # @param [Any] v The value validated
80
80
  def self.validate_string(v)
81
81
  DataTypeValidator.validate :string, String, v
82
- end
82
+ end
83
83
 
84
84
  # Requires that the value is a Float
85
85
  # @param [Any] v The value validated
86
86
  def self.validate_float(v)
87
87
  DataTypeValidator.validate :float, Float, v
88
- end
88
+ end
89
89
 
90
90
  # Requires that the value is valid pattern type.
91
91
  # valid pattern types must be one of :none, :solid, :mediumGray, :darkGray, :lightGray, :darkHorizontal, :darkVertical, :darkDown,
@@ -103,6 +103,13 @@ module Axlsx
103
103
  RestrictionValidator.validate :gradient_type, [:linear, :path], v
104
104
  end
105
105
 
106
+ # Requires that the value is a valid scatterStyle
107
+ # must be one of :none | :line | :lineMarker | :marker | :smooth | :smoothMarker
108
+ # must be one of "none" | "line" | "lineMarker" | "marker" | "smooth" | "smoothMarker"
109
+ # @param [Symbol|String] the value to validate
110
+ def self.validate_scatter_style(v)
111
+ Axlsx::RestrictionValidator.validate "ScatterChart.scatterStyle", [:none, :line, :lineMarker, :marker, :smooth, :smoothMarker], v.to_sym
112
+ end
106
113
  # Requires that the value is a valid horizontal_alignment
107
114
  # :general, :left, :center, :right, :fill, :justify, :centerContinuous, :distributed are allowed
108
115
  # @param [Any] v The value validated