axlsx 1.2.0 → 2.0.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 (208) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +3 -2
  3. data/.yardopts_guide +19 -0
  4. data/CHANGELOG.md +64 -1
  5. data/README.md +105 -87
  6. data/Rakefile +0 -5
  7. data/examples/2010_comments.rb +17 -0
  8. data/examples/anchor_swapping.rb +28 -0
  9. data/examples/auto_filter.rb +16 -0
  10. data/examples/basic_charts.rb +4 -0
  11. data/examples/colored_links.rb +59 -0
  12. data/examples/conditional_formatting/example_conditional_formatting.rb +4 -2
  13. data/examples/example.rb +569 -258
  14. data/examples/ios_preview.rb +14 -0
  15. data/examples/page_setup.rb +11 -0
  16. data/examples/pivot_table.rb +39 -0
  17. data/examples/skydrive/real_example.rb +8 -8
  18. data/examples/styles.rb +66 -0
  19. data/examples/underline.rb +13 -0
  20. data/examples/wrap_text.rb +21 -0
  21. data/lib/axlsx/content_type/abstract_content_type.rb +32 -0
  22. data/lib/axlsx/content_type/content_type.rb +1 -1
  23. data/lib/axlsx/content_type/default.rb +6 -37
  24. data/lib/axlsx/content_type/override.rb +6 -38
  25. data/lib/axlsx/doc_props/app.rb +10 -7
  26. data/lib/axlsx/doc_props/core.rb +6 -1
  27. data/lib/axlsx/drawing/axes.rb +61 -0
  28. data/lib/axlsx/drawing/axis.rb +20 -17
  29. data/lib/axlsx/drawing/bar_3D_chart.rb +31 -22
  30. data/lib/axlsx/drawing/cat_axis.rb +2 -10
  31. data/lib/axlsx/drawing/chart.rb +33 -6
  32. data/lib/axlsx/drawing/d_lbls.rb +21 -31
  33. data/lib/axlsx/drawing/drawing.rb +11 -17
  34. data/lib/axlsx/drawing/graphic_frame.rb +3 -3
  35. data/lib/axlsx/drawing/hyperlink.rb +42 -36
  36. data/lib/axlsx/drawing/line_3D_chart.rb +28 -70
  37. data/lib/axlsx/drawing/line_chart.rb +99 -0
  38. data/lib/axlsx/drawing/line_series.rb +20 -2
  39. data/lib/axlsx/drawing/marker.rb +38 -18
  40. data/lib/axlsx/drawing/num_data.rb +6 -6
  41. data/lib/axlsx/drawing/num_data_source.rb +17 -16
  42. data/lib/axlsx/drawing/one_cell_anchor.rb +28 -21
  43. data/lib/axlsx/drawing/pic.rb +43 -45
  44. data/lib/axlsx/drawing/picture_locking.rb +12 -44
  45. data/lib/axlsx/drawing/pie_3D_chart.rb +2 -1
  46. data/lib/axlsx/drawing/scaling.rb +13 -13
  47. data/lib/axlsx/drawing/scatter_chart.rb +32 -21
  48. data/lib/axlsx/drawing/ser_axis.rb +15 -16
  49. data/lib/axlsx/drawing/series.rb +3 -6
  50. data/lib/axlsx/drawing/str_data.rb +3 -3
  51. data/lib/axlsx/drawing/str_val.rb +7 -8
  52. data/lib/axlsx/drawing/two_cell_anchor.rb +7 -27
  53. data/lib/axlsx/drawing/val_axis.rb +14 -13
  54. data/lib/axlsx/drawing/view_3D.rb +52 -38
  55. data/lib/axlsx/drawing/vml_shape.rb +20 -79
  56. data/lib/axlsx/package.rb +58 -28
  57. data/lib/axlsx/rels/relationship.rb +75 -9
  58. data/lib/axlsx/rels/relationships.rb +8 -1
  59. data/lib/axlsx/stylesheet/border.rb +29 -20
  60. data/lib/axlsx/stylesheet/border_pr.rb +5 -4
  61. data/lib/axlsx/stylesheet/cell_alignment.rb +55 -29
  62. data/lib/axlsx/stylesheet/cell_protection.rb +7 -4
  63. data/lib/axlsx/stylesheet/cell_style.rb +19 -14
  64. data/lib/axlsx/stylesheet/color.rb +20 -17
  65. data/lib/axlsx/stylesheet/dxf.rb +4 -4
  66. data/lib/axlsx/stylesheet/font.rb +22 -22
  67. data/lib/axlsx/stylesheet/gradient_fill.rb +45 -21
  68. data/lib/axlsx/stylesheet/num_fmt.rb +23 -14
  69. data/lib/axlsx/stylesheet/pattern_fill.rb +12 -21
  70. data/lib/axlsx/stylesheet/styles.rb +37 -22
  71. data/lib/axlsx/stylesheet/table_style.rb +17 -16
  72. data/lib/axlsx/stylesheet/table_style_element.rb +15 -11
  73. data/lib/axlsx/stylesheet/table_styles.rb +14 -11
  74. data/lib/axlsx/stylesheet/xf.rb +28 -26
  75. data/lib/axlsx/util/accessors.rb +64 -0
  76. data/lib/axlsx/util/constants.rb +127 -6
  77. data/lib/axlsx/util/options_parser.rb +15 -0
  78. data/lib/axlsx/util/serialized_attributes.rb +79 -0
  79. data/lib/axlsx/util/simple_typed_list.rb +50 -15
  80. data/lib/axlsx/util/validators.rb +51 -16
  81. data/lib/axlsx/version.rb +2 -2
  82. data/lib/axlsx/workbook/defined_name.rb +14 -59
  83. data/lib/axlsx/workbook/shared_strings_table.rb +13 -4
  84. data/lib/axlsx/workbook/workbook.rb +85 -6
  85. data/lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb +77 -0
  86. data/lib/axlsx/workbook/worksheet/auto_filter/filter_column.rb +94 -0
  87. data/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +246 -0
  88. data/lib/axlsx/workbook/worksheet/break.rb +37 -0
  89. data/lib/axlsx/workbook/worksheet/cell.rb +109 -107
  90. data/lib/axlsx/workbook/worksheet/cell_serializer.rb +144 -0
  91. data/lib/axlsx/workbook/worksheet/cfvo.rb +15 -15
  92. data/lib/axlsx/workbook/worksheet/cfvos.rb +15 -0
  93. data/lib/axlsx/workbook/worksheet/col.rb +43 -29
  94. data/lib/axlsx/workbook/worksheet/col_breaks.rb +35 -0
  95. data/lib/axlsx/workbook/worksheet/color_scale.rb +62 -28
  96. data/lib/axlsx/workbook/worksheet/comment.rb +28 -37
  97. data/lib/axlsx/workbook/worksheet/comments.rb +3 -3
  98. data/lib/axlsx/workbook/worksheet/conditional_formatting.rb +11 -11
  99. data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +31 -27
  100. data/lib/axlsx/workbook/worksheet/data_bar.rb +75 -41
  101. data/lib/axlsx/workbook/worksheet/data_validation.rb +61 -62
  102. data/lib/axlsx/workbook/worksheet/date_time_converter.rb +6 -5
  103. data/lib/axlsx/workbook/worksheet/dimension.rb +0 -1
  104. data/lib/axlsx/workbook/worksheet/header_footer.rb +54 -0
  105. data/lib/axlsx/workbook/worksheet/icon_set.rb +20 -20
  106. data/lib/axlsx/workbook/worksheet/page_margins.rb +21 -19
  107. data/lib/axlsx/workbook/worksheet/page_set_up_pr.rb +44 -0
  108. data/lib/axlsx/workbook/worksheet/page_setup.rb +152 -23
  109. data/lib/axlsx/workbook/worksheet/pane.rb +48 -51
  110. data/lib/axlsx/workbook/worksheet/pivot_table.rb +273 -0
  111. data/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +66 -0
  112. data/lib/axlsx/workbook/worksheet/pivot_tables.rb +24 -0
  113. data/lib/axlsx/workbook/worksheet/print_options.rb +8 -30
  114. data/lib/axlsx/workbook/worksheet/protected_range.rb +16 -13
  115. data/lib/axlsx/workbook/worksheet/row.rb +59 -83
  116. data/lib/axlsx/workbook/worksheet/row_breaks.rb +33 -0
  117. data/lib/axlsx/workbook/worksheet/selection.rb +30 -38
  118. data/lib/axlsx/workbook/worksheet/sheet_calc_pr.rb +29 -0
  119. data/lib/axlsx/workbook/worksheet/sheet_format_pr.rb +60 -0
  120. data/lib/axlsx/workbook/worksheet/sheet_pr.rb +49 -4
  121. data/lib/axlsx/workbook/worksheet/sheet_protection.rb +51 -155
  122. data/lib/axlsx/workbook/worksheet/sheet_view.rb +68 -234
  123. data/lib/axlsx/workbook/worksheet/table.rb +25 -19
  124. data/lib/axlsx/workbook/worksheet/table_style_info.rb +51 -0
  125. data/lib/axlsx/workbook/worksheet/tables.rb +1 -1
  126. data/lib/axlsx/workbook/worksheet/worksheet.rb +174 -35
  127. data/lib/axlsx/workbook/worksheet/worksheet_comments.rb +6 -5
  128. data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +4 -10
  129. data/lib/axlsx/workbook/worksheet/worksheet_hyperlink.rb +74 -0
  130. data/lib/axlsx/workbook/worksheet/worksheet_hyperlinks.rb +38 -0
  131. data/lib/axlsx.rb +55 -5
  132. data/lib/schema/sml.xsd +4 -0
  133. data/test/axlsx.qcachegrind +2226 -0
  134. data/test/benchmark.rb +2 -3
  135. data/test/content_type/tc_default.rb +0 -11
  136. data/test/content_type/tc_override.rb +0 -13
  137. data/test/doc_props/tc_core.rb +7 -0
  138. data/test/drawing/tc_axes.rb +8 -0
  139. data/test/drawing/tc_axis.rb +15 -17
  140. data/test/drawing/tc_bar_3D_chart.rb +6 -0
  141. data/test/drawing/tc_cat_axis.rb +9 -9
  142. data/test/drawing/tc_chart.rb +20 -0
  143. data/test/drawing/tc_d_lbls.rb +14 -4
  144. data/test/drawing/tc_drawing.rb +0 -5
  145. data/test/drawing/tc_graphic_frame.rb +5 -3
  146. data/test/drawing/tc_hyperlink.rb +0 -4
  147. data/test/drawing/tc_line_chart.rb +39 -0
  148. data/test/drawing/tc_line_series.rb +8 -2
  149. data/test/drawing/tc_pic.rb +14 -3
  150. data/test/drawing/tc_ser_axis.rb +13 -12
  151. data/test/drawing/tc_two_cell_anchor.rb +3 -3
  152. data/test/drawing/tc_val_axis.rb +6 -6
  153. data/test/drawing/tc_vml_shape.rb +9 -3
  154. data/test/profile.rb +11 -21
  155. data/test/rels/tc_relationship.rb +32 -9
  156. data/test/rels/tc_relationships.rb +12 -1
  157. data/test/stylesheet/tc_color.rb +6 -0
  158. data/test/stylesheet/tc_styles.rb +15 -2
  159. data/test/tc_axlsx.rb +35 -2
  160. data/test/tc_helper.rb +7 -1
  161. data/test/tc_package.rb +44 -5
  162. data/test/util/tc_serialized_attributes.rb +19 -0
  163. data/test/util/tc_validators.rb +26 -1
  164. data/test/workbook/tc_defined_name.rb +2 -2
  165. data/test/workbook/tc_shared_strings_table.rb +6 -0
  166. data/test/workbook/tc_workbook.rb +38 -1
  167. data/test/workbook/worksheet/auto_filter/tc_auto_filter.rb +38 -0
  168. data/test/workbook/worksheet/auto_filter/tc_filter_column.rb +76 -0
  169. data/test/workbook/worksheet/auto_filter/tc_filters.rb +50 -0
  170. data/test/workbook/worksheet/tc_break.rb +49 -0
  171. data/test/workbook/worksheet/tc_cell.rb +40 -6
  172. data/test/workbook/worksheet/tc_col.rb +11 -1
  173. data/test/workbook/worksheet/tc_color_scale.rb +31 -2
  174. data/test/workbook/worksheet/tc_comment.rb +21 -6
  175. data/test/workbook/worksheet/tc_comments.rb +2 -2
  176. data/test/workbook/worksheet/tc_conditional_formatting.rb +7 -0
  177. data/test/workbook/worksheet/tc_data_bar.rb +7 -0
  178. data/test/workbook/worksheet/tc_date_time_converter.rb +3 -11
  179. data/test/workbook/worksheet/tc_header_footer.rb +151 -0
  180. data/test/workbook/worksheet/tc_page_set_up_pr.rb +15 -0
  181. data/test/workbook/worksheet/tc_page_setup.rb +6 -1
  182. data/test/workbook/worksheet/tc_pane.rb +5 -45
  183. data/test/workbook/worksheet/tc_pivot_table.rb +120 -0
  184. data/test/workbook/worksheet/tc_pivot_table_cache_definition.rb +54 -0
  185. data/test/workbook/worksheet/tc_row.rb +4 -4
  186. data/test/workbook/worksheet/tc_selection.rb +9 -48
  187. data/test/workbook/worksheet/tc_sheet_calc_pr.rb +18 -0
  188. data/test/workbook/worksheet/tc_sheet_format_pr.rb +88 -0
  189. data/test/workbook/worksheet/tc_sheet_pr.rb +27 -0
  190. data/test/workbook/worksheet/tc_sheet_view.rb +39 -39
  191. data/test/workbook/worksheet/{table/tc_table.rb → tc_table.rb} +8 -3
  192. data/test/workbook/worksheet/tc_table_style_info.rb +53 -0
  193. data/test/workbook/worksheet/tc_worksheet.rb +131 -16
  194. data/test/workbook/worksheet/tc_worksheet_hyperlink.rb +55 -0
  195. metadata +97 -64
  196. data/examples/example.xlsx +0 -0
  197. data/examples/example_streamed.xlsx +0 -0
  198. data/examples/extractive.pdf +0 -0
  199. data/examples/image1.gif +0 -0
  200. data/examples/image1.jpg +0 -0
  201. data/examples/image1.png +0 -0
  202. data/examples/no-use_autowidth.xlsx +0 -0
  203. data/examples/sample.png +0 -0
  204. data/examples/scraping_html.rb +0 -91
  205. data/examples/shared_strings_example.xlsx +0 -0
  206. data/examples/sheet_view.rb +0 -34
  207. data/examples/two_cell_anchor_image.rb +0 -11
  208. data/lib/axlsx/workbook/worksheet/auto_filter.rb +0 -34
@@ -0,0 +1,273 @@
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
+ parse_options options
29
+ yield self if block_given?
30
+ end
31
+
32
+ # The reference to the table data
33
+ # @return [String]
34
+ attr_reader :ref
35
+
36
+ # The name of the table.
37
+ # @return [String]
38
+ attr_reader :name
39
+
40
+ # The name of the sheet.
41
+ # @return [String]
42
+ attr_reader :sheet
43
+
44
+ # The sheet used as data source for the pivot table
45
+ # @return [Worksheet]
46
+ attr_writer :data_sheet
47
+
48
+ # @see #data_sheet
49
+ def data_sheet
50
+ @data_sheet || @sheet
51
+ end
52
+
53
+ # The range where the data for this pivot table lives.
54
+ # @return [String]
55
+ attr_reader :range
56
+
57
+ # (see #range)
58
+ def range=(v)
59
+ DataTypeValidator.validate "#{self.class}.range", [String], v
60
+ if v.is_a?(String)
61
+ @range = v
62
+ end
63
+ end
64
+
65
+ # The rows
66
+ # @return [Array]
67
+ attr_reader :rows
68
+
69
+
70
+ # (see #rows)
71
+ def rows=(v)
72
+ DataTypeValidator.validate "#{self.class}.rows", [Array], v
73
+ v.each do |ref|
74
+ DataTypeValidator.validate "#{self.class}.rows[]", [String], ref
75
+ end
76
+ @rows = v
77
+ end
78
+
79
+ # The columns
80
+ # @return [Array]
81
+ attr_reader :columns
82
+
83
+ # (see #columns)
84
+ def columns=(v)
85
+ DataTypeValidator.validate "#{self.class}.columns", [Array], v
86
+ v.each do |ref|
87
+ DataTypeValidator.validate "#{self.class}.columns[]", [String], ref
88
+ end
89
+ @columns = v
90
+ end
91
+
92
+ # The data
93
+ # @return [Array]
94
+ attr_reader :data
95
+
96
+ # (see #data)
97
+ def data=(v)
98
+ DataTypeValidator.validate "#{self.class}.data", [Array], v
99
+ @data = []
100
+ v.each do |data_field|
101
+ if data_field.is_a? String
102
+ data_field = {:ref => data_field}
103
+ end
104
+ data_field.values.each do |value|
105
+ DataTypeValidator.validate "#{self.class}.data[]", [String], value
106
+ end
107
+ @data << data_field
108
+ end
109
+ @data
110
+ end
111
+
112
+ # The pages
113
+ # @return [String]
114
+ attr_reader :pages
115
+
116
+ # (see #pages)
117
+ def pages=(v)
118
+ DataTypeValidator.validate "#{self.class}.pages", [Array], v
119
+ v.each do |ref|
120
+ DataTypeValidator.validate "#{self.class}.pages[]", [String], ref
121
+ end
122
+ @pages = v
123
+ end
124
+
125
+ # The index of this chart in the workbooks charts collection
126
+ # @return [Integer]
127
+ def index
128
+ @sheet.workbook.pivot_tables.index(self)
129
+ end
130
+
131
+ # The part name for this table
132
+ # @return [String]
133
+ def pn
134
+ "#{PIVOT_TABLE_PN % (index+1)}"
135
+ end
136
+
137
+ # The relationship part name of this pivot table
138
+ # @return [String]
139
+ def rels_pn
140
+ "#{PIVOT_TABLE_RELS_PN % (index+1)}"
141
+ end
142
+
143
+ # The cache_definition for this pivot table
144
+ # @return [PivotTableCacheDefinition]
145
+ def cache_definition
146
+ @cache_definition ||= PivotTableCacheDefinition.new(self)
147
+ end
148
+
149
+ # The relationships for this pivot table.
150
+ # @return [Relationships]
151
+ def relationships
152
+ r = Relationships.new
153
+ r << Relationship.new(cache_definition, PIVOT_TABLE_CACHE_DEFINITION_R, "../#{cache_definition.pn}")
154
+ r
155
+ end
156
+
157
+ # Serializes the object
158
+ # @param [String] str
159
+ # @return [String]
160
+ def to_xml_string(str = '')
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 << '">'
165
+ header_cell_values.each do |cell_value|
166
+ str << pivot_field_for(cell_value)
167
+ end
168
+ str << '</pivotFields>'
169
+ if rows.empty?
170
+ str << '<rowFields count="1"><field x="-2"/></rowFields>'
171
+ str << '<rowItems count="2"><i><x/></i> <i i="1"><x v="1"/></i></rowItems>'
172
+ else
173
+ str << '<rowFields count="' << rows.size.to_s << '">'
174
+ rows.each do |row_value|
175
+ str << '<field x="' << header_index_of(row_value).to_s << '"/>'
176
+ end
177
+ str << '</rowFields>'
178
+ str << '<rowItems count="' << rows.size.to_s << '">'
179
+ rows.size.times do |i|
180
+ str << '<i/>'
181
+ end
182
+ str << '</rowItems>'
183
+ end
184
+ if columns.empty?
185
+ str << '<colItems count="1"><i/></colItems>'
186
+ else
187
+ str << '<colFields count="' << columns.size.to_s << '">'
188
+ columns.each do |column_value|
189
+ str << '<field x="' << header_index_of(column_value).to_s << '"/>'
190
+ end
191
+ str << '</colFields>'
192
+ end
193
+ unless pages.empty?
194
+ str << '<pageFields count="' << pages.size.to_s << '">'
195
+ pages.each do |page_value|
196
+ str << '<pageField fld="' << header_index_of(page_value).to_s << '"/>'
197
+ end
198
+ str << '</pageFields>'
199
+ end
200
+ unless data.empty?
201
+ str << "<dataFields count=\"#{data.size}\">"
202
+ 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'"
204
+ str << " subtotal='#{datum_value[:subtotal]}' " if datum_value[:subtotal]
205
+ str << "/>"
206
+ end
207
+ str << '</dataFields>'
208
+ end
209
+ str << '</pivotTableDefinition>'
210
+ end
211
+
212
+ # References for header cells
213
+ # @return [Array]
214
+ def header_cell_refs
215
+ Axlsx::range_to_a(header_range).first
216
+ end
217
+
218
+ # The header cells for the pivot table
219
+ # @return [Array]
220
+ def header_cells
221
+ data_sheet[header_range]
222
+ end
223
+
224
+ # The values in the header cells collection
225
+ # @return [Array]
226
+ def header_cell_values
227
+ header_cells.map(&:value)
228
+ end
229
+
230
+ # The number of cells in the header_cells collection
231
+ # @return [Integer]
232
+ def header_cells_count
233
+ header_cells.count
234
+ end
235
+
236
+ # The index of a given value in the header cells
237
+ # @return [Integer]
238
+ def header_index_of(value)
239
+ header_cell_values.index(value)
240
+ end
241
+
242
+ private
243
+
244
+ def pivot_field_for(cell_ref)
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>'
249
+ 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>'
253
+ 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>'
257
+ elsif data_refs.include? cell_ref
258
+ '<pivotField dataField="1" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1">' <<
259
+ '</pivotField>'
260
+ else
261
+ '<pivotField compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1">' <<
262
+ '</pivotField>'
263
+ end
264
+ end
265
+ def data_refs
266
+ data.map { |hash| hash[:ref] }
267
+ end
268
+ def header_range
269
+ range.gsub(/^(\w+?)(\d+)\:(\w+?)\d+$/, '\1\2:\3\2')
270
+ end
271
+
272
+ end
273
+ end
@@ -0,0 +1,66 @@
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 PivotTableCacheDefinition
7
+
8
+ include Axlsx::OptionsParser
9
+
10
+ # Creates a new PivotTable object
11
+ # @param [String] pivot_table The pivot table this cache definition is in
12
+ def initialize(pivot_table)
13
+ @pivot_table = pivot_table
14
+ end
15
+
16
+ # # The reference to the pivot table data
17
+ # # @return [PivotTable]
18
+ attr_reader :pivot_table
19
+
20
+ # The index of this chart in the workbooks charts collection
21
+ # @return [Integer]
22
+ def index
23
+ pivot_table.sheet.workbook.pivot_tables.index(pivot_table)
24
+ end
25
+
26
+ # The part name for this table
27
+ # @return [String]
28
+ def pn
29
+ "#{PIVOT_TABLE_CACHE_DEFINITION_PN % (index+1)}"
30
+ end
31
+
32
+ # The identifier for this cache
33
+ # @return [Integer]
34
+ def cache_id
35
+ index + 1
36
+ end
37
+
38
+ # The relationship id for this pivot table cache definition.
39
+ # @see Relationship#Id
40
+ # @return [String]
41
+ def rId
42
+ pivot_table.relationships.for(self).Id
43
+ end
44
+
45
+ # Serializes the object
46
+ # @param [String] str
47
+ # @return [String]
48
+ def to_xml_string(str = '')
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">'
51
+ str << '<cacheSource type="worksheet">'
52
+ str << '<worksheetSource ref="' << pivot_table.range << '" sheet="' << pivot_table.data_sheet.name << '"/>'
53
+ str << '</cacheSource>'
54
+ str << '<cacheFields count="' << pivot_table.header_cells_count.to_s << '">'
55
+ pivot_table.header_cells.each do |cell|
56
+ str << '<cacheField name="' << cell.value << '" numFmtId="0">'
57
+ str << '<sharedItems count="0">'
58
+ str << '</sharedItems>'
59
+ str << '</cacheField>'
60
+ end
61
+ str << '</cacheFields>'
62
+ str << '</pivotCacheDefinition>'
63
+ end
64
+
65
+ end
66
+ end
@@ -0,0 +1,24 @@
1
+ module Axlsx
2
+
3
+ # A simple, self serializing class for storing pivot tables
4
+ class PivotTables < SimpleTypedList
5
+
6
+ # creates a new Tables object
7
+ def initialize(worksheet)
8
+ raise ArgumentError, "you must provide a worksheet" unless worksheet.is_a?(Worksheet)
9
+ super PivotTable
10
+ @worksheet = worksheet
11
+ end
12
+
13
+ # The worksheet that owns this collection of pivot tables
14
+ # @return [Worksheet]
15
+ attr_reader :worksheet
16
+
17
+ # returns the relationships required by this collection
18
+ def relationships
19
+ return [] if empty?
20
+ map{ |pivot_table| Relationship.new(pivot_table, PIVOT_TABLE_R, "../#{pivot_table.pn}") }
21
+ end
22
+ end
23
+
24
+ end
@@ -6,22 +6,9 @@ module Axlsx
6
6
  # @see Worksheet#initialize
7
7
  class PrintOptions
8
8
 
9
- # Whether grid lines should be printed.
10
- # @return [Boolean]
11
- attr_reader :grid_lines
12
-
13
- # Whether row and column headings should be printed.
14
- # @return [Boolean]
15
- attr_reader :headings
16
-
17
- # Whether the content should be centered horizontally on the page.
18
- # @return [Boolean]
19
- attr_reader :horizontal_centered
20
-
21
- # Whether the content should be centered vertically on the page.
22
- # @return [Boolean]
23
- attr_reader :vertical_centered
24
-
9
+ include Axlsx::OptionsParser
10
+ include Axlsx::SerializedAttributes
11
+ include Axlsx::Accessors
25
12
  # Creates a new PrintOptions object
26
13
  # @option options [Boolean] grid_lines Whether grid lines should be printed
27
14
  # @option options [Boolean] headings Whether row and column headings should be printed
@@ -32,31 +19,22 @@ module Axlsx
32
19
  set(options)
33
20
  end
34
21
 
22
+ serializable_attributes :grid_lines, :headings, :horizontal_centered, :vertical_centered
23
+ boolean_attr_accessor :grid_lines, :headings, :horizontal_centered, :vertical_centered
24
+
35
25
  # Set some or all options at once.
36
26
  # @param [Hash] options The options to set (possible keys are :grid_lines, :headings, :horizontal_centered, and :vertical_centered).
37
27
  def set(options)
38
- options.each do |k, v|
39
- send("#{k}=", v) if respond_to? "#{k}="
40
- end
28
+ parse_options options
41
29
  end
42
30
 
43
- # @see grid_lines
44
- def grid_lines=(v); Axlsx::validate_boolean(v); @grid_lines = v; end
45
- # @see headings
46
- def headings=(v); Axlsx::validate_boolean(v); @headings = v; end
47
- # @see horizontal_centered
48
- def horizontal_centered=(v); Axlsx::validate_boolean(v); @horizontal_centered = v; end
49
- # @see vertical_centered
50
- def vertical_centered=(v); Axlsx::validate_boolean(v); @vertical_centered = v; end
51
-
52
31
  # Serializes the page options element.
53
32
  # @note As all attributes default to "false" according to the xml schema definition, the generated xml includes only those attributes that are set to true.
54
33
  # @param [String] str
55
34
  # @return [String]
56
35
  def to_xml_string(str = '')
57
36
  str << '<printOptions '
58
- #
59
- str << instance_values.select{ |k,v| v == true }.map{ |k,v| k.gsub(/_(.)/){ $1.upcase } << %{="#{v}"} }.join(' ')
37
+ serialized_attributes str
60
38
  str << '/>'
61
39
  end
62
40
  end
@@ -4,6 +4,18 @@ module Axlsx
4
4
  # @see Worksheet#protect_range
5
5
  class ProtectedRange
6
6
 
7
+ include Axlsx::OptionsParser
8
+ include Axlsx::SerializedAttributes
9
+
10
+ # Initializes a new protected range object
11
+ # @option [String] sqref The cell range reference to protect. This can be an absolute or a relateve range however, it only applies to the current sheet.
12
+ # @option [String] name An optional name for the protected name.
13
+ def initialize(options={})
14
+ parse_options options
15
+ yield self if block_given?
16
+ end
17
+
18
+ serializable_attributes :sqref, :name
7
19
  # The reference for the protected range
8
20
  # @return [String]
9
21
  attr_reader :sqref
@@ -12,16 +24,6 @@ module Axlsx
12
24
  # @return [String]
13
25
  attr_reader :name
14
26
 
15
- # Initializes a new protected range object
16
- # @option [String] sqref The cell range reference to protect. This can be an absolute or a relateve range however, it only applies to the current sheet.
17
- # @option [String] name An optional name for the protected name.
18
- def initialize(options={})
19
- options.each do |o|
20
- self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
21
- end
22
- yield self if block_given?
23
- end
24
-
25
27
  # @see sqref
26
28
  def sqref=(v)
27
29
  Axlsx.validate_string(v)
@@ -33,14 +35,15 @@ module Axlsx
33
35
  Axlsx.validate_string(v)
34
36
  @name = v
35
37
  end
36
-
38
+
37
39
  # serializes the proteted range
38
40
  # @param [String] str if this string object is provided we append
39
41
  # our output to that object. Use this - it helps limit the number of
40
42
  # objects created during serialization
41
43
  def to_xml_string(str="")
42
- attrs = self.instance_values.reject{ |key, value| value == nil }
43
- str << '<protectedRange ' << attrs.map { |key, value| '' << key << '="' << value.to_s << '"' }.join(' ') << '/>'
44
+ str << '<protectedRange '
45
+ serialized_attributes str
46
+ str << '/>'
44
47
  end
45
48
  end
46
49
  end
@@ -5,59 +5,14 @@ module Axlsx
5
5
  # @see Worksheet#add_row
6
6
  class Row
7
7
 
8
+ include SerializedAttributes
9
+ include Accessors
8
10
  # No support is provided for the following attributes
9
11
  # spans
10
12
  # thickTop
11
13
  # thickBottom
12
14
 
13
-
14
- # A list of serilizable attributes.
15
- # @note height(ht) and customHeight are manages separately for now. Have a look at Row#height
16
- SERIALIZABLE_ATTRIBUTES = [:hidden, :outlineLevel, :collapsed, :s, :customFormat, :ph]
17
-
18
- # The worksheet this row belongs to
19
- # @return [Worksheet]
20
- attr_reader :worksheet
21
-
22
- # The cells this row holds
23
- # @return [SimpleTypedList]
24
- attr_reader :cells
25
-
26
- # Row height measured in point size. There is no margin padding on row height.
27
- # @return [Float]
28
- attr_reader :height
29
-
30
- # Flag indicating if the outlining of row.
31
- # @return [Boolean]
32
- attr_reader :collapsed
33
-
34
- # Flag indicating if the the row is hidden.
35
- # @return [Boolean]
36
- attr_reader :hidden
37
-
38
- # Outlining level of the row, when outlining is on
39
- # @return [Integer]
40
- attr_reader :outlineLevel
41
-
42
- # The style applied ot the row. This affects the entire row.
43
- # @return [Integer]
44
- attr_reader :s
45
-
46
- # indicates that a style has been applied directly to the row via Row#s
47
- # @return [Boolean]
48
- attr_reader :customFormat
49
-
50
- # indicates if the row should show phonetic
51
- # @return [Boolean]
52
- attr_reader :ph
53
-
54
- # NOTE removing this from the api as it is actually incorrect.
55
- # having a method to style a row's cells is fine, but it is not an attribute on the row.
56
- # The proper attribute is ':s'
57
- # attr_reader style
58
- #
59
-
60
- # Creates a new row. New Cell objects are created based on the values, types and style options.
15
+ # Creates a new row. New Cell objects are created based on the values, types and style options.
61
16
  # A new cell is created for each item in the values array. style and types options are applied as follows:
62
17
  # If the types option is defined and is a symbol it is applied to all the cells created.
63
18
  # If the types option is an array, cell types are applied by index for each cell
@@ -73,7 +28,7 @@ module Axlsx
73
28
  # @see Row#array_to_cells
74
29
  # @see Cell
75
30
  def initialize(worksheet, values=[], options={})
76
- @height = nil
31
+ @ht = nil
77
32
  self.worksheet = worksheet
78
33
  @cells = SimpleTypedList.new Cell
79
34
  @worksheet.rows << self
@@ -81,29 +36,48 @@ module Axlsx
81
36
  array_to_cells(values, options)
82
37
  end
83
38
 
84
- # @see Row#collapsed
85
- def collapsed=(v)
86
- Axlsx.validate_boolean(v)
87
- @collapsed = v
88
- end
39
+ # A list of serializable attributes.
40
+ serializable_attributes :hidden, :outline_level, :collapsed, :custom_format, :s, :ph, :custom_height, :ht
41
+
42
+ # Boolean row attribute accessors
43
+ boolean_attr_accessor :hidden, :collapsed, :custom_format, :ph, :custom_height
89
44
 
90
- # @see Row#hidden
91
- def hidden=(v)
92
- Axlsx.validate_boolean(v)
93
- @hidden = v
45
+ # The worksheet this row belongs to
46
+ # @return [Worksheet]
47
+ attr_reader :worksheet
48
+
49
+ # The cells this row holds
50
+ # @return [SimpleTypedList]
51
+ attr_reader :cells
52
+
53
+ # Row height measured in point size. There is no margin padding on row height.
54
+ # @return [Float]
55
+ def height
56
+ @ht
94
57
  end
95
-
96
- # @see Row#ph
97
- def ph=(v) Axlsx.validate_boolean(v); @ph = v end
58
+
59
+ # Outlining level of the row, when outlining is on
60
+ # @return [Integer]
61
+ attr_reader :outline_level
62
+ alias :outlineLevel :outline_level
63
+
64
+ # The style applied ot the row. This affects the entire row.
65
+ # @return [Integer]
66
+ attr_reader :s
98
67
 
99
68
  # @see Row#s
100
- def s=(v) Axlsx.validate_unsigned_numeric(v); @s = v; @customFormat = true end
69
+ def s=(v)
70
+ Axlsx.validate_unsigned_numeric(v)
71
+ @custom_format = true
72
+ @s = v
73
+ end
101
74
 
102
75
  # @see Row#outline
103
- def outlineLevel=(v)
76
+ def outline_level=(v)
104
77
  Axlsx.validate_unsigned_numeric(v)
105
- @outlineLevel = v
78
+ @outline_level = v
106
79
  end
80
+ alias :outlineLevel= :outline_level=
107
81
 
108
82
  # The index of this row in the worksheet
109
83
  # @return [Integer]
@@ -116,21 +90,14 @@ module Axlsx
116
90
  # @param [String] str The string this rows xml will be appended to.
117
91
  # @return [String]
118
92
  def to_xml_string(r_index, str = '')
119
- str << '<row r="' << (r_index + 1 ).to_s << '" '
120
- instance_values.select { |key, value| SERIALIZABLE_ATTRIBUTES.include? key.to_sym }.each do |key, value|
121
- str << key << '="' << value.to_s << '" '
122
- end
123
- if custom_height?
124
- str << 'customHeight="1" ht="' << height.to_s << '">'
125
- else
126
- str << '>'
127
- end
93
+ str << '<row '
94
+ serialized_attributes(str, { :r => r_index + 1 })
95
+ str << '>'
128
96
  @cells.each_with_index { |cell, c_index| cell.to_xml_string(r_index, c_index, str) }
129
97
  str << '</row>'
130
- str
131
98
  end
132
99
 
133
- # Adds a singel sell to the row based on the data provided and updates the worksheet's autofit data.
100
+ # Adds a single sell to the row based on the data provided and updates the worksheet's autofit data.
134
101
  # @return [Cell]
135
102
  def add_cell(value="", options={})
136
103
  c = Cell.new(self, value, options)
@@ -154,13 +121,13 @@ module Axlsx
154
121
  end
155
122
 
156
123
  # @see height
157
- def height=(v); Axlsx::validate_unsigned_numeric(v) unless v.nil?; @height = v end
158
-
159
- # true if the row height has been manually set
160
- # @return [Boolean]
161
- # @see #height
162
- def custom_height?
163
- @height != nil
124
+ def height=(v)
125
+ Axlsx::validate_unsigned_numeric(v)
126
+ unless v.nil?
127
+ @ht = v
128
+ @custom_height = true
129
+ end
130
+ @ht
164
131
  end
165
132
 
166
133
  private
@@ -180,15 +147,24 @@ module Axlsx
180
147
  def array_to_cells(values, options={})
181
148
  values = values
182
149
  DataTypeValidator.validate 'Row.array_to_cells', Array, values
183
- types, style = options.delete(:types), options.delete(:style)
150
+ types, style, formula_values = options.delete(:types), options.delete(:style), options.delete(:formula_values)
184
151
  values.each_with_index do |value, index|
152
+
153
+ #WTF IS THIS PAP?
185
154
  cell_style = style.is_a?(Array) ? style[index] : style
186
155
  options[:style] = cell_style if cell_style
156
+
187
157
  cell_type = types.is_a?(Array)? types[index] : types
188
158
  options[:type] = cell_type if cell_type
159
+
160
+ formula_value = formula_values[index] if formula_values.is_a?(Array)
161
+ options[:formula_value] = formula_value if formula_value
162
+
189
163
  Cell.new(self, value, options)
164
+
190
165
  options.delete(:style)
191
166
  options.delete(:type)
167
+ options.delete(:formula_value)
192
168
  end
193
169
  end
194
170
  end