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.
- checksums.yaml +7 -0
- data/.yardopts +3 -2
- data/.yardopts_guide +19 -0
- data/CHANGELOG.md +64 -1
- data/README.md +105 -87
- data/Rakefile +0 -5
- data/examples/2010_comments.rb +17 -0
- data/examples/anchor_swapping.rb +28 -0
- data/examples/auto_filter.rb +16 -0
- data/examples/basic_charts.rb +4 -0
- data/examples/colored_links.rb +59 -0
- data/examples/conditional_formatting/example_conditional_formatting.rb +4 -2
- data/examples/example.rb +569 -258
- data/examples/ios_preview.rb +14 -0
- data/examples/page_setup.rb +11 -0
- data/examples/pivot_table.rb +39 -0
- data/examples/skydrive/real_example.rb +8 -8
- data/examples/styles.rb +66 -0
- data/examples/underline.rb +13 -0
- data/examples/wrap_text.rb +21 -0
- data/lib/axlsx/content_type/abstract_content_type.rb +32 -0
- data/lib/axlsx/content_type/content_type.rb +1 -1
- data/lib/axlsx/content_type/default.rb +6 -37
- data/lib/axlsx/content_type/override.rb +6 -38
- data/lib/axlsx/doc_props/app.rb +10 -7
- data/lib/axlsx/doc_props/core.rb +6 -1
- data/lib/axlsx/drawing/axes.rb +61 -0
- data/lib/axlsx/drawing/axis.rb +20 -17
- data/lib/axlsx/drawing/bar_3D_chart.rb +31 -22
- data/lib/axlsx/drawing/cat_axis.rb +2 -10
- data/lib/axlsx/drawing/chart.rb +33 -6
- data/lib/axlsx/drawing/d_lbls.rb +21 -31
- data/lib/axlsx/drawing/drawing.rb +11 -17
- data/lib/axlsx/drawing/graphic_frame.rb +3 -3
- data/lib/axlsx/drawing/hyperlink.rb +42 -36
- data/lib/axlsx/drawing/line_3D_chart.rb +28 -70
- data/lib/axlsx/drawing/line_chart.rb +99 -0
- data/lib/axlsx/drawing/line_series.rb +20 -2
- data/lib/axlsx/drawing/marker.rb +38 -18
- data/lib/axlsx/drawing/num_data.rb +6 -6
- data/lib/axlsx/drawing/num_data_source.rb +17 -16
- data/lib/axlsx/drawing/one_cell_anchor.rb +28 -21
- data/lib/axlsx/drawing/pic.rb +43 -45
- data/lib/axlsx/drawing/picture_locking.rb +12 -44
- data/lib/axlsx/drawing/pie_3D_chart.rb +2 -1
- data/lib/axlsx/drawing/scaling.rb +13 -13
- data/lib/axlsx/drawing/scatter_chart.rb +32 -21
- data/lib/axlsx/drawing/ser_axis.rb +15 -16
- data/lib/axlsx/drawing/series.rb +3 -6
- data/lib/axlsx/drawing/str_data.rb +3 -3
- data/lib/axlsx/drawing/str_val.rb +7 -8
- data/lib/axlsx/drawing/two_cell_anchor.rb +7 -27
- data/lib/axlsx/drawing/val_axis.rb +14 -13
- data/lib/axlsx/drawing/view_3D.rb +52 -38
- data/lib/axlsx/drawing/vml_shape.rb +20 -79
- data/lib/axlsx/package.rb +58 -28
- data/lib/axlsx/rels/relationship.rb +75 -9
- data/lib/axlsx/rels/relationships.rb +8 -1
- data/lib/axlsx/stylesheet/border.rb +29 -20
- data/lib/axlsx/stylesheet/border_pr.rb +5 -4
- data/lib/axlsx/stylesheet/cell_alignment.rb +55 -29
- data/lib/axlsx/stylesheet/cell_protection.rb +7 -4
- data/lib/axlsx/stylesheet/cell_style.rb +19 -14
- data/lib/axlsx/stylesheet/color.rb +20 -17
- data/lib/axlsx/stylesheet/dxf.rb +4 -4
- data/lib/axlsx/stylesheet/font.rb +22 -22
- data/lib/axlsx/stylesheet/gradient_fill.rb +45 -21
- data/lib/axlsx/stylesheet/num_fmt.rb +23 -14
- data/lib/axlsx/stylesheet/pattern_fill.rb +12 -21
- data/lib/axlsx/stylesheet/styles.rb +37 -22
- data/lib/axlsx/stylesheet/table_style.rb +17 -16
- data/lib/axlsx/stylesheet/table_style_element.rb +15 -11
- data/lib/axlsx/stylesheet/table_styles.rb +14 -11
- data/lib/axlsx/stylesheet/xf.rb +28 -26
- data/lib/axlsx/util/accessors.rb +64 -0
- data/lib/axlsx/util/constants.rb +127 -6
- data/lib/axlsx/util/options_parser.rb +15 -0
- data/lib/axlsx/util/serialized_attributes.rb +79 -0
- data/lib/axlsx/util/simple_typed_list.rb +50 -15
- data/lib/axlsx/util/validators.rb +51 -16
- data/lib/axlsx/version.rb +2 -2
- data/lib/axlsx/workbook/defined_name.rb +14 -59
- data/lib/axlsx/workbook/shared_strings_table.rb +13 -4
- data/lib/axlsx/workbook/workbook.rb +85 -6
- data/lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb +77 -0
- data/lib/axlsx/workbook/worksheet/auto_filter/filter_column.rb +94 -0
- data/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +246 -0
- data/lib/axlsx/workbook/worksheet/break.rb +37 -0
- data/lib/axlsx/workbook/worksheet/cell.rb +109 -107
- data/lib/axlsx/workbook/worksheet/cell_serializer.rb +144 -0
- data/lib/axlsx/workbook/worksheet/cfvo.rb +15 -15
- data/lib/axlsx/workbook/worksheet/cfvos.rb +15 -0
- data/lib/axlsx/workbook/worksheet/col.rb +43 -29
- data/lib/axlsx/workbook/worksheet/col_breaks.rb +35 -0
- data/lib/axlsx/workbook/worksheet/color_scale.rb +62 -28
- data/lib/axlsx/workbook/worksheet/comment.rb +28 -37
- data/lib/axlsx/workbook/worksheet/comments.rb +3 -3
- data/lib/axlsx/workbook/worksheet/conditional_formatting.rb +11 -11
- data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +31 -27
- data/lib/axlsx/workbook/worksheet/data_bar.rb +75 -41
- data/lib/axlsx/workbook/worksheet/data_validation.rb +61 -62
- data/lib/axlsx/workbook/worksheet/date_time_converter.rb +6 -5
- data/lib/axlsx/workbook/worksheet/dimension.rb +0 -1
- data/lib/axlsx/workbook/worksheet/header_footer.rb +54 -0
- data/lib/axlsx/workbook/worksheet/icon_set.rb +20 -20
- data/lib/axlsx/workbook/worksheet/page_margins.rb +21 -19
- data/lib/axlsx/workbook/worksheet/page_set_up_pr.rb +44 -0
- data/lib/axlsx/workbook/worksheet/page_setup.rb +152 -23
- data/lib/axlsx/workbook/worksheet/pane.rb +48 -51
- data/lib/axlsx/workbook/worksheet/pivot_table.rb +273 -0
- data/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +66 -0
- data/lib/axlsx/workbook/worksheet/pivot_tables.rb +24 -0
- data/lib/axlsx/workbook/worksheet/print_options.rb +8 -30
- data/lib/axlsx/workbook/worksheet/protected_range.rb +16 -13
- data/lib/axlsx/workbook/worksheet/row.rb +59 -83
- data/lib/axlsx/workbook/worksheet/row_breaks.rb +33 -0
- data/lib/axlsx/workbook/worksheet/selection.rb +30 -38
- data/lib/axlsx/workbook/worksheet/sheet_calc_pr.rb +29 -0
- data/lib/axlsx/workbook/worksheet/sheet_format_pr.rb +60 -0
- data/lib/axlsx/workbook/worksheet/sheet_pr.rb +49 -4
- data/lib/axlsx/workbook/worksheet/sheet_protection.rb +51 -155
- data/lib/axlsx/workbook/worksheet/sheet_view.rb +68 -234
- data/lib/axlsx/workbook/worksheet/table.rb +25 -19
- data/lib/axlsx/workbook/worksheet/table_style_info.rb +51 -0
- data/lib/axlsx/workbook/worksheet/tables.rb +1 -1
- data/lib/axlsx/workbook/worksheet/worksheet.rb +174 -35
- data/lib/axlsx/workbook/worksheet/worksheet_comments.rb +6 -5
- data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +4 -10
- data/lib/axlsx/workbook/worksheet/worksheet_hyperlink.rb +74 -0
- data/lib/axlsx/workbook/worksheet/worksheet_hyperlinks.rb +38 -0
- data/lib/axlsx.rb +55 -5
- data/lib/schema/sml.xsd +4 -0
- data/test/axlsx.qcachegrind +2226 -0
- data/test/benchmark.rb +2 -3
- data/test/content_type/tc_default.rb +0 -11
- data/test/content_type/tc_override.rb +0 -13
- data/test/doc_props/tc_core.rb +7 -0
- data/test/drawing/tc_axes.rb +8 -0
- data/test/drawing/tc_axis.rb +15 -17
- data/test/drawing/tc_bar_3D_chart.rb +6 -0
- data/test/drawing/tc_cat_axis.rb +9 -9
- data/test/drawing/tc_chart.rb +20 -0
- data/test/drawing/tc_d_lbls.rb +14 -4
- data/test/drawing/tc_drawing.rb +0 -5
- data/test/drawing/tc_graphic_frame.rb +5 -3
- data/test/drawing/tc_hyperlink.rb +0 -4
- data/test/drawing/tc_line_chart.rb +39 -0
- data/test/drawing/tc_line_series.rb +8 -2
- data/test/drawing/tc_pic.rb +14 -3
- data/test/drawing/tc_ser_axis.rb +13 -12
- data/test/drawing/tc_two_cell_anchor.rb +3 -3
- data/test/drawing/tc_val_axis.rb +6 -6
- data/test/drawing/tc_vml_shape.rb +9 -3
- data/test/profile.rb +11 -21
- data/test/rels/tc_relationship.rb +32 -9
- data/test/rels/tc_relationships.rb +12 -1
- data/test/stylesheet/tc_color.rb +6 -0
- data/test/stylesheet/tc_styles.rb +15 -2
- data/test/tc_axlsx.rb +35 -2
- data/test/tc_helper.rb +7 -1
- data/test/tc_package.rb +44 -5
- data/test/util/tc_serialized_attributes.rb +19 -0
- data/test/util/tc_validators.rb +26 -1
- data/test/workbook/tc_defined_name.rb +2 -2
- data/test/workbook/tc_shared_strings_table.rb +6 -0
- data/test/workbook/tc_workbook.rb +38 -1
- data/test/workbook/worksheet/auto_filter/tc_auto_filter.rb +38 -0
- data/test/workbook/worksheet/auto_filter/tc_filter_column.rb +76 -0
- data/test/workbook/worksheet/auto_filter/tc_filters.rb +50 -0
- data/test/workbook/worksheet/tc_break.rb +49 -0
- data/test/workbook/worksheet/tc_cell.rb +40 -6
- data/test/workbook/worksheet/tc_col.rb +11 -1
- data/test/workbook/worksheet/tc_color_scale.rb +31 -2
- data/test/workbook/worksheet/tc_comment.rb +21 -6
- data/test/workbook/worksheet/tc_comments.rb +2 -2
- data/test/workbook/worksheet/tc_conditional_formatting.rb +7 -0
- data/test/workbook/worksheet/tc_data_bar.rb +7 -0
- data/test/workbook/worksheet/tc_date_time_converter.rb +3 -11
- data/test/workbook/worksheet/tc_header_footer.rb +151 -0
- data/test/workbook/worksheet/tc_page_set_up_pr.rb +15 -0
- data/test/workbook/worksheet/tc_page_setup.rb +6 -1
- data/test/workbook/worksheet/tc_pane.rb +5 -45
- data/test/workbook/worksheet/tc_pivot_table.rb +120 -0
- data/test/workbook/worksheet/tc_pivot_table_cache_definition.rb +54 -0
- data/test/workbook/worksheet/tc_row.rb +4 -4
- data/test/workbook/worksheet/tc_selection.rb +9 -48
- data/test/workbook/worksheet/tc_sheet_calc_pr.rb +18 -0
- data/test/workbook/worksheet/tc_sheet_format_pr.rb +88 -0
- data/test/workbook/worksheet/tc_sheet_pr.rb +27 -0
- data/test/workbook/worksheet/tc_sheet_view.rb +39 -39
- data/test/workbook/worksheet/{table/tc_table.rb → tc_table.rb} +8 -3
- data/test/workbook/worksheet/tc_table_style_info.rb +53 -0
- data/test/workbook/worksheet/tc_worksheet.rb +131 -16
- data/test/workbook/worksheet/tc_worksheet_hyperlink.rb +55 -0
- metadata +97 -64
- data/examples/example.xlsx +0 -0
- data/examples/example_streamed.xlsx +0 -0
- data/examples/extractive.pdf +0 -0
- data/examples/image1.gif +0 -0
- data/examples/image1.jpg +0 -0
- data/examples/image1.png +0 -0
- data/examples/no-use_autowidth.xlsx +0 -0
- data/examples/sample.png +0 -0
- data/examples/scraping_html.rb +0 -91
- data/examples/shared_strings_example.xlsx +0 -0
- data/examples/sheet_view.rb +0 -34
- data/examples/two_cell_anchor_image.rb +0 -11
- data/lib/axlsx/workbook/worksheet/auto_filter.rb +0 -34
|
@@ -14,6 +14,24 @@ module Axlsx
|
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
+
# Validate that the value provided is between a specific range
|
|
18
|
+
# Note that no data conversions will be done for you!
|
|
19
|
+
# Comparisons will be made using < and > or <= and <= when the inclusive parameter is true
|
|
20
|
+
class RangeValidator
|
|
21
|
+
# @param [String] name The name of what is being validated
|
|
22
|
+
# @param [Any] min The minimum allowed value
|
|
23
|
+
# @param [Any] max The maximum allowed value
|
|
24
|
+
# @param [Any] value The value to be validated
|
|
25
|
+
# @param [Boolean] inclusive Flag indicating if the comparison should be inclusive.
|
|
26
|
+
def self.validate(name, min, max, value, inclusive = true)
|
|
27
|
+
passes = if inclusive
|
|
28
|
+
min <= value && value <= max
|
|
29
|
+
else
|
|
30
|
+
min < value && value < max
|
|
31
|
+
end
|
|
32
|
+
raise ArgumentError, (ERR_RANGE % [value.inspect, min.to_s, max.to_s, inclusive]) unless passes
|
|
33
|
+
end
|
|
34
|
+
end
|
|
17
35
|
# Validates the value against the regular expression provided.
|
|
18
36
|
class RegexValidator
|
|
19
37
|
# @param [String] name The name of what is being validated. This is included in the output when the value is invalid
|
|
@@ -23,6 +41,7 @@ module Axlsx
|
|
|
23
41
|
raise ArgumentError, (ERR_REGEX % [v.inspect, regex.to_s]) unless (v.respond_to?(:to_s) && v.to_s.match(regex))
|
|
24
42
|
end
|
|
25
43
|
end
|
|
44
|
+
|
|
26
45
|
# Validate that the class of the value provided is either an instance or the class of the allowed types and that any specified additional validation returns true.
|
|
27
46
|
class DataTypeValidator
|
|
28
47
|
# Perform validation
|
|
@@ -32,17 +51,18 @@ module Axlsx
|
|
|
32
51
|
# @raise [ArugumentError] Raised if the class of the value provided is not in the specified array of types or the block passed returns false
|
|
33
52
|
# @return [Boolean] true if validation succeeds.
|
|
34
53
|
# @see validate_boolean
|
|
35
|
-
def self.validate(name, types, v, other=
|
|
54
|
+
def self.validate(name, types, v, other=false)
|
|
36
55
|
types = [types] unless types.is_a? Array
|
|
37
|
-
|
|
56
|
+
if other.is_a?(Proc)
|
|
57
|
+
raise ArgumentError, (ERR_TYPE % [v.inspect, name, types.inspect]) unless other.call(v)
|
|
58
|
+
end
|
|
38
59
|
if v.class == Class
|
|
39
|
-
types.each { |t|
|
|
60
|
+
types.each { |t| return if v.ancestors.include?(t) }
|
|
40
61
|
else
|
|
41
|
-
types.each { |t|
|
|
62
|
+
types.each { |t| return if v.is_a?(t) }
|
|
42
63
|
end
|
|
43
|
-
raise ArgumentError, (ERR_TYPE % [v.inspect, name, types.inspect])
|
|
64
|
+
raise ArgumentError, (ERR_TYPE % [v.inspect, name, types.inspect])
|
|
44
65
|
end
|
|
45
|
-
true
|
|
46
66
|
end
|
|
47
67
|
|
|
48
68
|
|
|
@@ -73,7 +93,7 @@ module Axlsx
|
|
|
73
93
|
# @raise [ArgumentError] raised if the value is not a Fixnun, Integer, Float value greater or equal to 0
|
|
74
94
|
# @return [Boolean] true if the data is valid
|
|
75
95
|
def self.validate_unsigned_numeric(v)
|
|
76
|
-
DataTypeValidator.validate("Invalid column width", [Fixnum, Integer, Float], v, lambda { |arg| arg.respond_to?(:>=) && arg >= 0 })
|
|
96
|
+
DataTypeValidator.validate("Invalid column width", [Fixnum, Integer, Float], v, lambda { |arg| arg.respond_to?(:>=) && arg.to_i >= 0 })
|
|
77
97
|
end
|
|
78
98
|
|
|
79
99
|
# Requires that the value is a Fixnum or Integer
|
|
@@ -112,7 +132,7 @@ module Axlsx
|
|
|
112
132
|
def self.validate_scale_10_400(v)
|
|
113
133
|
DataTypeValidator.validate "page_scale", [Fixnum, Integer], v, lambda { |arg| arg >= 10 && arg <= 400 }
|
|
114
134
|
end
|
|
115
|
-
|
|
135
|
+
|
|
116
136
|
# Requires that the value is an integer ranging from 10 to 400 or 0.
|
|
117
137
|
def self.validate_scale_0_10_400(v)
|
|
118
138
|
DataTypeValidator.validate "page_scale", [Fixnum, Integer], v, lambda { |arg| arg == 0 || (arg >= 10 && arg <= 400) }
|
|
@@ -122,14 +142,22 @@ module Axlsx
|
|
|
122
142
|
def self.validate_page_orientation(v)
|
|
123
143
|
RestrictionValidator.validate "page_orientation", [:default, :landscape, :portrait], v
|
|
124
144
|
end
|
|
145
|
+
# Requires that the value is one of :none, :single, :double, :singleAccounting, :doubleAccounting
|
|
146
|
+
def self.validate_cell_u(v)
|
|
147
|
+
RestrictionValidator.validate "cell run style u", [:none, :single, :double, :singleAccounting, :doubleAccounting], v
|
|
148
|
+
end
|
|
125
149
|
|
|
150
|
+
# validates cell style family which must be between 1 and 5
|
|
151
|
+
def self.validate_family(v)
|
|
152
|
+
RestrictionValidator.validate "cell run style family", 1..5, v
|
|
153
|
+
end
|
|
126
154
|
# Requires that the value is valid pattern type.
|
|
127
155
|
# valid pattern types must be one of :none, :solid, :mediumGray, :darkGray, :lightGray, :darkHorizontal, :darkVertical, :darkDown,
|
|
128
156
|
# :darkUp, :darkGrid, :darkTrellis, :lightHorizontal, :lightVertical, :lightDown, :lightUp, :lightGrid, :lightTrellis, :gray125, or :gray0625.
|
|
129
157
|
# @param [Any] v The value validated
|
|
130
158
|
def self.validate_pattern_type(v)
|
|
131
159
|
RestrictionValidator.validate :pattern_type, [:none, :solid, :mediumGray, :darkGray, :lightGray, :darkHorizontal, :darkVertical, :darkDown, :darkUp, :darkGrid,
|
|
132
|
-
|
|
160
|
+
:darkTrellis, :lightHorizontal, :lightVertical, :lightDown, :lightUp, :lightGrid, :lightTrellis, :gray125, :gray0625], v
|
|
133
161
|
end
|
|
134
162
|
|
|
135
163
|
# Requires that the value is one of the ST_TimePeriod types
|
|
@@ -203,14 +231,14 @@ module Axlsx
|
|
|
203
231
|
# TABLE_CT, WORKBOOK_CT, APP_CT, RELS_CT, STYLES_CT, XML_CT, WORKSHEET_CT, SHARED_STRINGS_CT, CORE_CT, CHART_CT, DRAWING_CT, COMMENT_CT are allowed
|
|
204
232
|
# @param [Any] v The value validated
|
|
205
233
|
def self.validate_content_type(v)
|
|
206
|
-
RestrictionValidator.validate :content_type, [TABLE_CT, WORKBOOK_CT, APP_CT, RELS_CT, STYLES_CT, XML_CT, WORKSHEET_CT, SHARED_STRINGS_CT, CORE_CT, CHART_CT, JPEG_CT, GIF_CT, PNG_CT, DRAWING_CT, COMMENT_CT, VML_DRAWING_CT], v
|
|
234
|
+
RestrictionValidator.validate :content_type, [TABLE_CT, WORKBOOK_CT, APP_CT, RELS_CT, STYLES_CT, XML_CT, WORKSHEET_CT, SHARED_STRINGS_CT, CORE_CT, CHART_CT, JPEG_CT, GIF_CT, PNG_CT, DRAWING_CT, COMMENT_CT, VML_DRAWING_CT, PIVOT_TABLE_CT, PIVOT_TABLE_CACHE_DEFINITION_CT], v
|
|
207
235
|
end
|
|
208
236
|
|
|
209
237
|
# Requires that the value is a valid relationship_type
|
|
210
238
|
# XML_NS_R, TABLE_R, WORKBOOK_R, WORKSHEET_R, APP_R, RELS_R, CORE_R, STYLES_R, CHART_R, DRAWING_R, IMAGE_R, HYPERLINK_R, SHARED_STRINGS_R are allowed
|
|
211
239
|
# @param [Any] v The value validated
|
|
212
240
|
def self.validate_relationship_type(v)
|
|
213
|
-
RestrictionValidator.validate :relationship_type, [XML_NS_R, TABLE_R, WORKBOOK_R, WORKSHEET_R, APP_R, RELS_R, CORE_R, STYLES_R, CHART_R, DRAWING_R, IMAGE_R, HYPERLINK_R, SHARED_STRINGS_R, COMMENT_R, VML_DRAWING_R, COMMENT_R_NULL], v
|
|
241
|
+
RestrictionValidator.validate :relationship_type, [XML_NS_R, TABLE_R, WORKBOOK_R, WORKSHEET_R, APP_R, RELS_R, CORE_R, STYLES_R, CHART_R, DRAWING_R, IMAGE_R, HYPERLINK_R, SHARED_STRINGS_R, COMMENT_R, VML_DRAWING_R, COMMENT_R_NULL, PIVOT_TABLE_R, PIVOT_TABLE_CACHE_DEFINITION_R], v
|
|
214
242
|
end
|
|
215
243
|
|
|
216
244
|
# Requires that the value is a valid table element type
|
|
@@ -226,7 +254,7 @@ module Axlsx
|
|
|
226
254
|
def self.validate_data_validation_error_style(v)
|
|
227
255
|
RestrictionValidator.validate :validate_data_validation_error_style, [:information, :stop, :warning], v
|
|
228
256
|
end
|
|
229
|
-
|
|
257
|
+
|
|
230
258
|
# Requires that the value is valid data validation operator.
|
|
231
259
|
# valid operators must be one of lessThan, lessThanOrEqual, equal,
|
|
232
260
|
# notEqual, greaterThanOrEqual, greaterThan, between, notBetween
|
|
@@ -234,32 +262,39 @@ module Axlsx
|
|
|
234
262
|
def self.validate_data_validation_operator(v)
|
|
235
263
|
RestrictionValidator.validate :data_validation_operator, [:lessThan, :lessThanOrEqual, :equal, :notEqual, :greaterThanOrEqual, :greaterThan, :between, :notBetween], v
|
|
236
264
|
end
|
|
237
|
-
|
|
265
|
+
|
|
238
266
|
# Requires that the value is valid data validation type.
|
|
239
267
|
# valid types must be one of custom, data, decimal, list, none, textLength, time, whole
|
|
240
268
|
# @param [Any] v The value validated
|
|
241
269
|
def self.validate_data_validation_type(v)
|
|
242
270
|
RestrictionValidator.validate :data_validation_type, [:custom, :data, :decimal, :list, :none, :textLength, :time, :whole], v
|
|
243
271
|
end
|
|
244
|
-
|
|
272
|
+
|
|
245
273
|
# Requires that the value is a valid sheet view type.
|
|
246
274
|
# valid types must be one of normal, page_break_preview, page_layout
|
|
247
275
|
# @param [Any] v The value validated
|
|
248
276
|
def self.validate_sheet_view_type(v)
|
|
249
277
|
RestrictionValidator.validate :sheet_view_type, [:normal, :page_break_preview, :page_layout], v
|
|
250
278
|
end
|
|
251
|
-
|
|
279
|
+
|
|
252
280
|
# Requires that the value is a valid active pane type.
|
|
253
281
|
# valid types must be one of bottom_left, bottom_right, top_left, top_right
|
|
254
282
|
# @param [Any] v The value validated
|
|
255
283
|
def self.validate_pane_type(v)
|
|
256
284
|
RestrictionValidator.validate :active_pane_type, [:bottom_left, :bottom_right, :top_left, :top_right], v
|
|
257
285
|
end
|
|
258
|
-
|
|
286
|
+
|
|
259
287
|
# Requires that the value is a valid split state type.
|
|
260
288
|
# valid types must be one of frozen, frozen_split, split
|
|
261
289
|
# @param [Any] v The value validated
|
|
262
290
|
def self.validate_split_state_type(v)
|
|
263
291
|
RestrictionValidator.validate :split_state_type, [:frozen, :frozen_split, :split], v
|
|
264
292
|
end
|
|
293
|
+
|
|
294
|
+
# Requires that the value is a valid "display blanks as" type.
|
|
295
|
+
# valid types must be one of gap, span, zero
|
|
296
|
+
# @param [Any] v The value validated
|
|
297
|
+
def self.validate_display_blanks_as(v)
|
|
298
|
+
RestrictionValidator.validate :display_blanks_as, [:gap, :span, :zero], v
|
|
299
|
+
end
|
|
265
300
|
end
|
data/lib/axlsx/version.rb
CHANGED
|
@@ -49,12 +49,15 @@ module Axlsx
|
|
|
49
49
|
# @example
|
|
50
50
|
# For clarification: LOG10 is always a cell reference, LOG10() is always formula, LOGO1000 can be a defined name that overrides a cell reference.
|
|
51
51
|
class DefinedName
|
|
52
|
+
include Axlsx::SerializedAttributes
|
|
53
|
+
include Axlsx::OptionsParser
|
|
54
|
+
include Axlsx::Accessors
|
|
52
55
|
# creates a new DefinedName.
|
|
53
56
|
# @param [String] formula - the formula the defined name references
|
|
54
57
|
# @param [Hash] options - A hash of key/value pairs that will be mapped to this instances attributes.
|
|
55
|
-
#
|
|
58
|
+
#
|
|
56
59
|
# @option [String] name - Specifies the name that appears in the user interface for the defined name.
|
|
57
|
-
# This attribute is required.
|
|
60
|
+
# This attribute is required.
|
|
58
61
|
# The following built-in names are defined in this SpreadsheetML specification:
|
|
59
62
|
# Print
|
|
60
63
|
# _xlnm.Print_Area: this defined name specifies the workbook's print area.
|
|
@@ -96,77 +99,29 @@ module Axlsx
|
|
|
96
99
|
# version of the workbook that is published to or rendered on a Web or application server.
|
|
97
100
|
def initialize(formula, options={})
|
|
98
101
|
@formula = formula
|
|
99
|
-
options
|
|
100
|
-
self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
|
|
101
|
-
end
|
|
102
|
+
parse_options options
|
|
102
103
|
end
|
|
104
|
+
|
|
103
105
|
attr_reader :local_sheet_id
|
|
104
106
|
|
|
105
107
|
# The local sheet index (0-based)
|
|
106
|
-
# @param [Integer] value the
|
|
108
|
+
# @param [Integer] value the unsigned integer index of the sheet this defined_name applies to.
|
|
107
109
|
def local_sheet_id=(value)
|
|
108
110
|
Axlsx::validate_unsigned_int(value)
|
|
109
111
|
@local_sheet_id = value
|
|
110
112
|
end
|
|
111
113
|
|
|
112
|
-
|
|
113
|
-
STRING_ATTRIBUTES = [:short_cut_key, :status_bar, :help, :description, :custom_menu, :comment]
|
|
114
|
-
|
|
115
|
-
# boolean attributes that will be added when this class is evaluated
|
|
116
|
-
BOOLEAN_ATTRIBUTES = [:workbook_parameter, :publish_to_server, :xlm, :vb_proceedure, :function, :hidden]
|
|
117
|
-
|
|
118
|
-
# Dynamically create string attribute accessors
|
|
119
|
-
STRING_ATTRIBUTES.each do |attr|
|
|
120
|
-
class_eval %{
|
|
121
|
-
# The #{attr} attribute reader
|
|
122
|
-
# @return [String]
|
|
123
|
-
attr_reader :#{attr}
|
|
124
|
-
|
|
125
|
-
# The #{attr} writer
|
|
126
|
-
# @param [String] value The value to assign to #{attr}
|
|
127
|
-
# @return [String]
|
|
128
|
-
def #{attr}=(value)
|
|
129
|
-
Axlsx::validate_string(value)
|
|
130
|
-
@#{attr}= value
|
|
131
|
-
end
|
|
132
|
-
}
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
# Dynamically create boolean attribute accessors
|
|
136
|
-
BOOLEAN_ATTRIBUTES.each do |attr|
|
|
137
|
-
class_eval %{
|
|
138
|
-
# The #{attr} attribute reader
|
|
139
|
-
# @return [Boolean]
|
|
140
|
-
attr_reader :#{attr}
|
|
114
|
+
string_attr_accessor :short_cut_key, :status_bar, :help, :description, :custom_menu, :comment, :name, :formula
|
|
141
115
|
|
|
142
|
-
|
|
143
|
-
# @param [Boolean] value The value to assign to #{attr}
|
|
144
|
-
# @return [Boolean]
|
|
145
|
-
def #{attr}=(value)
|
|
146
|
-
Axlsx::validate_boolean(value)
|
|
147
|
-
@#{attr} = value
|
|
148
|
-
end
|
|
149
|
-
}
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
attr_reader :name
|
|
153
|
-
# The name of this defined name. Please refer to the class documentation for more information
|
|
154
|
-
def name=(value)
|
|
155
|
-
Axlsx::RestrictionValidator.validate 'DefinedName.name', %w(_xlnm.Print_Area _xlnm.Print_Titles _xlnm.Criteria _xlnm._FilterDatabase _xlnm.Extract _xlnm.Consolidate_Area _xlnm.Database _xlnm.Sheet_Title), value
|
|
156
|
-
@name = value
|
|
157
|
-
end
|
|
116
|
+
boolean_attr_accessor :workbook_parameter, :publish_to_server, :xlm, :vb_proceedure, :function, :hidden
|
|
158
117
|
|
|
159
|
-
|
|
160
|
-
|
|
118
|
+
serializable_attributes :short_cut_key, :status_bar, :help, :description, :custom_menu, :comment,
|
|
119
|
+
:workbook_parameter, :publish_to_server, :xlm, :vb_proceedure, :function, :hidden, :name, :local_sheet_id
|
|
161
120
|
|
|
162
121
|
def to_xml_string(str='')
|
|
163
122
|
raise ArgumentError, 'you must specify the name for this defined name. Please read the documentation for Axlsx::DefinedName for more details' unless name
|
|
164
|
-
str << '<definedName'
|
|
165
|
-
|
|
166
|
-
unless name == 'formula'
|
|
167
|
-
str << ' ' << Axlsx::camel(name, false) << "='#{value}'"
|
|
168
|
-
end
|
|
169
|
-
end
|
|
123
|
+
str << '<definedName '
|
|
124
|
+
serialized_attributes str
|
|
170
125
|
str << '>' << @formula
|
|
171
126
|
str << '</definedName>'
|
|
172
127
|
end
|
|
@@ -26,10 +26,16 @@ module Axlsx
|
|
|
26
26
|
# @see Cell#sharable
|
|
27
27
|
attr_reader :unique_cells
|
|
28
28
|
|
|
29
|
+
# The xml:space attribute
|
|
30
|
+
# @see Workbook#xml_space
|
|
31
|
+
attr_reader :xml_space
|
|
32
|
+
|
|
29
33
|
# Creates a new Shared Strings Table agains an array of cells
|
|
30
34
|
# @param [Array] cells This is an array of all of the cells in the workbook
|
|
31
|
-
|
|
35
|
+
# @param [Symbol] xml_space The xml:space behavior for the shared string table.
|
|
36
|
+
def initialize(cells, xml_space=:preserve)
|
|
32
37
|
@index = 0
|
|
38
|
+
@xml_space = xml_space
|
|
33
39
|
@unique_cells = {}
|
|
34
40
|
@shared_xml_string = ""
|
|
35
41
|
shareable_cells = cells.flatten.select{ |cell| cell.plain_string? }
|
|
@@ -40,8 +46,11 @@ module Axlsx
|
|
|
40
46
|
# Serializes the object
|
|
41
47
|
# @param [String] str
|
|
42
48
|
# @return [String]
|
|
43
|
-
def to_xml_string
|
|
44
|
-
'<?xml version="1.0" encoding="UTF-8"?><sst xmlns="' << XML_NS << '"
|
|
49
|
+
def to_xml_string(str='')
|
|
50
|
+
str << '<?xml version="1.0" encoding="UTF-8"?><sst xmlns="' << XML_NS << '"'
|
|
51
|
+
str << ' count="' << @count.to_s << '" uniqueCount="' << unique_count.to_s << '"'
|
|
52
|
+
str << ' xml:space="' << xml_space.to_s << '">' << @shared_xml_string << '</sst>'
|
|
53
|
+
str = Axlsx::sanitize(str)
|
|
45
54
|
end
|
|
46
55
|
|
|
47
56
|
private
|
|
@@ -58,7 +67,7 @@ module Axlsx
|
|
|
58
67
|
cell.send :ssti=, index
|
|
59
68
|
else
|
|
60
69
|
cell.send :ssti=, @index
|
|
61
|
-
@shared_xml_string << '<si>' <<
|
|
70
|
+
@shared_xml_string << '<si>' << CellSerializer.run_xml_string(cell) << '</si>'
|
|
62
71
|
@unique_cells[cell_hash] = @index
|
|
63
72
|
@index += 1
|
|
64
73
|
end
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
module Axlsx
|
|
3
|
-
require 'axlsx/workbook/worksheet/
|
|
3
|
+
require 'axlsx/workbook/worksheet/sheet_calc_pr.rb'
|
|
4
|
+
require 'axlsx/workbook/worksheet/auto_filter/auto_filter.rb'
|
|
4
5
|
require 'axlsx/workbook/worksheet/date_time_converter.rb'
|
|
5
6
|
require 'axlsx/workbook/worksheet/protected_range.rb'
|
|
6
7
|
require 'axlsx/workbook/worksheet/protected_ranges.rb'
|
|
8
|
+
require 'axlsx/workbook/worksheet/cell_serializer.rb'
|
|
7
9
|
require 'axlsx/workbook/worksheet/cell.rb'
|
|
8
10
|
require 'axlsx/workbook/worksheet/page_margins.rb'
|
|
11
|
+
require 'axlsx/workbook/worksheet/page_set_up_pr.rb'
|
|
9
12
|
require 'axlsx/workbook/worksheet/page_setup.rb'
|
|
13
|
+
require 'axlsx/workbook/worksheet/header_footer.rb'
|
|
10
14
|
require 'axlsx/workbook/worksheet/print_options.rb'
|
|
11
15
|
require 'axlsx/workbook/worksheet/cfvo.rb'
|
|
16
|
+
require 'axlsx/workbook/worksheet/cfvos.rb'
|
|
12
17
|
require 'axlsx/workbook/worksheet/color_scale.rb'
|
|
13
18
|
require 'axlsx/workbook/worksheet/data_bar.rb'
|
|
14
19
|
require 'axlsx/workbook/worksheet/icon_set.rb'
|
|
@@ -27,15 +32,28 @@ require 'axlsx/workbook/worksheet/dimension.rb'
|
|
|
27
32
|
require 'axlsx/workbook/worksheet/sheet_data.rb'
|
|
28
33
|
require 'axlsx/workbook/worksheet/worksheet_drawing.rb'
|
|
29
34
|
require 'axlsx/workbook/worksheet/worksheet_comments.rb'
|
|
35
|
+
require 'axlsx/workbook/worksheet/worksheet_hyperlink'
|
|
36
|
+
require 'axlsx/workbook/worksheet/worksheet_hyperlinks'
|
|
37
|
+
require 'axlsx/workbook/worksheet/break'
|
|
38
|
+
require 'axlsx/workbook/worksheet/row_breaks'
|
|
39
|
+
require 'axlsx/workbook/worksheet/col_breaks'
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
30
43
|
require 'axlsx/workbook/worksheet/worksheet.rb'
|
|
31
44
|
require 'axlsx/workbook/shared_strings_table.rb'
|
|
32
45
|
require 'axlsx/workbook/defined_name.rb'
|
|
33
46
|
require 'axlsx/workbook/defined_names.rb'
|
|
47
|
+
require 'axlsx/workbook/worksheet/table_style_info.rb'
|
|
34
48
|
require 'axlsx/workbook/worksheet/table.rb'
|
|
35
49
|
require 'axlsx/workbook/worksheet/tables.rb'
|
|
50
|
+
require 'axlsx/workbook/worksheet/pivot_table_cache_definition.rb'
|
|
51
|
+
require 'axlsx/workbook/worksheet/pivot_table.rb'
|
|
52
|
+
require 'axlsx/workbook/worksheet/pivot_tables.rb'
|
|
36
53
|
require 'axlsx/workbook/worksheet/data_validation.rb'
|
|
37
54
|
require 'axlsx/workbook/worksheet/data_validations.rb'
|
|
38
55
|
require 'axlsx/workbook/worksheet/sheet_view.rb'
|
|
56
|
+
require 'axlsx/workbook/worksheet/sheet_format_pr.rb'
|
|
39
57
|
require 'axlsx/workbook/worksheet/pane.rb'
|
|
40
58
|
require 'axlsx/workbook/worksheet/selection.rb'
|
|
41
59
|
# The Workbook class is an xlsx workbook that manages worksheets, charts, drawings and styles.
|
|
@@ -114,10 +132,17 @@ require 'axlsx/workbook/worksheet/selection.rb'
|
|
|
114
132
|
# @return [SimpleTypedList]
|
|
115
133
|
attr_reader :tables
|
|
116
134
|
|
|
135
|
+
# A colllection of pivot tables associated with this workbook
|
|
136
|
+
# @note The recommended way to manage drawings is Worksheet#add_table
|
|
137
|
+
# @see Worksheet#add_table
|
|
138
|
+
# @see Table
|
|
139
|
+
# @return [SimpleTypedList]
|
|
140
|
+
attr_reader :pivot_tables
|
|
141
|
+
|
|
117
142
|
|
|
118
143
|
# A collection of defined names for this workbook
|
|
119
144
|
# @note The recommended way to manage defined names is Workbook#add_defined_name
|
|
120
|
-
# @see DefinedName
|
|
145
|
+
# @see DefinedName
|
|
121
146
|
# @return [DefinedNames]
|
|
122
147
|
def defined_names
|
|
123
148
|
@defined_names ||= DefinedNames.new
|
|
@@ -147,6 +172,14 @@ require 'axlsx/workbook/worksheet/selection.rb'
|
|
|
147
172
|
@@date1904 = false
|
|
148
173
|
|
|
149
174
|
|
|
175
|
+
# A quick helper to retrive a worksheet by name
|
|
176
|
+
# @param [String] name The name of the sheet you are looking for
|
|
177
|
+
# @return [Worksheet] The sheet found, or nil
|
|
178
|
+
def sheet_by_name(name)
|
|
179
|
+
index = @worksheets.index { |sheet| sheet.name == name }
|
|
180
|
+
@worksheets[index] if index
|
|
181
|
+
end
|
|
182
|
+
|
|
150
183
|
# lets come back to this later when we are ready for parsing.
|
|
151
184
|
#def self.parse entry
|
|
152
185
|
# io = entry.get_input_stream
|
|
@@ -167,6 +200,7 @@ require 'axlsx/workbook/worksheet/selection.rb'
|
|
|
167
200
|
@images = SimpleTypedList.new Pic
|
|
168
201
|
# Are these even used????? Check package serialization parts
|
|
169
202
|
@tables = SimpleTypedList.new Table
|
|
203
|
+
@pivot_tables = SimpleTypedList.new PivotTable
|
|
170
204
|
@comments = SimpleTypedList.new Comments
|
|
171
205
|
|
|
172
206
|
|
|
@@ -201,6 +235,23 @@ require 'axlsx/workbook/worksheet/selection.rb'
|
|
|
201
235
|
# see @use_autowidth
|
|
202
236
|
def use_autowidth=(v=true) Axlsx::validate_boolean v; @use_autowidth = v; end
|
|
203
237
|
|
|
238
|
+
# inserts a worksheet into this workbook at the position specified.
|
|
239
|
+
# It the index specified is out of range, the worksheet will be added to the end of the
|
|
240
|
+
# worksheets collection
|
|
241
|
+
# @return [Worksheet]
|
|
242
|
+
# @param index The zero based position to insert the newly created worksheet
|
|
243
|
+
# @param [Hash] options Options to pass into the worksheed during initialization.
|
|
244
|
+
# @option options [String] name The name of the worksheet
|
|
245
|
+
# @option options [Hash] page_margins The page margins for the worksheet
|
|
246
|
+
def insert_worksheet(index=0, options={})
|
|
247
|
+
worksheet = Worksheet.new(self, options)
|
|
248
|
+
@worksheets.delete_at(@worksheets.size - 1)
|
|
249
|
+
@worksheets.insert(index, worksheet)
|
|
250
|
+
yield worksheet if block_given?
|
|
251
|
+
worksheet
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
#
|
|
204
255
|
# Adds a worksheet to this workbook
|
|
205
256
|
# @return [Worksheet]
|
|
206
257
|
# @option options [String] name The name of the worksheet.
|
|
@@ -225,11 +276,14 @@ require 'axlsx/workbook/worksheet/selection.rb'
|
|
|
225
276
|
def relationships
|
|
226
277
|
r = Relationships.new
|
|
227
278
|
@worksheets.each do |sheet|
|
|
228
|
-
r << Relationship.new(WORKSHEET_R, WORKSHEET_PN % (r.size+1))
|
|
279
|
+
r << Relationship.new(sheet, WORKSHEET_R, WORKSHEET_PN % (r.size+1))
|
|
280
|
+
end
|
|
281
|
+
pivot_tables.each_with_index do |pivot_table, index|
|
|
282
|
+
r << Relationship.new(pivot_table.cache_definition, PIVOT_TABLE_CACHE_DEFINITION_R, PIVOT_TABLE_CACHE_DEFINITION_PN % (index+1))
|
|
229
283
|
end
|
|
230
|
-
r << Relationship.new(STYLES_R, STYLES_PN)
|
|
284
|
+
r << Relationship.new(self, STYLES_R, STYLES_PN)
|
|
231
285
|
if use_shared_strings
|
|
232
|
-
r << Relationship.new(SHARED_STRINGS_R, SHARED_STRINGS_PN)
|
|
286
|
+
r << Relationship.new(self, SHARED_STRINGS_R, SHARED_STRINGS_PN)
|
|
233
287
|
end
|
|
234
288
|
r
|
|
235
289
|
end
|
|
@@ -237,7 +291,25 @@ require 'axlsx/workbook/worksheet/selection.rb'
|
|
|
237
291
|
# generates a shared string object against all cells in all worksheets.
|
|
238
292
|
# @return [SharedStringTable]
|
|
239
293
|
def shared_strings
|
|
240
|
-
SharedStringsTable.new(worksheets.collect { |ws| ws.cells })
|
|
294
|
+
SharedStringsTable.new(worksheets.collect { |ws| ws.cells }, xml_space)
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
# The xml:space attribute for the worksheet.
|
|
298
|
+
# This determines how whitespace is handled withing the document.
|
|
299
|
+
# The most relevant part being whitespace in the cell text.
|
|
300
|
+
# allowed values are :preserve and :default. Axlsx uses :preserve unless
|
|
301
|
+
# you explicily set this to :default.
|
|
302
|
+
# @return Symbol
|
|
303
|
+
def xml_space
|
|
304
|
+
@xml_space ||= :preserve
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
# Sets the xml:space attribute for the worksheet
|
|
308
|
+
# @see Worksheet#xml_space
|
|
309
|
+
# @param [Symbol] space must be one of :preserve or :default
|
|
310
|
+
def xml_space=(space)
|
|
311
|
+
Axlsx::RestrictionValidator.validate(:xml_space, [:preserve, :default], space)
|
|
312
|
+
@xml_space = space;
|
|
241
313
|
end
|
|
242
314
|
|
|
243
315
|
# returns a range of cells in a worksheet
|
|
@@ -268,6 +340,13 @@ require 'axlsx/workbook/worksheet/selection.rb'
|
|
|
268
340
|
end
|
|
269
341
|
str << '</sheets>'
|
|
270
342
|
defined_names.to_xml_string(str)
|
|
343
|
+
unless pivot_tables.empty?
|
|
344
|
+
str << '<pivotCaches>'
|
|
345
|
+
pivot_tables.each do |pivot_table|
|
|
346
|
+
str << '<pivotCache cacheId="' << pivot_table.cache_definition.cache_id.to_s << '" r:id="' << pivot_table.cache_definition.rId << '"/>'
|
|
347
|
+
end
|
|
348
|
+
str << '</pivotCaches>'
|
|
349
|
+
end
|
|
271
350
|
str << '</workbook>'
|
|
272
351
|
end
|
|
273
352
|
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
|
|
2
|
+
require 'axlsx/workbook/worksheet/auto_filter/filter_column.rb'
|
|
3
|
+
require 'axlsx/workbook/worksheet/auto_filter/filters.rb'
|
|
4
|
+
|
|
5
|
+
module Axlsx
|
|
6
|
+
|
|
7
|
+
#This class represents an auto filter range in a worksheet
|
|
8
|
+
class AutoFilter
|
|
9
|
+
|
|
10
|
+
# creates a new Autofilter object
|
|
11
|
+
# @param [Worksheet] worksheet
|
|
12
|
+
def initialize(worksheet)
|
|
13
|
+
raise ArgumentError, 'you must provide a worksheet' unless worksheet.is_a?(Worksheet)
|
|
14
|
+
@worksheet = worksheet
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
attr_reader :worksheet
|
|
18
|
+
|
|
19
|
+
# The range the autofilter should be applied to.
|
|
20
|
+
# This should be a string like 'A1:B8'
|
|
21
|
+
# @return [String]
|
|
22
|
+
attr_accessor :range
|
|
23
|
+
|
|
24
|
+
# the formula for the defined name required for this auto filter
|
|
25
|
+
# This prepends the worksheet name to the absolute cell reference
|
|
26
|
+
# e.g. A1:B2 -> 'Sheet1'!$A$1:$B$2
|
|
27
|
+
# @return [String]
|
|
28
|
+
def defined_name
|
|
29
|
+
return unless range
|
|
30
|
+
Axlsx.cell_range(range.split(':').collect { |name| worksheet.name_to_cell(name)})
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# A collection of filterColumns for this auto_filter
|
|
34
|
+
# @return [SimpleTypedList]
|
|
35
|
+
def columns
|
|
36
|
+
@columns ||= SimpleTypedList.new FilterColumn
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Adds a filter column. This is the recommended way to create and manage filter columns for your autofilter.
|
|
40
|
+
# In addition to the require id and type parameters, options will be passed to the filter column during instantiation.
|
|
41
|
+
# @param [String] col_id Zero-based index indicating the AutoFilter column to which this filter information applies.
|
|
42
|
+
# @param [Symbol] filter_type A symbol representing one of the supported filter types.
|
|
43
|
+
# @param [Hash] options a hash of options to pass into the generated filter
|
|
44
|
+
# @return [FilterColumn]
|
|
45
|
+
def add_column(col_id, filter_type, options = {})
|
|
46
|
+
columns << FilterColumn.new(col_id, filter_type, options)
|
|
47
|
+
columns.last
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# actually performs the filtering of rows who's cells do not
|
|
51
|
+
# match the filter.
|
|
52
|
+
def apply
|
|
53
|
+
first_cell, last_cell = range.split(':')
|
|
54
|
+
start_point = Axlsx::name_to_indices(first_cell)
|
|
55
|
+
end_point = Axlsx::name_to_indices(last_cell)
|
|
56
|
+
# The +1 is so we skip the header row with the filter drop downs
|
|
57
|
+
rows = worksheet.rows[(start_point.last+1)..end_point.last] || []
|
|
58
|
+
|
|
59
|
+
column_offset = start_point.first
|
|
60
|
+
columns.each do |column|
|
|
61
|
+
rows.each do |row|
|
|
62
|
+
next if row.hidden
|
|
63
|
+
column.apply(row, column_offset)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
# serialize the object
|
|
68
|
+
# @return [String]
|
|
69
|
+
def to_xml_string(str='')
|
|
70
|
+
return unless range
|
|
71
|
+
str << "<autoFilter ref='#{range}'>"
|
|
72
|
+
columns.each { |filter_column| filter_column.to_xml_string(str) }
|
|
73
|
+
str << "</autoFilter>"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
module Axlsx
|
|
2
|
+
# The filterColumn collection identifies a particular column in the AutoFilter
|
|
3
|
+
# range and specifies filter information that has been applied to this column.
|
|
4
|
+
# If a column in the AutoFilter range has no criteria specified,
|
|
5
|
+
# then there is no corresponding filterColumn collection expressed for that column.
|
|
6
|
+
class FilterColumn
|
|
7
|
+
|
|
8
|
+
include Axlsx::OptionsParser
|
|
9
|
+
include Axlsx::SerializedAttributes
|
|
10
|
+
|
|
11
|
+
# Creates a new FilterColumn object
|
|
12
|
+
# @note This class yeilds its filter object as that is where the vast majority of processing will be done
|
|
13
|
+
# @param [Integer|Cell] col_id The zero based index for the column to which this filter will be applied
|
|
14
|
+
# @param [Symbol] filter_type The symbolized class name of the filter to apply to this column.
|
|
15
|
+
# @param [Hash] options options for this object and the filter
|
|
16
|
+
# @option [Boolean] hidden_button @see hidden_button
|
|
17
|
+
# @option [Boolean] show_button @see show_button
|
|
18
|
+
def initialize(col_id, filter_type, options = {})
|
|
19
|
+
RestrictionValidator.validate 'FilterColumn.filter', FILTERS, filter_type
|
|
20
|
+
#Axlsx::validate_unsigned_int(col_id)
|
|
21
|
+
self.col_id = col_id
|
|
22
|
+
parse_options options
|
|
23
|
+
@filter = Axlsx.const_get(Axlsx.camel(filter_type)).new(options)
|
|
24
|
+
yield @filter if block_given?
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
serializable_attributes :col_id, :hidden_button, :show_button
|
|
28
|
+
|
|
29
|
+
# Allowed filters
|
|
30
|
+
FILTERS = [:filters] #, :top10, :custom_filters, :dynamic_filters, :color_filters, :icon_filters]
|
|
31
|
+
|
|
32
|
+
# Zero-based index indicating the AutoFilter column to which this filter information applies.
|
|
33
|
+
# @return [Integer]
|
|
34
|
+
attr_reader :col_id
|
|
35
|
+
|
|
36
|
+
# The actual filter being dealt with here
|
|
37
|
+
# This could be any one of the allowed filter types
|
|
38
|
+
attr_reader :filter
|
|
39
|
+
|
|
40
|
+
# Flag indicating whether the filter button is visible.
|
|
41
|
+
# When the cell containing the filter button is merged with another cell,
|
|
42
|
+
# the filter button can be hidden, and not drawn.
|
|
43
|
+
# @return [Boolean]
|
|
44
|
+
def show_button
|
|
45
|
+
@show_button ||= true
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Flag indicating whether the AutoFilter button for this column is hidden.
|
|
49
|
+
# @return [Boolean]
|
|
50
|
+
def hidden_button
|
|
51
|
+
@hidden_button ||= false
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Sets the col_id attribute for this filter column.
|
|
55
|
+
# @param [Integer | Cell] column_index The zero based index of the column to which this filter applies.
|
|
56
|
+
# When you specify a cell, the column index will be read off the cell
|
|
57
|
+
# @return [Integer]
|
|
58
|
+
def col_id=(column_index)
|
|
59
|
+
column_index = column_index.col if column_index.is_a?(Cell)
|
|
60
|
+
Axlsx.validate_unsigned_int column_index
|
|
61
|
+
@col_id = column_index
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Apply the filters for this column
|
|
65
|
+
# @param [Array] row A row from a worksheet that needs to be
|
|
66
|
+
# filtered.
|
|
67
|
+
def apply(row, offset)
|
|
68
|
+
row.hidden = @filter.apply(row.cells[offset+col_id.to_i])
|
|
69
|
+
end
|
|
70
|
+
# @param [Boolean] hidden Flag indicating whether the AutoFilter button for this column is hidden.
|
|
71
|
+
# @return [Boolean]
|
|
72
|
+
def hidden_button=(hidden)
|
|
73
|
+
Axlsx.validate_boolean hidden
|
|
74
|
+
@hidden_button = hidden
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Flag indicating whether the AutoFilter button is show. This is
|
|
78
|
+
# undocumented in the spec, but exists in the schema file as an
|
|
79
|
+
# optional attribute.
|
|
80
|
+
# @param [Boolean] show Show or hide the button
|
|
81
|
+
# @return [Boolean]
|
|
82
|
+
def show_button=(show)
|
|
83
|
+
Axlsx.validate_boolean show
|
|
84
|
+
@show_botton = show
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Serialize the object to xml
|
|
88
|
+
def to_xml_string(str='')
|
|
89
|
+
str << "<filterColumn #{serialized_attributes}>"
|
|
90
|
+
@filter.to_xml_string(str)
|
|
91
|
+
str << "</filterColumn>"
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|