caxlsx 3.3.0 → 4.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 +4 -4
- data/CHANGELOG.md +25 -0
- data/README.md +25 -7
- data/Rakefile +7 -6
- data/lib/axlsx/content_type/abstract_content_type.rb +11 -9
- data/lib/axlsx/content_type/content_type.rb +7 -9
- data/lib/axlsx/content_type/default.rb +4 -6
- data/lib/axlsx/content_type/override.rb +3 -5
- data/lib/axlsx/doc_props/app.rb +27 -30
- data/lib/axlsx/doc_props/core.rb +9 -12
- data/lib/axlsx/drawing/area_chart.rb +13 -14
- data/lib/axlsx/drawing/area_series.rb +13 -14
- data/lib/axlsx/drawing/ax_data_source.rb +3 -6
- data/lib/axlsx/drawing/axes.rb +10 -9
- data/lib/axlsx/drawing/axis.rb +27 -30
- data/lib/axlsx/drawing/bar_3D_chart.rb +17 -18
- data/lib/axlsx/drawing/bar_chart.rb +16 -17
- data/lib/axlsx/drawing/bar_series.rb +9 -13
- data/lib/axlsx/drawing/bubble_chart.rb +8 -9
- data/lib/axlsx/drawing/bubble_series.rb +9 -10
- data/lib/axlsx/drawing/cat_axis.rb +14 -17
- data/lib/axlsx/drawing/chart.rb +25 -28
- data/lib/axlsx/drawing/d_lbls.rb +29 -26
- data/lib/axlsx/drawing/drawing.rb +60 -62
- data/lib/axlsx/drawing/graphic_frame.rb +6 -7
- data/lib/axlsx/drawing/hyperlink.rb +12 -13
- data/lib/axlsx/drawing/line_3D_chart.rb +13 -15
- data/lib/axlsx/drawing/line_chart.rb +13 -14
- data/lib/axlsx/drawing/line_series.rb +13 -14
- data/lib/axlsx/drawing/marker.rb +14 -16
- data/lib/axlsx/drawing/num_data.rb +13 -16
- data/lib/axlsx/drawing/num_data_source.rb +11 -13
- data/lib/axlsx/drawing/num_val.rb +9 -10
- data/lib/axlsx/drawing/one_cell_anchor.rb +10 -10
- data/lib/axlsx/drawing/pic.rb +57 -22
- data/lib/axlsx/drawing/picture_locking.rb +6 -7
- data/lib/axlsx/drawing/pie_3D_chart.rb +6 -9
- data/lib/axlsx/drawing/pie_series.rb +9 -12
- data/lib/axlsx/drawing/scaling.rb +9 -10
- data/lib/axlsx/drawing/scatter_chart.rb +9 -10
- data/lib/axlsx/drawing/scatter_series.rb +15 -16
- data/lib/axlsx/drawing/ser_axis.rb +9 -11
- data/lib/axlsx/drawing/series.rb +8 -8
- data/lib/axlsx/drawing/series_title.rb +6 -6
- data/lib/axlsx/drawing/str_data.rb +10 -13
- data/lib/axlsx/drawing/str_val.rb +8 -9
- data/lib/axlsx/drawing/title.rb +23 -27
- data/lib/axlsx/drawing/two_cell_anchor.rb +8 -8
- data/lib/axlsx/drawing/val_axis.rb +5 -6
- data/lib/axlsx/drawing/view_3D.rb +32 -30
- data/lib/axlsx/drawing/vml_drawing.rb +19 -20
- data/lib/axlsx/drawing/vml_shape.rb +25 -26
- data/lib/axlsx/package.rb +81 -79
- data/lib/axlsx/rels/relationship.rb +30 -28
- data/lib/axlsx/rels/relationships.rb +7 -8
- data/lib/axlsx/stylesheet/border.rb +7 -8
- data/lib/axlsx/stylesheet/border_pr.rb +8 -8
- data/lib/axlsx/stylesheet/cell_alignment.rb +14 -20
- data/lib/axlsx/stylesheet/cell_protection.rb +6 -7
- data/lib/axlsx/stylesheet/cell_style.rb +12 -14
- data/lib/axlsx/stylesheet/color.rb +15 -12
- data/lib/axlsx/stylesheet/dxf.rb +7 -9
- data/lib/axlsx/stylesheet/fill.rb +3 -5
- data/lib/axlsx/stylesheet/font.rb +24 -21
- data/lib/axlsx/stylesheet/gradient_fill.rb +9 -9
- data/lib/axlsx/stylesheet/gradient_stop.rb +7 -6
- data/lib/axlsx/stylesheet/num_fmt.rb +9 -14
- data/lib/axlsx/stylesheet/pattern_fill.rb +8 -8
- data/lib/axlsx/stylesheet/styles.rb +104 -98
- data/lib/axlsx/stylesheet/table_style.rb +8 -9
- data/lib/axlsx/stylesheet/table_style_element.rb +7 -8
- data/lib/axlsx/stylesheet/table_styles.rb +8 -10
- data/lib/axlsx/stylesheet/xf.rb +21 -22
- data/lib/axlsx/util/accessors.rb +6 -6
- data/lib/axlsx/util/buffered_zip_output_stream.rb +60 -0
- data/lib/axlsx/util/constants.rb +119 -108
- data/lib/axlsx/util/mime_type_utils.rb +11 -0
- data/lib/axlsx/util/options_parser.rb +4 -3
- data/lib/axlsx/util/serialized_attributes.rb +45 -21
- data/lib/axlsx/util/simple_typed_list.rb +58 -57
- data/lib/axlsx/util/storage.rb +38 -41
- data/lib/axlsx/util/validators.rb +107 -44
- data/lib/axlsx/util/zip_command.rb +10 -12
- data/lib/axlsx/version.rb +3 -2
- data/lib/axlsx/workbook/defined_name.rb +11 -8
- data/lib/axlsx/workbook/defined_names.rb +4 -3
- data/lib/axlsx/workbook/shared_strings_table.rb +10 -11
- data/lib/axlsx/workbook/workbook.rb +121 -114
- data/lib/axlsx/workbook/workbook_view.rb +8 -11
- data/lib/axlsx/workbook/workbook_views.rb +4 -4
- data/lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb +72 -14
- data/lib/axlsx/workbook/worksheet/auto_filter/filter_column.rb +11 -7
- data/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +24 -21
- data/lib/axlsx/workbook/worksheet/auto_filter/sort_condition.rb +51 -0
- data/lib/axlsx/workbook/worksheet/auto_filter/sort_state.rb +56 -0
- data/lib/axlsx/workbook/worksheet/border_creator.rb +30 -25
- data/lib/axlsx/workbook/worksheet/break.rb +4 -5
- data/lib/axlsx/workbook/worksheet/cell.rb +92 -65
- data/lib/axlsx/workbook/worksheet/cell_serializer.rb +32 -28
- data/lib/axlsx/workbook/worksheet/cfvo.rb +7 -5
- data/lib/axlsx/workbook/worksheet/cfvos.rb +5 -5
- data/lib/axlsx/workbook/worksheet/col.rb +9 -10
- data/lib/axlsx/workbook/worksheet/col_breaks.rb +8 -7
- data/lib/axlsx/workbook/worksheet/color_scale.rb +16 -16
- data/lib/axlsx/workbook/worksheet/cols.rb +9 -7
- data/lib/axlsx/workbook/worksheet/comment.rb +12 -11
- data/lib/axlsx/workbook/worksheet/comments.rb +10 -12
- data/lib/axlsx/workbook/worksheet/conditional_formatting.rb +12 -8
- data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +19 -21
- data/lib/axlsx/workbook/worksheet/conditional_formattings.rb +5 -5
- data/lib/axlsx/workbook/worksheet/data_bar.rb +29 -30
- data/lib/axlsx/workbook/worksheet/data_validation.rb +34 -33
- data/lib/axlsx/workbook/worksheet/data_validations.rb +5 -6
- data/lib/axlsx/workbook/worksheet/date_time_converter.rb +8 -8
- data/lib/axlsx/workbook/worksheet/dimension.rb +9 -6
- data/lib/axlsx/workbook/worksheet/header_footer.rb +4 -3
- data/lib/axlsx/workbook/worksheet/icon_set.rb +24 -8
- data/lib/axlsx/workbook/worksheet/merged_cells.rb +10 -10
- data/lib/axlsx/workbook/worksheet/outline_pr.rb +6 -3
- data/lib/axlsx/workbook/worksheet/page_margins.rb +17 -12
- data/lib/axlsx/workbook/worksheet/page_set_up_pr.rb +6 -4
- data/lib/axlsx/workbook/worksheet/page_setup.rb +128 -129
- data/lib/axlsx/workbook/worksheet/pane.rb +27 -26
- data/lib/axlsx/workbook/worksheet/pivot_table.rb +23 -25
- data/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +12 -13
- data/lib/axlsx/workbook/worksheet/pivot_tables.rb +5 -4
- data/lib/axlsx/workbook/worksheet/print_options.rb +3 -2
- data/lib/axlsx/workbook/worksheet/protected_range.rb +6 -5
- data/lib/axlsx/workbook/worksheet/protected_ranges.rb +12 -10
- data/lib/axlsx/workbook/worksheet/rich_text.rb +6 -6
- data/lib/axlsx/workbook/worksheet/rich_text_run.rb +35 -17
- data/lib/axlsx/workbook/worksheet/row.rb +30 -22
- data/lib/axlsx/workbook/worksheet/row_breaks.rb +8 -7
- data/lib/axlsx/workbook/worksheet/selection.rb +16 -16
- data/lib/axlsx/workbook/worksheet/sheet_calc_pr.rb +10 -7
- data/lib/axlsx/workbook/worksheet/sheet_data.rb +7 -7
- data/lib/axlsx/workbook/worksheet/sheet_format_pr.rb +23 -19
- data/lib/axlsx/workbook/worksheet/sheet_pr.rb +11 -7
- data/lib/axlsx/workbook/worksheet/sheet_protection.rb +21 -20
- data/lib/axlsx/workbook/worksheet/sheet_view.rb +48 -53
- data/lib/axlsx/workbook/worksheet/table.rb +13 -13
- data/lib/axlsx/workbook/worksheet/table_style_info.rb +6 -5
- data/lib/axlsx/workbook/worksheet/tables.rb +7 -5
- data/lib/axlsx/workbook/worksheet/worksheet.rb +92 -63
- data/lib/axlsx/workbook/worksheet/worksheet_comments.rb +10 -8
- data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +11 -4
- data/lib/axlsx/workbook/worksheet/worksheet_hyperlink.rb +9 -8
- data/lib/axlsx/workbook/worksheet/worksheet_hyperlinks.rb +7 -5
- data/lib/axlsx.rb +75 -47
- data/lib/caxlsx.rb +3 -2
- metadata +50 -44
@@ -1,4 +1,5 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Axlsx
|
3
4
|
# Validate a value against a specific list of allowed values.
|
4
5
|
class RestrictionValidator
|
@@ -9,7 +10,8 @@ module Axlsx
|
|
9
10
|
# @raise [ArgumentError] Raised if the value provided is not in the list of choices.
|
10
11
|
# @return [Boolean] true if validation succeeds.
|
11
12
|
def self.validate(name, choices, v)
|
12
|
-
raise ArgumentError, (ERR_RESTRICTION
|
13
|
+
raise ArgumentError, format(ERR_RESTRICTION, v.to_s, name, choices.inspect) unless choices.include?(v)
|
14
|
+
|
13
15
|
true
|
14
16
|
end
|
15
17
|
end
|
@@ -29,16 +31,17 @@ module Axlsx
|
|
29
31
|
else
|
30
32
|
min < value && value < max
|
31
33
|
end
|
32
|
-
raise ArgumentError, (ERR_RANGE
|
34
|
+
raise ArgumentError, format(ERR_RANGE, value.inspect, min.to_s, max.to_s, inclusive) unless passes
|
33
35
|
end
|
34
36
|
end
|
37
|
+
|
35
38
|
# Validates the value against the regular expression provided.
|
36
39
|
class RegexValidator
|
37
40
|
# @param [String] name The name of what is being validated. This is included in the output when the value is invalid
|
38
41
|
# @param [Regexp] regex The regular expression to evaluate
|
39
42
|
# @param [Any] v The value to validate.
|
40
43
|
def self.validate(name, regex, v)
|
41
|
-
raise ArgumentError, (ERR_REGEX
|
44
|
+
raise ArgumentError, format(ERR_REGEX, v.inspect, regex.to_s) unless v.respond_to?(:to_s) && regex.match?(v.to_s)
|
42
45
|
end
|
43
46
|
end
|
44
47
|
|
@@ -51,24 +54,23 @@ module Axlsx
|
|
51
54
|
# @raise [ArugumentError] Raised if the class of the value provided is not in the specified array of types or the block passed returns false
|
52
55
|
# @return [Boolean] true if validation succeeds.
|
53
56
|
# @see validate_boolean
|
54
|
-
def self.validate(name, types, v, other=false)
|
55
|
-
if other.is_a?(Proc)
|
56
|
-
|
57
|
+
def self.validate(name, types, v, other = false)
|
58
|
+
if other.is_a?(Proc) && !other.call(v)
|
59
|
+
raise ArgumentError, format(ERR_TYPE, v.inspect, name, types.inspect)
|
57
60
|
end
|
61
|
+
|
58
62
|
v_class = v.is_a?(Class) ? v : v.class
|
59
|
-
Array(types).
|
60
|
-
|
61
|
-
|
62
|
-
raise ArgumentError, (ERR_TYPE % [v.inspect, name, types.inspect])
|
63
|
+
return if Array(types).any? { |t| v_class <= t }
|
64
|
+
|
65
|
+
raise ArgumentError, format(ERR_TYPE, v.inspect, name, types.inspect)
|
63
66
|
end
|
64
67
|
end
|
65
68
|
|
66
|
-
|
67
69
|
# Requires that the value can be converted to an integer
|
68
70
|
# @para, [Any] v the value to validate
|
69
71
|
# @raise [ArgumentError] raised if the value cannot be converted to an integer
|
70
72
|
def self.validate_integerish(v)
|
71
|
-
raise ArgumentError, (ERR_INTEGERISH
|
73
|
+
raise ArgumentError, format(ERR_INTEGERISH, v.inspect) unless v.respond_to?(:to_i) && v.to_i.is_a?(Integer)
|
72
74
|
end
|
73
75
|
|
74
76
|
# Requires that the value is between -54000000 and 54000000
|
@@ -76,11 +78,11 @@ module Axlsx
|
|
76
78
|
# @raise [ArgumentError] raised if the value cannot be converted to an integer between the allowed angle values for chart label rotation.
|
77
79
|
# @return [Boolean] true if the data is valid
|
78
80
|
def self.validate_angle(v)
|
79
|
-
raise ArgumentError, (ERR_ANGLE
|
81
|
+
raise ArgumentError, format(ERR_ANGLE, v.inspect) unless v.to_i >= -5400000 && v.to_i <= 5400000
|
80
82
|
end
|
81
83
|
|
82
84
|
# Validates an unsigned intger
|
83
|
-
UINT_VALIDATOR =
|
85
|
+
UINT_VALIDATOR = ->(arg) { arg.respond_to?(:>=) && arg >= 0 }
|
84
86
|
|
85
87
|
# Requires that the value is a Integer and is greater or equal to 0
|
86
88
|
# @param [Any] v The value validated
|
@@ -104,12 +106,16 @@ module Axlsx
|
|
104
106
|
DataTypeValidator.validate :signed_int, Integer, v
|
105
107
|
end
|
106
108
|
|
109
|
+
VALID_BOOLEAN_CLASSES = [TrueClass, FalseClass, Integer, String, Symbol].freeze
|
110
|
+
VALID_BOOLEAN_VALUES = [true, false, 1, 0, '1', '0', 'true', 'false', :true, :false].freeze
|
111
|
+
BOOLEAN_VALIDATOR = ->(arg) { VALID_BOOLEAN_VALUES.include?(arg) }
|
112
|
+
|
107
113
|
# Requires that the value is a form that can be evaluated as a boolean in an xml document.
|
108
114
|
# The value must be an instance of String, Integer, Symbol, TrueClass or FalseClass and
|
109
115
|
# it must be one of 0, 1, "true", "false", :true, :false, true, false, "0", or "1"
|
110
116
|
# @param [Any] v The value validated
|
111
117
|
def self.validate_boolean(v)
|
112
|
-
DataTypeValidator.validate(:boolean,
|
118
|
+
DataTypeValidator.validate(:boolean, VALID_BOOLEAN_CLASSES, v, BOOLEAN_VALIDATOR)
|
113
119
|
end
|
114
120
|
|
115
121
|
# Requires that the value is a String
|
@@ -130,51 +136,71 @@ module Axlsx
|
|
130
136
|
RegexValidator.validate "number_with_unit", /\A[0-9]+(\.[0-9]+)?(mm|cm|in|pt|pc|pi)\Z/, v
|
131
137
|
end
|
132
138
|
|
139
|
+
SCALE_10_400_VALIDATOR = ->(arg) { arg >= 10 && arg <= 400 }
|
140
|
+
|
133
141
|
# Requires that the value is an integer ranging from 10 to 400.
|
134
142
|
def self.validate_scale_10_400(v)
|
135
|
-
DataTypeValidator.validate "page_scale", Integer, v,
|
143
|
+
DataTypeValidator.validate "page_scale", Integer, v, SCALE_10_400_VALIDATOR
|
136
144
|
end
|
137
145
|
|
146
|
+
SCALE_0_10_400_VALIDATOR = ->(arg) { arg == 0 || (arg >= 10 && arg <= 400) }
|
147
|
+
|
138
148
|
# Requires that the value is an integer ranging from 10 to 400 or 0.
|
139
149
|
def self.validate_scale_0_10_400(v)
|
140
|
-
DataTypeValidator.validate "page_scale", Integer, v,
|
150
|
+
DataTypeValidator.validate "page_scale", Integer, v, SCALE_0_10_400_VALIDATOR
|
141
151
|
end
|
142
152
|
|
153
|
+
VALID_PAGE_ORIENTATION_VALUES = [:default, :landscape, :portrait].freeze
|
154
|
+
|
143
155
|
# Requires that the value is one of :default, :landscape, or :portrait.
|
144
156
|
def self.validate_page_orientation(v)
|
145
|
-
RestrictionValidator.validate "page_orientation",
|
157
|
+
RestrictionValidator.validate "page_orientation", VALID_PAGE_ORIENTATION_VALUES, v
|
146
158
|
end
|
159
|
+
|
160
|
+
VALID_CELL_U_VALUES = [:none, :single, :double, :singleAccounting, :doubleAccounting].freeze
|
161
|
+
|
147
162
|
# Requires that the value is one of :none, :single, :double, :singleAccounting, :doubleAccounting
|
148
163
|
def self.validate_cell_u(v)
|
149
|
-
RestrictionValidator.validate "cell run style u",
|
164
|
+
RestrictionValidator.validate "cell run style u", VALID_CELL_U_VALUES, v
|
150
165
|
end
|
151
166
|
|
167
|
+
VALID_FAMILY_VALUES = (1..5).freeze
|
168
|
+
|
152
169
|
# validates cell style family which must be between 1 and 5
|
153
170
|
def self.validate_family(v)
|
154
|
-
RestrictionValidator.validate "cell run style family",
|
171
|
+
RestrictionValidator.validate "cell run style family", VALID_FAMILY_VALUES, v
|
155
172
|
end
|
173
|
+
|
174
|
+
VALID_PATTERN_TYPE_VALUES = [:none, :solid, :mediumGray, :darkGray, :lightGray, :darkHorizontal, :darkVertical, :darkDown, :darkUp, :darkGrid,
|
175
|
+
:darkTrellis, :lightHorizontal, :lightVertical, :lightDown, :lightUp, :lightGrid, :lightTrellis, :gray125, :gray0625].freeze
|
176
|
+
|
156
177
|
# Requires that the value is valid pattern type.
|
157
178
|
# valid pattern types must be one of :none, :solid, :mediumGray, :darkGray, :lightGray, :darkHorizontal, :darkVertical, :darkDown,
|
158
179
|
# :darkUp, :darkGrid, :darkTrellis, :lightHorizontal, :lightVertical, :lightDown, :lightUp, :lightGrid, :lightTrellis, :gray125, or :gray0625.
|
159
180
|
# @param [Any] v The value validated
|
160
181
|
def self.validate_pattern_type(v)
|
161
|
-
RestrictionValidator.validate :pattern_type,
|
162
|
-
:darkTrellis, :lightHorizontal, :lightVertical, :lightDown, :lightUp, :lightGrid, :lightTrellis, :gray125, :gray0625], v
|
182
|
+
RestrictionValidator.validate :pattern_type, VALID_PATTERN_TYPE_VALUES, v
|
163
183
|
end
|
164
184
|
|
185
|
+
VALID_TIME_PERIOD_TYPE_VALUES = [:today, :yesterday, :tomorrow, :last7Days, :thisMonth, :lastMonth, :nextMonth, :thisWeek, :lastWeek, :nextWeek].freeze
|
186
|
+
|
165
187
|
# Requires that the value is one of the ST_TimePeriod types
|
166
188
|
# valid time period types are today, yesterday, tomorrow, last7Days,
|
167
189
|
# thisMonth, lastMonth, nextMonth, thisWeek, lastWeek, nextWeek
|
168
190
|
def self.validate_time_period_type(v)
|
169
|
-
RestrictionValidator.validate :time_period_type,
|
191
|
+
RestrictionValidator.validate :time_period_type, VALID_TIME_PERIOD_TYPE_VALUES, v
|
170
192
|
end
|
171
193
|
|
194
|
+
VALID_ICON_SET_VALUES = ["3Arrows", "3ArrowsGray", "3Flags", "3TrafficLights1", "3TrafficLights2", "3Signs", "3Symbols", "3Symbols2", "4Arrows", "4ArrowsGray", "4RedToBlack", "4Rating", "4TrafficLights", "5Arrows", "5ArrowsGray", "5Rating", "5Quarters"].freeze
|
195
|
+
|
172
196
|
# Requires that the value is one of the valid ST_IconSet types
|
173
197
|
# Allowed values are: 3Arrows, 3ArrowsGray, 3Flags, 3TrafficLights1, 3TrafficLights2, 3Signs, 3Symbols, 3Symbols2, 4Arrows, 4ArrowsGray, 4RedToBlack, 4Rating, 4TrafficLights, 5Arrows, 5ArrowsGray, 5Rating, 5Quarters
|
174
198
|
def self.validate_icon_set(v)
|
175
|
-
RestrictionValidator.validate :iconSet,
|
199
|
+
RestrictionValidator.validate :iconSet, VALID_ICON_SET_VALUES, v
|
176
200
|
end
|
177
201
|
|
202
|
+
VALID_CONDITIONAL_FORMATTING_TYPE_VALUES = [:expression, :cellIs, :colorScale, :dataBar, :iconSet, :top10, :uniqueValues, :duplicateValues, :containsText, :notContainsText, :beginsWith, :endsWith, :containsBlanks, :notContainsBlanks, :containsErrors, :notContainsErrors, :timePeriod, :aboveAverage].freeze
|
203
|
+
|
178
204
|
# Requires that the value is valid conditional formatting type.
|
179
205
|
# valid types must be one of expression, cellIs, colorScale,
|
180
206
|
# dataBar, iconSet, top10, uniqueValues, duplicateValues,
|
@@ -183,130 +209,167 @@ module Axlsx
|
|
183
209
|
# notContainsErrors, timePeriod, aboveAverage
|
184
210
|
# @param [Any] v The value validated
|
185
211
|
def self.validate_conditional_formatting_type(v)
|
186
|
-
RestrictionValidator.validate :conditional_formatting_type,
|
212
|
+
RestrictionValidator.validate :conditional_formatting_type, VALID_CONDITIONAL_FORMATTING_TYPE_VALUES, v
|
187
213
|
end
|
188
214
|
|
215
|
+
VALID_CONDITION_FORMATTING_VALUE_OBJECT_TYPE_VALUES = [:num, :percent, :max, :min, :formula, :percentile].freeze
|
216
|
+
|
189
217
|
# Requires thatt he value is a valid conditional formatting value object type.
|
190
218
|
# valid types must be one of num, percent, max, min, formula and percentile
|
191
219
|
def self.validate_conditional_formatting_value_object_type(v)
|
192
|
-
RestrictionValidator.validate :conditional_formatting_value_object_type,
|
220
|
+
RestrictionValidator.validate :conditional_formatting_value_object_type, VALID_CONDITION_FORMATTING_VALUE_OBJECT_TYPE_VALUES, v
|
193
221
|
end
|
194
222
|
|
223
|
+
VALID_CONDITIONAL_FORMATTING_OPERATOR_VALUES = [:lessThan, :lessThanOrEqual, :equal, :notEqual, :greaterThanOrEqual, :greaterThan, :between, :notBetween, :containsText, :notContains, :beginsWith, :endsWith].freeze
|
224
|
+
|
195
225
|
# Requires that the value is valid conditional formatting operator.
|
196
226
|
# valid operators must be one of lessThan, lessThanOrEqual, equal,
|
197
227
|
# notEqual, greaterThanOrEqual, greaterThan, between, notBetween,
|
198
228
|
# containsText, notContains, beginsWith, endsWith
|
199
229
|
# @param [Any] v The value validated
|
200
230
|
def self.validate_conditional_formatting_operator(v)
|
201
|
-
RestrictionValidator.validate :conditional_formatting_type,
|
231
|
+
RestrictionValidator.validate :conditional_formatting_type, VALID_CONDITIONAL_FORMATTING_OPERATOR_VALUES, v
|
202
232
|
end
|
203
233
|
|
234
|
+
VALID_GRADIENT_TYPE_VALUES = [:linear, :path].freeze
|
235
|
+
|
204
236
|
# Requires that the value is a gradient_type.
|
205
237
|
# valid types are :linear and :path
|
206
238
|
# @param [Any] v The value validated
|
207
239
|
def self.validate_gradient_type(v)
|
208
|
-
RestrictionValidator.validate :gradient_type,
|
240
|
+
RestrictionValidator.validate :gradient_type, VALID_GRADIENT_TYPE_VALUES, v
|
209
241
|
end
|
210
242
|
|
243
|
+
VALID_SCATTER_STYLE_VALUES = [:none, :line, :lineMarker, :marker, :smooth, :smoothMarker].freeze
|
244
|
+
|
211
245
|
# Requires that the value is a valid scatterStyle
|
212
246
|
# must be one of :none | :line | :lineMarker | :marker | :smooth | :smoothMarker
|
213
247
|
# must be one of "none" | "line" | "lineMarker" | "marker" | "smooth" | "smoothMarker"
|
214
248
|
# @param [Symbol|String] v the value to validate
|
215
249
|
def self.validate_scatter_style(v)
|
216
|
-
Axlsx::RestrictionValidator.validate "ScatterChart.scatterStyle",
|
250
|
+
Axlsx::RestrictionValidator.validate "ScatterChart.scatterStyle", VALID_SCATTER_STYLE_VALUES, v.to_sym
|
217
251
|
end
|
252
|
+
|
253
|
+
VALID_HORIZONTAL_ALIGNMENT_VALUES = [:general, :left, :center, :right, :fill, :justify, :centerContinuous, :distributed].freeze
|
254
|
+
|
218
255
|
# Requires that the value is a valid horizontal_alignment
|
219
256
|
# :general, :left, :center, :right, :fill, :justify, :centerContinuous, :distributed are allowed
|
220
257
|
# @param [Any] v The value validated
|
221
258
|
def self.validate_horizontal_alignment(v)
|
222
|
-
RestrictionValidator.validate :horizontal_alignment,
|
259
|
+
RestrictionValidator.validate :horizontal_alignment, VALID_HORIZONTAL_ALIGNMENT_VALUES, v
|
223
260
|
end
|
224
261
|
|
262
|
+
VALID_VERTICAL_ALIGNMENT_VALUES = [:top, :center, :bottom, :justify, :distributed].freeze
|
263
|
+
|
225
264
|
# Requires that the value is a valid vertical_alignment
|
226
265
|
# :top, :center, :bottom, :justify, :distributed are allowed
|
227
266
|
# @param [Any] v The value validated
|
228
267
|
def self.validate_vertical_alignment(v)
|
229
|
-
RestrictionValidator.validate :vertical_alignment,
|
268
|
+
RestrictionValidator.validate :vertical_alignment, VALID_VERTICAL_ALIGNMENT_VALUES, v
|
230
269
|
end
|
231
270
|
|
271
|
+
VALID_CONTENT_TYPE_VALUES = [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].freeze
|
272
|
+
|
232
273
|
# Requires that the value is a valid content_type
|
233
274
|
# 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
|
234
275
|
# @param [Any] v The value validated
|
235
276
|
def self.validate_content_type(v)
|
236
|
-
RestrictionValidator.validate :content_type,
|
277
|
+
RestrictionValidator.validate :content_type, VALID_CONTENT_TYPE_VALUES, v
|
237
278
|
end
|
238
279
|
|
280
|
+
VALID_RELATIONSHIP_TYPE_VALUES = [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].freeze
|
281
|
+
|
239
282
|
# Requires that the value is a valid relationship_type
|
240
283
|
# 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
|
241
284
|
# @param [Any] v The value validated
|
242
285
|
def self.validate_relationship_type(v)
|
243
|
-
RestrictionValidator.validate :relationship_type,
|
286
|
+
RestrictionValidator.validate :relationship_type, VALID_RELATIONSHIP_TYPE_VALUES, v
|
244
287
|
end
|
245
288
|
|
289
|
+
VALID_TABLE_ELEMENT_TYPE_VALUES = [:wholeTable, :headerRow, :totalRow, :firstColumn, :lastColumn, :firstRowStripe, :secondRowStripe, :firstColumnStripe, :secondColumnStripe, :firstHeaderCell, :lastHeaderCell, :firstTotalCell, :lastTotalCell, :firstSubtotalColumn, :secondSubtotalColumn, :thirdSubtotalColumn, :firstSubtotalRow, :secondSubtotalRow, :thirdSubtotalRow, :blankRow, :firstColumnSubheading, :secondColumnSubheading, :thirdColumnSubheading, :firstRowSubheading, :secondRowSubheading, :thirdRowSubheading, :pageFieldLabels, :pageFieldValues].freeze
|
290
|
+
|
246
291
|
# Requires that the value is a valid table element type
|
247
292
|
# :wholeTable, :headerRow, :totalRow, :firstColumn, :lastColumn, :firstRowStripe, :secondRowStripe, :firstColumnStripe, :secondColumnStripe, :firstHeaderCell, :lastHeaderCell, :firstTotalCell, :lastTotalCell, :firstSubtotalColumn, :secondSubtotalColumn, :thirdSubtotalColumn, :firstSubtotalRow, :secondSubtotalRow, :thirdSubtotalRow, :blankRow, :firstColumnSubheading, :secondColumnSubheading, :thirdColumnSubheading, :firstRowSubheading, :secondRowSubheading, :thirdRowSubheading, :pageFieldLabels, :pageFieldValues are allowed
|
248
293
|
# @param [Any] v The value validated
|
249
294
|
def self.validate_table_element_type(v)
|
250
|
-
RestrictionValidator.validate :table_element_type,
|
295
|
+
RestrictionValidator.validate :table_element_type, VALID_TABLE_ELEMENT_TYPE_VALUES, v
|
251
296
|
end
|
252
297
|
|
298
|
+
VALID_DATA_VALIDATION_ERROR_STYLE_VALUES = [:information, :stop, :warning].freeze
|
299
|
+
|
253
300
|
# Requires that the value is a valid data_validation_error_style
|
254
301
|
# :information, :stop, :warning
|
255
302
|
# @param [Any] v The value validated
|
256
303
|
def self.validate_data_validation_error_style(v)
|
257
|
-
RestrictionValidator.validate :validate_data_validation_error_style,
|
304
|
+
RestrictionValidator.validate :validate_data_validation_error_style, VALID_DATA_VALIDATION_ERROR_STYLE_VALUES, v
|
258
305
|
end
|
259
306
|
|
307
|
+
VALID_DATA_VALIDATION_OPERATOR_VALUES = [:lessThan, :lessThanOrEqual, :equal, :notEqual, :greaterThanOrEqual, :greaterThan, :between, :notBetween].freeze
|
308
|
+
|
260
309
|
# Requires that the value is valid data validation operator.
|
261
310
|
# valid operators must be one of lessThan, lessThanOrEqual, equal,
|
262
311
|
# notEqual, greaterThanOrEqual, greaterThan, between, notBetween
|
263
312
|
# @param [Any] v The value validated
|
264
313
|
def self.validate_data_validation_operator(v)
|
265
|
-
RestrictionValidator.validate :data_validation_operator,
|
314
|
+
RestrictionValidator.validate :data_validation_operator, VALID_DATA_VALIDATION_OPERATOR_VALUES, v
|
266
315
|
end
|
267
316
|
|
317
|
+
VALID_DATA_VALIDATION_TYPE_VALUES = [:custom, :data, :decimal, :list, :none, :textLength, :date, :time, :whole].freeze
|
318
|
+
|
268
319
|
# Requires that the value is valid data validation type.
|
269
320
|
# valid types must be one of custom, data, decimal, list, none, textLength, time, whole
|
270
321
|
# @param [Any] v The value validated
|
271
322
|
def self.validate_data_validation_type(v)
|
272
|
-
RestrictionValidator.validate :data_validation_type,
|
323
|
+
RestrictionValidator.validate :data_validation_type, VALID_DATA_VALIDATION_TYPE_VALUES, v
|
273
324
|
end
|
274
325
|
|
326
|
+
VALID_SHEET_VIEW_TYPE_VALUES = [:normal, :page_break_preview, :page_layout].freeze
|
327
|
+
|
275
328
|
# Requires that the value is a valid sheet view type.
|
276
329
|
# valid types must be one of normal, page_break_preview, page_layout
|
277
330
|
# @param [Any] v The value validated
|
278
331
|
def self.validate_sheet_view_type(v)
|
279
|
-
RestrictionValidator.validate :sheet_view_type,
|
332
|
+
RestrictionValidator.validate :sheet_view_type, VALID_SHEET_VIEW_TYPE_VALUES, v
|
280
333
|
end
|
281
334
|
|
335
|
+
VALID_PANE_TYPE_VALUES = [:bottom_left, :bottom_right, :top_left, :top_right].freeze
|
336
|
+
|
282
337
|
# Requires that the value is a valid active pane type.
|
283
338
|
# valid types must be one of bottom_left, bottom_right, top_left, top_right
|
284
339
|
# @param [Any] v The value validated
|
285
340
|
def self.validate_pane_type(v)
|
286
|
-
RestrictionValidator.validate :active_pane_type,
|
341
|
+
RestrictionValidator.validate :active_pane_type, VALID_PANE_TYPE_VALUES, v
|
287
342
|
end
|
288
343
|
|
344
|
+
VALID_SPLIT_STATE_TYPE_VALUES = [:frozen, :frozen_split, :split].freeze
|
345
|
+
|
289
346
|
# Requires that the value is a valid split state type.
|
290
347
|
# valid types must be one of frozen, frozen_split, split
|
291
348
|
# @param [Any] v The value validated
|
292
349
|
def self.validate_split_state_type(v)
|
293
|
-
RestrictionValidator.validate :split_state_type,
|
350
|
+
RestrictionValidator.validate :split_state_type, VALID_SPLIT_STATE_TYPE_VALUES, v
|
294
351
|
end
|
295
352
|
|
353
|
+
VALID_DISPLAY_BLANK_AS_VALUES = [:gap, :span, :zero].freeze
|
354
|
+
|
296
355
|
# Requires that the value is a valid "display blanks as" type.
|
297
356
|
# valid types must be one of gap, span, zero
|
298
357
|
# @param [Any] v The value validated
|
299
358
|
def self.validate_display_blanks_as(v)
|
300
|
-
RestrictionValidator.validate :display_blanks_as,
|
359
|
+
RestrictionValidator.validate :display_blanks_as, VALID_DISPLAY_BLANK_AS_VALUES, v
|
301
360
|
end
|
302
361
|
|
362
|
+
VALID_VIEW_VISIBILITY_VALUES = [:visible, :hidden, :very_hidden].freeze
|
363
|
+
|
303
364
|
# Requires that the value is one of :visible, :hidden, :very_hidden
|
304
365
|
def self.validate_view_visibility(v)
|
305
|
-
RestrictionValidator.validate :visibility,
|
366
|
+
RestrictionValidator.validate :visibility, VALID_VIEW_VISIBILITY_VALUES, v
|
306
367
|
end
|
307
368
|
|
369
|
+
VALID_MARKER_SYMBOL_VALUES = [:default, :circle, :dash, :diamond, :dot, :picture, :plus, :square, :star, :triangle, :x].freeze
|
370
|
+
|
308
371
|
# Requires that the value is one of :default, :circle, :dash, :diamond, :dot, :picture, :plus, :square, :star, :triangle, :x
|
309
372
|
def self.validate_marker_symbol(v)
|
310
|
-
RestrictionValidator.validate :marker_symbol,
|
373
|
+
RestrictionValidator.validate :marker_symbol, VALID_MARKER_SYMBOL_VALUES, v
|
311
374
|
end
|
312
375
|
end
|
@@ -1,9 +1,9 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'open3'
|
3
4
|
require 'shellwords'
|
4
5
|
|
5
6
|
module Axlsx
|
6
|
-
|
7
7
|
# The ZipCommand class supports zipping the Excel file contents using
|
8
8
|
# a binary zip program instead of RubyZip's `Zip::OutputStream`.
|
9
9
|
#
|
@@ -25,10 +25,10 @@ module Axlsx
|
|
25
25
|
# Create a temporary directory for writing files to.
|
26
26
|
#
|
27
27
|
# The directory and its contents are removed at the end of the block.
|
28
|
-
def open(output
|
28
|
+
def open(output)
|
29
29
|
Dir.mktmpdir do |dir|
|
30
30
|
@dir = dir
|
31
|
-
|
31
|
+
yield(self)
|
32
32
|
write_file
|
33
33
|
zip_parts(output)
|
34
34
|
end
|
@@ -40,23 +40,21 @@ module Axlsx
|
|
40
40
|
@current_file = "#{@dir}/#{entry.name}"
|
41
41
|
@files << entry.name
|
42
42
|
FileUtils.mkdir_p(File.dirname(@current_file))
|
43
|
+
@io = File.open(@current_file, "wb")
|
43
44
|
end
|
44
45
|
|
45
46
|
# Write to a buffer that will be written to the current entry
|
46
47
|
def write(content)
|
47
|
-
@
|
48
|
+
@io << content
|
48
49
|
end
|
49
50
|
alias << write
|
50
51
|
|
51
52
|
private
|
52
53
|
|
53
54
|
def write_file
|
54
|
-
if @current_file
|
55
|
-
@buffer.rewind
|
56
|
-
File.open(@current_file, "wb") { |f| f.write @buffer.read }
|
57
|
-
end
|
55
|
+
@io.close if @current_file
|
58
56
|
@current_file = nil
|
59
|
-
@
|
57
|
+
@io = nil
|
60
58
|
end
|
61
59
|
|
62
60
|
def zip_parts(output)
|
@@ -65,8 +63,8 @@ module Axlsx
|
|
65
63
|
escaped_dir = Shellwords.shellescape(@dir)
|
66
64
|
command = "cd #{escaped_dir} && #{@zip_command} #{output} #{inputs}"
|
67
65
|
stdout_and_stderr, status = Open3.capture2e(command)
|
68
|
-
|
69
|
-
raise
|
66
|
+
unless status.success?
|
67
|
+
raise ZipError, stdout_and_stderr
|
70
68
|
end
|
71
69
|
end
|
72
70
|
end
|
data/lib/axlsx/version.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# <definedNames>
|
2
4
|
# <definedName name="_xlnm.Print_Titles" localSheetId="0">Sheet1!$1:$1</definedName>
|
3
5
|
# </definedNames>
|
4
6
|
|
5
|
-
|
7
|
+
# <xsd:complexType name="CT_DefinedName">
|
6
8
|
# <xsd:simpleContent>
|
7
|
-
|
9
|
+
#  <xsd:extension base="ST_Formula">
|
8
10
|
# <xsd:attribute name="name" type="s:ST_Xstring" use="required"/>
|
9
11
|
# <xsd:attribute name="comment" type="s:ST_Xstring" use="optional"/>
|
10
12
|
# <xsd:attribute name="customMenu" type="s:ST_Xstring" use="optional"/>
|
@@ -97,7 +99,7 @@ module Axlsx
|
|
97
99
|
# version of the workbook that is published to or rendered on a Web or application server.
|
98
100
|
# @option [Boolean] workbook_parameter - Specifies a boolean value that indicates that the name is used as a workbook parameter on a
|
99
101
|
# version of the workbook that is published to or rendered on a Web or application server.
|
100
|
-
def initialize(formula, options={})
|
102
|
+
def initialize(formula, options = {})
|
101
103
|
@formula = formula
|
102
104
|
parse_options options
|
103
105
|
end
|
@@ -107,7 +109,7 @@ module Axlsx
|
|
107
109
|
# The local sheet index (0-based)
|
108
110
|
# @param [Integer] value the unsigned integer index of the sheet this defined_name applies to.
|
109
111
|
def local_sheet_id=(value)
|
110
|
-
Axlsx
|
112
|
+
Axlsx.validate_unsigned_int(value)
|
111
113
|
@local_sheet_id = value
|
112
114
|
end
|
113
115
|
|
@@ -116,13 +118,14 @@ module Axlsx
|
|
116
118
|
boolean_attr_accessor :workbook_parameter, :publish_to_server, :xlm, :vb_proceedure, :function, :hidden
|
117
119
|
|
118
120
|
serializable_attributes :short_cut_key, :status_bar, :help, :description, :custom_menu, :comment,
|
119
|
-
|
121
|
+
:workbook_parameter, :publish_to_server, :xlm, :vb_proceedure, :function, :hidden, :local_sheet_id
|
120
122
|
|
121
|
-
def to_xml_string(str='')
|
123
|
+
def to_xml_string(str = +'')
|
122
124
|
raise ArgumentError, 'you must specify the name for this defined name. Please read the documentation for Axlsx::DefinedName for more details' unless name
|
123
|
-
|
125
|
+
|
126
|
+
str << '<definedName ' << 'name="' << name << '" '
|
124
127
|
serialized_attributes str
|
125
|
-
str <<
|
128
|
+
str << '>' << @formula << '</definedName>'
|
126
129
|
end
|
127
130
|
end
|
128
131
|
end
|
@@ -1,7 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Axlsx
|
2
4
|
# a simple types list of DefinedName objects
|
3
5
|
class DefinedNames < SimpleTypedList
|
4
|
-
|
5
6
|
# creates the DefinedNames object
|
6
7
|
def initialize
|
7
8
|
super DefinedName
|
@@ -10,12 +11,12 @@ module Axlsx
|
|
10
11
|
# Serialize to xml
|
11
12
|
# @param [String] str
|
12
13
|
# @return [String]
|
13
|
-
def to_xml_string(str = '')
|
14
|
+
def to_xml_string(str = +'')
|
14
15
|
return if empty?
|
16
|
+
|
15
17
|
str << '<definedNames>'
|
16
18
|
each { |defined_name| defined_name.to_xml_string(str) }
|
17
19
|
str << '</definedNames>'
|
18
20
|
end
|
19
21
|
end
|
20
22
|
end
|
21
|
-
|
@@ -1,6 +1,6 @@
|
|
1
|
-
#
|
2
|
-
module Axlsx
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
3
|
+
module Axlsx
|
4
4
|
# The Shared String Table class is responsible for managing and serializing common strings in a workbook.
|
5
5
|
# While the ECMA-376 spec allows for both inline and shared strings it seems that at least some applications like iWorks Numbers
|
6
6
|
# and Google Docs require that the shared string table is populated in order to interoperate properly.
|
@@ -9,7 +9,6 @@ module Axlsx
|
|
9
9
|
# @note Serialization performance is affected by using this serialization method so if you do not need interoperability
|
10
10
|
# it is recomended that you use the default inline string method of serialization.
|
11
11
|
class SharedStringsTable
|
12
|
-
|
13
12
|
# The total number of strings in the workbook including duplicates
|
14
13
|
# Empty cells are treated as blank strings
|
15
14
|
# @return [Integer]
|
@@ -33,12 +32,12 @@ module Axlsx
|
|
33
32
|
# Creates a new Shared Strings Table agains an array of cells
|
34
33
|
# @param [Array] cells This is an array of all of the cells in the workbook
|
35
34
|
# @param [Symbol] xml_space The xml:space behavior for the shared string table.
|
36
|
-
def initialize(cells, xml_space
|
35
|
+
def initialize(cells, xml_space = :preserve)
|
37
36
|
@index = 0
|
38
37
|
@xml_space = xml_space
|
39
38
|
@unique_cells = {}
|
40
|
-
@shared_xml_string =
|
41
|
-
shareable_cells = cells.flatten.select{ |cell| cell.plain_string? || cell.contains_rich_text? }
|
39
|
+
@shared_xml_string = +''
|
40
|
+
shareable_cells = cells.flatten.select { |cell| cell.plain_string? || cell.contains_rich_text? }
|
42
41
|
@count = shareable_cells.size
|
43
42
|
resolve(shareable_cells)
|
44
43
|
end
|
@@ -46,11 +45,11 @@ module Axlsx
|
|
46
45
|
# Serializes the object
|
47
46
|
# @param [String] str
|
48
47
|
# @return [String]
|
49
|
-
def to_xml_string(str='')
|
50
|
-
Axlsx
|
51
|
-
str <<
|
52
|
-
str <<
|
53
|
-
str <<
|
48
|
+
def to_xml_string(str = +'')
|
49
|
+
Axlsx.sanitize(@shared_xml_string)
|
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>'
|
54
53
|
end
|
55
54
|
|
56
55
|
private
|