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,5 +1,5 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
3
|
module Axlsx
|
4
4
|
# A cell in a worksheet.
|
5
5
|
# Cell stores inforamation requried to serialize a single worksheet cell to xml. You must provde the Row that the cell belongs to and the cells value. The data type will automatically be determed if you do not specify the :type option. The default style will be applied if you do not supply the :style option. Changing the cell's type will recast the value to the type specified. Altering the cell's value via the property accessor will also automatically cast the provided value to the cell's type.
|
@@ -7,7 +7,6 @@ module Axlsx
|
|
7
7
|
#
|
8
8
|
# @see Worksheet#add_row
|
9
9
|
class Cell
|
10
|
-
|
11
10
|
include Axlsx::OptionsParser
|
12
11
|
|
13
12
|
# @param [Row] row The row this cell belongs to.
|
@@ -30,10 +29,9 @@ module Axlsx
|
|
30
29
|
# @option options [String] color an 8 letter rgb specification
|
31
30
|
# @option options [Number] formula_value The value to cache for a formula cell.
|
32
31
|
# @option options [Symbol] scheme must be one of :none, major, :minor
|
33
|
-
# @option options [Boolean] escape_formulas
|
34
|
-
#
|
35
|
-
#
|
36
|
-
# (see https://www.owasp.org/index.php/CSV_Injection for details).
|
32
|
+
# @option options [Boolean] escape_formulas Whether to treat values starting with an equals
|
33
|
+
# sign as formulas or as literal strings. Allowing user-generated data to be interpreted as
|
34
|
+
# formulas is a security risk. See https://www.owasp.org/index.php/CSV_Injection for details.
|
37
35
|
def initialize(row, value = nil, options = {})
|
38
36
|
@row = row
|
39
37
|
# Do not use instance vars if not needed to use less RAM
|
@@ -42,15 +40,14 @@ module Axlsx
|
|
42
40
|
type = options.delete(:type) || cell_type_from_value(value)
|
43
41
|
self.type = type unless type == :string
|
44
42
|
|
45
|
-
escape_formulas = options[:escape_formulas]
|
46
|
-
self.escape_formulas = escape_formulas unless escape_formulas.nil?
|
47
|
-
|
48
43
|
val = options.delete(:style)
|
49
|
-
self.style = val unless val.nil? || val
|
44
|
+
self.style = val unless val.nil? || val.zero?
|
50
45
|
val = options.delete(:formula_value)
|
51
46
|
self.formula_value = val unless val.nil?
|
47
|
+
val = options.delete(:escape_formulas)
|
48
|
+
self.escape_formulas = val unless val.nil?
|
52
49
|
|
53
|
-
parse_options(options)
|
50
|
+
parse_options(options) unless options.empty?
|
54
51
|
|
55
52
|
self.value = value
|
56
53
|
value.cell = self if contains_rich_text?
|
@@ -75,6 +72,9 @@ module Axlsx
|
|
75
72
|
CELL_TYPES = [:date, :time, :float, :integer, :richtext,
|
76
73
|
:string, :boolean, :iso_8601, :text].freeze
|
77
74
|
|
75
|
+
# A regular expression to match the alpha(column)numeric(row) reference of a cell
|
76
|
+
CELL_REFERENCE_REGEX = /([A-Z]+)([0-9]+)/.freeze
|
77
|
+
|
78
78
|
# The index of the cellXfs item to be applied to this cell.
|
79
79
|
# @return [Integer]
|
80
80
|
# @see Axlsx::Styles
|
@@ -82,10 +82,15 @@ module Axlsx
|
|
82
82
|
defined?(@style) ? @style : 0
|
83
83
|
end
|
84
84
|
|
85
|
+
# Internal
|
86
|
+
def style_str
|
87
|
+
defined?(@style) ? @style.to_s : '0'
|
88
|
+
end
|
89
|
+
|
85
90
|
attr_accessor :raw_style
|
86
91
|
|
87
92
|
# The index of the cellXfs item to be applied to this cell.
|
88
|
-
# @param [Hash]
|
93
|
+
# @param [Hash] style
|
89
94
|
# @see Axlsx::Styles
|
90
95
|
def add_style(style)
|
91
96
|
self.raw_style ||= {}
|
@@ -104,7 +109,7 @@ module Axlsx
|
|
104
109
|
self.raw_style = new_style
|
105
110
|
|
106
111
|
wb = row.worksheet.workbook
|
107
|
-
|
112
|
+
|
108
113
|
wb.styled_cells << self
|
109
114
|
end
|
110
115
|
|
@@ -117,7 +122,7 @@ module Axlsx
|
|
117
122
|
# automatically determed.
|
118
123
|
# @see Cell#cell_type_from_value
|
119
124
|
# @return [Symbol] The type of data this cell's value is cast to.
|
120
|
-
# @raise [
|
125
|
+
# @raise [ArgumentError] Cell.type must be one of [:date, time, :float, :integer, :string, :boolean]
|
121
126
|
# @note
|
122
127
|
# If the value provided cannot be cast into the type specified, type is changed to :string and the following logic is applied.
|
123
128
|
# :string to :integer or :float, type conversions always return 0 or 0.0
|
@@ -134,16 +139,19 @@ module Axlsx
|
|
134
139
|
self.value = @value unless !defined?(@value) || @value.nil?
|
135
140
|
end
|
136
141
|
|
137
|
-
# Whether to treat
|
138
|
-
#
|
139
|
-
#
|
140
|
-
# (see https://www.owasp.org/index.php/CSV_Injection for details).
|
142
|
+
# Whether to treat values starting with an equals sign as formulas or as literal strings.
|
143
|
+
# Allowing user-generated data to be interpreted as formulas is a security risk.
|
144
|
+
# See https://www.owasp.org/index.php/CSV_Injection for details.
|
141
145
|
# @return [Boolean]
|
142
|
-
|
146
|
+
def escape_formulas
|
147
|
+
defined?(@escape_formulas) ? @escape_formulas : row.worksheet.escape_formulas
|
148
|
+
end
|
143
149
|
|
144
|
-
|
145
|
-
|
146
|
-
|
150
|
+
# Sets whether to treat values starting with an equals sign as formulas or as literal strings.
|
151
|
+
# @param [Boolean] value The value to set.
|
152
|
+
def escape_formulas=(value)
|
153
|
+
Axlsx.validate_boolean(value)
|
154
|
+
@escape_formulas = value
|
147
155
|
end
|
148
156
|
|
149
157
|
# The value of this cell.
|
@@ -152,13 +160,13 @@ module Axlsx
|
|
152
160
|
|
153
161
|
# @see value
|
154
162
|
def value=(v)
|
155
|
-
#TODO: consider doing value based type determination first?
|
163
|
+
# TODO: consider doing value based type determination first?
|
156
164
|
@value = cast_value(v)
|
157
165
|
end
|
158
166
|
|
159
167
|
# Indicates that the cell has one or more of the custom cell styles applied.
|
160
168
|
# @return [Boolean]
|
161
|
-
def is_text_run?
|
169
|
+
def is_text_run? # rubocop:disable Naming/PredicateName
|
162
170
|
defined?(@is_text_run) && @is_text_run && !contains_rich_text?
|
163
171
|
end
|
164
172
|
|
@@ -168,16 +176,18 @@ module Axlsx
|
|
168
176
|
|
169
177
|
# Indicates if the cell is good for shared string table
|
170
178
|
def plain_string?
|
171
|
-
(type == :string || type == :text) &&
|
172
|
-
!
|
173
|
-
|
174
|
-
|
175
|
-
|
179
|
+
(type == :string || type == :text) && # String typed
|
180
|
+
!value.nil? &&
|
181
|
+
!value.empty? &&
|
182
|
+
!is_text_run? && # No inline styles
|
183
|
+
!is_formula? &&
|
184
|
+
!is_array_formula?
|
176
185
|
end
|
177
186
|
|
178
187
|
# The inline font_name property for the cell
|
179
188
|
# @return [String]
|
180
189
|
attr_reader :font_name
|
190
|
+
|
181
191
|
# @see font_name
|
182
192
|
def font_name=(v) set_run_style :validate_string, :font_name, v; end
|
183
193
|
|
@@ -204,6 +214,7 @@ module Axlsx
|
|
204
214
|
# 255  OEM_CHARSET
|
205
215
|
# @return [String]
|
206
216
|
attr_reader :charset
|
217
|
+
|
207
218
|
# @see charset
|
208
219
|
def charset=(v) set_run_style :validate_unsigned_int, :charset, v; end
|
209
220
|
|
@@ -215,6 +226,7 @@ module Axlsx
|
|
215
226
|
# 4 Script
|
216
227
|
# 5 Decorative
|
217
228
|
attr_reader :family
|
229
|
+
|
218
230
|
# @see family
|
219
231
|
def family=(v)
|
220
232
|
set_run_style :validate_family, :family, v.to_i
|
@@ -223,69 +235,77 @@ module Axlsx
|
|
223
235
|
# The inline bold property for the cell
|
224
236
|
# @return [Boolean]
|
225
237
|
attr_reader :b
|
238
|
+
|
226
239
|
# @see b
|
227
240
|
def b=(v) set_run_style :validate_boolean, :b, v; end
|
228
241
|
|
229
242
|
# The inline italic property for the cell
|
230
243
|
# @return [Boolean]
|
231
244
|
attr_reader :i
|
245
|
+
|
232
246
|
# @see i
|
233
247
|
def i=(v) set_run_style :validate_boolean, :i, v; end
|
234
248
|
|
235
249
|
# The inline strike property for the cell
|
236
250
|
# @return [Boolean]
|
237
251
|
attr_reader :strike
|
252
|
+
|
238
253
|
# @see strike
|
239
254
|
def strike=(v) set_run_style :validate_boolean, :strike, v; end
|
240
255
|
|
241
256
|
# The inline outline property for the cell
|
242
257
|
# @return [Boolean]
|
243
258
|
attr_reader :outline
|
259
|
+
|
244
260
|
# @see outline
|
245
261
|
def outline=(v) set_run_style :validate_boolean, :outline, v; end
|
246
262
|
|
247
263
|
# The inline shadow property for the cell
|
248
264
|
# @return [Boolean]
|
249
265
|
attr_reader :shadow
|
266
|
+
|
250
267
|
# @see shadow
|
251
268
|
def shadow=(v) set_run_style :validate_boolean, :shadow, v; end
|
252
269
|
|
253
270
|
# The inline condense property for the cell
|
254
271
|
# @return [Boolean]
|
255
272
|
attr_reader :condense
|
273
|
+
|
256
274
|
# @see condense
|
257
275
|
def condense=(v) set_run_style :validate_boolean, :condense, v; end
|
258
276
|
|
259
277
|
# The inline extend property for the cell
|
260
278
|
# @return [Boolean]
|
261
279
|
attr_reader :extend
|
280
|
+
|
262
281
|
# @see extend
|
263
282
|
def extend=(v) set_run_style :validate_boolean, :extend, v; end
|
264
283
|
|
265
284
|
# The inline underline property for the cell.
|
266
|
-
# It must be one of :none, :single, :double, :singleAccounting, :doubleAccounting
|
285
|
+
# It must be one of :none, :single, :double, :singleAccounting, :doubleAccounting
|
267
286
|
# @return [Boolean]
|
268
287
|
# @return [String]
|
269
|
-
# @note true is for backwards compatability and is reassigned to :single
|
270
288
|
attr_reader :u
|
289
|
+
|
271
290
|
# @see u
|
272
291
|
def u=(v)
|
273
|
-
v = :single if (v == true || v == 1 || v == :true || v == 'true')
|
274
292
|
set_run_style :validate_cell_u, :u, v
|
275
293
|
end
|
276
294
|
|
277
295
|
# The inline color property for the cell
|
278
296
|
# @return [Color]
|
279
297
|
attr_reader :color
|
298
|
+
|
280
299
|
# @param [String] v The 8 character representation for an rgb color #FFFFFFFF"
|
281
300
|
def color=(v)
|
282
|
-
@color = v.is_a?(Color) ? v : Color.new(:
|
301
|
+
@color = v.is_a?(Color) ? v : Color.new(rgb: v)
|
283
302
|
@is_text_run = true
|
284
303
|
end
|
285
304
|
|
286
305
|
# The inline sz property for the cell
|
287
306
|
# @return [Inteter]
|
288
307
|
attr_reader :sz
|
308
|
+
|
289
309
|
# @see sz
|
290
310
|
def sz=(v) set_run_style :validate_unsigned_int, :sz, v; end
|
291
311
|
|
@@ -293,6 +313,7 @@ module Axlsx
|
|
293
313
|
# this must be one of [:baseline, :subscript, :superscript]
|
294
314
|
# @return [Symbol]
|
295
315
|
attr_reader :vertAlign
|
316
|
+
|
296
317
|
# @see vertAlign
|
297
318
|
def vertAlign=(v)
|
298
319
|
RestrictionValidator.validate :cell_vertAlign, [:baseline, :subscript, :superscript], v
|
@@ -303,6 +324,7 @@ module Axlsx
|
|
303
324
|
# this must be one of [:none, major, minor]
|
304
325
|
# @return [Symbol]
|
305
326
|
attr_reader :scheme
|
327
|
+
|
306
328
|
# @see scheme
|
307
329
|
def scheme=(v)
|
308
330
|
RestrictionValidator.validate :cell_scheme, [:none, :major, :minor], v
|
@@ -322,22 +344,23 @@ module Axlsx
|
|
322
344
|
# @example Relative Cell Reference
|
323
345
|
# ws.rows.first.cells.first.r #=> "A1"
|
324
346
|
def r
|
325
|
-
Axlsx
|
347
|
+
Axlsx.cell_r index, @row.row_index
|
326
348
|
end
|
327
349
|
|
328
|
-
# @return [String] The absolute alpha(column)numeric(row) reference for this
|
350
|
+
# @return [String] The absolute alpha(column)numeric(row) reference for this cell.
|
329
351
|
# @example Absolute Cell Reference
|
330
352
|
# ws.rows.first.cells.first.r #=> "$A$1"
|
331
353
|
def r_abs
|
332
|
-
"$#{
|
354
|
+
"$#{CELL_REFERENCE_REGEX.match(r)[1, 2].join('$')}"
|
333
355
|
end
|
334
356
|
|
335
357
|
# @return [Integer] The cellXfs item index applied to this cell.
|
336
358
|
# @raise [ArgumentError] Invalid cellXfs id if the value provided is not within cellXfs items range.
|
337
359
|
def style=(v)
|
338
|
-
Axlsx
|
360
|
+
Axlsx.validate_unsigned_int(v)
|
339
361
|
count = styles.cellXfs.size
|
340
362
|
raise ArgumentError, "Invalid cellXfs id" unless v < count
|
363
|
+
|
341
364
|
@style = v
|
342
365
|
end
|
343
366
|
|
@@ -351,11 +374,11 @@ module Axlsx
|
|
351
374
|
# @param [Cell, String] target The last cell, or str ref for the cell in the merge range
|
352
375
|
def merge(target)
|
353
376
|
start, stop = if target.is_a?(String)
|
354
|
-
[
|
355
|
-
elsif
|
356
|
-
Axlsx.sort_cells([self, target]).map
|
377
|
+
[r, target]
|
378
|
+
elsif target.is_a?(Cell)
|
379
|
+
Axlsx.sort_cells([self, target]).map(&:r)
|
357
380
|
end
|
358
|
-
|
381
|
+
row.worksheet.merge_cells "#{start}:#{stop}" unless stop.nil?
|
359
382
|
end
|
360
383
|
|
361
384
|
# Serializes the cell
|
@@ -363,18 +386,22 @@ module Axlsx
|
|
363
386
|
# @param [Integer] c_index The cell index in the row.
|
364
387
|
# @param [String] str The string index the cell content will be appended to. Defaults to empty string.
|
365
388
|
# @return [String] xml text for the cell
|
366
|
-
def to_xml_string(r_index, c_index, str = '')
|
389
|
+
def to_xml_string(r_index, c_index, str = +'')
|
367
390
|
CellSerializer.to_xml_string r_index, c_index, self, str
|
368
391
|
end
|
369
392
|
|
370
|
-
def is_formula?
|
393
|
+
def is_formula? # rubocop:disable Naming/PredicateName
|
371
394
|
return false if escape_formulas
|
372
395
|
|
373
|
-
type == :string && @value.to_s.start_with?(
|
396
|
+
type == :string && @value.to_s.start_with?(FORMULA_PREFIX)
|
374
397
|
end
|
375
398
|
|
376
|
-
def is_array_formula?
|
377
|
-
|
399
|
+
def is_array_formula? # rubocop:disable Naming/PredicateName
|
400
|
+
return false if escape_formulas
|
401
|
+
|
402
|
+
type == :string &&
|
403
|
+
@value.to_s.start_with?(ARRAY_FORMULA_PREFIX) &&
|
404
|
+
@value.to_s.end_with?(ARRAY_FORMULA_SUFFIX)
|
378
405
|
end
|
379
406
|
|
380
407
|
# returns the absolute or relative string style reference for
|
@@ -382,7 +409,7 @@ module Axlsx
|
|
382
409
|
# @param [Boolean] absolute -when false a relative reference will be
|
383
410
|
# returned.
|
384
411
|
# @return [String]
|
385
|
-
def reference(absolute=true)
|
412
|
+
def reference(absolute = true)
|
386
413
|
absolute ? r_abs : r
|
387
414
|
end
|
388
415
|
|
@@ -398,7 +425,7 @@ module Axlsx
|
|
398
425
|
# Attempts to determine the correct width for this cell's content
|
399
426
|
# @return [Float]
|
400
427
|
def autowidth
|
401
|
-
return if
|
428
|
+
return if value.nil? || is_formula?
|
402
429
|
|
403
430
|
if contains_rich_text?
|
404
431
|
string_width('', font_size) + value.autowidth
|
@@ -414,12 +441,13 @@ module Axlsx
|
|
414
441
|
end
|
415
442
|
end
|
416
443
|
|
417
|
-
# Returns the
|
418
|
-
# TODO find a better way to do this as it accounts for 30% of
|
444
|
+
# Returns the sanitized value
|
445
|
+
# TODO: find a better way to do this as it accounts for 30% of
|
419
446
|
# processing time in benchmarking...
|
447
|
+
# @return [String] The sanitized value
|
420
448
|
def clean_value
|
421
|
-
if (type == :string || type == :text) && !Axlsx
|
422
|
-
Axlsx
|
449
|
+
if (type == :string || type == :text) && !Axlsx.trust_input
|
450
|
+
Axlsx.sanitize(::CGI.escapeHTML(@value.to_s))
|
423
451
|
else
|
424
452
|
@value.to_s
|
425
453
|
end
|
@@ -452,14 +480,15 @@ module Axlsx
|
|
452
480
|
# Utility method for setting inline style attributes
|
453
481
|
def set_run_style(validator, attr, value)
|
454
482
|
return unless INLINE_STYLES.include?(attr.to_sym)
|
483
|
+
|
455
484
|
Axlsx.send(validator, value) unless validator.nil?
|
456
|
-
|
485
|
+
instance_variable_set :"@#{attr}", value
|
457
486
|
@is_text_run = true
|
458
487
|
end
|
459
488
|
|
460
489
|
# @see ssti
|
461
490
|
def ssti=(v)
|
462
|
-
Axlsx
|
491
|
+
Axlsx.validate_unsigned_int(v)
|
463
492
|
@ssti = v
|
464
493
|
end
|
465
494
|
|
@@ -478,13 +507,11 @@ module Axlsx
|
|
478
507
|
:time
|
479
508
|
elsif v.is_a?(TrueClass) || v.is_a?(FalseClass)
|
480
509
|
:boolean
|
481
|
-
elsif v.
|
510
|
+
elsif v.respond_to?(:to_i) && Axlsx::NUMERIC_REGEX.match?(v.to_s)
|
482
511
|
:integer
|
483
|
-
elsif v.
|
512
|
+
elsif v.respond_to?(:to_f) && (Axlsx::SAFE_FLOAT_REGEX.match?(v.to_s) || ((matchdata = MAYBE_FLOAT_REGEX.match(v.to_s)) && matchdata[:exp].to_i.between?(Float::MIN_10_EXP, Float::MAX_10_EXP)))
|
484
513
|
:float
|
485
|
-
elsif
|
486
|
-
:float
|
487
|
-
elsif v.to_s =~ Axlsx::ISO_8601_REGEX
|
514
|
+
elsif Axlsx::ISO_8601_REGEX.match?(v.to_s)
|
488
515
|
:iso_8601
|
489
516
|
elsif v.is_a? RichText
|
490
517
|
:richtext
|
@@ -498,17 +525,18 @@ module Axlsx
|
|
498
525
|
# About Time - Time in OOXML is *different* from what you might expect. The history as to why is interesting, but you can safely assume that if you are generating docs on a mac, you will want to specify Workbook.1904 as true when using time typed values.
|
499
526
|
# @see Axlsx#date1904
|
500
527
|
def cast_value(v)
|
501
|
-
return v if v.
|
528
|
+
return v if v.nil? || v.is_a?(RichText)
|
529
|
+
|
502
530
|
case type
|
503
531
|
when :date
|
504
|
-
self.style = STYLE_DATE if
|
532
|
+
self.style = STYLE_DATE if style.zero?
|
505
533
|
if !v.is_a?(Date) && v.respond_to?(:to_date)
|
506
534
|
v.to_date
|
507
535
|
else
|
508
536
|
v
|
509
537
|
end
|
510
538
|
when :time
|
511
|
-
self.style = STYLE_DATE if
|
539
|
+
self.style = STYLE_DATE if style.zero?
|
512
540
|
if !v.is_a?(Time) && v.respond_to?(:to_time)
|
513
541
|
v.to_time
|
514
542
|
else
|
@@ -521,12 +549,11 @@ module Axlsx
|
|
521
549
|
when :boolean
|
522
550
|
v ? 1 : 0
|
523
551
|
when :iso_8601
|
524
|
-
#consumer is responsible for ensuring the iso_8601 format when specifying this type
|
552
|
+
# consumer is responsible for ensuring the iso_8601 format when specifying this type
|
525
553
|
v
|
526
554
|
else
|
527
555
|
v.to_s
|
528
556
|
end
|
529
557
|
end
|
530
|
-
|
531
558
|
end
|
532
559
|
end
|
@@ -1,5 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
+
module Axlsx
|
3
4
|
# The Cell Serializer class contains the logic for serializing cells based on their type.
|
4
5
|
class CellSerializer
|
5
6
|
class << self
|
@@ -8,27 +9,30 @@ module Axlsx
|
|
8
9
|
# @param [Integer] column_index The index of the cell's column
|
9
10
|
# @param [String] str The string to apend serialization to.
|
10
11
|
# @return [String]
|
11
|
-
def to_xml_string(row_index, column_index, cell, str='')
|
12
|
-
str <<
|
12
|
+
def to_xml_string(row_index, column_index, cell, str = +'')
|
13
|
+
str << '<c r="'
|
14
|
+
str << Axlsx.col_ref(column_index) << Axlsx.row_ref(row_index)
|
15
|
+
str << '" s="' << cell.style_str << '" '
|
13
16
|
return str << '/>' if cell.value.nil?
|
17
|
+
|
14
18
|
method = cell.type
|
15
|
-
|
19
|
+
send(method, cell, str)
|
16
20
|
str << '</c>'
|
17
21
|
end
|
18
22
|
|
19
23
|
# builds an xml text run based on this cells attributes.
|
20
24
|
# @param [String] str The string instance this run will be concated to.
|
21
25
|
# @return [String]
|
22
|
-
def run_xml_string(cell, str = '')
|
26
|
+
def run_xml_string(cell, str = +'')
|
23
27
|
if cell.is_text_run?
|
24
28
|
valid = RichTextRun::INLINE_STYLES - [:value, :type]
|
25
|
-
data =
|
26
|
-
data = data.select { |key, value| valid.include?(key)
|
29
|
+
data = Axlsx.instance_values_for(cell).transform_keys(&:to_sym)
|
30
|
+
data = data.select { |key, value| !value.nil? && valid.include?(key) }
|
27
31
|
RichText.new(cell.value.to_s, data).to_xml_string(str)
|
28
32
|
elsif cell.contains_rich_text?
|
29
33
|
cell.value.to_xml_string(str)
|
30
34
|
else
|
31
|
-
str <<
|
35
|
+
str << '<t>' << cell.clean_value << '</t>'
|
32
36
|
end
|
33
37
|
str
|
34
38
|
end
|
@@ -37,7 +41,7 @@ module Axlsx
|
|
37
41
|
# @param [Cell] cell The cell that is being serialized
|
38
42
|
# @param [String] str The string the serialized content will be appended to.
|
39
43
|
# @return [String]
|
40
|
-
def iso_8601(cell, str='')
|
44
|
+
def iso_8601(cell, str = +'')
|
41
45
|
value_serialization 'd', cell.value, str
|
42
46
|
end
|
43
47
|
|
@@ -45,23 +49,23 @@ module Axlsx
|
|
45
49
|
# @param [Cell] cell The cell that is being serialized
|
46
50
|
# @param [String] str The string the serialized content will be appended to.
|
47
51
|
# @return [String]
|
48
|
-
def date(cell, str='')
|
49
|
-
value_serialization false, DateTimeConverter
|
52
|
+
def date(cell, str = +'')
|
53
|
+
value_serialization false, DateTimeConverter.date_to_serial(cell.value).to_s, str
|
50
54
|
end
|
51
55
|
|
52
56
|
# Serializes cells that are type time
|
53
57
|
# @param [Cell] cell The cell that is being serialized
|
54
58
|
# @param [String] str The string the serialized content will be appended to.
|
55
59
|
# @return [String]
|
56
|
-
def time(cell, str='')
|
57
|
-
value_serialization false, DateTimeConverter
|
60
|
+
def time(cell, str = +'')
|
61
|
+
value_serialization false, DateTimeConverter.time_to_serial(cell.value).to_s, str
|
58
62
|
end
|
59
63
|
|
60
64
|
# Serializes cells that are type boolean
|
61
65
|
# @param [Cell] cell The cell that is being serialized
|
62
66
|
# @param [String] str The string the serialized content will be appended to.
|
63
67
|
# @return [String]
|
64
|
-
def boolean(cell, str='')
|
68
|
+
def boolean(cell, str = +'')
|
65
69
|
value_serialization 'b', cell.value.to_s, str
|
66
70
|
end
|
67
71
|
|
@@ -69,7 +73,7 @@ module Axlsx
|
|
69
73
|
# @param [Cell] cell The cell that is being serialized
|
70
74
|
# @param [String] str The string the serialized content will be appended to.
|
71
75
|
# @return [String]
|
72
|
-
def float(cell, str='')
|
76
|
+
def float(cell, str = +'')
|
73
77
|
numeric cell, str
|
74
78
|
end
|
75
79
|
|
@@ -77,7 +81,7 @@ module Axlsx
|
|
77
81
|
# @param [Cell] cell The cell that is being serialized
|
78
82
|
# @param [String] str The string the serialized content will be appended to.
|
79
83
|
# @return [String]
|
80
|
-
def integer(cell, str = '')
|
84
|
+
def integer(cell, str = +'')
|
81
85
|
numeric cell, str
|
82
86
|
end
|
83
87
|
|
@@ -85,25 +89,25 @@ module Axlsx
|
|
85
89
|
# @param [Cell] cell The cell that is being serialized
|
86
90
|
# @param [String] str The string the serialized content will be appended to.
|
87
91
|
# @return [String]
|
88
|
-
def formula_serialization(cell, str='')
|
89
|
-
str <<
|
90
|
-
str <<
|
92
|
+
def formula_serialization(cell, str = +'')
|
93
|
+
str << 't="str"><f>' << cell.clean_value.delete_prefix(FORMULA_PREFIX) << '</f>'
|
94
|
+
str << '<v>' << cell.formula_value.to_s << '</v>' unless cell.formula_value.nil?
|
91
95
|
end
|
92
96
|
|
93
97
|
# Serializes cells that are type array formula
|
94
98
|
# @param [Cell] cell The cell that is being serialized
|
95
99
|
# @param [String] str The string the serialized content will be appended to.
|
96
100
|
# @return [String]
|
97
|
-
def array_formula_serialization(cell, str='')
|
98
|
-
str <<
|
99
|
-
str <<
|
101
|
+
def array_formula_serialization(cell, str = +'')
|
102
|
+
str << 't="str">' << '<f t="array" ref="' << cell.r << '">' << cell.clean_value.delete_prefix(ARRAY_FORMULA_PREFIX).delete_suffix(ARRAY_FORMULA_SUFFIX) << '</f>'
|
103
|
+
str << '<v>' << cell.formula_value.to_s << '</v>' unless cell.formula_value.nil?
|
100
104
|
end
|
101
105
|
|
102
106
|
# Serializes cells that are type inline_string
|
103
107
|
# @param [Cell] cell The cell that is being serialized
|
104
108
|
# @param [String] str The string the serialized content will be appended to.
|
105
109
|
# @return [String]
|
106
|
-
def inline_string_serialization(cell, str = '')
|
110
|
+
def inline_string_serialization(cell, str = +'')
|
107
111
|
str << 't="inlineStr"><is>'
|
108
112
|
run_xml_string cell, str
|
109
113
|
str << '</is>'
|
@@ -113,7 +117,7 @@ module Axlsx
|
|
113
117
|
# @param [Cell] cell The cell that is being serialized
|
114
118
|
# @param [String] str The string the serialized content will be appended to.
|
115
119
|
# @return [String]
|
116
|
-
def string(cell, str='')
|
120
|
+
def string(cell, str = +'')
|
117
121
|
if cell.is_array_formula?
|
118
122
|
array_formula_serialization cell, str
|
119
123
|
elsif cell.is_formula?
|
@@ -151,13 +155,13 @@ module Axlsx
|
|
151
155
|
|
152
156
|
private
|
153
157
|
|
154
|
-
def numeric(cell, str = '')
|
158
|
+
def numeric(cell, str = +'')
|
155
159
|
value_serialization 'n', cell.value, str
|
156
160
|
end
|
157
161
|
|
158
|
-
def value_serialization(serialization_type, serialization_value, str = '')
|
159
|
-
str <<
|
160
|
-
str <<
|
162
|
+
def value_serialization(serialization_type, serialization_value, str = +'')
|
163
|
+
str << 't="' << serialization_type.to_s << '"' if serialization_type
|
164
|
+
str << '><v>' << serialization_value.to_s << '</v>'
|
161
165
|
end
|
162
166
|
end
|
163
167
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Axlsx
|
2
4
|
# Conditional Format Value Object
|
3
5
|
# Describes the values of the interpolation points in a gradient scale. This object is used by ColorScale, DataBar and IconSet classes
|
@@ -7,7 +9,6 @@ module Axlsx
|
|
7
9
|
# @see ConditionalFormattingRule#initialize
|
8
10
|
#
|
9
11
|
class Cfvo
|
10
|
-
|
11
12
|
include Axlsx::OptionsParser
|
12
13
|
include Axlsx::SerializedAttributes
|
13
14
|
|
@@ -15,7 +16,7 @@ module Axlsx
|
|
15
16
|
# @option options [Symbol] type The type of conditional formatting value object
|
16
17
|
# @option options [Boolean] gte threshold value usage indicator
|
17
18
|
# @option options [String] val The value of the conditional formatting object
|
18
|
-
def initialize(options={})
|
19
|
+
def initialize(options = {})
|
19
20
|
@gte = true
|
20
21
|
parse_options options
|
21
22
|
end
|
@@ -39,21 +40,22 @@ module Axlsx
|
|
39
40
|
attr_reader :val
|
40
41
|
|
41
42
|
# @see type
|
42
|
-
def type=(v); Axlsx
|
43
|
+
def type=(v); Axlsx.validate_conditional_formatting_value_object_type(v); @type = v end
|
43
44
|
|
44
45
|
# @see gte
|
45
|
-
def gte=(v); Axlsx
|
46
|
+
def gte=(v); Axlsx.validate_boolean(v); @gte = v end
|
46
47
|
|
47
48
|
# @see val
|
48
49
|
def val=(v)
|
49
50
|
raise ArgumentError, "#{v.inspect} must respond to to_s" unless v.respond_to?(:to_s)
|
51
|
+
|
50
52
|
@val = v.to_s
|
51
53
|
end
|
52
54
|
|
53
55
|
# serialize the Csvo object
|
54
56
|
# @param [String] str
|
55
57
|
# @return [String]
|
56
|
-
def to_xml_string(str = '')
|
58
|
+
def to_xml_string(str = +'')
|
57
59
|
serialized_tag('cfvo', str)
|
58
60
|
end
|
59
61
|
end
|
@@ -1,9 +1,9 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
#
|
3
|
+
module Axlsx
|
4
|
+
# A collection of Cfvo objects that initializes with the required
|
5
|
+
# first two items
|
5
6
|
class Cfvos < SimpleTypedList
|
6
|
-
|
7
7
|
def initialize
|
8
8
|
super(Cfvo)
|
9
9
|
end
|
@@ -11,7 +11,7 @@ module Axlsx
|
|
11
11
|
# Serialize the Cfvo object
|
12
12
|
# @param [String] str
|
13
13
|
# @return [String]
|
14
|
-
def to_xml_string(str='')
|
14
|
+
def to_xml_string(str = +'')
|
15
15
|
each { |cfvo| cfvo.to_xml_string(str) }
|
16
16
|
end
|
17
17
|
end
|