caxlsx 2.0.2 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (181) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/README.md +41 -33
  4. data/Rakefile +9 -11
  5. data/examples/auto_filter.rb +10 -1
  6. data/examples/conditional_formatting/example_conditional_formatting.rb +18 -3
  7. data/examples/data_validation.rb +57 -40
  8. data/examples/example.rb +115 -7
  9. data/examples/merge_cells.rb +17 -0
  10. data/examples/no_grid_with_borders.rb +18 -0
  11. data/examples/pivot_test.rb +63 -0
  12. data/examples/split.rb +16 -0
  13. data/lib/axlsx.rb +34 -15
  14. data/lib/axlsx/content_type/abstract_content_type.rb +1 -1
  15. data/lib/axlsx/content_type/content_type.rb +1 -1
  16. data/lib/axlsx/doc_props/app.rb +1 -1
  17. data/lib/axlsx/doc_props/core.rb +5 -5
  18. data/lib/axlsx/drawing/area_chart.rb +99 -0
  19. data/lib/axlsx/drawing/area_series.rb +110 -0
  20. data/lib/axlsx/drawing/axes.rb +1 -1
  21. data/lib/axlsx/drawing/axis.rb +12 -9
  22. data/lib/axlsx/drawing/bar_3D_chart.rb +13 -13
  23. data/lib/axlsx/drawing/bar_chart.rb +143 -0
  24. data/lib/axlsx/drawing/bar_series.rb +9 -9
  25. data/lib/axlsx/drawing/bubble_chart.rb +59 -0
  26. data/lib/axlsx/drawing/bubble_series.rb +63 -0
  27. data/lib/axlsx/drawing/cat_axis.rb +5 -5
  28. data/lib/axlsx/drawing/chart.rb +52 -8
  29. data/lib/axlsx/drawing/d_lbls.rb +3 -3
  30. data/lib/axlsx/drawing/drawing.rb +6 -1
  31. data/lib/axlsx/drawing/graphic_frame.rb +3 -3
  32. data/lib/axlsx/drawing/hyperlink.rb +1 -3
  33. data/lib/axlsx/drawing/line_3D_chart.rb +2 -2
  34. data/lib/axlsx/drawing/line_chart.rb +10 -10
  35. data/lib/axlsx/drawing/line_series.rb +32 -3
  36. data/lib/axlsx/drawing/marker.rb +1 -1
  37. data/lib/axlsx/drawing/num_data.rb +4 -4
  38. data/lib/axlsx/drawing/num_data_source.rb +6 -6
  39. data/lib/axlsx/drawing/num_val.rb +3 -1
  40. data/lib/axlsx/drawing/one_cell_anchor.rb +3 -2
  41. data/lib/axlsx/drawing/pic.rb +25 -19
  42. data/lib/axlsx/drawing/picture_locking.rb +1 -3
  43. data/lib/axlsx/drawing/pie_3D_chart.rb +5 -6
  44. data/lib/axlsx/drawing/pie_series.rb +6 -6
  45. data/lib/axlsx/drawing/scaling.rb +6 -6
  46. data/lib/axlsx/drawing/scatter_chart.rb +10 -10
  47. data/lib/axlsx/drawing/scatter_series.rb +40 -7
  48. data/lib/axlsx/drawing/ser_axis.rb +2 -2
  49. data/lib/axlsx/drawing/series.rb +3 -3
  50. data/lib/axlsx/drawing/series_title.rb +2 -2
  51. data/lib/axlsx/drawing/str_data.rb +3 -3
  52. data/lib/axlsx/drawing/str_val.rb +3 -1
  53. data/lib/axlsx/drawing/title.rb +22 -4
  54. data/lib/axlsx/drawing/two_cell_anchor.rb +6 -1
  55. data/lib/axlsx/drawing/val_axis.rb +1 -1
  56. data/lib/axlsx/drawing/view_3D.rb +2 -2
  57. data/lib/axlsx/drawing/vml_drawing.rb +1 -1
  58. data/lib/axlsx/package.rb +33 -31
  59. data/lib/axlsx/rels/relationship.rb +1 -1
  60. data/lib/axlsx/rels/relationships.rb +7 -4
  61. data/lib/axlsx/stylesheet/border_pr.rb +2 -2
  62. data/lib/axlsx/stylesheet/cell_alignment.rb +1 -3
  63. data/lib/axlsx/stylesheet/cell_protection.rb +1 -3
  64. data/lib/axlsx/stylesheet/cell_style.rb +1 -3
  65. data/lib/axlsx/stylesheet/color.rb +1 -3
  66. data/lib/axlsx/stylesheet/font.rb +1 -1
  67. data/lib/axlsx/stylesheet/gradient_stop.rb +1 -1
  68. data/lib/axlsx/stylesheet/num_fmt.rb +10 -3
  69. data/lib/axlsx/stylesheet/pattern_fill.rb +1 -1
  70. data/lib/axlsx/stylesheet/styles.rb +7 -7
  71. data/lib/axlsx/stylesheet/table_style_element.rb +1 -3
  72. data/lib/axlsx/util/accessors.rb +6 -6
  73. data/lib/axlsx/util/constants.rb +107 -99
  74. data/lib/axlsx/util/mime_type_utils.rb +11 -0
  75. data/lib/axlsx/util/options_parser.rb +2 -1
  76. data/lib/axlsx/util/parser.rb +4 -4
  77. data/lib/axlsx/util/serialized_attributes.rb +16 -6
  78. data/lib/axlsx/util/simple_typed_list.rb +28 -52
  79. data/lib/axlsx/util/storage.rb +4 -4
  80. data/lib/axlsx/util/validators.rb +29 -17
  81. data/lib/axlsx/version.rb +1 -1
  82. data/lib/axlsx/workbook/defined_name.rb +11 -12
  83. data/lib/axlsx/workbook/defined_names.rb +2 -2
  84. data/lib/axlsx/workbook/shared_strings_table.rb +5 -5
  85. data/lib/axlsx/workbook/workbook.rb +36 -11
  86. data/lib/axlsx/workbook/workbook_view.rb +80 -0
  87. data/lib/axlsx/workbook/workbook_views.rb +22 -0
  88. data/lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb +2 -2
  89. data/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +1 -3
  90. data/lib/axlsx/workbook/worksheet/break.rb +1 -3
  91. data/lib/axlsx/workbook/worksheet/cell.rb +136 -74
  92. data/lib/axlsx/workbook/worksheet/cell_serializer.rb +63 -43
  93. data/lib/axlsx/workbook/worksheet/cfvo.rb +1 -3
  94. data/lib/axlsx/workbook/worksheet/cfvos.rb +4 -1
  95. data/lib/axlsx/workbook/worksheet/col.rb +7 -10
  96. data/lib/axlsx/workbook/worksheet/col_breaks.rb +2 -2
  97. data/lib/axlsx/workbook/worksheet/cols.rb +5 -2
  98. data/lib/axlsx/workbook/worksheet/comment.rb +5 -6
  99. data/lib/axlsx/workbook/worksheet/comments.rb +9 -12
  100. data/lib/axlsx/workbook/worksheet/conditional_formatting.rb +1 -1
  101. data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +1 -1
  102. data/lib/axlsx/workbook/worksheet/data_bar.rb +4 -6
  103. data/lib/axlsx/workbook/worksheet/data_validation.rb +6 -4
  104. data/lib/axlsx/workbook/worksheet/dimension.rb +2 -2
  105. data/lib/axlsx/workbook/worksheet/header_footer.rb +6 -8
  106. data/lib/axlsx/workbook/worksheet/icon_set.rb +3 -5
  107. data/lib/axlsx/workbook/worksheet/merged_cells.rb +4 -2
  108. data/lib/axlsx/workbook/worksheet/outline_pr.rb +33 -0
  109. data/lib/axlsx/workbook/worksheet/page_margins.rb +1 -3
  110. data/lib/axlsx/workbook/worksheet/page_set_up_pr.rb +1 -1
  111. data/lib/axlsx/workbook/worksheet/page_setup.rb +21 -23
  112. data/lib/axlsx/workbook/worksheet/pane.rb +1 -3
  113. data/lib/axlsx/workbook/worksheet/pivot_table.rb +44 -28
  114. data/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +4 -4
  115. data/lib/axlsx/workbook/worksheet/print_options.rb +1 -3
  116. data/lib/axlsx/workbook/worksheet/protected_range.rb +1 -3
  117. data/lib/axlsx/workbook/worksheet/protected_ranges.rb +5 -2
  118. data/lib/axlsx/workbook/worksheet/rich_text.rb +55 -0
  119. data/lib/axlsx/workbook/worksheet/rich_text_run.rb +250 -0
  120. data/lib/axlsx/workbook/worksheet/row.rb +40 -51
  121. data/lib/axlsx/workbook/worksheet/row_breaks.rb +2 -2
  122. data/lib/axlsx/workbook/worksheet/selection.rb +1 -3
  123. data/lib/axlsx/workbook/worksheet/sheet_data.rb +3 -1
  124. data/lib/axlsx/workbook/worksheet/sheet_pr.rb +21 -3
  125. data/lib/axlsx/workbook/worksheet/sheet_protection.rb +1 -3
  126. data/lib/axlsx/workbook/worksheet/table.rb +6 -6
  127. data/lib/axlsx/workbook/worksheet/table_style_info.rb +1 -3
  128. data/lib/axlsx/workbook/worksheet/tables.rb +4 -1
  129. data/lib/axlsx/workbook/worksheet/worksheet.rb +64 -78
  130. data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +10 -10
  131. data/lib/axlsx/workbook/worksheet/worksheet_hyperlinks.rb +3 -3
  132. data/test/drawing/tc_area_chart.rb +39 -0
  133. data/test/drawing/tc_area_series.rb +71 -0
  134. data/test/drawing/tc_axis.rb +27 -0
  135. data/test/drawing/tc_bar_chart.rb +71 -0
  136. data/test/drawing/tc_bubble_chart.rb +44 -0
  137. data/test/drawing/tc_bubble_series.rb +21 -0
  138. data/test/drawing/tc_chart.rb +23 -10
  139. data/test/drawing/tc_data_source.rb +6 -0
  140. data/test/drawing/tc_drawing.rb +2 -2
  141. data/test/drawing/tc_line_chart.rb +5 -5
  142. data/test/drawing/tc_line_series.rb +47 -6
  143. data/test/drawing/tc_pic.rb +11 -15
  144. data/test/drawing/tc_scatter_series.rb +36 -1
  145. data/test/drawing/tc_str_val.rb +9 -0
  146. data/test/drawing/tc_title.rb +5 -0
  147. data/test/stylesheet/tc_styles.rb +2 -2
  148. data/test/tc_axlsx.rb +31 -0
  149. data/test/tc_helper.rb +2 -0
  150. data/test/tc_package.rb +19 -1
  151. data/test/util/tc_mime_type_utils.rb +13 -0
  152. data/test/util/tc_simple_typed_list.rb +2 -3
  153. data/test/util/tc_validators.rb +34 -10
  154. data/test/workbook/tc_defined_name.rb +12 -4
  155. data/test/workbook/tc_shared_strings_table.rb +16 -1
  156. data/test/workbook/tc_workbook.rb +38 -3
  157. data/test/workbook/tc_workbook_view.rb +50 -0
  158. data/test/workbook/worksheet/auto_filter/tc_filters.rb +1 -1
  159. data/test/workbook/worksheet/tc_break.rb +1 -1
  160. data/test/workbook/worksheet/tc_cell.rb +76 -8
  161. data/test/workbook/worksheet/tc_col.rb +2 -2
  162. data/test/workbook/worksheet/tc_conditional_formatting.rb +2 -2
  163. data/test/workbook/worksheet/tc_data_bar.rb +1 -1
  164. data/test/workbook/worksheet/tc_data_validation.rb +11 -11
  165. data/test/workbook/worksheet/tc_header_footer.rb +2 -2
  166. data/test/workbook/worksheet/tc_icon_set.rb +1 -1
  167. data/test/workbook/worksheet/tc_outline_pr.rb +19 -0
  168. data/test/workbook/worksheet/tc_page_setup.rb +3 -3
  169. data/test/workbook/worksheet/tc_pivot_table.rb +21 -6
  170. data/test/workbook/worksheet/tc_print_options.rb +1 -1
  171. data/test/workbook/worksheet/tc_rich_text.rb +44 -0
  172. data/test/workbook/worksheet/tc_rich_text_run.rb +172 -0
  173. data/test/workbook/worksheet/tc_row.rb +7 -2
  174. data/test/workbook/worksheet/tc_sheet_calc_pr.rb +1 -1
  175. data/test/workbook/worksheet/tc_sheet_format_pr.rb +4 -4
  176. data/test/workbook/worksheet/tc_sheet_pr.rb +26 -4
  177. data/test/workbook/worksheet/tc_sheet_protection.rb +5 -5
  178. data/test/workbook/worksheet/tc_sheet_view.rb +4 -4
  179. data/test/workbook/worksheet/tc_table.rb +2 -3
  180. data/test/workbook/worksheet/tc_worksheet.rb +99 -45
  181. metadata +89 -16
@@ -43,13 +43,13 @@ module Axlsx
43
43
  # The first cell in the dimension
44
44
  # @return [String]
45
45
  def first_cell_reference
46
- dimension_reference(worksheet.rows.first.cells.first, Dimension.default_first)
46
+ dimension_reference(worksheet.rows.first.first, Dimension.default_first)
47
47
  end
48
48
 
49
49
  # the last cell in the dimension
50
50
  # @return [String]
51
51
  def last_cell_reference
52
- dimension_reference(worksheet.rows.last.cells.last, Dimension.default_last)
52
+ dimension_reference(worksheet.rows.last.last, Dimension.default_last)
53
53
  end
54
54
 
55
55
  private
@@ -19,8 +19,8 @@ module Axlsx
19
19
  # @option options [String] odd_footer The content for footers on odd numbered pages.
20
20
  # @option options [String] even_header The content for headers on even numbered pages.
21
21
  # @option options [String] even_footer The content for footers on even numbered pages.
22
- # @option options [String] first_header The content for headers on even numbered pages.
23
- # @option options [String] first_footer The content for footers on even numbered pages.
22
+ # @option options [String] first_header The content for headers on the first page.
23
+ # @option options [String] first_footer The content for footers on the first page.
24
24
  # @option options [Boolean] different_odd_even Setting this to true will show different headers/footers on odd and even pages. When false, the odd headers/footers are used on each page. (Default: false)
25
25
  # @option options [Boolean] different_first If true, will use the first header/footer on page 1. Otherwise, the odd header/footer is used.
26
26
  def initialize(options = {})
@@ -42,13 +42,11 @@ module Axlsx
42
42
  # @param [String] str
43
43
  # @return [String]
44
44
  def to_xml_string(str = '')
45
- str << "<headerFooter "
46
- serialized_attributes str
47
- str << ">"
48
- serialized_element_attributes(str) do |value|
49
- value = ::CGI.escapeHTML(value)
45
+ serialized_tag('headerFooter', str) do
46
+ serialized_element_attributes(str) do |value|
47
+ value = ::CGI.escapeHTML(value)
48
+ end
50
49
  end
51
- str << "</headerFooter>"
52
50
  end
53
51
  end
54
52
  end
@@ -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,10 +15,12 @@ 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)
22
+ elsif cells.is_a?(Row)
23
+ Axlsx::cell_range(cells, false)
22
24
  end
23
25
  end
24
26
 
@@ -26,7 +28,7 @@ module Axlsx
26
28
  # @param [String] str
27
29
  # @return [String]
28
30
  def to_xml_string(str = '')
29
- return if @list.empty?
31
+ return if empty?
30
32
  str << "<mergeCells count='#{size}'>"
31
33
  each { |merged_cell| str << "<mergeCell ref='#{merged_cell}'></mergeCell>" }
32
34
  str << '</mergeCells>'
@@ -0,0 +1,33 @@
1
+ module Axlsx
2
+
3
+ # The OutlinePr class manages serialization of a worksheet's outlinePr element, which provides various
4
+ # options to control outlining.
5
+ class OutlinePr
6
+ include Axlsx::OptionsParser
7
+ include Axlsx::Accessors
8
+ include Axlsx::SerializedAttributes
9
+
10
+ serializable_attributes :summary_below,
11
+ :summary_right,
12
+ :apply_styles
13
+
14
+ # These attributes are all boolean so I'm doing a bit of a hand
15
+ # waving magic show to set up the attriubte accessors
16
+ boolean_attr_accessor :summary_below,
17
+ :summary_right,
18
+ :apply_styles
19
+
20
+ # Creates a new OutlinePr object
21
+ # @param [Hash] options used to create the outline_pr
22
+ def initialize(options = {})
23
+ parse_options options
24
+ end
25
+
26
+ # Serialize the object
27
+ # @param [String] str serialized output will be appended to this object if provided.
28
+ # @return [String]
29
+ def to_xml_string(str = '')
30
+ str << "<outlinePr #{serialized_attributes} />"
31
+ end
32
+ end
33
+ end
@@ -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
 
@@ -25,10 +25,20 @@ module Axlsx
25
25
  @data = []
26
26
  @pages = []
27
27
  @subtotal = nil
28
+ @no_subtotals_on_headers = []
29
+ @style_info = {}
28
30
  parse_options options
29
31
  yield self if block_given?
30
32
  end
31
33
 
34
+ # Defines the headers in which subtotals are not to be included
35
+ # @return[Array]
36
+ attr_accessor :no_subtotals_on_headers
37
+
38
+ # Style info for the pivot table
39
+ # @return[Hash]
40
+ attr_accessor :style_info
41
+
32
42
  # The reference to the table data
33
43
  # @return [String]
34
44
  attr_reader :ref
@@ -159,23 +169,23 @@ module Axlsx
159
169
  # @return [String]
160
170
  def to_xml_string(str = '')
161
171
  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 << '">'
172
+ 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">')
173
+ str << ('<location firstDataCol="1" firstDataRow="1" firstHeaderRow="1" ref="' << ref << '"/>')
174
+ str << ('<pivotFields count="' << header_cells_count.to_s << '">')
165
175
  header_cell_values.each do |cell_value|
166
- str << pivot_field_for(cell_value)
176
+ str << pivot_field_for(cell_value, !no_subtotals_on_headers.include?(cell_value))
167
177
  end
168
- str << '</pivotFields>'
178
+ str << '</pivotFields>'
169
179
  if rows.empty?
170
180
  str << '<rowFields count="1"><field x="-2"/></rowFields>'
171
181
  str << '<rowItems count="2"><i><x/></i> <i i="1"><x v="1"/></i></rowItems>'
172
182
  else
173
- str << '<rowFields count="' << rows.size.to_s << '">'
183
+ str << ('<rowFields count="' << rows.size.to_s << '">')
174
184
  rows.each do |row_value|
175
- str << '<field x="' << header_index_of(row_value).to_s << '"/>'
185
+ str << ('<field x="' << header_index_of(row_value).to_s << '"/>')
176
186
  end
177
187
  str << '</rowFields>'
178
- str << '<rowItems count="' << rows.size.to_s << '">'
188
+ str << ('<rowItems count="' << rows.size.to_s << '">')
179
189
  rows.size.times do |i|
180
190
  str << '<i/>'
181
191
  end
@@ -184,28 +194,37 @@ module Axlsx
184
194
  if columns.empty?
185
195
  str << '<colItems count="1"><i/></colItems>'
186
196
  else
187
- str << '<colFields count="' << columns.size.to_s << '">'
197
+ str << ('<colFields count="' << columns.size.to_s << '">')
188
198
  columns.each do |column_value|
189
- str << '<field x="' << header_index_of(column_value).to_s << '"/>'
199
+ str << ('<field x="' << header_index_of(column_value).to_s << '"/>')
190
200
  end
191
201
  str << '</colFields>'
192
202
  end
193
203
  unless pages.empty?
194
- str << '<pageFields count="' << pages.size.to_s << '">'
204
+ str << ('<pageFields count="' << pages.size.to_s << '">')
195
205
  pages.each do |page_value|
196
- str << '<pageField fld="' << header_index_of(page_value).to_s << '"/>'
206
+ str << ('<pageField fld="' << header_index_of(page_value).to_s << '"/>')
197
207
  end
198
208
  str << '</pageFields>'
199
209
  end
200
210
  unless data.empty?
201
211
  str << "<dataFields count=\"#{data.size}\">"
202
212
  data.each do |datum_value|
203
- str << "<dataField name='#{@subtotal} of #{datum_value[:ref]}' fld='#{header_index_of(datum_value[:ref])}' baseField='0' baseItem='0'"
213
+ # The correct name prefix in ["Sum","Average", etc...]
214
+ str << "<dataField name='#{(datum_value[:subtotal]||'')} of #{datum_value[:ref]}' fld='#{header_index_of(datum_value[:ref])}' baseField='0' baseItem='0'"
204
215
  str << " subtotal='#{datum_value[:subtotal]}' " if datum_value[:subtotal]
205
216
  str << "/>"
206
217
  end
207
218
  str << '</dataFields>'
208
219
  end
220
+ # custom pivot table style
221
+ unless style_info.empty?
222
+ str << '<pivotTableStyleInfo'
223
+ style_info.each do |k,v|
224
+ str << ' ' << k.to_s << '="' << v.to_s << '"'
225
+ end
226
+ str << ' />'
227
+ end
209
228
  str << '</pivotTableDefinition>'
210
229
  end
211
230
 
@@ -241,33 +260,30 @@ module Axlsx
241
260
 
242
261
  private
243
262
 
244
- def pivot_field_for(cell_ref)
263
+ def pivot_field_for(cell_ref, subtotal=true)
245
264
  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>'
265
+ if subtotal
266
+ '<pivotField axis="axisRow" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1"><items count="1"><item t="default"/></items></pivotField>'
267
+ else
268
+ '<pivotField axis="axisRow" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1" defaultSubtotal="0"></pivotField>'
269
+ end
249
270
  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>'
271
+ '<pivotField axis="axisCol" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1"><items count="1"><item t="default"/></items></pivotField>'
253
272
  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>'
273
+ '<pivotField axis="axisPage" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1"><items count="1"><item t="default"/></items></pivotField>'
257
274
  elsif data_refs.include? cell_ref
258
- '<pivotField dataField="1" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1">' <<
259
- '</pivotField>'
275
+ '<pivotField dataField="1" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1"></pivotField>'
260
276
  else
261
- '<pivotField compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1">' <<
262
- '</pivotField>'
277
+ '<pivotField compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1"></pivotField>'
263
278
  end
264
279
  end
280
+
265
281
  def data_refs
266
282
  data.map { |hash| hash[:ref] }
267
283
  end
284
+
268
285
  def header_range
269
286
  range.gsub(/^(\w+?)(\d+)\:(\w+?)\d+$/, '\1\2:\3\2')
270
287
  end
271
-
272
288
  end
273
289
  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