axlsx 2.0.1 → 2.1.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (155) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -3
  3. data/Rakefile +9 -10
  4. data/examples/IMAGE1UP.JPEG +0 -0
  5. data/examples/auto_filter.rb +10 -1
  6. data/examples/conditional_formatting/example_conditional_formatting.rb +3 -3
  7. data/examples/example.rb +72 -4
  8. data/examples/merge_cells.rb +17 -0
  9. data/examples/no_grid_with_borders.rb +18 -0
  10. data/examples/pivot_test.rb +63 -0
  11. data/examples/split.rb +16 -0
  12. data/lib/axlsx.rb +30 -16
  13. data/lib/axlsx/content_type/abstract_content_type.rb +1 -1
  14. data/lib/axlsx/content_type/content_type.rb +1 -1
  15. data/lib/axlsx/doc_props/app.rb +1 -1
  16. data/lib/axlsx/doc_props/core.rb +5 -5
  17. data/lib/axlsx/drawing/axes.rb +1 -1
  18. data/lib/axlsx/drawing/axis.rb +12 -9
  19. data/lib/axlsx/drawing/bar_3D_chart.rb +13 -13
  20. data/lib/axlsx/drawing/bar_series.rb +9 -9
  21. data/lib/axlsx/drawing/bubble_chart.rb +59 -0
  22. data/lib/axlsx/drawing/bubble_series.rb +63 -0
  23. data/lib/axlsx/drawing/cat_axis.rb +5 -5
  24. data/lib/axlsx/drawing/chart.rb +44 -7
  25. data/lib/axlsx/drawing/drawing.rb +3 -1
  26. data/lib/axlsx/drawing/graphic_frame.rb +3 -3
  27. data/lib/axlsx/drawing/hyperlink.rb +1 -3
  28. data/lib/axlsx/drawing/line_3D_chart.rb +2 -2
  29. data/lib/axlsx/drawing/line_chart.rb +10 -10
  30. data/lib/axlsx/drawing/line_series.rb +14 -2
  31. data/lib/axlsx/drawing/marker.rb +1 -1
  32. data/lib/axlsx/drawing/num_data.rb +4 -4
  33. data/lib/axlsx/drawing/num_data_source.rb +6 -6
  34. data/lib/axlsx/drawing/num_val.rb +1 -1
  35. data/lib/axlsx/drawing/one_cell_anchor.rb +1 -1
  36. data/lib/axlsx/drawing/pic.rb +2 -3
  37. data/lib/axlsx/drawing/picture_locking.rb +1 -3
  38. data/lib/axlsx/drawing/pie_3D_chart.rb +5 -6
  39. data/lib/axlsx/drawing/pie_series.rb +6 -6
  40. data/lib/axlsx/drawing/scaling.rb +4 -4
  41. data/lib/axlsx/drawing/scatter_chart.rb +10 -10
  42. data/lib/axlsx/drawing/scatter_series.rb +26 -7
  43. data/lib/axlsx/drawing/ser_axis.rb +2 -2
  44. data/lib/axlsx/drawing/series.rb +3 -3
  45. data/lib/axlsx/drawing/series_title.rb +2 -2
  46. data/lib/axlsx/drawing/str_data.rb +3 -3
  47. data/lib/axlsx/drawing/str_val.rb +1 -1
  48. data/lib/axlsx/drawing/title.rb +3 -3
  49. data/lib/axlsx/drawing/val_axis.rb +1 -1
  50. data/lib/axlsx/drawing/vml_drawing.rb +1 -1
  51. data/lib/axlsx/package.rb +39 -28
  52. data/lib/axlsx/rels/relationship.rb +1 -1
  53. data/lib/axlsx/rels/relationships.rb +2 -2
  54. data/lib/axlsx/stylesheet/border_pr.rb +2 -2
  55. data/lib/axlsx/stylesheet/cell_alignment.rb +1 -3
  56. data/lib/axlsx/stylesheet/cell_protection.rb +1 -3
  57. data/lib/axlsx/stylesheet/cell_style.rb +1 -3
  58. data/lib/axlsx/stylesheet/color.rb +1 -3
  59. data/lib/axlsx/stylesheet/font.rb +1 -1
  60. data/lib/axlsx/stylesheet/gradient_stop.rb +1 -1
  61. data/lib/axlsx/stylesheet/num_fmt.rb +1 -3
  62. data/lib/axlsx/stylesheet/pattern_fill.rb +1 -1
  63. data/lib/axlsx/stylesheet/styles.rb +6 -6
  64. data/lib/axlsx/stylesheet/table_style_element.rb +1 -3
  65. data/lib/axlsx/util/accessors.rb +6 -6
  66. data/lib/axlsx/util/constants.rb +106 -101
  67. data/lib/axlsx/util/options_parser.rb +2 -1
  68. data/lib/axlsx/util/parser.rb +4 -4
  69. data/lib/axlsx/util/serialized_attributes.rb +16 -6
  70. data/lib/axlsx/util/simple_typed_list.rb +28 -52
  71. data/lib/axlsx/util/storage.rb +4 -4
  72. data/lib/axlsx/util/string.rb +7 -0
  73. data/lib/axlsx/util/validators.rb +20 -13
  74. data/lib/axlsx/version.rb +1 -1
  75. data/lib/axlsx/workbook/defined_name.rb +11 -12
  76. data/lib/axlsx/workbook/defined_names.rb +2 -2
  77. data/lib/axlsx/workbook/shared_strings_table.rb +5 -5
  78. data/lib/axlsx/workbook/workbook.rb +19 -12
  79. data/lib/axlsx/workbook/workbook_view.rb +78 -0
  80. data/lib/axlsx/workbook/workbook_views.rb +22 -0
  81. data/lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb +2 -2
  82. data/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +1 -3
  83. data/lib/axlsx/workbook/worksheet/break.rb +1 -3
  84. data/lib/axlsx/workbook/worksheet/cell.rb +128 -73
  85. data/lib/axlsx/workbook/worksheet/cell_serializer.rb +50 -40
  86. data/lib/axlsx/workbook/worksheet/cfvo.rb +1 -3
  87. data/lib/axlsx/workbook/worksheet/cfvos.rb +1 -1
  88. data/lib/axlsx/workbook/worksheet/col.rb +7 -10
  89. data/lib/axlsx/workbook/worksheet/col_breaks.rb +2 -2
  90. data/lib/axlsx/workbook/worksheet/comment.rb +5 -6
  91. data/lib/axlsx/workbook/worksheet/comments.rb +9 -12
  92. data/lib/axlsx/workbook/worksheet/conditional_formatting.rb +1 -1
  93. data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +1 -1
  94. data/lib/axlsx/workbook/worksheet/data_bar.rb +4 -6
  95. data/lib/axlsx/workbook/worksheet/data_validation.rb +6 -4
  96. data/lib/axlsx/workbook/worksheet/dimension.rb +2 -2
  97. data/lib/axlsx/workbook/worksheet/header_footer.rb +6 -8
  98. data/lib/axlsx/workbook/worksheet/icon_set.rb +3 -5
  99. data/lib/axlsx/workbook/worksheet/merged_cells.rb +2 -2
  100. data/lib/axlsx/workbook/worksheet/page_margins.rb +1 -3
  101. data/lib/axlsx/workbook/worksheet/page_set_up_pr.rb +1 -1
  102. data/lib/axlsx/workbook/worksheet/page_setup.rb +21 -23
  103. data/lib/axlsx/workbook/worksheet/pane.rb +1 -3
  104. data/lib/axlsx/workbook/worksheet/pivot_table.rb +17 -24
  105. data/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +4 -4
  106. data/lib/axlsx/workbook/worksheet/print_options.rb +1 -3
  107. data/lib/axlsx/workbook/worksheet/protected_range.rb +1 -3
  108. data/lib/axlsx/workbook/worksheet/protected_ranges.rb +1 -1
  109. data/lib/axlsx/workbook/worksheet/rich_text.rb +35 -0
  110. data/lib/axlsx/workbook/worksheet/rich_text_run.rb +254 -0
  111. data/lib/axlsx/workbook/worksheet/row.rb +33 -51
  112. data/lib/axlsx/workbook/worksheet/row_breaks.rb +2 -2
  113. data/lib/axlsx/workbook/worksheet/selection.rb +1 -3
  114. data/lib/axlsx/workbook/worksheet/sheet_data.rb +3 -1
  115. data/lib/axlsx/workbook/worksheet/sheet_protection.rb +1 -3
  116. data/lib/axlsx/workbook/worksheet/table.rb +6 -6
  117. data/lib/axlsx/workbook/worksheet/table_style_info.rb +1 -3
  118. data/lib/axlsx/workbook/worksheet/tables.rb +1 -1
  119. data/lib/axlsx/workbook/worksheet/worksheet.rb +59 -30
  120. data/lib/axlsx/workbook/worksheet/worksheet_hyperlinks.rb +3 -3
  121. data/test/drawing/tc_axis.rb +27 -0
  122. data/test/drawing/tc_bubble_chart.rb +44 -0
  123. data/test/drawing/tc_bubble_series.rb +21 -0
  124. data/test/drawing/tc_data_source.rb +6 -0
  125. data/test/drawing/tc_line_chart.rb +5 -5
  126. data/test/drawing/tc_line_series.rb +10 -2
  127. data/test/drawing/tc_pic.rb +4 -0
  128. data/test/drawing/tc_scatter_series.rb +25 -1
  129. data/test/tc_helper.rb +1 -1
  130. data/test/tc_package.rb +7 -1
  131. data/test/util/tc_simple_typed_list.rb +1 -2
  132. data/test/workbook/tc_defined_name.rb +12 -4
  133. data/test/workbook/tc_workbook.rb +16 -2
  134. data/test/workbook/tc_workbook_view.rb +50 -0
  135. data/test/workbook/worksheet/auto_filter/tc_filters.rb +1 -1
  136. data/test/workbook/worksheet/tc_break.rb +1 -1
  137. data/test/workbook/worksheet/tc_cell.rb +30 -4
  138. data/test/workbook/worksheet/tc_col.rb +2 -2
  139. data/test/workbook/worksheet/tc_conditional_formatting.rb +2 -2
  140. data/test/workbook/worksheet/tc_data_bar.rb +1 -1
  141. data/test/workbook/worksheet/tc_data_validation.rb +11 -11
  142. data/test/workbook/worksheet/tc_header_footer.rb +2 -2
  143. data/test/workbook/worksheet/tc_icon_set.rb +1 -1
  144. data/test/workbook/worksheet/tc_page_setup.rb +3 -3
  145. data/test/workbook/worksheet/tc_print_options.rb +1 -1
  146. data/test/workbook/worksheet/tc_rich_text.rb +44 -0
  147. data/test/workbook/worksheet/tc_rich_text_run.rb +172 -0
  148. data/test/workbook/worksheet/tc_row.rb +2 -2
  149. data/test/workbook/worksheet/tc_sheet_calc_pr.rb +1 -1
  150. data/test/workbook/worksheet/tc_sheet_format_pr.rb +4 -4
  151. data/test/workbook/worksheet/tc_sheet_protection.rb +5 -5
  152. data/test/workbook/worksheet/tc_sheet_view.rb +4 -4
  153. data/test/workbook/worksheet/tc_worksheet.rb +49 -10
  154. metadata +81 -55
  155. data/test/axlsx.qcachegrind +0 -2226
@@ -63,11 +63,9 @@ module Axlsx
63
63
  # @param [String] str
64
64
  # @return [String]
65
65
  def to_xml_string(str="")
66
- str << '<iconSet '
67
- serialized_attributes str
68
- str << '>'
69
- @value_objects.each { |cfvo| cfvo.to_xml_string(str) }
70
- str << '</iconSet>'
66
+ serialized_tag('iconSet', str) do
67
+ @value_objects.each { |cfvo| cfvo.to_xml_string(str) }
68
+ end
71
69
  end
72
70
 
73
71
  private
@@ -15,7 +15,7 @@ module Axlsx
15
15
  # collection. This can be an array of actual cells or a string style
16
16
  # range like 'A1:C1'
17
17
  def add(cells)
18
- @list << if cells.is_a?(String)
18
+ self << if cells.is_a?(String)
19
19
  cells
20
20
  elsif cells.is_a?(Array)
21
21
  Axlsx::cell_range(cells, false)
@@ -26,7 +26,7 @@ module Axlsx
26
26
  # @param [String] str
27
27
  # @return [String]
28
28
  def to_xml_string(str = '')
29
- return if @list.empty?
29
+ return if empty?
30
30
  str << "<mergeCells count='#{size}'>"
31
31
  each { |merged_cell| str << "<mergeCell ref='#{merged_cell}'></mergeCell>" }
32
32
  str << '</mergeCells>'
@@ -91,9 +91,7 @@ module Axlsx
91
91
  # @note For compatibility, this is a noop unless custom margins have been specified.
92
92
  # @see #custom_margins_specified?
93
93
  def to_xml_string(str = '')
94
- str << '<pageMargins '
95
- serialized_attributes str
96
- str << '/>'
94
+ serialized_tag('pageMargins', str)
97
95
  end
98
96
  end
99
97
  end
@@ -38,7 +38,7 @@ module Axlsx
38
38
 
39
39
  # serialize to xml
40
40
  def to_xml_string(str='')
41
- str << '<pageSetUpPr ' << serialized_attributes << '/>'
41
+ str << ('<pageSetUpPr ' << serialized_attributes << '/>')
42
42
  end
43
43
  end
44
44
  end
@@ -44,13 +44,13 @@ module Axlsx
44
44
 
45
45
  # Number of horizontal pages to fit on.
46
46
  # @note PageSetup#fit_to is the recomended way to manage page fitting as only specifying one of width/height will result in the counterpart
47
- # being set to 1.
47
+ # being set to 1.
48
48
  # @return [Integer]
49
49
  attr_reader :fit_to_width
50
50
 
51
51
  # Orientation of the page (:default, :landscape, :portrait)
52
52
  # @return [Symbol]
53
- attr_reader :orientation
53
+ attr_reader :orientation
54
54
 
55
55
  # Height of paper (string containing a number followed by a unit identifier: "297mm", "11in")
56
56
  # @return [String]
@@ -74,18 +74,18 @@ module Axlsx
74
74
  #7 = Executive paper (7.25 in. by 10.5 in.)
75
75
  #8 = A3 paper (297 mm by 420 mm)
76
76
  #9 = A4 paper (210 mm by 297 mm)
77
- #10 = A4 small paper (210 mm by 297 mm)
77
+ #10 = A4 small paper (210 mm by 297 mm)
78
78
  #11 = A5 paper (148 mm by 210 mm)
79
79
  #12 = B4 paper (250 mm by 353 mm)
80
80
  #13 = B5 paper (176 mm by 250 mm)
81
81
  #14 = Folio paper (8.5 in. by 13 in.)
82
- #15 = Quarto paper (215 mm by 275 mm)
82
+ #15 = Quarto paper (215 mm by 275 mm)
83
83
  #16 = Standard paper (10 in. by 14 in.)
84
84
  #17 = Standard paper (11 in. by 17 in.)
85
85
  #18 = Note paper (8.5 in. by 11 in.)
86
- #19 = #9 envelope (3.875 in. by 8.875 in.)
87
- #20 = #10 envelope (4.125 in. by 9.5 in.)
88
- #21 = #11 envelope (4.5 in. by 10.375 in.)
86
+ #19 = #9 envelope (3.875 in. by 8.875 in.)
87
+ #20 = #10 envelope (4.125 in. by 9.5 in.)
88
+ #21 = #11 envelope (4.5 in. by 10.375 in.)
89
89
  #22 = #12 envelope (4.75 in. by 11 in.)
90
90
  #23 = #14 envelope (5 in. by 11.5 in.) 24 = C paper (17 in. by 22 in.)
91
91
  #25 = D paper (22 in. by 34 in.)
@@ -105,7 +105,7 @@ module Axlsx
105
105
  #40 = German standard fanfold (8.5 in. by 12 in.)
106
106
  #41 = German legal fanfold (8.5 in. by 13 in.)
107
107
  #42 = ISO B4 (250 mm by 353 mm)
108
- #43 = Japanese double postcard (200 mm by 148 mm)
108
+ #43 = Japanese double postcard (200 mm by 148 mm)
109
109
  #44 = Standard paper (9 in. by 11 in.)
110
110
  #45 = Standard paper (10 in. by 11 in.)
111
111
  #46 = Standard paper (15 in. by 11 in.)
@@ -116,9 +116,9 @@ module Axlsx
116
116
  #53 = A4 extra paper (236 mm by 322 mm)
117
117
  #54 = Letter transverse paper (8.275 in. by 11 in.)
118
118
  #55 = A4 transverse paper (210 mm by 297 mm)
119
- #56 = Letter extra transverse paper (9.275 in. by 12 in.)
120
- #57 = SuperA/SuperA/A4 paper (227 mm by 356 mm)
121
- #58 = SuperB/SuperB/A3 paper (305 mm by 487 mm)
119
+ #56 = Letter extra transverse paper (9.275 in. by 12 in.)
120
+ #57 = SuperA/SuperA/A4 paper (227 mm by 356 mm)
121
+ #58 = SuperB/SuperB/A3 paper (305 mm by 487 mm)
122
122
  #59 = Letter plus paper (8.5 in. by 12.69 in.)
123
123
  #60 = A4 plus paper (210 mm by 330 mm)
124
124
  #61 = A5 transverse paper (148 mm by 210 mm)
@@ -128,8 +128,8 @@ module Axlsx
128
128
  #65 = ISO B5 extra paper (201 mm by 276 mm)
129
129
  #66 = A2 paper (420 mm by 594 mm)
130
130
  #67 = A3 transverse paper (297 mm by 420 mm)
131
- #68 = A3 extra transverse paper (322 mm by 445 mm)
132
- #69 = Japanese Double Postcard (200 mm x 148 mm)
131
+ #68 = A3 extra transverse paper (322 mm by 445 mm)
132
+ #69 = Japanese Double Postcard (200 mm x 148 mm)
133
133
  #70 = A6 (105 mm x 148 mm
134
134
  #71 = Japanese Envelope Kaku #2
135
135
  #72 = Japanese Envelope Kaku #3
@@ -142,7 +142,7 @@ module Axlsx
142
142
  #79 = B4 (JIS) Rotated (364 mm x 257 mm)
143
143
  #80 = B5 (JIS) Rotated (257 mm x 182 mm)
144
144
  #81 = Japanese Postcard Rotated (148 mm x 100 mm)
145
- #82 = Double Japanese Postcard Rotated (148 mm x 200 mm)
145
+ #82 = Double Japanese Postcard Rotated (148 mm x 200 mm)
146
146
  #83 = A6 Rotated (148 mm x 105 mm)
147
147
  #84 = Japanese Envelope Kaku #2 Rotated
148
148
  #85 = Japanese Envelope Kaku #3 Rotated
@@ -210,20 +210,20 @@ module Axlsx
210
210
  # @see scale
211
211
  def scale=(v); Axlsx::validate_scale_10_400(v); @scale = v; end
212
212
 
213
- # convenience method to achieve sanity when setting fit_to_width and fit_to_height
213
+ # convenience method to achieve sanity when setting fit_to_width and fit_to_height
214
214
  # as they both default to 1 if only their counterpart is specified.
215
215
  # @note This method will overwrite any value you explicitly set via the fit_to_height or fit_to_width methods.
216
- # @option options [Integer] width The number of pages to fit this worksheet on horizontally. Default 9999
217
- # @option options [Integer] height The number of pages to fit this worksheet on vertically. Default 9999
216
+ # @option options [Integer] width The number of pages to fit this worksheet on horizontally. Default 999
217
+ # @option options [Integer] height The number of pages to fit this worksheet on vertically. Default 999
218
218
  def fit_to(options={})
219
- self.fit_to_width = options[:width] || 9999
220
- self.fit_to_height = options[:height] || 9999
219
+ self.fit_to_width = options[:width] || 999
220
+ self.fit_to_height = options[:height] || 999
221
221
  [@fit_to_width, @fit_to_height]
222
222
  end
223
223
 
224
224
 
225
225
  # helper method for worksheet to determine if the page setup is configured for fit to page printing
226
- # We treat any page set up that has a value set for fit_to_width or fit_to_height value as fit_to_page.
226
+ # We treat any page set up that has a value set for fit_to_width or fit_to_height value as fit_to_page.
227
227
  # @return [Boolean]
228
228
  def fit_to_page?
229
229
  # is there some better what to express this?
@@ -234,9 +234,7 @@ module Axlsx
234
234
  # @param [String] str
235
235
  # @return [String]
236
236
  def to_xml_string(str = '')
237
- str << '<pageSetup '
238
- serialized_attributes str
239
- str << '/>'
237
+ serialized_tag('pageSetup', str)
240
238
  end
241
239
  end
242
240
  end
@@ -124,9 +124,7 @@ module Axlsx
124
124
  # @return [String]
125
125
  def to_xml_string(str = '')
126
126
  finalize
127
- str << '<pane '
128
- serialized_attributes str
129
- str << '/>'
127
+ serialized_tag 'pane', str
130
128
  end
131
129
  private
132
130
 
@@ -159,9 +159,9 @@ module Axlsx
159
159
  # @return [String]
160
160
  def to_xml_string(str = '')
161
161
  str << '<?xml version="1.0" encoding="UTF-8"?>'
162
- str << '<pivotTableDefinition xmlns="' << XML_NS << '" name="' << name << '" cacheId="' << cache_definition.cache_id.to_s << '" dataOnRows="1" applyNumberFormats="0" applyBorderFormats="0" applyFontFormats="0" applyPatternFormats="0" applyAlignmentFormats="0" applyWidthHeightFormats="1" dataCaption="Data" showMultipleLabel="0" showMemberPropertyTips="0" useAutoFormatting="1" indent="0" compact="0" compactData="0" gridDropZones="1" multipleFieldFilters="0">'
163
- str << '<location firstDataCol="1" firstDataRow="1" firstHeaderRow="1" ref="' << ref << '"/>'
164
- str << '<pivotFields count="' << header_cells_count.to_s << '">'
162
+ str << ('<pivotTableDefinition xmlns="' << XML_NS << '" name="' << name << '" cacheId="' << cache_definition.cache_id.to_s << '" dataOnRows="1" applyNumberFormats="0" applyBorderFormats="0" applyFontFormats="0" applyPatternFormats="0" applyAlignmentFormats="0" applyWidthHeightFormats="1" dataCaption="Data" showMultipleLabel="0" showMemberPropertyTips="0" useAutoFormatting="1" indent="0" compact="0" compactData="0" gridDropZones="1" multipleFieldFilters="0">')
163
+ str << ( '<location firstDataCol="1" firstDataRow="1" firstHeaderRow="1" ref="' << ref << '"/>')
164
+ str << ( '<pivotFields count="' << header_cells_count.to_s << '">')
165
165
  header_cell_values.each do |cell_value|
166
166
  str << pivot_field_for(cell_value)
167
167
  end
@@ -170,12 +170,12 @@ module Axlsx
170
170
  str << '<rowFields count="1"><field x="-2"/></rowFields>'
171
171
  str << '<rowItems count="2"><i><x/></i> <i i="1"><x v="1"/></i></rowItems>'
172
172
  else
173
- str << '<rowFields count="' << rows.size.to_s << '">'
173
+ str << ('<rowFields count="' << rows.size.to_s << '">')
174
174
  rows.each do |row_value|
175
- str << '<field x="' << header_index_of(row_value).to_s << '"/>'
175
+ str << ('<field x="' << header_index_of(row_value).to_s << '"/>')
176
176
  end
177
177
  str << '</rowFields>'
178
- str << '<rowItems count="' << rows.size.to_s << '">'
178
+ str << ('<rowItems count="' << rows.size.to_s << '">')
179
179
  rows.size.times do |i|
180
180
  str << '<i/>'
181
181
  end
@@ -184,16 +184,16 @@ module Axlsx
184
184
  if columns.empty?
185
185
  str << '<colItems count="1"><i/></colItems>'
186
186
  else
187
- str << '<colFields count="' << columns.size.to_s << '">'
187
+ str << ('<colFields count="' << columns.size.to_s << '">')
188
188
  columns.each do |column_value|
189
- str << '<field x="' << header_index_of(column_value).to_s << '"/>'
189
+ str << ('<field x="' << header_index_of(column_value).to_s << '"/>')
190
190
  end
191
191
  str << '</colFields>'
192
192
  end
193
193
  unless pages.empty?
194
- str << '<pageFields count="' << pages.size.to_s << '">'
194
+ str << ('<pageFields count="' << pages.size.to_s << '">')
195
195
  pages.each do |page_value|
196
- str << '<pageField fld="' << header_index_of(page_value).to_s << '"/>'
196
+ str << ('<pageField fld="' << header_index_of(page_value).to_s << '"/>')
197
197
  end
198
198
  str << '</pageFields>'
199
199
  end
@@ -243,31 +243,24 @@ module Axlsx
243
243
 
244
244
  def pivot_field_for(cell_ref)
245
245
  if rows.include? cell_ref
246
- '<pivotField axis="axisRow" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1">' <<
247
- '<items count="1"><item t="default"/></items>' <<
248
- '</pivotField>'
246
+ '<pivotField axis="axisRow" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1">' + '<items count="1"><item t="default"/></items>' + '</pivotField>'
249
247
  elsif columns.include? cell_ref
250
- '<pivotField axis="axisCol" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1">' <<
251
- '<items count="1"><item t="default"/></items>' <<
252
- '</pivotField>'
248
+ '<pivotField axis="axisCol" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1">' + '<items count="1"><item t="default"/></items>' + '</pivotField>'
253
249
  elsif pages.include? cell_ref
254
- '<pivotField axis="axisCol" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1">' <<
255
- '<items count="1"><item t="default"/></items>' <<
256
- '</pivotField>'
250
+ '<pivotField axis="axisCol" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1">' + '<items count="1"><item t="default"/></items>' + '</pivotField>'
257
251
  elsif data_refs.include? cell_ref
258
- '<pivotField dataField="1" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1">' <<
259
- '</pivotField>'
252
+ '<pivotField dataField="1" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1">' + '</pivotField>'
260
253
  else
261
- '<pivotField compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1">' <<
262
- '</pivotField>'
254
+ '<pivotField compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1">' + '</pivotField>'
263
255
  end
264
256
  end
257
+
265
258
  def data_refs
266
259
  data.map { |hash| hash[:ref] }
267
260
  end
261
+
268
262
  def header_range
269
263
  range.gsub(/^(\w+?)(\d+)\:(\w+?)\d+$/, '\1\2:\3\2')
270
264
  end
271
-
272
265
  end
273
266
  end
@@ -47,13 +47,13 @@ module Axlsx
47
47
  # @return [String]
48
48
  def to_xml_string(str = '')
49
49
  str << '<?xml version="1.0" encoding="UTF-8"?>'
50
- str << '<pivotCacheDefinition xmlns="' << XML_NS << '" xmlns:r="' << XML_NS_R << '" invalid="1" refreshOnLoad="1" recordCount="0">'
50
+ str << ('<pivotCacheDefinition xmlns="' << XML_NS << '" xmlns:r="' << XML_NS_R << '" invalid="1" refreshOnLoad="1" recordCount="0">')
51
51
  str << '<cacheSource type="worksheet">'
52
- str << '<worksheetSource ref="' << pivot_table.range << '" sheet="' << pivot_table.data_sheet.name << '"/>'
52
+ str << ( '<worksheetSource ref="' << pivot_table.range << '" sheet="' << pivot_table.data_sheet.name << '"/>')
53
53
  str << '</cacheSource>'
54
- str << '<cacheFields count="' << pivot_table.header_cells_count.to_s << '">'
54
+ str << ( '<cacheFields count="' << pivot_table.header_cells_count.to_s << '">')
55
55
  pivot_table.header_cells.each do |cell|
56
- str << '<cacheField name="' << cell.value << '" numFmtId="0">'
56
+ str << ( '<cacheField name="' << cell.value << '" numFmtId="0">')
57
57
  str << '<sharedItems count="0">'
58
58
  str << '</sharedItems>'
59
59
  str << '</cacheField>'
@@ -33,9 +33,7 @@ module Axlsx
33
33
  # @param [String] str
34
34
  # @return [String]
35
35
  def to_xml_string(str = '')
36
- str << '<printOptions '
37
- serialized_attributes str
38
- str << '/>'
36
+ serialized_tag 'printOptions', str
39
37
  end
40
38
  end
41
39
  end
@@ -41,9 +41,7 @@ module Axlsx
41
41
  # our output to that object. Use this - it helps limit the number of
42
42
  # objects created during serialization
43
43
  def to_xml_string(str="")
44
- str << '<protectedRange '
45
- serialized_attributes str
46
- str << '/>'
44
+ serialized_tag 'protectedRange', str
47
45
  end
48
46
  end
49
47
  end
@@ -20,7 +20,7 @@ module Axlsx
20
20
  elsif cells.is_a?(SimpleTypedList) || cells.is_a?(Array)
21
21
  Axlsx::cell_range(cells, false)
22
22
  end
23
- @list << ProtectedRange.new(:sqref => sqref, :name => "Range#{size}")
23
+ self << ProtectedRange.new(:sqref => sqref, :name => "Range#{size}")
24
24
  last
25
25
  end
26
26
 
@@ -0,0 +1,35 @@
1
+ module Axlsx
2
+ class RichText < SimpleTypedList
3
+ def initialize(text = nil, options={})
4
+ super(RichTextRun)
5
+ add_run(text, options) unless text.nil?
6
+ yield self if block_given?
7
+ end
8
+
9
+ attr_reader :cell
10
+
11
+ def cell=(cell)
12
+ @cell = cell
13
+ each { |run| run.cell = cell }
14
+ end
15
+
16
+ def autowidth
17
+ widtharray = [0] # Are arrays the best way of solving this problem?
18
+ each { |run| run.autowidth(widtharray) }
19
+ widtharray.max
20
+ end
21
+
22
+ def add_run(text, options={})
23
+ self << RichTextRun.new(text, options)
24
+ end
25
+
26
+ def runs
27
+ self
28
+ end
29
+
30
+ def to_xml_string(str='')
31
+ each{ |run| run.to_xml_string(str) }
32
+ str
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,254 @@
1
+ module Axlsx
2
+ class RichTextRun
3
+
4
+ include Axlsx::OptionsParser
5
+
6
+ attr_reader :value
7
+
8
+ INLINE_STYLES = [:font_name, :charset,
9
+ :family, :b, :i, :strike, :outline,
10
+ :shadow, :condense, :extend, :u,
11
+ :vertAlign, :sz, :color, :scheme].freeze
12
+
13
+ def initialize(value, options={})
14
+ self.value = value
15
+ parse_options(options)
16
+ end
17
+
18
+ def value=(value)
19
+ @value = value
20
+ end
21
+
22
+ attr_accessor :cell
23
+
24
+ # The inline font_name property for the cell
25
+ # @return [String]
26
+ attr_reader :font_name
27
+ # @see font_name
28
+ def font_name=(v) set_run_style :validate_string, :font_name, v; end
29
+
30
+ # The inline charset property for the cell
31
+ # As far as I can tell, this is pretty much ignored. However, based on the spec it should be one of the following:
32
+ # 0  ANSI_CHARSET
33
+ # 1 DEFAULT_CHARSET
34
+ # 2 SYMBOL_CHARSET
35
+ # 77 MAC_CHARSET
36
+ # 128 SHIFTJIS_CHARSET
37
+ # 129  HANGUL_CHARSET
38
+ # 130  JOHAB_CHARSET
39
+ # 134  GB2312_CHARSET
40
+ # 136  CHINESEBIG5_CHARSET
41
+ # 161  GREEK_CHARSET
42
+ # 162  TURKISH_CHARSET
43
+ # 163  VIETNAMESE_CHARSET
44
+ # 177  HEBREW_CHARSET
45
+ # 178  ARABIC_CHARSET
46
+ # 186  BALTIC_CHARSET
47
+ # 204  RUSSIAN_CHARSET
48
+ # 222  THAI_CHARSET
49
+ # 238  EASTEUROPE_CHARSET
50
+ # 255  OEM_CHARSET
51
+ # @return [String]
52
+ attr_reader :charset
53
+ # @see charset
54
+ def charset=(v) set_run_style :validate_unsigned_int, :charset, v; end
55
+
56
+ # The inline family property for the cell
57
+ # @return [Integer]
58
+ # 1 Roman
59
+ # 2 Swiss
60
+ # 3 Modern
61
+ # 4 Script
62
+ # 5 Decorative
63
+ attr_reader :family
64
+ # @see family
65
+ def family=(v)
66
+ set_run_style :validate_family, :family, v.to_i
67
+ end
68
+
69
+ # The inline bold property for the cell
70
+ # @return [Boolean]
71
+ attr_reader :b
72
+ # @see b
73
+ def b=(v) set_run_style :validate_boolean, :b, v; end
74
+
75
+ # The inline italic property for the cell
76
+ # @return [Boolean]
77
+ attr_reader :i
78
+ # @see i
79
+ def i=(v) set_run_style :validate_boolean, :i, v; end
80
+
81
+ # The inline strike property for the cell
82
+ # @return [Boolean]
83
+ attr_reader :strike
84
+ # @see strike
85
+ def strike=(v) set_run_style :validate_boolean, :strike, v; end
86
+
87
+ # The inline outline property for the cell
88
+ # @return [Boolean]
89
+ attr_reader :outline
90
+ # @see outline
91
+ def outline=(v) set_run_style :validate_boolean, :outline, v; end
92
+
93
+ # The inline shadow property for the cell
94
+ # @return [Boolean]
95
+ attr_reader :shadow
96
+ # @see shadow
97
+ def shadow=(v) set_run_style :validate_boolean, :shadow, v; end
98
+
99
+ # The inline condense property for the cell
100
+ # @return [Boolean]
101
+ attr_reader :condense
102
+ # @see condense
103
+ def condense=(v) set_run_style :validate_boolean, :condense, v; end
104
+
105
+ # The inline extend property for the cell
106
+ # @return [Boolean]
107
+ attr_reader :extend
108
+ # @see extend
109
+ def extend=(v) set_run_style :validate_boolean, :extend, v; end
110
+
111
+ # The inline underline property for the cell.
112
+ # It must be one of :none, :single, :double, :singleAccounting, :doubleAccounting, true
113
+ # @return [Boolean]
114
+ # @return [String]
115
+ # @note true is for backwards compatability and is reassigned to :single
116
+ attr_reader :u
117
+ # @see u
118
+ def u=(v)
119
+ v = :single if (v == true || v == 1 || v == :true || v == 'true')
120
+ set_run_style :validate_cell_u, :u, v
121
+ end
122
+
123
+ # The inline color property for the cell
124
+ # @return [Color]
125
+ attr_reader :color
126
+ # @param [String] v The 8 character representation for an rgb color #FFFFFFFF"
127
+ def color=(v)
128
+ @color = v.is_a?(Color) ? v : Color.new(:rgb=>v)
129
+ end
130
+
131
+ # The inline sz property for the cell
132
+ # @return [Inteter]
133
+ attr_reader :sz
134
+ # @see sz
135
+ def sz=(v) set_run_style :validate_unsigned_int, :sz, v; end
136
+
137
+ # The inline vertical alignment property for the cell
138
+ # this must be one of [:baseline, :subscript, :superscript]
139
+ # @return [Symbol]
140
+ attr_reader :vertAlign
141
+ # @see vertAlign
142
+ def vertAlign=(v)
143
+ RestrictionValidator.validate :cell_vertAlign, [:baseline, :subscript, :superscript], v
144
+ set_run_style nil, :vertAlign, v
145
+ end
146
+
147
+ # The inline scheme property for the cell
148
+ # this must be one of [:none, major, minor]
149
+ # @return [Symbol]
150
+ attr_reader :scheme
151
+ # @see scheme
152
+ def scheme=(v)
153
+ RestrictionValidator.validate :cell_scheme, [:none, :major, :minor], v
154
+ set_run_style nil, :scheme, v
155
+ end
156
+
157
+ # The Shared Strings Table index for this cell
158
+ # @return [Integer]
159
+ attr_reader :ssti
160
+
161
+ # @return [Integer] The cellXfs item index applied to this cell.
162
+ # @raise [ArgumentError] Invalid cellXfs id if the value provided is not within cellXfs items range.
163
+ def style=(v)
164
+ Axlsx::validate_unsigned_int(v)
165
+ count = styles.cellXfs.size
166
+ raise ArgumentError, "Invalid cellXfs id" unless v < count
167
+ @style = v
168
+ end
169
+
170
+ def autowidth(widtharray)
171
+ return if value.nil?
172
+ if styles.cellXfs[style].alignment && styles.cellXfs[style].alignment.wrap_text
173
+ first = true
174
+ value.to_s.split(/\r?\n/, -1).each do |line|
175
+ if first
176
+ first = false
177
+ else
178
+ widtharray << 0
179
+ end
180
+ widtharray[-1] += string_width(line, font_size)
181
+ end
182
+ else
183
+ widtharray[-1] += string_width(value.to_s, font_size)
184
+ end
185
+ widtharray
186
+ end
187
+
188
+ # Utility method for setting inline style attributes
189
+ def set_run_style(validator, attr, value)
190
+ return unless INLINE_STYLES.include?(attr.to_sym)
191
+ Axlsx.send(validator, value) unless validator.nil?
192
+ self.instance_variable_set :"@#{attr.to_s}", value
193
+ end
194
+
195
+ def to_xml_string(str = '')
196
+ valid = RichTextRun::INLINE_STYLES
197
+ data = Hash[self.instance_values.map{ |k, v| [k.to_sym, v] }]
198
+ data = data.select { |key, value| valid.include?(key) && !value.nil? }
199
+
200
+ str << '<r><rPr>'
201
+ data.keys.each do |key|
202
+ case key
203
+ when :font_name
204
+ str << ('<rFont val="' << font_name << '"/>')
205
+ when :color
206
+ str << data[key].to_xml_string
207
+ else
208
+ str << ('<' << key.to_s << ' val="' << xml_value(data[key]) << '"/>')
209
+ end
210
+ end
211
+ clean_value = Axlsx::trust_input ? @value.to_s : ::CGI.escapeHTML(Axlsx::sanitize(@value.to_s))
212
+ str << ('</rPr><t>' << clean_value << '</t></r>')
213
+ end
214
+
215
+ private
216
+
217
+ # Returns the width of a string according to the current style
218
+ # This is still not perfect...
219
+ # - scaling is not linear as font sizes increase
220
+ def string_width(string, font_size)
221
+ font_scale = font_size / 10.0
222
+ string.count(Worksheet::THIN_CHARS) * font_scale
223
+ end
224
+
225
+ # we scale the font size if bold style is applied to either the style font or
226
+ # the cell itself. Yes, it is a bit of a hack, but it is much better than using
227
+ # imagemagick and loading metrics for every character.
228
+ def font_size
229
+ return sz if sz
230
+ font = styles.fonts[styles.cellXfs[style].fontId] || styles.fonts[0]
231
+ (font.b || (defined?(@b) && @b)) ? (font.sz * 1.5) : font.sz
232
+ end
233
+
234
+ def style
235
+ cell.style
236
+ end
237
+
238
+ def styles
239
+ cell.row.worksheet.styles
240
+ end
241
+
242
+ # Converts the value to the correct XML representation (fixes issues with
243
+ # Numbers)
244
+ def xml_value value
245
+ if value == true
246
+ 1
247
+ elsif value == false
248
+ 0
249
+ else
250
+ value
251
+ end.to_s
252
+ end
253
+ end
254
+ end