caxlsx 3.4.1 → 4.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (153) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +24 -1
  3. data/README.md +9 -11
  4. data/Rakefile +7 -5
  5. data/examples/generate.rb +3 -1
  6. data/lib/axlsx/content_type/abstract_content_type.rb +12 -4
  7. data/lib/axlsx/content_type/content_type.rb +8 -6
  8. data/lib/axlsx/content_type/default.rb +7 -2
  9. data/lib/axlsx/content_type/override.rb +7 -2
  10. data/lib/axlsx/doc_props/app.rb +95 -26
  11. data/lib/axlsx/doc_props/core.rb +8 -6
  12. data/lib/axlsx/drawing/area_chart.rb +10 -8
  13. data/lib/axlsx/drawing/area_series.rb +20 -12
  14. data/lib/axlsx/drawing/ax_data_source.rb +2 -0
  15. data/lib/axlsx/drawing/axes.rb +6 -4
  16. data/lib/axlsx/drawing/axis.rb +42 -22
  17. data/lib/axlsx/drawing/bar_3D_chart.rb +14 -12
  18. data/lib/axlsx/drawing/bar_chart.rb +13 -11
  19. data/lib/axlsx/drawing/bar_series.rb +20 -9
  20. data/lib/axlsx/drawing/bubble_chart.rb +6 -4
  21. data/lib/axlsx/drawing/bubble_series.rb +8 -6
  22. data/lib/axlsx/drawing/cat_axis.rb +29 -12
  23. data/lib/axlsx/drawing/chart.rb +46 -20
  24. data/lib/axlsx/drawing/d_lbls.rb +10 -8
  25. data/lib/axlsx/drawing/drawing.rb +59 -56
  26. data/lib/axlsx/drawing/graphic_frame.rb +6 -4
  27. data/lib/axlsx/drawing/hyperlink.rb +19 -8
  28. data/lib/axlsx/drawing/line_3D_chart.rb +7 -5
  29. data/lib/axlsx/drawing/line_chart.rb +10 -8
  30. data/lib/axlsx/drawing/line_series.rb +20 -12
  31. data/lib/axlsx/drawing/marker.rb +24 -7
  32. data/lib/axlsx/drawing/num_data.rb +9 -7
  33. data/lib/axlsx/drawing/num_data_source.rb +9 -7
  34. data/lib/axlsx/drawing/num_val.rb +7 -5
  35. data/lib/axlsx/drawing/one_cell_anchor.rb +13 -5
  36. data/lib/axlsx/drawing/pic.rb +26 -15
  37. data/lib/axlsx/drawing/picture_locking.rb +3 -1
  38. data/lib/axlsx/drawing/pie_3D_chart.rb +6 -4
  39. data/lib/axlsx/drawing/pie_chart.rb +36 -0
  40. data/lib/axlsx/drawing/pie_series.rb +23 -9
  41. data/lib/axlsx/drawing/scaling.rb +25 -9
  42. data/lib/axlsx/drawing/scatter_chart.rb +7 -5
  43. data/lib/axlsx/drawing/scatter_series.rb +14 -12
  44. data/lib/axlsx/drawing/ser_axis.rb +13 -5
  45. data/lib/axlsx/drawing/series.rb +13 -5
  46. data/lib/axlsx/drawing/series_title.rb +6 -4
  47. data/lib/axlsx/drawing/str_data.rb +7 -5
  48. data/lib/axlsx/drawing/str_val.rb +6 -4
  49. data/lib/axlsx/drawing/title.rb +13 -14
  50. data/lib/axlsx/drawing/two_cell_anchor.rb +4 -2
  51. data/lib/axlsx/drawing/val_axis.rb +4 -2
  52. data/lib/axlsx/drawing/view_3D.rb +16 -8
  53. data/lib/axlsx/drawing/vml_drawing.rb +18 -16
  54. data/lib/axlsx/drawing/vml_shape.rb +24 -22
  55. data/lib/axlsx/package.rb +73 -67
  56. data/lib/axlsx/rels/relationship.rb +21 -6
  57. data/lib/axlsx/rels/relationships.rb +6 -4
  58. data/lib/axlsx/stylesheet/border.rb +15 -4
  59. data/lib/axlsx/stylesheet/border_pr.rb +19 -6
  60. data/lib/axlsx/stylesheet/cell_alignment.rb +41 -10
  61. data/lib/axlsx/stylesheet/cell_protection.rb +12 -3
  62. data/lib/axlsx/stylesheet/cell_style.rb +33 -8
  63. data/lib/axlsx/stylesheet/color.rb +15 -7
  64. data/lib/axlsx/stylesheet/dxf.rb +34 -9
  65. data/lib/axlsx/stylesheet/fill.rb +7 -2
  66. data/lib/axlsx/stylesheet/font.rb +65 -17
  67. data/lib/axlsx/stylesheet/gradient_fill.rb +12 -4
  68. data/lib/axlsx/stylesheet/gradient_stop.rb +14 -5
  69. data/lib/axlsx/stylesheet/num_fmt.rb +14 -10
  70. data/lib/axlsx/stylesheet/pattern_fill.rb +18 -5
  71. data/lib/axlsx/stylesheet/styles.rb +124 -82
  72. data/lib/axlsx/stylesheet/table_style.rb +19 -6
  73. data/lib/axlsx/stylesheet/table_style_element.rb +15 -4
  74. data/lib/axlsx/stylesheet/table_styles.rb +14 -5
  75. data/lib/axlsx/stylesheet/xf.rb +73 -18
  76. data/lib/axlsx/util/accessors.rb +10 -6
  77. data/lib/axlsx/util/buffered_zip_output_stream.rb +60 -0
  78. data/lib/axlsx/util/constants.rb +117 -104
  79. data/lib/axlsx/util/mime_type_utils.rb +3 -5
  80. data/lib/axlsx/util/options_parser.rb +3 -1
  81. data/lib/axlsx/util/serialized_attributes.rb +42 -17
  82. data/lib/axlsx/util/simple_typed_list.rb +47 -47
  83. data/lib/axlsx/util/storage.rb +11 -10
  84. data/lib/axlsx/util/validators.rb +101 -41
  85. data/lib/axlsx/util/zip_command.rb +10 -10
  86. data/lib/axlsx/version.rb +3 -1
  87. data/lib/axlsx/workbook/defined_name.rb +6 -4
  88. data/lib/axlsx/workbook/defined_names.rb +4 -2
  89. data/lib/axlsx/workbook/shared_strings_table.rb +8 -6
  90. data/lib/axlsx/workbook/workbook.rb +94 -79
  91. data/lib/axlsx/workbook/workbook_view.rb +3 -1
  92. data/lib/axlsx/workbook/workbook_views.rb +4 -2
  93. data/lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb +65 -8
  94. data/lib/axlsx/workbook/worksheet/auto_filter/filter_column.rb +11 -5
  95. data/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +11 -7
  96. data/lib/axlsx/workbook/worksheet/auto_filter/sort_condition.rb +51 -0
  97. data/lib/axlsx/workbook/worksheet/auto_filter/sort_state.rb +56 -0
  98. data/lib/axlsx/workbook/worksheet/border_creator.rb +5 -3
  99. data/lib/axlsx/workbook/worksheet/break.rb +3 -1
  100. data/lib/axlsx/workbook/worksheet/cell.rb +83 -64
  101. data/lib/axlsx/workbook/worksheet/cell_serializer.rb +31 -27
  102. data/lib/axlsx/workbook/worksheet/cfvo.rb +11 -3
  103. data/lib/axlsx/workbook/worksheet/cfvos.rb +3 -1
  104. data/lib/axlsx/workbook/worksheet/col.rb +5 -3
  105. data/lib/axlsx/workbook/worksheet/col_breaks.rb +6 -4
  106. data/lib/axlsx/workbook/worksheet/color_scale.rb +12 -10
  107. data/lib/axlsx/workbook/worksheet/cols.rb +4 -2
  108. data/lib/axlsx/workbook/worksheet/comment.rb +8 -6
  109. data/lib/axlsx/workbook/worksheet/comments.rb +6 -4
  110. data/lib/axlsx/workbook/worksheet/conditional_formatting.rb +16 -5
  111. data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +73 -16
  112. data/lib/axlsx/workbook/worksheet/conditional_formattings.rb +4 -2
  113. data/lib/axlsx/workbook/worksheet/data_bar.rb +14 -13
  114. data/lib/axlsx/workbook/worksheet/data_validation.rb +69 -28
  115. data/lib/axlsx/workbook/worksheet/data_validations.rb +4 -2
  116. data/lib/axlsx/workbook/worksheet/date_time_converter.rb +7 -5
  117. data/lib/axlsx/workbook/worksheet/dimension.rb +4 -2
  118. data/lib/axlsx/workbook/worksheet/header_footer.rb +4 -2
  119. data/lib/axlsx/workbook/worksheet/icon_set.rb +38 -9
  120. data/lib/axlsx/workbook/worksheet/merged_cells.rb +6 -6
  121. data/lib/axlsx/workbook/worksheet/outline_pr.rb +6 -2
  122. data/lib/axlsx/workbook/worksheet/page_margins.rb +39 -11
  123. data/lib/axlsx/workbook/worksheet/page_set_up_pr.rb +7 -4
  124. data/lib/axlsx/workbook/worksheet/page_setup.rb +34 -9
  125. data/lib/axlsx/workbook/worksheet/pane.rb +17 -9
  126. data/lib/axlsx/workbook/worksheet/pivot_table.rb +20 -19
  127. data/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +8 -6
  128. data/lib/axlsx/workbook/worksheet/pivot_tables.rb +3 -1
  129. data/lib/axlsx/workbook/worksheet/print_options.rb +3 -1
  130. data/lib/axlsx/workbook/worksheet/protected_range.rb +3 -1
  131. data/lib/axlsx/workbook/worksheet/protected_ranges.rb +6 -4
  132. data/lib/axlsx/workbook/worksheet/rich_text.rb +3 -1
  133. data/lib/axlsx/workbook/worksheet/rich_text_run.rb +46 -24
  134. data/lib/axlsx/workbook/worksheet/row.rb +11 -9
  135. data/lib/axlsx/workbook/worksheet/row_breaks.rb +7 -5
  136. data/lib/axlsx/workbook/worksheet/selection.rb +15 -7
  137. data/lib/axlsx/workbook/worksheet/sheet_calc_pr.rb +6 -2
  138. data/lib/axlsx/workbook/worksheet/sheet_data.rb +3 -1
  139. data/lib/axlsx/workbook/worksheet/sheet_format_pr.rb +6 -2
  140. data/lib/axlsx/workbook/worksheet/sheet_pr.rb +8 -4
  141. data/lib/axlsx/workbook/worksheet/sheet_protection.rb +11 -9
  142. data/lib/axlsx/workbook/worksheet/sheet_view.rb +38 -15
  143. data/lib/axlsx/workbook/worksheet/table.rb +9 -7
  144. data/lib/axlsx/workbook/worksheet/table_style_info.rb +4 -2
  145. data/lib/axlsx/workbook/worksheet/tables.rb +4 -2
  146. data/lib/axlsx/workbook/worksheet/worksheet.rb +56 -39
  147. data/lib/axlsx/workbook/worksheet/worksheet_comments.rb +4 -2
  148. data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +8 -2
  149. data/lib/axlsx/workbook/worksheet/worksheet_hyperlink.rb +7 -5
  150. data/lib/axlsx/workbook/worksheet/worksheet_hyperlinks.rb +5 -3
  151. data/lib/axlsx.rb +56 -42
  152. data/lib/caxlsx.rb +3 -1
  153. metadata +39 -71
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Axlsx
2
4
  # When multiple values are chosen to filter by, or when a group of date values are chosen to filter by,
3
5
  # this object groups those criteria together.
@@ -22,7 +24,7 @@ module Axlsx
22
24
  serializable_attributes :blank, :calendar_type
23
25
 
24
26
  # Allowed calendar types
25
- CALENDAR_TYPES = %w(gregorian gregorianUs gregorianMeFrench gregorianArabic hijri hebrew taiwan japan thai korea saka gregorianXlitEnglish gregorianXlitFrench none)
27
+ CALENDAR_TYPES = %w(gregorian gregorianUs gregorianMeFrench gregorianArabic hijri hebrew taiwan japan thai korea saka gregorianXlitEnglish gregorianXlitFrench none).freeze
26
28
 
27
29
  # Flag indicating whether to filter by blank.
28
30
  # @return [Boolean]
@@ -74,8 +76,10 @@ module Axlsx
74
76
  end
75
77
 
76
78
  # Serialize the object to xml
77
- def to_xml_string(str = '')
78
- str << "<filters #{serialized_attributes}>"
79
+ def to_xml_string(str = +'')
80
+ str << '<filters '
81
+ serialized_attributes(str)
82
+ str << '>'
79
83
  filter_items.each { |filter| filter.to_xml_string(str) }
80
84
  date_group_items.each { |date_group_item| date_group_item.to_xml_string(str) }
81
85
  str << '</filters>'
@@ -118,8 +122,8 @@ module Axlsx
118
122
 
119
123
  # Serializes the filter value object
120
124
  # @param [String] str The string to concact the serialization information to.
121
- def to_xml_string(str = '')
122
- str << "<filter val='#{@val.to_s}' />"
125
+ def to_xml_string(str = +'')
126
+ str << "<filter val='#{@val}' />"
123
127
  end
124
128
  end
125
129
 
@@ -153,7 +157,7 @@ module Axlsx
153
157
  serializable_attributes :date_time_grouping, :year, :month, :day, :hour, :minute, :second
154
158
 
155
159
  # Allowed date time groupings
156
- DATE_TIME_GROUPING = %w(year month day hour minute second)
160
+ DATE_TIME_GROUPING = %w(year month day hour minute second).freeze
157
161
 
158
162
  # Grouping level
159
163
  # This must be one of year, month, day, hour, minute or second.
@@ -235,7 +239,7 @@ module Axlsx
235
239
 
236
240
  # Serialize the object to xml
237
241
  # @param [String] str The string object this serialization will be concatenated to.
238
- def to_xml_string(str = '')
242
+ def to_xml_string(str = +'')
239
243
  serialized_tag('dateGroupItem', str)
240
244
  end
241
245
  end
@@ -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
@@ -187,7 +189,9 @@ module Axlsx
187
189
  attr_reader :font_name
188
190
 
189
191
  # @see font_name
190
- def font_name=(v) set_run_style :validate_string, :font_name, v; end
192
+ def font_name=(v)
193
+ set_run_style :validate_string, :font_name, v
194
+ end
191
195
 
192
196
  # The inline charset property for the cell
193
197
  # As far as I can tell, this is pretty much ignored. However, based on the spec it should be one of the following:
@@ -214,7 +218,9 @@ module Axlsx
214
218
  attr_reader :charset
215
219
 
216
220
  # @see charset
217
- def charset=(v) set_run_style :validate_unsigned_int, :charset, v; end
221
+ def charset=(v)
222
+ set_run_style :validate_unsigned_int, :charset, v
223
+ end
218
224
 
219
225
  # The inline family property for the cell
220
226
  # @return [Integer]
@@ -235,60 +241,72 @@ module Axlsx
235
241
  attr_reader :b
236
242
 
237
243
  # @see b
238
- def b=(v) set_run_style :validate_boolean, :b, v; end
244
+ def b=(v)
245
+ set_run_style :validate_boolean, :b, v
246
+ end
239
247
 
240
248
  # The inline italic property for the cell
241
249
  # @return [Boolean]
242
250
  attr_reader :i
243
251
 
244
252
  # @see i
245
- def i=(v) set_run_style :validate_boolean, :i, v; end
253
+ def i=(v)
254
+ set_run_style :validate_boolean, :i, v
255
+ end
246
256
 
247
257
  # The inline strike property for the cell
248
258
  # @return [Boolean]
249
259
  attr_reader :strike
250
260
 
251
261
  # @see strike
252
- def strike=(v) set_run_style :validate_boolean, :strike, v; end
262
+ def strike=(v)
263
+ set_run_style :validate_boolean, :strike, v
264
+ end
253
265
 
254
266
  # The inline outline property for the cell
255
267
  # @return [Boolean]
256
268
  attr_reader :outline
257
269
 
258
270
  # @see outline
259
- def outline=(v) set_run_style :validate_boolean, :outline, v; end
271
+ def outline=(v)
272
+ set_run_style :validate_boolean, :outline, v
273
+ end
260
274
 
261
275
  # The inline shadow property for the cell
262
276
  # @return [Boolean]
263
277
  attr_reader :shadow
264
278
 
265
279
  # @see shadow
266
- def shadow=(v) set_run_style :validate_boolean, :shadow, v; end
280
+ def shadow=(v)
281
+ set_run_style :validate_boolean, :shadow, v
282
+ end
267
283
 
268
284
  # The inline condense property for the cell
269
285
  # @return [Boolean]
270
286
  attr_reader :condense
271
287
 
272
288
  # @see condense
273
- def condense=(v) set_run_style :validate_boolean, :condense, v; end
289
+ def condense=(v)
290
+ set_run_style :validate_boolean, :condense, v
291
+ end
274
292
 
275
293
  # The inline extend property for the cell
276
294
  # @return [Boolean]
277
295
  attr_reader :extend
278
296
 
279
297
  # @see extend
280
- def extend=(v) set_run_style :validate_boolean, :extend, v; end
298
+ def extend=(v)
299
+ set_run_style :validate_boolean, :extend, v
300
+ end
281
301
 
282
302
  # The inline underline property for the cell.
283
- # It must be one of :none, :single, :double, :singleAccounting, :doubleAccounting, true
303
+ # It must be one of :none, :single, :double, :singleAccounting, :doubleAccounting
284
304
  # @return [Boolean]
285
305
  # @return [String]
286
- # @note true is for backwards compatability and is reassigned to :single
287
306
  attr_reader :u
288
307
 
289
308
  # @see u
290
309
  def u=(v)
291
- v = :single if (v == true || v == 1 || v == :true || v == 'true')
292
310
  set_run_style :validate_cell_u, :u, v
293
311
  end
294
312
 
@@ -298,7 +316,7 @@ module Axlsx
298
316
 
299
317
  # @param [String] v The 8 character representation for an rgb color #FFFFFFFF"
300
318
  def color=(v)
301
- @color = v.is_a?(Color) ? v : Color.new(:rgb => v)
319
+ @color = v.is_a?(Color) ? v : Color.new(rgb: v)
302
320
  @is_text_run = true
303
321
  end
304
322
 
@@ -307,7 +325,9 @@ module Axlsx
307
325
  attr_reader :sz
308
326
 
309
327
  # @see sz
310
- def sz=(v) set_run_style :validate_unsigned_int, :sz, v; end
328
+ def sz=(v)
329
+ set_run_style :validate_unsigned_int, :sz, v
330
+ end
311
331
 
312
332
  # The inline vertical alignment property for the cell
313
333
  # this must be one of [:baseline, :subscript, :superscript]
@@ -344,20 +364,20 @@ module Axlsx
344
364
  # @example Relative Cell Reference
345
365
  # ws.rows.first.cells.first.r #=> "A1"
346
366
  def r
347
- Axlsx::cell_r index, @row.row_index
367
+ Axlsx.cell_r index, @row.row_index
348
368
  end
349
369
 
350
- # @return [String] The absolute alpha(column)numeric(row) reference for this sell.
370
+ # @return [String] The absolute alpha(column)numeric(row) reference for this cell.
351
371
  # @example Absolute Cell Reference
352
372
  # ws.rows.first.cells.first.r #=> "$A$1"
353
373
  def r_abs
354
- "$#{r.match(%r{([A-Z]+)([0-9]+)})[1, 2].join('$')}"
374
+ "$#{CELL_REFERENCE_REGEX.match(r)[1, 2].join('$')}"
355
375
  end
356
376
 
357
377
  # @return [Integer] The cellXfs item index applied to this cell.
358
378
  # @raise [ArgumentError] Invalid cellXfs id if the value provided is not within cellXfs items range.
359
379
  def style=(v)
360
- Axlsx::validate_unsigned_int(v)
380
+ Axlsx.validate_unsigned_int(v)
361
381
  count = styles.cellXfs.size
362
382
  raise ArgumentError, "Invalid cellXfs id" unless v < count
363
383
 
@@ -374,11 +394,11 @@ module Axlsx
374
394
  # @param [Cell, String] target The last cell, or str ref for the cell in the merge range
375
395
  def merge(target)
376
396
  start, stop = if target.is_a?(String)
377
- [self.r, target]
397
+ [r, target]
378
398
  elsif target.is_a?(Cell)
379
- Axlsx.sort_cells([self, target]).map { |c| c.r }
399
+ Axlsx.sort_cells([self, target]).map(&:r)
380
400
  end
381
- self.row.worksheet.merge_cells "#{start}:#{stop}" unless stop.nil?
401
+ row.worksheet.merge_cells "#{start}:#{stop}" unless stop.nil?
382
402
  end
383
403
 
384
404
  # Serializes the cell
@@ -386,21 +406,21 @@ module Axlsx
386
406
  # @param [Integer] c_index The cell index in the row.
387
407
  # @param [String] str The string index the cell content will be appended to. Defaults to empty string.
388
408
  # @return [String] xml text for the cell
389
- def to_xml_string(r_index, c_index, str = '')
409
+ def to_xml_string(r_index, c_index, str = +'')
390
410
  CellSerializer.to_xml_string r_index, c_index, self, str
391
411
  end
392
412
 
393
- def is_formula?
413
+ def is_formula? # rubocop:disable Naming/PredicateName
394
414
  return false if escape_formulas
395
415
 
396
- type == :string && @value.to_s.start_with?(*FORMULA_PREFIXES)
416
+ type == :string && @value.to_s.start_with?(FORMULA_PREFIX)
397
417
  end
398
418
 
399
- def is_array_formula?
419
+ def is_array_formula? # rubocop:disable Naming/PredicateName
400
420
  return false if escape_formulas
401
421
 
402
422
  type == :string &&
403
- @value.to_s.start_with?(*ARRAY_FORMULA_PREFIXES) &&
423
+ @value.to_s.start_with?(ARRAY_FORMULA_PREFIX) &&
404
424
  @value.to_s.end_with?(ARRAY_FORMULA_SUFFIX)
405
425
  end
406
426
 
@@ -425,7 +445,7 @@ module Axlsx
425
445
  # Attempts to determine the correct width for this cell's content
426
446
  # @return [Float]
427
447
  def autowidth
428
- return if is_formula? || value.nil?
448
+ return if value.nil? || is_formula?
429
449
 
430
450
  if contains_rich_text?
431
451
  string_width('', font_size) + value.autowidth
@@ -441,12 +461,13 @@ module Axlsx
441
461
  end
442
462
  end
443
463
 
444
- # Returns the sanatized value
445
- # TODO find a better way to do this as it accounts for 30% of
464
+ # Returns the sanitized value
465
+ # TODO: find a better way to do this as it accounts for 30% of
446
466
  # processing time in benchmarking...
467
+ # @return [String] The sanitized value
447
468
  def clean_value
448
- if (type == :string || type == :text) && !Axlsx::trust_input
449
- Axlsx::sanitize(::CGI.escapeHTML(@value.to_s))
469
+ if (type == :string || type == :text) && !Axlsx.trust_input
470
+ Axlsx.sanitize(::CGI.escapeHTML(@value.to_s))
450
471
  else
451
472
  @value.to_s
452
473
  end
@@ -481,13 +502,13 @@ module Axlsx
481
502
  return unless INLINE_STYLES.include?(attr.to_sym)
482
503
 
483
504
  Axlsx.send(validator, value) unless validator.nil?
484
- self.instance_variable_set :"@#{attr.to_s}", value
505
+ instance_variable_set :"@#{attr}", value
485
506
  @is_text_run = true
486
507
  end
487
508
 
488
509
  # @see ssti
489
510
  def ssti=(v)
490
- Axlsx::validate_unsigned_int(v)
511
+ Axlsx.validate_unsigned_int(v)
491
512
  @ssti = v
492
513
  end
493
514
 
@@ -506,13 +527,11 @@ module Axlsx
506
527
  :time
507
528
  elsif v.is_a?(TrueClass) || v.is_a?(FalseClass)
508
529
  :boolean
509
- elsif v.to_s =~ Axlsx::NUMERIC_REGEX && v.respond_to?(:to_i)
530
+ elsif v.respond_to?(:to_i) && Axlsx::NUMERIC_REGEX.match?(v.to_s)
510
531
  :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)
532
+ 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
533
  :float
515
- elsif v.to_s =~ Axlsx::ISO_8601_REGEX
534
+ elsif Axlsx::ISO_8601_REGEX.match?(v.to_s)
516
535
  :iso_8601
517
536
  elsif v.is_a? RichText
518
537
  :richtext
@@ -526,18 +545,18 @@ module Axlsx
526
545
  # 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
546
  # @see Axlsx#date1904
528
547
  def cast_value(v)
529
- return v if v.is_a?(RichText) || v.nil?
548
+ return v if v.nil? || v.is_a?(RichText)
530
549
 
531
550
  case type
532
551
  when :date
533
- self.style = STYLE_DATE if self.style == 0
552
+ self.style = STYLE_DATE if style.zero?
534
553
  if !v.is_a?(Date) && v.respond_to?(:to_date)
535
554
  v.to_date
536
555
  else
537
556
  v
538
557
  end
539
558
  when :time
540
- self.style = STYLE_DATE if self.style == 0
559
+ self.style = STYLE_DATE if style.zero?
541
560
  if !v.is_a?(Time) && v.respond_to?(:to_time)
542
561
  v.to_time
543
562
  else