caxlsx 3.2.0 → 3.3.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 (300) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +9 -9
  3. data/.yardopts_guide +18 -18
  4. data/CHANGELOG.md +385 -354
  5. data/LICENSE +21 -21
  6. data/README.md +165 -168
  7. data/Rakefile +29 -29
  8. data/examples/generate.rb +15 -15
  9. data/lib/axlsx/content_type/abstract_content_type.rb +32 -32
  10. data/lib/axlsx/content_type/content_type.rb +26 -26
  11. data/lib/axlsx/content_type/default.rb +25 -25
  12. data/lib/axlsx/content_type/override.rb +25 -25
  13. data/lib/axlsx/doc_props/app.rb +235 -235
  14. data/lib/axlsx/doc_props/core.rb +39 -39
  15. data/lib/axlsx/drawing/area_chart.rb +99 -99
  16. data/lib/axlsx/drawing/area_series.rb +110 -110
  17. data/lib/axlsx/drawing/ax_data_source.rb +26 -26
  18. data/lib/axlsx/drawing/axes.rb +61 -61
  19. data/lib/axlsx/drawing/axis.rb +190 -190
  20. data/lib/axlsx/drawing/bar_3D_chart.rb +148 -148
  21. data/lib/axlsx/drawing/bar_chart.rb +138 -138
  22. data/lib/axlsx/drawing/bar_series.rb +97 -97
  23. data/lib/axlsx/drawing/bubble_chart.rb +59 -59
  24. data/lib/axlsx/drawing/bubble_series.rb +63 -63
  25. data/lib/axlsx/drawing/cat_axis.rb +85 -85
  26. data/lib/axlsx/drawing/chart.rb +299 -276
  27. data/lib/axlsx/drawing/d_lbls.rb +91 -90
  28. data/lib/axlsx/drawing/drawing.rb +167 -167
  29. data/lib/axlsx/drawing/graphic_frame.rb +54 -54
  30. data/lib/axlsx/drawing/hyperlink.rb +100 -100
  31. data/lib/axlsx/drawing/line_3D_chart.rb +68 -68
  32. data/lib/axlsx/drawing/line_chart.rb +99 -99
  33. data/lib/axlsx/drawing/line_series.rb +110 -110
  34. data/lib/axlsx/drawing/marker.rb +84 -84
  35. data/lib/axlsx/drawing/num_data.rb +52 -52
  36. data/lib/axlsx/drawing/num_data_source.rb +62 -62
  37. data/lib/axlsx/drawing/num_val.rb +34 -34
  38. data/lib/axlsx/drawing/one_cell_anchor.rb +99 -99
  39. data/lib/axlsx/drawing/pic.rb +211 -211
  40. data/lib/axlsx/drawing/picture_locking.rb +42 -42
  41. data/lib/axlsx/drawing/pie_3D_chart.rb +47 -47
  42. data/lib/axlsx/drawing/pie_series.rb +74 -74
  43. data/lib/axlsx/drawing/scaling.rb +60 -60
  44. data/lib/axlsx/drawing/scatter_chart.rb +74 -74
  45. data/lib/axlsx/drawing/scatter_series.rb +129 -129
  46. data/lib/axlsx/drawing/ser_axis.rb +45 -45
  47. data/lib/axlsx/drawing/series.rb +69 -69
  48. data/lib/axlsx/drawing/series_title.rb +25 -25
  49. data/lib/axlsx/drawing/str_data.rb +42 -42
  50. data/lib/axlsx/drawing/str_val.rb +34 -34
  51. data/lib/axlsx/drawing/title.rb +107 -97
  52. data/lib/axlsx/drawing/two_cell_anchor.rb +97 -97
  53. data/lib/axlsx/drawing/val_axis.rb +37 -37
  54. data/lib/axlsx/drawing/view_3D.rb +115 -115
  55. data/lib/axlsx/drawing/vml_drawing.rb +42 -42
  56. data/lib/axlsx/drawing/vml_shape.rb +66 -66
  57. data/lib/axlsx/package.rb +398 -388
  58. data/lib/axlsx/rels/relationship.rb +130 -130
  59. data/lib/axlsx/rels/relationships.rb +32 -32
  60. data/lib/axlsx/stylesheet/border.rb +73 -73
  61. data/lib/axlsx/stylesheet/border_pr.rb +71 -71
  62. data/lib/axlsx/stylesheet/cell_alignment.rb +132 -132
  63. data/lib/axlsx/stylesheet/cell_protection.rb +41 -41
  64. data/lib/axlsx/stylesheet/cell_style.rb +72 -72
  65. data/lib/axlsx/stylesheet/color.rb +76 -76
  66. data/lib/axlsx/stylesheet/dxf.rb +79 -79
  67. data/lib/axlsx/stylesheet/fill.rb +35 -35
  68. data/lib/axlsx/stylesheet/font.rb +156 -156
  69. data/lib/axlsx/stylesheet/gradient_fill.rb +103 -103
  70. data/lib/axlsx/stylesheet/gradient_stop.rb +37 -37
  71. data/lib/axlsx/stylesheet/num_fmt.rb +86 -86
  72. data/lib/axlsx/stylesheet/pattern_fill.rb +73 -73
  73. data/lib/axlsx/stylesheet/styles.rb +535 -494
  74. data/lib/axlsx/stylesheet/table_style.rb +54 -54
  75. data/lib/axlsx/stylesheet/table_style_element.rb +77 -77
  76. data/lib/axlsx/stylesheet/table_styles.rb +46 -46
  77. data/lib/axlsx/stylesheet/xf.rb +147 -147
  78. data/lib/axlsx/util/accessors.rb +64 -64
  79. data/lib/axlsx/util/constants.rb +416 -410
  80. data/lib/axlsx/util/mime_type_utils.rb +11 -11
  81. data/lib/axlsx/util/options_parser.rb +16 -16
  82. data/lib/axlsx/util/serialized_attributes.rb +89 -89
  83. data/lib/axlsx/util/simple_typed_list.rb +179 -179
  84. data/lib/axlsx/util/storage.rb +146 -146
  85. data/lib/axlsx/util/validators.rb +312 -312
  86. data/lib/axlsx/util/zip_command.rb +73 -73
  87. data/lib/axlsx/version.rb +5 -5
  88. data/lib/axlsx/workbook/defined_name.rb +128 -128
  89. data/lib/axlsx/workbook/defined_names.rb +21 -21
  90. data/lib/axlsx/workbook/shared_strings_table.rb +77 -77
  91. data/lib/axlsx/workbook/workbook.rb +425 -395
  92. data/lib/axlsx/workbook/workbook_view.rb +80 -80
  93. data/lib/axlsx/workbook/workbook_views.rb +22 -22
  94. data/lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb +77 -77
  95. data/lib/axlsx/workbook/worksheet/auto_filter/filter_column.rb +94 -94
  96. data/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +244 -244
  97. data/lib/axlsx/workbook/worksheet/border_creator.rb +76 -0
  98. data/lib/axlsx/workbook/worksheet/break.rb +35 -35
  99. data/lib/axlsx/workbook/worksheet/cell.rb +532 -506
  100. data/lib/axlsx/workbook/worksheet/cell_serializer.rb +164 -164
  101. data/lib/axlsx/workbook/worksheet/cfvo.rb +60 -60
  102. data/lib/axlsx/workbook/worksheet/cfvos.rb +18 -18
  103. data/lib/axlsx/workbook/worksheet/col.rb +145 -145
  104. data/lib/axlsx/workbook/worksheet/col_breaks.rb +35 -35
  105. data/lib/axlsx/workbook/worksheet/color_scale.rb +110 -110
  106. data/lib/axlsx/workbook/worksheet/cols.rb +23 -23
  107. data/lib/axlsx/workbook/worksheet/comment.rb +91 -91
  108. data/lib/axlsx/workbook/worksheet/comments.rb +82 -82
  109. data/lib/axlsx/workbook/worksheet/conditional_formatting.rb +82 -82
  110. data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +220 -220
  111. data/lib/axlsx/workbook/worksheet/conditional_formattings.rb +25 -25
  112. data/lib/axlsx/workbook/worksheet/data_bar.rb +129 -129
  113. data/lib/axlsx/workbook/worksheet/data_validation.rb +267 -246
  114. data/lib/axlsx/workbook/worksheet/data_validations.rb +28 -28
  115. data/lib/axlsx/workbook/worksheet/date_time_converter.rb +30 -30
  116. data/lib/axlsx/workbook/worksheet/dimension.rb +64 -64
  117. data/lib/axlsx/workbook/worksheet/header_footer.rb +52 -52
  118. data/lib/axlsx/workbook/worksheet/icon_set.rb +81 -81
  119. data/lib/axlsx/workbook/worksheet/merged_cells.rb +37 -37
  120. data/lib/axlsx/workbook/worksheet/outline_pr.rb +33 -33
  121. data/lib/axlsx/workbook/worksheet/page_margins.rb +97 -97
  122. data/lib/axlsx/workbook/worksheet/page_set_up_pr.rb +44 -44
  123. data/lib/axlsx/workbook/worksheet/page_setup.rb +240 -240
  124. data/lib/axlsx/workbook/worksheet/pane.rb +139 -139
  125. data/lib/axlsx/workbook/worksheet/pivot_table.rb +335 -296
  126. data/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +66 -66
  127. data/lib/axlsx/workbook/worksheet/pivot_tables.rb +24 -24
  128. data/lib/axlsx/workbook/worksheet/print_options.rb +39 -39
  129. data/lib/axlsx/workbook/worksheet/protected_range.rb +47 -47
  130. data/lib/axlsx/workbook/worksheet/protected_ranges.rb +37 -37
  131. data/lib/axlsx/workbook/worksheet/rich_text.rb +55 -55
  132. data/lib/axlsx/workbook/worksheet/rich_text_run.rb +250 -250
  133. data/lib/axlsx/workbook/worksheet/row.rb +164 -164
  134. data/lib/axlsx/workbook/worksheet/row_breaks.rb +33 -33
  135. data/lib/axlsx/workbook/worksheet/selection.rb +101 -101
  136. data/lib/axlsx/workbook/worksheet/sheet_calc_pr.rb +29 -29
  137. data/lib/axlsx/workbook/worksheet/sheet_data.rb +27 -27
  138. data/lib/axlsx/workbook/worksheet/sheet_pr.rb +87 -87
  139. data/lib/axlsx/workbook/worksheet/sheet_protection.rb +118 -118
  140. data/lib/axlsx/workbook/worksheet/sheet_view.rb +213 -213
  141. data/lib/axlsx/workbook/worksheet/table.rb +102 -102
  142. data/lib/axlsx/workbook/worksheet/table_style_info.rb +49 -49
  143. data/lib/axlsx/workbook/worksheet/tables.rb +34 -34
  144. data/lib/axlsx/workbook/worksheet/worksheet.rb +829 -786
  145. data/lib/axlsx/workbook/worksheet/worksheet_comments.rb +58 -58
  146. data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +58 -58
  147. data/lib/axlsx/workbook/worksheet/worksheet_hyperlink.rb +74 -74
  148. data/lib/axlsx/workbook/worksheet/worksheet_hyperlinks.rb +38 -38
  149. data/lib/axlsx.rb +204 -185
  150. data/lib/caxlsx.rb +2 -2
  151. data/lib/schema/dc.xsd +118 -118
  152. data/lib/schema/dcmitype.xsd +51 -51
  153. data/lib/schema/dcterms.xsd +331 -331
  154. data/lib/schema/dml-chartDrawing.xsd +146 -146
  155. data/lib/schema/dml-compatibility.xsd +14 -14
  156. data/lib/schema/dml-lockedCanvas.xsd +11 -11
  157. data/lib/schema/dml-main.xsd +3048 -3048
  158. data/lib/schema/dml-picture.xsd +23 -23
  159. data/lib/schema/dml-spreadsheetDrawing.xsd +185 -185
  160. data/lib/schema/dml-wordprocessingDrawing.xsd +185 -185
  161. data/lib/schema/shared-additionalCharacteristics.xsd +28 -28
  162. data/lib/schema/shared-bibliography.xsd +144 -144
  163. data/lib/schema/shared-commonSimpleTypes.xsd +166 -166
  164. data/lib/schema/shared-customXmlDataProperties.xsd +25 -25
  165. data/lib/schema/shared-customXmlSchemaProperties.xsd +18 -18
  166. data/lib/schema/shared-documentPropertiesCustom.xsd +59 -59
  167. data/lib/schema/shared-documentPropertiesExtended.xsd +56 -56
  168. data/lib/schema/shared-documentPropertiesVariantTypes.xsd +195 -195
  169. data/lib/schema/shared-relationshipReference.xsd +25 -25
  170. data/lib/schema/vml-main.xsd +569 -569
  171. data/lib/schema/vml-officeDrawing.xsd +509 -509
  172. data/lib/schema/vml-presentationDrawing.xsd +12 -12
  173. data/lib/schema/vml-spreadsheetDrawing.xsd +108 -108
  174. data/lib/schema/vml-wordprocessingDrawing.xsd +96 -96
  175. data/lib/schema/xml.xsd +116 -116
  176. metadata +5 -252
  177. data/test/benchmark.rb +0 -72
  178. data/test/content_type/tc_content_type.rb +0 -76
  179. data/test/content_type/tc_default.rb +0 -16
  180. data/test/content_type/tc_override.rb +0 -14
  181. data/test/doc_props/tc_app.rb +0 -43
  182. data/test/doc_props/tc_core.rb +0 -42
  183. data/test/drawing/tc_area_chart.rb +0 -39
  184. data/test/drawing/tc_area_series.rb +0 -71
  185. data/test/drawing/tc_axes.rb +0 -8
  186. data/test/drawing/tc_axis.rb +0 -112
  187. data/test/drawing/tc_bar_3D_chart.rb +0 -86
  188. data/test/drawing/tc_bar_chart.rb +0 -86
  189. data/test/drawing/tc_bar_series.rb +0 -46
  190. data/test/drawing/tc_bubble_chart.rb +0 -44
  191. data/test/drawing/tc_bubble_series.rb +0 -21
  192. data/test/drawing/tc_cat_axis.rb +0 -31
  193. data/test/drawing/tc_cat_axis_data.rb +0 -27
  194. data/test/drawing/tc_chart.rb +0 -123
  195. data/test/drawing/tc_d_lbls.rb +0 -57
  196. data/test/drawing/tc_data_source.rb +0 -23
  197. data/test/drawing/tc_drawing.rb +0 -80
  198. data/test/drawing/tc_graphic_frame.rb +0 -27
  199. data/test/drawing/tc_hyperlink.rb +0 -64
  200. data/test/drawing/tc_line_3d_chart.rb +0 -47
  201. data/test/drawing/tc_line_chart.rb +0 -39
  202. data/test/drawing/tc_line_series.rb +0 -71
  203. data/test/drawing/tc_marker.rb +0 -44
  204. data/test/drawing/tc_named_axis_data.rb +0 -27
  205. data/test/drawing/tc_num_data.rb +0 -31
  206. data/test/drawing/tc_num_val.rb +0 -29
  207. data/test/drawing/tc_one_cell_anchor.rb +0 -66
  208. data/test/drawing/tc_pic.rb +0 -103
  209. data/test/drawing/tc_picture_locking.rb +0 -72
  210. data/test/drawing/tc_pie_3D_chart.rb +0 -28
  211. data/test/drawing/tc_pie_series.rb +0 -33
  212. data/test/drawing/tc_scaling.rb +0 -36
  213. data/test/drawing/tc_scatter_chart.rb +0 -48
  214. data/test/drawing/tc_scatter_series.rb +0 -74
  215. data/test/drawing/tc_ser_axis.rb +0 -31
  216. data/test/drawing/tc_series.rb +0 -23
  217. data/test/drawing/tc_series_title.rb +0 -54
  218. data/test/drawing/tc_str_data.rb +0 -18
  219. data/test/drawing/tc_str_val.rb +0 -30
  220. data/test/drawing/tc_title.rb +0 -70
  221. data/test/drawing/tc_two_cell_anchor.rb +0 -36
  222. data/test/drawing/tc_val_axis.rb +0 -24
  223. data/test/drawing/tc_view_3D.rb +0 -54
  224. data/test/drawing/tc_vml_drawing.rb +0 -25
  225. data/test/drawing/tc_vml_shape.rb +0 -106
  226. data/test/fixtures/image1.gif +0 -0
  227. data/test/fixtures/image1.jpeg +0 -0
  228. data/test/fixtures/image1.jpg +0 -0
  229. data/test/fixtures/image1.png +0 -0
  230. data/test/fixtures/image1_fake.jpg +0 -0
  231. data/test/profile.rb +0 -24
  232. data/test/rels/tc_relationship.rb +0 -52
  233. data/test/rels/tc_relationships.rb +0 -37
  234. data/test/stylesheet/tc_border.rb +0 -37
  235. data/test/stylesheet/tc_border_pr.rb +0 -32
  236. data/test/stylesheet/tc_cell_alignment.rb +0 -81
  237. data/test/stylesheet/tc_cell_protection.rb +0 -29
  238. data/test/stylesheet/tc_cell_style.rb +0 -57
  239. data/test/stylesheet/tc_color.rb +0 -43
  240. data/test/stylesheet/tc_dxf.rb +0 -81
  241. data/test/stylesheet/tc_fill.rb +0 -18
  242. data/test/stylesheet/tc_font.rb +0 -133
  243. data/test/stylesheet/tc_gradient_fill.rb +0 -72
  244. data/test/stylesheet/tc_gradient_stop.rb +0 -31
  245. data/test/stylesheet/tc_num_fmt.rb +0 -30
  246. data/test/stylesheet/tc_pattern_fill.rb +0 -43
  247. data/test/stylesheet/tc_styles.rb +0 -309
  248. data/test/stylesheet/tc_table_style.rb +0 -44
  249. data/test/stylesheet/tc_table_style_element.rb +0 -45
  250. data/test/stylesheet/tc_table_styles.rb +0 -29
  251. data/test/stylesheet/tc_xf.rb +0 -120
  252. data/test/tc_axlsx.rb +0 -109
  253. data/test/tc_helper.rb +0 -10
  254. data/test/tc_package.rb +0 -317
  255. data/test/util/tc_mime_type_utils.rb +0 -13
  256. data/test/util/tc_serialized_attributes.rb +0 -19
  257. data/test/util/tc_simple_typed_list.rb +0 -77
  258. data/test/util/tc_validators.rb +0 -210
  259. data/test/workbook/tc_defined_name.rb +0 -49
  260. data/test/workbook/tc_shared_strings_table.rb +0 -59
  261. data/test/workbook/tc_workbook.rb +0 -165
  262. data/test/workbook/tc_workbook_view.rb +0 -50
  263. data/test/workbook/worksheet/auto_filter/tc_auto_filter.rb +0 -38
  264. data/test/workbook/worksheet/auto_filter/tc_filter_column.rb +0 -76
  265. data/test/workbook/worksheet/auto_filter/tc_filters.rb +0 -50
  266. data/test/workbook/worksheet/tc_break.rb +0 -49
  267. data/test/workbook/worksheet/tc_cell.rb +0 -465
  268. data/test/workbook/worksheet/tc_cfvo.rb +0 -31
  269. data/test/workbook/worksheet/tc_col.rb +0 -93
  270. data/test/workbook/worksheet/tc_color_scale.rb +0 -58
  271. data/test/workbook/worksheet/tc_comment.rb +0 -72
  272. data/test/workbook/worksheet/tc_comments.rb +0 -57
  273. data/test/workbook/worksheet/tc_conditional_formatting.rb +0 -224
  274. data/test/workbook/worksheet/tc_data_bar.rb +0 -46
  275. data/test/workbook/worksheet/tc_data_validation.rb +0 -265
  276. data/test/workbook/worksheet/tc_date_time_converter.rb +0 -124
  277. data/test/workbook/worksheet/tc_header_footer.rb +0 -151
  278. data/test/workbook/worksheet/tc_icon_set.rb +0 -45
  279. data/test/workbook/worksheet/tc_outline_pr.rb +0 -19
  280. data/test/workbook/worksheet/tc_page_margins.rb +0 -97
  281. data/test/workbook/worksheet/tc_page_set_up_pr.rb +0 -15
  282. data/test/workbook/worksheet/tc_page_setup.rb +0 -143
  283. data/test/workbook/worksheet/tc_pane.rb +0 -54
  284. data/test/workbook/worksheet/tc_pivot_table.rb +0 -180
  285. data/test/workbook/worksheet/tc_pivot_table_cache_definition.rb +0 -62
  286. data/test/workbook/worksheet/tc_print_options.rb +0 -72
  287. data/test/workbook/worksheet/tc_protected_range.rb +0 -17
  288. data/test/workbook/worksheet/tc_rich_text.rb +0 -44
  289. data/test/workbook/worksheet/tc_rich_text_run.rb +0 -173
  290. data/test/workbook/worksheet/tc_row.rb +0 -160
  291. data/test/workbook/worksheet/tc_selection.rb +0 -55
  292. data/test/workbook/worksheet/tc_sheet_calc_pr.rb +0 -18
  293. data/test/workbook/worksheet/tc_sheet_format_pr.rb +0 -88
  294. data/test/workbook/worksheet/tc_sheet_pr.rb +0 -49
  295. data/test/workbook/worksheet/tc_sheet_protection.rb +0 -117
  296. data/test/workbook/worksheet/tc_sheet_view.rb +0 -214
  297. data/test/workbook/worksheet/tc_table.rb +0 -77
  298. data/test/workbook/worksheet/tc_table_style_info.rb +0 -53
  299. data/test/workbook/worksheet/tc_worksheet.rb +0 -632
  300. data/test/workbook/worksheet/tc_worksheet_hyperlink.rb +0 -55
@@ -1,296 +1,335 @@
1
- # encoding: UTF-8
2
- module Axlsx
3
- # Table
4
- # @note Worksheet#add_pivot_table is the recommended way to create tables for your worksheets.
5
- # @see README for examples
6
- class PivotTable
7
-
8
- include Axlsx::OptionsParser
9
-
10
- # Creates a new PivotTable object
11
- # @param [String] ref The reference to where the pivot table lives like 'G4:L17'.
12
- # @param [String] range The reference to the pivot table data like 'A1:D31'.
13
- # @param [Worksheet] sheet The sheet containing the table data.
14
- # @option options [Cell, String] name
15
- # @option options [TableStyle] style
16
- def initialize(ref, range, sheet, options={})
17
- @ref = ref
18
- self.range = range
19
- @sheet = sheet
20
- @sheet.workbook.pivot_tables << self
21
- @name = "PivotTable#{index+1}"
22
- @data_sheet = nil
23
- @rows = []
24
- @columns = []
25
- @data = []
26
- @pages = []
27
- @subtotal = nil
28
- @no_subtotals_on_headers = []
29
- @style_info = {}
30
- parse_options options
31
- yield self if block_given?
32
- end
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
-
42
- # The reference to the table data
43
- # @return [String]
44
- attr_reader :ref
45
-
46
- # The name of the table.
47
- # @return [String]
48
- attr_reader :name
49
-
50
- # The name of the sheet.
51
- # @return [String]
52
- attr_reader :sheet
53
-
54
- # The sheet used as data source for the pivot table
55
- # @return [Worksheet]
56
- attr_writer :data_sheet
57
-
58
- # @see #data_sheet
59
- def data_sheet
60
- @data_sheet || @sheet
61
- end
62
-
63
- # The range where the data for this pivot table lives.
64
- # @return [String]
65
- attr_reader :range
66
-
67
- # (see #range)
68
- def range=(v)
69
- DataTypeValidator.validate "#{self.class}.range", [String], v
70
- if v.is_a?(String)
71
- @range = v
72
- end
73
- end
74
-
75
- # The rows
76
- # @return [Array]
77
- attr_reader :rows
78
-
79
-
80
- # (see #rows)
81
- def rows=(v)
82
- DataTypeValidator.validate "#{self.class}.rows", [Array], v
83
- v.each do |ref|
84
- DataTypeValidator.validate "#{self.class}.rows[]", [String], ref
85
- end
86
- @rows = v
87
- end
88
-
89
- # The columns
90
- # @return [Array]
91
- attr_reader :columns
92
-
93
- # (see #columns)
94
- def columns=(v)
95
- DataTypeValidator.validate "#{self.class}.columns", [Array], v
96
- v.each do |ref|
97
- DataTypeValidator.validate "#{self.class}.columns[]", [String], ref
98
- end
99
- @columns = v
100
- end
101
-
102
- # The data
103
- # @return [Array]
104
- attr_reader :data
105
-
106
- # (see #data)
107
- def data=(v)
108
- DataTypeValidator.validate "#{self.class}.data", [Array], v
109
- @data = []
110
- v.each do |data_field|
111
- if data_field.is_a? String
112
- data_field = {:ref => data_field}
113
- end
114
- data_field.each do |key, value|
115
- if key == :num_fmt
116
- DataTypeValidator.validate "#{self.class}.data[]", [Integer], value
117
- else
118
- DataTypeValidator.validate "#{self.class}.data[]", [String], value
119
- end
120
- end
121
- @data << data_field
122
- end
123
- @data
124
- end
125
-
126
- # The pages
127
- # @return [String]
128
- attr_reader :pages
129
-
130
- # (see #pages)
131
- def pages=(v)
132
- DataTypeValidator.validate "#{self.class}.pages", [Array], v
133
- v.each do |ref|
134
- DataTypeValidator.validate "#{self.class}.pages[]", [String], ref
135
- end
136
- @pages = v
137
- end
138
-
139
- # The index of this chart in the workbooks charts collection
140
- # @return [Integer]
141
- def index
142
- @sheet.workbook.pivot_tables.index(self)
143
- end
144
-
145
- # The part name for this table
146
- # @return [String]
147
- def pn
148
- "#{PIVOT_TABLE_PN % (index+1)}"
149
- end
150
-
151
- # The relationship part name of this pivot table
152
- # @return [String]
153
- def rels_pn
154
- "#{PIVOT_TABLE_RELS_PN % (index+1)}"
155
- end
156
-
157
- # The cache_definition for this pivot table
158
- # @return [PivotTableCacheDefinition]
159
- def cache_definition
160
- @cache_definition ||= PivotTableCacheDefinition.new(self)
161
- end
162
-
163
- # The relationships for this pivot table.
164
- # @return [Relationships]
165
- def relationships
166
- r = Relationships.new
167
- r << Relationship.new(cache_definition, PIVOT_TABLE_CACHE_DEFINITION_R, "../#{cache_definition.pn}")
168
- r
169
- end
170
-
171
- # Serializes the object
172
- # @param [String] str
173
- # @return [String]
174
- def to_xml_string(str = '')
175
- str << '<?xml version="1.0" encoding="UTF-8"?>'
176
-
177
- str << ('<pivotTableDefinition xmlns="' << XML_NS << '" name="' << name << '" cacheId="' << cache_definition.cache_id.to_s << '"' << (data.size <= 1 ? ' 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">')
178
-
179
- str << ('<location firstDataCol="1" firstDataRow="1" firstHeaderRow="1" ref="' << ref << '"/>')
180
- str << ('<pivotFields count="' << header_cells_count.to_s << '">')
181
- header_cell_values.each do |cell_value|
182
- str << pivot_field_for(cell_value, !no_subtotals_on_headers.include?(cell_value))
183
- end
184
- str << '</pivotFields>'
185
- if rows.empty?
186
- str << '<rowFields count="1"><field x="-2"/></rowFields>'
187
- str << '<rowItems count="2"><i><x/></i> <i i="1"><x v="1"/></i></rowItems>'
188
- else
189
- str << ('<rowFields count="' << rows.size.to_s << '">')
190
- rows.each do |row_value|
191
- str << ('<field x="' << header_index_of(row_value).to_s << '"/>')
192
- end
193
- str << '</rowFields>'
194
- str << ('<rowItems count="' << rows.size.to_s << '">')
195
- rows.size.times do |i|
196
- str << '<i/>'
197
- end
198
- str << '</rowItems>'
199
- end
200
- if columns.empty? && data.size <= 1
201
- str << '<colItems count="1"><i/></colItems>'
202
- else
203
- str << ('<colFields count="' << columns.size.to_s << '">')
204
- columns.each do |column_value|
205
- str << ('<field x="' << header_index_of(column_value).to_s << '"/>')
206
- end
207
- str << '</colFields>'
208
- end
209
- unless pages.empty?
210
- str << ('<pageFields count="' << pages.size.to_s << '">')
211
- pages.each do |page_value|
212
- str << ('<pageField fld="' << header_index_of(page_value).to_s << '"/>')
213
- end
214
- str << '</pageFields>'
215
- end
216
- unless data.empty?
217
- str << "<dataFields count=\"#{data.size}\">"
218
- data.each do |datum_value|
219
- # The correct name prefix in ["Sum","Average", etc...]
220
- str << "<dataField name='#{(datum_value[:subtotal]||'')} of #{datum_value[:ref]}' fld='#{header_index_of(datum_value[:ref])}' baseField='0' baseItem='0'"
221
- str << " numFmtId='#{datum_value[:num_fmt]}'" if datum_value[:num_fmt]
222
- str << " subtotal='#{datum_value[:subtotal]}' " if datum_value[:subtotal]
223
- str << "/>"
224
- end
225
- str << '</dataFields>'
226
- end
227
- # custom pivot table style
228
- unless style_info.empty?
229
- str << '<pivotTableStyleInfo'
230
- style_info.each do |k,v|
231
- str << ' ' << k.to_s << '="' << v.to_s << '"'
232
- end
233
- str << ' />'
234
- end
235
- str << '</pivotTableDefinition>'
236
- end
237
-
238
- # References for header cells
239
- # @return [Array]
240
- def header_cell_refs
241
- Axlsx::range_to_a(header_range).first
242
- end
243
-
244
- # The header cells for the pivot table
245
- # @return [Array]
246
- def header_cells
247
- data_sheet[header_range]
248
- end
249
-
250
- # The values in the header cells collection
251
- # @return [Array]
252
- def header_cell_values
253
- header_cells.map(&:value)
254
- end
255
-
256
- # The number of cells in the header_cells collection
257
- # @return [Integer]
258
- def header_cells_count
259
- header_cells.count
260
- end
261
-
262
- # The index of a given value in the header cells
263
- # @return [Integer]
264
- def header_index_of(value)
265
- header_cell_values.index(value)
266
- end
267
-
268
- private
269
-
270
- def pivot_field_for(cell_ref, subtotal=true)
271
- if rows.include? cell_ref
272
- if subtotal
273
- '<pivotField axis="axisRow" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1"><items count="1"><item t="default"/></items></pivotField>'
274
- else
275
- '<pivotField axis="axisRow" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1" defaultSubtotal="0"></pivotField>'
276
- end
277
- elsif columns.include? cell_ref
278
- '<pivotField axis="axisCol" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1"><items count="1"><item t="default"/></items></pivotField>'
279
- elsif pages.include? cell_ref
280
- '<pivotField axis="axisPage" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1"><items count="1"><item t="default"/></items></pivotField>'
281
- elsif data_refs.include? cell_ref
282
- '<pivotField dataField="1" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1"></pivotField>'
283
- else
284
- '<pivotField compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1"></pivotField>'
285
- end
286
- end
287
-
288
- def data_refs
289
- data.map { |hash| hash[:ref] }
290
- end
291
-
292
- def header_range
293
- range.gsub(/^(\w+?)(\d+)\:(\w+?)\d+$/, '\1\2:\3\2')
294
- end
295
- end
296
- end
1
+ # encoding: UTF-8
2
+ module Axlsx
3
+ # Table
4
+ # @note Worksheet#add_pivot_table is the recommended way to create tables for your worksheets.
5
+ # @see README for examples
6
+ class PivotTable
7
+
8
+ include Axlsx::OptionsParser
9
+
10
+ # Creates a new PivotTable object
11
+ # @param [String] ref The reference to where the pivot table lives like 'G4:L17'.
12
+ # @param [String] range The reference to the pivot table data like 'A1:D31'.
13
+ # @param [Worksheet] sheet The sheet containing the table data.
14
+ # @option options [Cell, String] name
15
+ # @option options [TableStyle] style
16
+ def initialize(ref, range, sheet, options={})
17
+ @ref = ref
18
+ self.range = range
19
+ @sheet = sheet
20
+ @sheet.workbook.pivot_tables << self
21
+ @name = "PivotTable#{index+1}"
22
+ @data_sheet = nil
23
+ @rows = []
24
+ @columns = []
25
+ @data = []
26
+ @pages = []
27
+ @subtotal = nil
28
+ @no_subtotals_on_headers = []
29
+ @sort_on_headers = {}
30
+ @style_info = {}
31
+ parse_options options
32
+ yield self if block_given?
33
+ end
34
+
35
+ # Defines the headers in which subtotals are not to be included.
36
+ # @return [Array]
37
+ attr_accessor :no_subtotals_on_headers
38
+
39
+ # Defines the headers in which sort is applied.
40
+ # Can be an array of headers to sort ascending by default, or a hash for specific control
41
+ # (with headers as keys, `:ascending` or `:descending` as values).
42
+ #
43
+ # Examples: `["year", "month"]` or `{"year" => :descending, "month" => :descending}`
44
+ # @return [Hash]
45
+ attr_reader :sort_on_headers
46
+
47
+ # (see #sort_on_headers)
48
+ def sort_on_headers=(headers)
49
+ headers ||= {}
50
+ headers = Hash[*headers.map { |h| [h, :ascending] }.flatten] if headers.is_a?(Array)
51
+ @sort_on_headers = headers
52
+ end
53
+
54
+ # Style info for the pivot table
55
+ # @return [Hash]
56
+ attr_accessor :style_info
57
+
58
+ # The reference to the table data
59
+ # @return [String]
60
+ attr_reader :ref
61
+
62
+ # The name of the table.
63
+ # @return [String]
64
+ attr_reader :name
65
+
66
+ # The name of the sheet.
67
+ # @return [String]
68
+ attr_reader :sheet
69
+
70
+ # The sheet used as data source for the pivot table
71
+ # @return [Worksheet]
72
+ attr_writer :data_sheet
73
+
74
+ # @see #data_sheet
75
+ def data_sheet
76
+ @data_sheet || @sheet
77
+ end
78
+
79
+ # The range where the data for this pivot table lives.
80
+ # @return [String]
81
+ attr_reader :range
82
+
83
+ # (see #range)
84
+ def range=(v)
85
+ DataTypeValidator.validate "#{self.class}.range", [String], v
86
+ if v.is_a?(String)
87
+ @range = v
88
+ end
89
+ end
90
+
91
+ # The rows
92
+ # @return [Array]
93
+ attr_reader :rows
94
+
95
+
96
+ # (see #rows)
97
+ def rows=(v)
98
+ DataTypeValidator.validate "#{self.class}.rows", [Array], v
99
+ v.each do |ref|
100
+ DataTypeValidator.validate "#{self.class}.rows[]", [String], ref
101
+ end
102
+ @rows = v
103
+ end
104
+
105
+ # The columns
106
+ # @return [Array]
107
+ attr_reader :columns
108
+
109
+ # (see #columns)
110
+ def columns=(v)
111
+ DataTypeValidator.validate "#{self.class}.columns", [Array], v
112
+ v.each do |ref|
113
+ DataTypeValidator.validate "#{self.class}.columns[]", [String], ref
114
+ end
115
+ @columns = v
116
+ end
117
+
118
+ # The data
119
+ # @return [Array]
120
+ attr_reader :data
121
+
122
+ # (see #data)
123
+ def data=(v)
124
+ DataTypeValidator.validate "#{self.class}.data", [Array], v
125
+ @data = []
126
+ v.each do |data_field|
127
+ if data_field.is_a? String
128
+ data_field = {:ref => data_field}
129
+ end
130
+ data_field.each do |key, value|
131
+ if key == :num_fmt
132
+ DataTypeValidator.validate "#{self.class}.data[]", [Integer], value
133
+ else
134
+ DataTypeValidator.validate "#{self.class}.data[]", [String], value
135
+ end
136
+ end
137
+ @data << data_field
138
+ end
139
+ @data
140
+ end
141
+
142
+ # The pages
143
+ # @return [String]
144
+ attr_reader :pages
145
+
146
+ # (see #pages)
147
+ def pages=(v)
148
+ DataTypeValidator.validate "#{self.class}.pages", [Array], v
149
+ v.each do |ref|
150
+ DataTypeValidator.validate "#{self.class}.pages[]", [String], ref
151
+ end
152
+ @pages = v
153
+ end
154
+
155
+ # The index of this chart in the workbooks charts collection
156
+ # @return [Integer]
157
+ def index
158
+ @sheet.workbook.pivot_tables.index(self)
159
+ end
160
+
161
+ # The part name for this table
162
+ # @return [String]
163
+ def pn
164
+ "#{PIVOT_TABLE_PN % (index+1)}"
165
+ end
166
+
167
+ # The relationship part name of this pivot table
168
+ # @return [String]
169
+ def rels_pn
170
+ "#{PIVOT_TABLE_RELS_PN % (index+1)}"
171
+ end
172
+
173
+ # The cache_definition for this pivot table
174
+ # @return [PivotTableCacheDefinition]
175
+ def cache_definition
176
+ @cache_definition ||= PivotTableCacheDefinition.new(self)
177
+ end
178
+
179
+ # The relationships for this pivot table.
180
+ # @return [Relationships]
181
+ def relationships
182
+ r = Relationships.new
183
+ r << Relationship.new(cache_definition, PIVOT_TABLE_CACHE_DEFINITION_R, "../#{cache_definition.pn}")
184
+ r
185
+ end
186
+
187
+ # Serializes the object
188
+ # @param [String] str
189
+ # @return [String]
190
+ def to_xml_string(str = '')
191
+ str << '<?xml version="1.0" encoding="UTF-8"?>'
192
+
193
+ str << ('<pivotTableDefinition xmlns="' << XML_NS << '" name="' << name << '" cacheId="' << cache_definition.cache_id.to_s << '"' << (data.size <= 1 ? ' 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">')
194
+
195
+ str << ('<location firstDataCol="1" firstDataRow="1" firstHeaderRow="1" ref="' << ref << '"/>')
196
+ str << ('<pivotFields count="' << header_cells_count.to_s << '">')
197
+
198
+ header_cell_values.each do |cell_value|
199
+ subtotal = !no_subtotals_on_headers.include?(cell_value)
200
+ sorttype = sort_on_headers[cell_value]
201
+ str << pivot_field_for(cell_value, subtotal, sorttype)
202
+ end
203
+
204
+ str << '</pivotFields>'
205
+ if rows.empty?
206
+ str << '<rowFields count="1"><field x="-2"/></rowFields>'
207
+ str << '<rowItems count="2"><i><x/></i> <i i="1"><x v="1"/></i></rowItems>'
208
+ else
209
+ str << ('<rowFields count="' << rows.size.to_s << '">')
210
+ rows.each do |row_value|
211
+ str << ('<field x="' << header_index_of(row_value).to_s << '"/>')
212
+ end
213
+ str << '</rowFields>'
214
+ str << ('<rowItems count="' << rows.size.to_s << '">')
215
+ rows.size.times do |i|
216
+ str << '<i/>'
217
+ end
218
+ str << '</rowItems>'
219
+ end
220
+ if columns.empty?
221
+ if data.size > 1
222
+ str << '<colFields count="1"><field x="-2"/></colFields>'
223
+ str << "<colItems count=\"#{data.size}\">"
224
+ str << '<i><x/></i>'
225
+ data[1..-1].each_with_index do |datum_value,i|
226
+ str << "<i i=\"#{i + 1}\"><x v=\"#{i + 1}\"/></i>"
227
+ end
228
+ str << '</colItems>'
229
+ else
230
+ str << '<colItems count="1"><i/></colItems>'
231
+ end
232
+ else
233
+ str << ('<colFields count="' << columns.size.to_s << '">')
234
+ columns.each do |column_value|
235
+ str << ('<field x="' << header_index_of(column_value).to_s << '"/>')
236
+ end
237
+ str << '</colFields>'
238
+ end
239
+ unless pages.empty?
240
+ str << ('<pageFields count="' << pages.size.to_s << '">')
241
+ pages.each do |page_value|
242
+ str << ('<pageField fld="' << header_index_of(page_value).to_s << '"/>')
243
+ end
244
+ str << '</pageFields>'
245
+ end
246
+ unless data.empty?
247
+ str << "<dataFields count=\"#{data.size}\">"
248
+ data.each do |datum_value|
249
+ # The correct name prefix in ["Sum","Average", etc...]
250
+ str << "<dataField name='#{(datum_value[:subtotal]||'')} of #{datum_value[:ref]}' fld='#{header_index_of(datum_value[:ref])}' baseField='0' baseItem='0'"
251
+ str << " numFmtId='#{datum_value[:num_fmt]}'" if datum_value[:num_fmt]
252
+ str << " subtotal='#{datum_value[:subtotal]}' " if datum_value[:subtotal]
253
+ str << "/>"
254
+ end
255
+ str << '</dataFields>'
256
+ end
257
+ # custom pivot table style
258
+ unless style_info.empty?
259
+ str << '<pivotTableStyleInfo'
260
+ style_info.each do |k,v|
261
+ str << ' ' << k.to_s << '="' << v.to_s << '"'
262
+ end
263
+ str << ' />'
264
+ end
265
+ str << '</pivotTableDefinition>'
266
+ end
267
+
268
+ # References for header cells
269
+ # @return [Array]
270
+ def header_cell_refs
271
+ Axlsx::range_to_a(header_range).first
272
+ end
273
+
274
+ # The header cells for the pivot table
275
+ # @return [Array]
276
+ def header_cells
277
+ data_sheet[header_range]
278
+ end
279
+
280
+ # The values in the header cells collection
281
+ # @return [Array]
282
+ def header_cell_values
283
+ header_cells.map(&:value)
284
+ end
285
+
286
+ # The number of cells in the header_cells collection
287
+ # @return [Integer]
288
+ def header_cells_count
289
+ header_cells.count
290
+ end
291
+
292
+ # The index of a given value in the header cells
293
+ # @return [Integer]
294
+ def header_index_of(value)
295
+ header_cell_values.index(value)
296
+ end
297
+
298
+ private
299
+
300
+ def pivot_field_for(cell_ref, subtotal, sorttype)
301
+ attributes = %w[compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1"]
302
+ items_tag = '<items count="1"><item t="default"/></items>'
303
+ include_items_tag = false
304
+
305
+ if rows.include? cell_ref
306
+ attributes << 'axis="axisRow"'
307
+ attributes << "sortType=\"#{sorttype == :descending ? 'descending' : 'ascending'}\"" if sorttype
308
+ if subtotal
309
+ include_items_tag = true
310
+ else
311
+ attributes << 'defaultSubtotal="0"'
312
+ end
313
+ elsif columns.include? cell_ref
314
+ attributes << 'axis="axisCol"'
315
+ attributes << "sortType=\"#{sorttype == :descending ? 'descending' : 'ascending'}\"" if sorttype
316
+ include_items_tag = true
317
+ elsif pages.include? cell_ref
318
+ attributes << 'axis="axisPage"'
319
+ include_items_tag = true
320
+ elsif data_refs.include? cell_ref
321
+ attributes << 'dataField="1"'
322
+ end
323
+
324
+ "<pivotField #{attributes.join(' ')}>#{include_items_tag ? items_tag : nil}</pivotField>"
325
+ end
326
+
327
+ def data_refs
328
+ data.map { |hash| hash[:ref] }
329
+ end
330
+
331
+ def header_range
332
+ range.gsub(/^(\w+?)(\d+)\:(\w+?)\d+$/, '\1\2:\3\2')
333
+ end
334
+ end
335
+ end