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.
Files changed (151) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -0
  3. data/README.md +25 -7
  4. data/Rakefile +7 -6
  5. data/lib/axlsx/content_type/abstract_content_type.rb +11 -9
  6. data/lib/axlsx/content_type/content_type.rb +7 -9
  7. data/lib/axlsx/content_type/default.rb +4 -6
  8. data/lib/axlsx/content_type/override.rb +3 -5
  9. data/lib/axlsx/doc_props/app.rb +27 -30
  10. data/lib/axlsx/doc_props/core.rb +9 -12
  11. data/lib/axlsx/drawing/area_chart.rb +13 -14
  12. data/lib/axlsx/drawing/area_series.rb +13 -14
  13. data/lib/axlsx/drawing/ax_data_source.rb +3 -6
  14. data/lib/axlsx/drawing/axes.rb +10 -9
  15. data/lib/axlsx/drawing/axis.rb +27 -30
  16. data/lib/axlsx/drawing/bar_3D_chart.rb +17 -18
  17. data/lib/axlsx/drawing/bar_chart.rb +16 -17
  18. data/lib/axlsx/drawing/bar_series.rb +9 -13
  19. data/lib/axlsx/drawing/bubble_chart.rb +8 -9
  20. data/lib/axlsx/drawing/bubble_series.rb +9 -10
  21. data/lib/axlsx/drawing/cat_axis.rb +14 -17
  22. data/lib/axlsx/drawing/chart.rb +25 -28
  23. data/lib/axlsx/drawing/d_lbls.rb +29 -26
  24. data/lib/axlsx/drawing/drawing.rb +60 -62
  25. data/lib/axlsx/drawing/graphic_frame.rb +6 -7
  26. data/lib/axlsx/drawing/hyperlink.rb +12 -13
  27. data/lib/axlsx/drawing/line_3D_chart.rb +13 -15
  28. data/lib/axlsx/drawing/line_chart.rb +13 -14
  29. data/lib/axlsx/drawing/line_series.rb +13 -14
  30. data/lib/axlsx/drawing/marker.rb +14 -16
  31. data/lib/axlsx/drawing/num_data.rb +13 -16
  32. data/lib/axlsx/drawing/num_data_source.rb +11 -13
  33. data/lib/axlsx/drawing/num_val.rb +9 -10
  34. data/lib/axlsx/drawing/one_cell_anchor.rb +10 -10
  35. data/lib/axlsx/drawing/pic.rb +57 -22
  36. data/lib/axlsx/drawing/picture_locking.rb +6 -7
  37. data/lib/axlsx/drawing/pie_3D_chart.rb +6 -9
  38. data/lib/axlsx/drawing/pie_series.rb +9 -12
  39. data/lib/axlsx/drawing/scaling.rb +9 -10
  40. data/lib/axlsx/drawing/scatter_chart.rb +9 -10
  41. data/lib/axlsx/drawing/scatter_series.rb +15 -16
  42. data/lib/axlsx/drawing/ser_axis.rb +9 -11
  43. data/lib/axlsx/drawing/series.rb +8 -8
  44. data/lib/axlsx/drawing/series_title.rb +6 -6
  45. data/lib/axlsx/drawing/str_data.rb +10 -13
  46. data/lib/axlsx/drawing/str_val.rb +8 -9
  47. data/lib/axlsx/drawing/title.rb +23 -27
  48. data/lib/axlsx/drawing/two_cell_anchor.rb +8 -8
  49. data/lib/axlsx/drawing/val_axis.rb +5 -6
  50. data/lib/axlsx/drawing/view_3D.rb +32 -30
  51. data/lib/axlsx/drawing/vml_drawing.rb +19 -20
  52. data/lib/axlsx/drawing/vml_shape.rb +25 -26
  53. data/lib/axlsx/package.rb +81 -79
  54. data/lib/axlsx/rels/relationship.rb +30 -28
  55. data/lib/axlsx/rels/relationships.rb +7 -8
  56. data/lib/axlsx/stylesheet/border.rb +7 -8
  57. data/lib/axlsx/stylesheet/border_pr.rb +8 -8
  58. data/lib/axlsx/stylesheet/cell_alignment.rb +14 -20
  59. data/lib/axlsx/stylesheet/cell_protection.rb +6 -7
  60. data/lib/axlsx/stylesheet/cell_style.rb +12 -14
  61. data/lib/axlsx/stylesheet/color.rb +15 -12
  62. data/lib/axlsx/stylesheet/dxf.rb +7 -9
  63. data/lib/axlsx/stylesheet/fill.rb +3 -5
  64. data/lib/axlsx/stylesheet/font.rb +24 -21
  65. data/lib/axlsx/stylesheet/gradient_fill.rb +9 -9
  66. data/lib/axlsx/stylesheet/gradient_stop.rb +7 -6
  67. data/lib/axlsx/stylesheet/num_fmt.rb +9 -14
  68. data/lib/axlsx/stylesheet/pattern_fill.rb +8 -8
  69. data/lib/axlsx/stylesheet/styles.rb +104 -98
  70. data/lib/axlsx/stylesheet/table_style.rb +8 -9
  71. data/lib/axlsx/stylesheet/table_style_element.rb +7 -8
  72. data/lib/axlsx/stylesheet/table_styles.rb +8 -10
  73. data/lib/axlsx/stylesheet/xf.rb +21 -22
  74. data/lib/axlsx/util/accessors.rb +6 -6
  75. data/lib/axlsx/util/buffered_zip_output_stream.rb +60 -0
  76. data/lib/axlsx/util/constants.rb +119 -108
  77. data/lib/axlsx/util/mime_type_utils.rb +11 -0
  78. data/lib/axlsx/util/options_parser.rb +4 -3
  79. data/lib/axlsx/util/serialized_attributes.rb +45 -21
  80. data/lib/axlsx/util/simple_typed_list.rb +58 -57
  81. data/lib/axlsx/util/storage.rb +38 -41
  82. data/lib/axlsx/util/validators.rb +107 -44
  83. data/lib/axlsx/util/zip_command.rb +10 -12
  84. data/lib/axlsx/version.rb +3 -2
  85. data/lib/axlsx/workbook/defined_name.rb +11 -8
  86. data/lib/axlsx/workbook/defined_names.rb +4 -3
  87. data/lib/axlsx/workbook/shared_strings_table.rb +10 -11
  88. data/lib/axlsx/workbook/workbook.rb +121 -114
  89. data/lib/axlsx/workbook/workbook_view.rb +8 -11
  90. data/lib/axlsx/workbook/workbook_views.rb +4 -4
  91. data/lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb +72 -14
  92. data/lib/axlsx/workbook/worksheet/auto_filter/filter_column.rb +11 -7
  93. data/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +24 -21
  94. data/lib/axlsx/workbook/worksheet/auto_filter/sort_condition.rb +51 -0
  95. data/lib/axlsx/workbook/worksheet/auto_filter/sort_state.rb +56 -0
  96. data/lib/axlsx/workbook/worksheet/border_creator.rb +30 -25
  97. data/lib/axlsx/workbook/worksheet/break.rb +4 -5
  98. data/lib/axlsx/workbook/worksheet/cell.rb +92 -65
  99. data/lib/axlsx/workbook/worksheet/cell_serializer.rb +32 -28
  100. data/lib/axlsx/workbook/worksheet/cfvo.rb +7 -5
  101. data/lib/axlsx/workbook/worksheet/cfvos.rb +5 -5
  102. data/lib/axlsx/workbook/worksheet/col.rb +9 -10
  103. data/lib/axlsx/workbook/worksheet/col_breaks.rb +8 -7
  104. data/lib/axlsx/workbook/worksheet/color_scale.rb +16 -16
  105. data/lib/axlsx/workbook/worksheet/cols.rb +9 -7
  106. data/lib/axlsx/workbook/worksheet/comment.rb +12 -11
  107. data/lib/axlsx/workbook/worksheet/comments.rb +10 -12
  108. data/lib/axlsx/workbook/worksheet/conditional_formatting.rb +12 -8
  109. data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +19 -21
  110. data/lib/axlsx/workbook/worksheet/conditional_formattings.rb +5 -5
  111. data/lib/axlsx/workbook/worksheet/data_bar.rb +29 -30
  112. data/lib/axlsx/workbook/worksheet/data_validation.rb +34 -33
  113. data/lib/axlsx/workbook/worksheet/data_validations.rb +5 -6
  114. data/lib/axlsx/workbook/worksheet/date_time_converter.rb +8 -8
  115. data/lib/axlsx/workbook/worksheet/dimension.rb +9 -6
  116. data/lib/axlsx/workbook/worksheet/header_footer.rb +4 -3
  117. data/lib/axlsx/workbook/worksheet/icon_set.rb +24 -8
  118. data/lib/axlsx/workbook/worksheet/merged_cells.rb +10 -10
  119. data/lib/axlsx/workbook/worksheet/outline_pr.rb +6 -3
  120. data/lib/axlsx/workbook/worksheet/page_margins.rb +17 -12
  121. data/lib/axlsx/workbook/worksheet/page_set_up_pr.rb +6 -4
  122. data/lib/axlsx/workbook/worksheet/page_setup.rb +128 -129
  123. data/lib/axlsx/workbook/worksheet/pane.rb +27 -26
  124. data/lib/axlsx/workbook/worksheet/pivot_table.rb +23 -25
  125. data/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +12 -13
  126. data/lib/axlsx/workbook/worksheet/pivot_tables.rb +5 -4
  127. data/lib/axlsx/workbook/worksheet/print_options.rb +3 -2
  128. data/lib/axlsx/workbook/worksheet/protected_range.rb +6 -5
  129. data/lib/axlsx/workbook/worksheet/protected_ranges.rb +12 -10
  130. data/lib/axlsx/workbook/worksheet/rich_text.rb +6 -6
  131. data/lib/axlsx/workbook/worksheet/rich_text_run.rb +35 -17
  132. data/lib/axlsx/workbook/worksheet/row.rb +30 -22
  133. data/lib/axlsx/workbook/worksheet/row_breaks.rb +8 -7
  134. data/lib/axlsx/workbook/worksheet/selection.rb +16 -16
  135. data/lib/axlsx/workbook/worksheet/sheet_calc_pr.rb +10 -7
  136. data/lib/axlsx/workbook/worksheet/sheet_data.rb +7 -7
  137. data/lib/axlsx/workbook/worksheet/sheet_format_pr.rb +23 -19
  138. data/lib/axlsx/workbook/worksheet/sheet_pr.rb +11 -7
  139. data/lib/axlsx/workbook/worksheet/sheet_protection.rb +21 -20
  140. data/lib/axlsx/workbook/worksheet/sheet_view.rb +48 -53
  141. data/lib/axlsx/workbook/worksheet/table.rb +13 -13
  142. data/lib/axlsx/workbook/worksheet/table_style_info.rb +6 -5
  143. data/lib/axlsx/workbook/worksheet/tables.rb +7 -5
  144. data/lib/axlsx/workbook/worksheet/worksheet.rb +92 -63
  145. data/lib/axlsx/workbook/worksheet/worksheet_comments.rb +10 -8
  146. data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +11 -4
  147. data/lib/axlsx/workbook/worksheet/worksheet_hyperlink.rb +9 -8
  148. data/lib/axlsx/workbook/worksheet/worksheet_hyperlinks.rb +7 -5
  149. data/lib/axlsx.rb +75 -47
  150. data/lib/caxlsx.rb +3 -2
  151. metadata +50 -44
@@ -1,5 +1,5 @@
1
- # encoding: UTF-8
2
- require 'cgi'
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 - Whether to treat a value starting with an equal
34
- # sign as formula (default) or as simple string.
35
- # Allowing user generated data to be interpreted as formulas can be dangerous
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 == 0
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] styles
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 [ArgumentExeption] Cell.type must be one of [:date, time, :float, :integer, :string, :boolean]
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 a value starting with an equal
138
- # sign as formula (default) or as simple string.
139
- # Allowing user generated data to be interpreted as formulas can be dangerous
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
- attr_reader :escape_formulas
146
+ def escape_formulas
147
+ defined?(@escape_formulas) ? @escape_formulas : row.worksheet.escape_formulas
148
+ end
143
149
 
144
- def escape_formulas=(v)
145
- Axlsx.validate_boolean(v)
146
- @escape_formulas = v
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) && # String typed
172
- !is_text_run? && # No inline styles
173
- !@value.nil? && # Not nil
174
- !@value.empty? && # Not empty
175
- !@value.start_with?(?=) # Not a formula
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, true
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(:rgb=>v)
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::cell_r index, @row.row_index
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 sell.
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
- "$#{r.match(%r{([A-Z]+)([0-9]+)})[1,2].join('$')}"
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::validate_unsigned_int(v)
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
- [self.r, target]
355
- elsif(target.is_a?(Cell))
356
- Axlsx.sort_cells([self, target]).map { |c| c.r }
377
+ [r, target]
378
+ elsif target.is_a?(Cell)
379
+ Axlsx.sort_cells([self, target]).map(&:r)
357
380
  end
358
- self.row.worksheet.merge_cells "#{start}:#{stop}" unless stop.nil?
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
- type == :string && @value.to_s.start_with?('{=') && @value.to_s.end_with?('}')
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 is_formula? || value.nil?
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 sanatized value
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::trust_input
422
- Axlsx::sanitize(::CGI.escapeHTML(@value.to_s))
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
- self.instance_variable_set :"@#{attr.to_s}", value
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::validate_unsigned_int(v)
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.to_s =~ Axlsx::NUMERIC_REGEX && v.respond_to?(:to_i)
510
+ elsif v.respond_to?(:to_i) && Axlsx::NUMERIC_REGEX.match?(v.to_s)
482
511
  :integer
483
- elsif v.to_s =~ Axlsx::SAFE_FLOAT_REGEX && v.respond_to?(:to_f)
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 (matchdata = v.to_s.match(MAYBE_FLOAT_REGEX)) && (Float::MIN_10_EXP..Float::MAX_10_EXP).cover?(matchdata[:exp].to_i) && v.respond_to?(:to_f)
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.is_a?(RichText) || v.nil?
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 self.style == 0
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 self.style == 0
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
- module Axlsx
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 << ('<c r="' << Axlsx::cell_r(column_index, row_index) << '" s="' << cell.style.to_s << '" ')
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
- self.send(method, cell, str)
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 = Hash[Axlsx.instance_values_for(cell).map{ |k, v| [k.to_sym, v] }]
26
- data = data.select { |key, value| valid.include?(key) && !value.nil? }
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 << ('<t>' << cell.clean_value << '</t>')
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::date_to_serial(cell.value).to_s, str
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::time_to_serial(cell.value).to_s, str
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 << ('t="str"><f>' << cell.clean_value.to_s.sub('=', '') << '</f>')
90
- str << ('<v>' << cell.formula_value.to_s << '</v>') unless cell.formula_value.nil?
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 << ('t="str">' << '<f t="array" ref="' << cell.r << '">' << cell.clean_value.to_s.sub('{=', '').sub(/}$/, '') << '</f>')
99
- str << ('<v>' << cell.formula_value.to_s << '</v>') unless cell.formula_value.nil?
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 << ('t="' << serialization_type.to_s << '"') if serialization_type
160
- str << ('><v>' << serialization_value.to_s << '</v>')
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::validate_conditional_formatting_value_object_type(v); @type = v end
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::validate_boolean(v); @gte = v end
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
- module Axlsx
1
+ # frozen_string_literal: true
2
2
 
3
- #A collection of Cfvo objects that initializes with the required
4
- #first two items
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