caxlsx 3.4.1 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (151) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +16 -1
  3. data/README.md +9 -11
  4. data/Rakefile +7 -5
  5. data/lib/axlsx/content_type/abstract_content_type.rb +9 -4
  6. data/lib/axlsx/content_type/content_type.rb +7 -5
  7. data/lib/axlsx/content_type/default.rb +4 -2
  8. data/lib/axlsx/content_type/override.rb +4 -2
  9. data/lib/axlsx/doc_props/app.rb +26 -24
  10. data/lib/axlsx/doc_props/core.rb +8 -6
  11. data/lib/axlsx/drawing/area_chart.rb +10 -8
  12. data/lib/axlsx/drawing/area_series.rb +12 -10
  13. data/lib/axlsx/drawing/ax_data_source.rb +2 -0
  14. data/lib/axlsx/drawing/axes.rb +6 -4
  15. data/lib/axlsx/drawing/axis.rb +21 -19
  16. data/lib/axlsx/drawing/bar_3D_chart.rb +14 -12
  17. data/lib/axlsx/drawing/bar_chart.rb +13 -11
  18. data/lib/axlsx/drawing/bar_series.rb +8 -6
  19. data/lib/axlsx/drawing/bubble_chart.rb +6 -4
  20. data/lib/axlsx/drawing/bubble_series.rb +8 -6
  21. data/lib/axlsx/drawing/cat_axis.rb +12 -10
  22. data/lib/axlsx/drawing/chart.rb +20 -18
  23. data/lib/axlsx/drawing/d_lbls.rb +7 -5
  24. data/lib/axlsx/drawing/drawing.rb +58 -56
  25. data/lib/axlsx/drawing/graphic_frame.rb +6 -4
  26. data/lib/axlsx/drawing/hyperlink.rb +10 -8
  27. data/lib/axlsx/drawing/line_3D_chart.rb +7 -5
  28. data/lib/axlsx/drawing/line_chart.rb +10 -8
  29. data/lib/axlsx/drawing/line_series.rb +12 -10
  30. data/lib/axlsx/drawing/marker.rb +9 -7
  31. data/lib/axlsx/drawing/num_data.rb +9 -7
  32. data/lib/axlsx/drawing/num_data_source.rb +9 -7
  33. data/lib/axlsx/drawing/num_val.rb +7 -5
  34. data/lib/axlsx/drawing/one_cell_anchor.rb +7 -5
  35. data/lib/axlsx/drawing/pic.rb +16 -14
  36. data/lib/axlsx/drawing/picture_locking.rb +3 -1
  37. data/lib/axlsx/drawing/pie_3D_chart.rb +5 -3
  38. data/lib/axlsx/drawing/pie_series.rb +8 -6
  39. data/lib/axlsx/drawing/scaling.rb +8 -6
  40. data/lib/axlsx/drawing/scatter_chart.rb +7 -5
  41. data/lib/axlsx/drawing/scatter_series.rb +14 -12
  42. data/lib/axlsx/drawing/ser_axis.rb +7 -5
  43. data/lib/axlsx/drawing/series.rb +6 -4
  44. data/lib/axlsx/drawing/series_title.rb +6 -4
  45. data/lib/axlsx/drawing/str_data.rb +7 -5
  46. data/lib/axlsx/drawing/str_val.rb +6 -4
  47. data/lib/axlsx/drawing/title.rb +13 -14
  48. data/lib/axlsx/drawing/two_cell_anchor.rb +4 -2
  49. data/lib/axlsx/drawing/val_axis.rb +4 -2
  50. data/lib/axlsx/drawing/view_3D.rb +9 -7
  51. data/lib/axlsx/drawing/vml_drawing.rb +18 -16
  52. data/lib/axlsx/drawing/vml_shape.rb +24 -22
  53. data/lib/axlsx/package.rb +69 -66
  54. data/lib/axlsx/rels/relationship.rb +10 -5
  55. data/lib/axlsx/rels/relationships.rb +5 -3
  56. data/lib/axlsx/stylesheet/border.rb +6 -4
  57. data/lib/axlsx/stylesheet/border_pr.rb +5 -3
  58. data/lib/axlsx/stylesheet/cell_alignment.rb +12 -10
  59. data/lib/axlsx/stylesheet/cell_protection.rb +5 -3
  60. data/lib/axlsx/stylesheet/cell_style.rb +10 -8
  61. data/lib/axlsx/stylesheet/color.rb +9 -7
  62. data/lib/axlsx/stylesheet/dxf.rb +5 -3
  63. data/lib/axlsx/stylesheet/fill.rb +3 -1
  64. data/lib/axlsx/stylesheet/font.rb +18 -16
  65. data/lib/axlsx/stylesheet/gradient_fill.rb +6 -4
  66. data/lib/axlsx/stylesheet/gradient_stop.rb +6 -4
  67. data/lib/axlsx/stylesheet/num_fmt.rb +8 -10
  68. data/lib/axlsx/stylesheet/pattern_fill.rb +5 -3
  69. data/lib/axlsx/stylesheet/styles.rb +69 -71
  70. data/lib/axlsx/stylesheet/table_style.rb +7 -5
  71. data/lib/axlsx/stylesheet/table_style_element.rb +6 -4
  72. data/lib/axlsx/stylesheet/table_styles.rb +6 -4
  73. data/lib/axlsx/stylesheet/xf.rb +18 -16
  74. data/lib/axlsx/util/accessors.rb +4 -2
  75. data/lib/axlsx/util/buffered_zip_output_stream.rb +60 -0
  76. data/lib/axlsx/util/constants.rb +117 -104
  77. data/lib/axlsx/util/mime_type_utils.rb +3 -5
  78. data/lib/axlsx/util/options_parser.rb +3 -1
  79. data/lib/axlsx/util/serialized_attributes.rb +42 -17
  80. data/lib/axlsx/util/simple_typed_list.rb +47 -47
  81. data/lib/axlsx/util/storage.rb +11 -10
  82. data/lib/axlsx/util/validators.rb +101 -41
  83. data/lib/axlsx/util/zip_command.rb +10 -10
  84. data/lib/axlsx/version.rb +3 -1
  85. data/lib/axlsx/workbook/defined_name.rb +6 -4
  86. data/lib/axlsx/workbook/defined_names.rb +3 -1
  87. data/lib/axlsx/workbook/shared_strings_table.rb +8 -6
  88. data/lib/axlsx/workbook/workbook.rb +78 -76
  89. data/lib/axlsx/workbook/workbook_view.rb +3 -1
  90. data/lib/axlsx/workbook/workbook_views.rb +3 -1
  91. data/lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb +65 -8
  92. data/lib/axlsx/workbook/worksheet/auto_filter/filter_column.rb +7 -3
  93. data/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +11 -7
  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 +5 -3
  97. data/lib/axlsx/workbook/worksheet/break.rb +3 -1
  98. data/lib/axlsx/workbook/worksheet/cell.rb +53 -54
  99. data/lib/axlsx/workbook/worksheet/cell_serializer.rb +31 -27
  100. data/lib/axlsx/workbook/worksheet/cfvo.rb +5 -3
  101. data/lib/axlsx/workbook/worksheet/cfvos.rb +3 -1
  102. data/lib/axlsx/workbook/worksheet/col.rb +5 -3
  103. data/lib/axlsx/workbook/worksheet/col_breaks.rb +5 -3
  104. data/lib/axlsx/workbook/worksheet/color_scale.rb +12 -10
  105. data/lib/axlsx/workbook/worksheet/cols.rb +3 -1
  106. data/lib/axlsx/workbook/worksheet/comment.rb +8 -6
  107. data/lib/axlsx/workbook/worksheet/comments.rb +6 -4
  108. data/lib/axlsx/workbook/worksheet/conditional_formatting.rb +9 -4
  109. data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +18 -16
  110. data/lib/axlsx/workbook/worksheet/conditional_formattings.rb +3 -1
  111. data/lib/axlsx/workbook/worksheet/data_bar.rb +14 -13
  112. data/lib/axlsx/workbook/worksheet/data_validation.rb +30 -28
  113. data/lib/axlsx/workbook/worksheet/data_validations.rb +3 -1
  114. data/lib/axlsx/workbook/worksheet/date_time_converter.rb +7 -5
  115. data/lib/axlsx/workbook/worksheet/dimension.rb +4 -2
  116. data/lib/axlsx/workbook/worksheet/header_footer.rb +4 -2
  117. data/lib/axlsx/workbook/worksheet/icon_set.rb +23 -6
  118. data/lib/axlsx/workbook/worksheet/merged_cells.rb +5 -5
  119. data/lib/axlsx/workbook/worksheet/outline_pr.rb +6 -2
  120. data/lib/axlsx/workbook/worksheet/page_margins.rb +15 -10
  121. data/lib/axlsx/workbook/worksheet/page_set_up_pr.rb +6 -2
  122. data/lib/axlsx/workbook/worksheet/page_setup.rb +11 -9
  123. data/lib/axlsx/workbook/worksheet/pane.rb +11 -9
  124. data/lib/axlsx/workbook/worksheet/pivot_table.rb +20 -19
  125. data/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +8 -6
  126. data/lib/axlsx/workbook/worksheet/pivot_tables.rb +2 -0
  127. data/lib/axlsx/workbook/worksheet/print_options.rb +3 -1
  128. data/lib/axlsx/workbook/worksheet/protected_range.rb +3 -1
  129. data/lib/axlsx/workbook/worksheet/protected_ranges.rb +5 -3
  130. data/lib/axlsx/workbook/worksheet/rich_text.rb +3 -1
  131. data/lib/axlsx/workbook/worksheet/rich_text_run.rb +16 -14
  132. data/lib/axlsx/workbook/worksheet/row.rb +6 -7
  133. data/lib/axlsx/workbook/worksheet/row_breaks.rb +6 -4
  134. data/lib/axlsx/workbook/worksheet/selection.rb +9 -7
  135. data/lib/axlsx/workbook/worksheet/sheet_calc_pr.rb +6 -2
  136. data/lib/axlsx/workbook/worksheet/sheet_data.rb +3 -1
  137. data/lib/axlsx/workbook/worksheet/sheet_format_pr.rb +6 -2
  138. data/lib/axlsx/workbook/worksheet/sheet_pr.rb +8 -4
  139. data/lib/axlsx/workbook/worksheet/sheet_protection.rb +10 -8
  140. data/lib/axlsx/workbook/worksheet/sheet_view.rb +15 -13
  141. data/lib/axlsx/workbook/worksheet/table.rb +9 -7
  142. data/lib/axlsx/workbook/worksheet/table_style_info.rb +4 -2
  143. data/lib/axlsx/workbook/worksheet/tables.rb +3 -1
  144. data/lib/axlsx/workbook/worksheet/worksheet.rb +38 -37
  145. data/lib/axlsx/workbook/worksheet/worksheet_comments.rb +4 -2
  146. data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +8 -2
  147. data/lib/axlsx/workbook/worksheet/worksheet_hyperlink.rb +6 -4
  148. data/lib/axlsx/workbook/worksheet/worksheet_hyperlinks.rb +4 -2
  149. data/lib/axlsx.rb +56 -42
  150. data/lib/caxlsx.rb +3 -1
  151. metadata +49 -43
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Axlsx
4
+ # This class represents a individual sort condition belonging to the sort state of an auto filter
5
+ class SortCondition
6
+ # Creates a new SortCondition object
7
+ # @param [Integer] column_index Zero-based index indicating the AutoFilter column to which the sorting should be applied to
8
+ # @param [Symbol] order The order the column should be sorted on, can only be :asc or :desc
9
+ # @param [Array] custom_list An array containg a custom sorting list in order.
10
+ def initialize(column_index:, order:, custom_list:)
11
+ Axlsx.validate_int column_index
12
+ @column_index = column_index
13
+
14
+ RestrictionValidator.validate 'SortCondition.order', [:asc, :desc], order
15
+ @order = order
16
+
17
+ DataTypeValidator.validate :sort_condition_custom_list, Array, custom_list
18
+ @custom_list = custom_list
19
+ end
20
+
21
+ attr_reader :column_index, :order, :custom_list
22
+
23
+ # converts the ref String from the sort_state to a string representing the ref of a single column
24
+ # for the xml string to be returned.
25
+ def ref_to_single_column(ref, column_index)
26
+ first_cell, last_cell = ref.split(':')
27
+
28
+ start_point = Axlsx.name_to_indices(first_cell)
29
+
30
+ first_row = first_cell[/\d+/]
31
+ last_row = last_cell[/\d+/]
32
+
33
+ first_column = Axlsx.col_ref(column_index + start_point.first)
34
+ last_column = first_column
35
+
36
+ "#{first_column}#{first_row}:#{last_column}#{last_row}"
37
+ end
38
+
39
+ # serialize the object
40
+ # @return [String]
41
+ def to_xml_string(str, ref)
42
+ ref = ref_to_single_column(ref, column_index)
43
+
44
+ str << "<sortCondition "
45
+ str << "descending='1' " if order == :desc
46
+ str << "ref='#{ref}' "
47
+ str << "customList='#{custom_list.join(',')}' " unless custom_list.empty?
48
+ str << "/>"
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'axlsx/workbook/worksheet/auto_filter/sort_condition'
4
+
5
+ module Axlsx
6
+ # This class performs sorting on a range in a worksheet
7
+ class SortState
8
+ # creates a new SortState object
9
+ # @param [AutoFilter] auto_filter the auto_filter that this sort_state belongs to
10
+ def initialize(auto_filter)
11
+ @auto_filter = auto_filter
12
+ end
13
+
14
+ # A collection of SortConditions for this sort_state
15
+ # @return [SimpleTypedList]
16
+ def sort_conditions
17
+ @sort_conditions ||= SimpleTypedList.new SortCondition
18
+ end
19
+
20
+ # Adds a SortCondition to the sort_state. This is the recommended way to add conditions to it.
21
+ # It requires a column_index for the sorting, descending and the custom order are optional.
22
+ # @param [Integer] column_index Zero-based index indicating the AutoFilter column to which the sorting should be applied to
23
+ # @param [Symbol] order The order the column should be sorted on, can only be :asc or :desc
24
+ # @param [Array] custom_list An array containg a custom sorting list in order.
25
+ # @return [SortCondition]
26
+ def add_sort_condition(column_index:, order: :asc, custom_list: [])
27
+ sort_conditions << SortCondition.new(column_index: column_index, order: order, custom_list: custom_list)
28
+ sort_conditions.last
29
+ end
30
+
31
+ # method to increment the String representing the first cell of the range of the autofilter by 1 row for the sortCondition
32
+ # xml string
33
+ def increment_cell_value(str)
34
+ letter = str[/[A-Za-z]+/]
35
+ number = str[/\d+/].to_i
36
+
37
+ incremented_number = number + 1
38
+
39
+ "#{letter}#{incremented_number}"
40
+ end
41
+
42
+ # serialize the object
43
+ # @return [String]
44
+ def to_xml_string(str = +'')
45
+ return if sort_conditions.empty?
46
+
47
+ ref = @auto_filter.range
48
+ first_cell, last_cell = ref.split(':')
49
+ ref = "#{increment_cell_value(first_cell)}:#{last_cell}"
50
+
51
+ str << "<sortState xmlns:xlrd2='http://schemas.microsoft.com/office/spreadsheetml/2017/richdata2' ref='#{ref}'>"
52
+ sort_conditions.each { |sort_condition| sort_condition.to_xml_string(str, ref) }
53
+ str << "</sortState>"
54
+ end
55
+ end
56
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Axlsx
2
4
  class BorderCreator
3
5
  def initialize(worksheet:, cells:, edges: nil, style: nil, color: nil)
@@ -11,12 +13,12 @@ module Axlsx
11
13
  if @edges == :all
12
14
  @edges = Axlsx::Border::EDGES
13
15
  elsif !@edges.is_a?(Array)
14
- raise ArgumentError.new("Invalid edges provided, #{@edges}")
16
+ raise ArgumentError, "Invalid edges provided, #{@edges}"
15
17
  else
16
18
  @edges = @edges.map { |x| x&.to_sym }.uniq
17
19
 
18
- if !(@edges - Axlsx::Border::EDGES).empty?
19
- raise ArgumentError.new("Invalid edges provided, #{edges}")
20
+ unless (@edges - Axlsx::Border::EDGES).empty?
21
+ raise ArgumentError, "Invalid edges provided, #{edges}"
20
22
  end
21
23
  end
22
24
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Axlsx
2
4
  # The Break class stores the details for row and column page breaks.
3
5
  # @see RowBreaks, ColBreaks
@@ -25,7 +27,7 @@ module Axlsx
25
27
  serializable_attributes :id, :min, :max, :man, :pt
26
28
 
27
29
  # serializes the break to xml
28
- def to_xml_string(str = '')
30
+ def to_xml_string(str = +'')
29
31
  serialized_tag('brk', str)
30
32
  end
31
33
  end
@@ -1,4 +1,5 @@
1
- require 'cgi'
1
+ # frozen_string_literal: true
2
+
2
3
  module Axlsx
3
4
  # A cell in a worksheet.
4
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.
@@ -40,12 +41,13 @@ module Axlsx
40
41
  self.type = type unless type == :string
41
42
 
42
43
  val = options.delete(:style)
43
- self.style = val unless val.nil? || val == 0
44
+ self.style = val unless val.nil? || val.zero?
44
45
  val = options.delete(:formula_value)
45
46
  self.formula_value = val unless val.nil?
47
+ val = options.delete(:escape_formulas)
48
+ self.escape_formulas = val unless val.nil?
46
49
 
47
- parse_options(options)
48
- self.escape_formulas = row.worksheet.escape_formulas if escape_formulas.nil?
50
+ parse_options(options) unless options.empty?
49
51
 
50
52
  self.value = value
51
53
  value.cell = self if contains_rich_text?
@@ -70,15 +72,8 @@ module Axlsx
70
72
  CELL_TYPES = [:date, :time, :float, :integer, :richtext,
71
73
  :string, :boolean, :iso_8601, :text].freeze
72
74
 
73
- # Leading characters that indicate a formula.
74
- # See: https://owasp.org/www-community/attacks/CSV_Injection
75
- FORMULA_PREFIXES = ['='.freeze].freeze
76
-
77
- # Leading characters that indicate an array formula.
78
- ARRAY_FORMULA_PREFIXES = ['{='.freeze].freeze
79
-
80
- # Trailing character that indicates an array formula.
81
- ARRAY_FORMULA_SUFFIX = '}'.freeze
75
+ # A regular expression to match the alpha(column)numeric(row) reference of a cell
76
+ CELL_REFERENCE_REGEX = /([A-Z]+)([0-9]+)/.freeze
82
77
 
83
78
  # The index of the cellXfs item to be applied to this cell.
84
79
  # @return [Integer]
@@ -87,10 +82,15 @@ module Axlsx
87
82
  defined?(@style) ? @style : 0
88
83
  end
89
84
 
85
+ # Internal
86
+ def style_str
87
+ defined?(@style) ? @style.to_s : '0'
88
+ end
89
+
90
90
  attr_accessor :raw_style
91
91
 
92
92
  # The index of the cellXfs item to be applied to this cell.
93
- # @param [Hash] styles
93
+ # @param [Hash] style
94
94
  # @see Axlsx::Styles
95
95
  def add_style(style)
96
96
  self.raw_style ||= {}
@@ -122,7 +122,7 @@ module Axlsx
122
122
  # automatically determed.
123
123
  # @see Cell#cell_type_from_value
124
124
  # @return [Symbol] The type of data this cell's value is cast to.
125
- # @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]
126
126
  # @note
127
127
  # If the value provided cannot be cast into the type specified, type is changed to :string and the following logic is applied.
128
128
  # :string to :integer or :float, type conversions always return 0 or 0.0
@@ -143,7 +143,9 @@ module Axlsx
143
143
  # Allowing user-generated data to be interpreted as formulas is a security risk.
144
144
  # See https://www.owasp.org/index.php/CSV_Injection for details.
145
145
  # @return [Boolean]
146
- attr_reader :escape_formulas
146
+ def escape_formulas
147
+ defined?(@escape_formulas) ? @escape_formulas : row.worksheet.escape_formulas
148
+ end
147
149
 
148
150
  # Sets whether to treat values starting with an equals sign as formulas or as literal strings.
149
151
  # @param [Boolean] value The value to set.
@@ -164,7 +166,7 @@ module Axlsx
164
166
 
165
167
  # Indicates that the cell has one or more of the custom cell styles applied.
166
168
  # @return [Boolean]
167
- def is_text_run?
169
+ def is_text_run? # rubocop:disable Naming/PredicateName
168
170
  defined?(@is_text_run) && @is_text_run && !contains_rich_text?
169
171
  end
170
172
 
@@ -174,12 +176,12 @@ module Axlsx
174
176
 
175
177
  # Indicates if the cell is good for shared string table
176
178
  def plain_string?
177
- (type == :string || type == :text) && # String typed
178
- !is_text_run? && # No inline styles
179
- !@value.nil? && # Not nil
180
- !@value.empty? && # Not empty
181
- !is_formula? && # Not a formula
182
- !is_array_formula? # Not an array 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?
183
185
  end
184
186
 
185
187
  # The inline font_name property for the cell
@@ -280,15 +282,13 @@ module Axlsx
280
282
  def extend=(v) set_run_style :validate_boolean, :extend, v; end
281
283
 
282
284
  # The inline underline property for the cell.
283
- # It must be one of :none, :single, :double, :singleAccounting, :doubleAccounting, true
285
+ # It must be one of :none, :single, :double, :singleAccounting, :doubleAccounting
284
286
  # @return [Boolean]
285
287
  # @return [String]
286
- # @note true is for backwards compatability and is reassigned to :single
287
288
  attr_reader :u
288
289
 
289
290
  # @see u
290
291
  def u=(v)
291
- v = :single if (v == true || v == 1 || v == :true || v == 'true')
292
292
  set_run_style :validate_cell_u, :u, v
293
293
  end
294
294
 
@@ -298,7 +298,7 @@ module Axlsx
298
298
 
299
299
  # @param [String] v The 8 character representation for an rgb color #FFFFFFFF"
300
300
  def color=(v)
301
- @color = v.is_a?(Color) ? v : Color.new(:rgb => v)
301
+ @color = v.is_a?(Color) ? v : Color.new(rgb: v)
302
302
  @is_text_run = true
303
303
  end
304
304
 
@@ -344,20 +344,20 @@ module Axlsx
344
344
  # @example Relative Cell Reference
345
345
  # ws.rows.first.cells.first.r #=> "A1"
346
346
  def r
347
- Axlsx::cell_r index, @row.row_index
347
+ Axlsx.cell_r index, @row.row_index
348
348
  end
349
349
 
350
- # @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.
351
351
  # @example Absolute Cell Reference
352
352
  # ws.rows.first.cells.first.r #=> "$A$1"
353
353
  def r_abs
354
- "$#{r.match(%r{([A-Z]+)([0-9]+)})[1, 2].join('$')}"
354
+ "$#{CELL_REFERENCE_REGEX.match(r)[1, 2].join('$')}"
355
355
  end
356
356
 
357
357
  # @return [Integer] The cellXfs item index applied to this cell.
358
358
  # @raise [ArgumentError] Invalid cellXfs id if the value provided is not within cellXfs items range.
359
359
  def style=(v)
360
- Axlsx::validate_unsigned_int(v)
360
+ Axlsx.validate_unsigned_int(v)
361
361
  count = styles.cellXfs.size
362
362
  raise ArgumentError, "Invalid cellXfs id" unless v < count
363
363
 
@@ -374,11 +374,11 @@ module Axlsx
374
374
  # @param [Cell, String] target The last cell, or str ref for the cell in the merge range
375
375
  def merge(target)
376
376
  start, stop = if target.is_a?(String)
377
- [self.r, target]
377
+ [r, target]
378
378
  elsif target.is_a?(Cell)
379
- Axlsx.sort_cells([self, target]).map { |c| c.r }
379
+ Axlsx.sort_cells([self, target]).map(&:r)
380
380
  end
381
- self.row.worksheet.merge_cells "#{start}:#{stop}" unless stop.nil?
381
+ row.worksheet.merge_cells "#{start}:#{stop}" unless stop.nil?
382
382
  end
383
383
 
384
384
  # Serializes the cell
@@ -386,21 +386,21 @@ module Axlsx
386
386
  # @param [Integer] c_index The cell index in the row.
387
387
  # @param [String] str The string index the cell content will be appended to. Defaults to empty string.
388
388
  # @return [String] xml text for the cell
389
- def to_xml_string(r_index, c_index, str = '')
389
+ def to_xml_string(r_index, c_index, str = +'')
390
390
  CellSerializer.to_xml_string r_index, c_index, self, str
391
391
  end
392
392
 
393
- def is_formula?
393
+ def is_formula? # rubocop:disable Naming/PredicateName
394
394
  return false if escape_formulas
395
395
 
396
- type == :string && @value.to_s.start_with?(*FORMULA_PREFIXES)
396
+ type == :string && @value.to_s.start_with?(FORMULA_PREFIX)
397
397
  end
398
398
 
399
- def is_array_formula?
399
+ def is_array_formula? # rubocop:disable Naming/PredicateName
400
400
  return false if escape_formulas
401
401
 
402
402
  type == :string &&
403
- @value.to_s.start_with?(*ARRAY_FORMULA_PREFIXES) &&
403
+ @value.to_s.start_with?(ARRAY_FORMULA_PREFIX) &&
404
404
  @value.to_s.end_with?(ARRAY_FORMULA_SUFFIX)
405
405
  end
406
406
 
@@ -425,7 +425,7 @@ module Axlsx
425
425
  # Attempts to determine the correct width for this cell's content
426
426
  # @return [Float]
427
427
  def autowidth
428
- return if is_formula? || value.nil?
428
+ return if value.nil? || is_formula?
429
429
 
430
430
  if contains_rich_text?
431
431
  string_width('', font_size) + value.autowidth
@@ -441,12 +441,13 @@ module Axlsx
441
441
  end
442
442
  end
443
443
 
444
- # Returns the sanatized value
445
- # 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
446
446
  # processing time in benchmarking...
447
+ # @return [String] The sanitized value
447
448
  def clean_value
448
- if (type == :string || type == :text) && !Axlsx::trust_input
449
- Axlsx::sanitize(::CGI.escapeHTML(@value.to_s))
449
+ if (type == :string || type == :text) && !Axlsx.trust_input
450
+ Axlsx.sanitize(::CGI.escapeHTML(@value.to_s))
450
451
  else
451
452
  @value.to_s
452
453
  end
@@ -481,13 +482,13 @@ module Axlsx
481
482
  return unless INLINE_STYLES.include?(attr.to_sym)
482
483
 
483
484
  Axlsx.send(validator, value) unless validator.nil?
484
- self.instance_variable_set :"@#{attr.to_s}", value
485
+ instance_variable_set :"@#{attr}", value
485
486
  @is_text_run = true
486
487
  end
487
488
 
488
489
  # @see ssti
489
490
  def ssti=(v)
490
- Axlsx::validate_unsigned_int(v)
491
+ Axlsx.validate_unsigned_int(v)
491
492
  @ssti = v
492
493
  end
493
494
 
@@ -506,13 +507,11 @@ module Axlsx
506
507
  :time
507
508
  elsif v.is_a?(TrueClass) || v.is_a?(FalseClass)
508
509
  :boolean
509
- 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)
510
511
  :integer
511
- elsif v.to_s =~ Axlsx::SAFE_FLOAT_REGEX && v.respond_to?(:to_f)
512
- :float
513
- 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)
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)))
514
513
  :float
515
- elsif v.to_s =~ Axlsx::ISO_8601_REGEX
514
+ elsif Axlsx::ISO_8601_REGEX.match?(v.to_s)
516
515
  :iso_8601
517
516
  elsif v.is_a? RichText
518
517
  :richtext
@@ -526,18 +525,18 @@ module Axlsx
526
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.
527
526
  # @see Axlsx#date1904
528
527
  def cast_value(v)
529
- return v if v.is_a?(RichText) || v.nil?
528
+ return v if v.nil? || v.is_a?(RichText)
530
529
 
531
530
  case type
532
531
  when :date
533
- self.style = STYLE_DATE if self.style == 0
532
+ self.style = STYLE_DATE if style.zero?
534
533
  if !v.is_a?(Date) && v.respond_to?(:to_date)
535
534
  v.to_date
536
535
  else
537
536
  v
538
537
  end
539
538
  when :time
540
- self.style = STYLE_DATE if self.style == 0
539
+ self.style = STYLE_DATE if style.zero?
541
540
  if !v.is_a?(Time) && v.respond_to?(:to_time)
542
541
  v.to_time
543
542
  else
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Axlsx
2
4
  # The Cell Serializer class contains the logic for serializing cells based on their type.
3
5
  class CellSerializer
@@ -7,28 +9,30 @@ module Axlsx
7
9
  # @param [Integer] column_index The index of the cell's column
8
10
  # @param [String] str The string to apend serialization to.
9
11
  # @return [String]
10
- def to_xml_string(row_index, column_index, cell, str = '')
11
- 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 << '" '
12
16
  return str << '/>' if cell.value.nil?
13
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
@@ -38,10 +40,10 @@ module Axlsx
38
40
  attr_reader :val
39
41
 
40
42
  # @see type
41
- 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
42
44
 
43
45
  # @see gte
44
- def gte=(v); Axlsx::validate_boolean(v); @gte = v end
46
+ def gte=(v); Axlsx.validate_boolean(v); @gte = v end
45
47
 
46
48
  # @see val
47
49
  def val=(v)
@@ -53,7 +55,7 @@ module Axlsx
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,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Axlsx
2
4
  # A collection of Cfvo objects that initializes with the required
3
5
  # first two items
@@ -9,7 +11,7 @@ module Axlsx
9
11
  # Serialize the Cfvo object
10
12
  # @param [String] str
11
13
  # @return [String]
12
- def to_xml_string(str = '')
14
+ def to_xml_string(str = +'')
13
15
  each { |cfvo| cfvo.to_xml_string(str) }
14
16
  end
15
17
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Axlsx
2
4
  # The Col class defines column attributes for columns in sheets.
3
5
  class Col
@@ -86,7 +88,7 @@ module Axlsx
86
88
  # @see Col#outline
87
89
  def outline_level=(v)
88
90
  Axlsx.validate_unsigned_numeric(v)
89
- raise ArgumentError, 'outlineLevel must be between 0 and 7' unless 0 <= v && v <= 7
91
+ raise ArgumentError, 'outlineLevel must be between 0 and 7' unless v >= 0 && v <= 7
90
92
 
91
93
  @outline_level = v
92
94
  end
@@ -112,7 +114,7 @@ module Axlsx
112
114
  # current @width value.
113
115
  # TODO!!!
114
116
  # Axlsx.validate_unsigned_numeric(v) unless v == nil
115
- @custom_width = @best_fit = v != nil
117
+ @custom_width = @best_fit = !v.nil?
116
118
  @width = v.nil? ? v : [v, MAX_WIDTH].min
117
119
  end
118
120
 
@@ -135,7 +137,7 @@ module Axlsx
135
137
  # Serialize this columns data to an xml string
136
138
  # @param [String] str
137
139
  # @return [String]
138
- def to_xml_string(str = '')
140
+ def to_xml_string(str = +'')
139
141
  serialized_tag('col', str)
140
142
  end
141
143
  end