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,65 +1,65 @@
1
- # -*- coding: utf-8 -*-
1
+ # frozen_string_literal: true
2
+
2
3
  module Axlsx
3
- require 'axlsx/workbook/worksheet/sheet_calc_pr.rb'
4
- require 'axlsx/workbook/worksheet/auto_filter/auto_filter.rb'
5
- require 'axlsx/workbook/worksheet/date_time_converter.rb'
6
- require 'axlsx/workbook/worksheet/protected_range.rb'
7
- require 'axlsx/workbook/worksheet/protected_ranges.rb'
8
- require 'axlsx/workbook/worksheet/rich_text_run'
9
- require 'axlsx/workbook/worksheet/rich_text'
10
- require 'axlsx/workbook/worksheet/cell_serializer.rb'
11
- require 'axlsx/workbook/worksheet/cell.rb'
12
- require 'axlsx/workbook/worksheet/page_margins.rb'
13
- require 'axlsx/workbook/worksheet/page_set_up_pr.rb'
14
- require 'axlsx/workbook/worksheet/outline_pr.rb'
15
- require 'axlsx/workbook/worksheet/page_setup.rb'
16
- require 'axlsx/workbook/worksheet/header_footer.rb'
17
- require 'axlsx/workbook/worksheet/print_options.rb'
18
- require 'axlsx/workbook/worksheet/cfvo.rb'
19
- require 'axlsx/workbook/worksheet/cfvos.rb'
20
- require 'axlsx/workbook/worksheet/color_scale.rb'
21
- require 'axlsx/workbook/worksheet/data_bar.rb'
22
- require 'axlsx/workbook/worksheet/icon_set.rb'
23
- require 'axlsx/workbook/worksheet/conditional_formatting.rb'
24
- require 'axlsx/workbook/worksheet/conditional_formatting_rule.rb'
25
- require 'axlsx/workbook/worksheet/conditional_formattings.rb'
26
- require 'axlsx/workbook/worksheet/row.rb'
27
- require 'axlsx/workbook/worksheet/col.rb'
28
- require 'axlsx/workbook/worksheet/cols.rb'
29
- require 'axlsx/workbook/worksheet/comments.rb'
30
- require 'axlsx/workbook/worksheet/comment.rb'
31
- require 'axlsx/workbook/worksheet/merged_cells.rb'
32
- require 'axlsx/workbook/worksheet/sheet_protection.rb'
33
- require 'axlsx/workbook/worksheet/sheet_pr.rb'
34
- require 'axlsx/workbook/worksheet/dimension.rb'
35
- require 'axlsx/workbook/worksheet/sheet_data.rb'
36
- require 'axlsx/workbook/worksheet/worksheet_drawing.rb'
37
- require 'axlsx/workbook/worksheet/worksheet_comments.rb'
38
- require 'axlsx/workbook/worksheet/worksheet_hyperlink'
39
- require 'axlsx/workbook/worksheet/worksheet_hyperlinks'
40
- require 'axlsx/workbook/worksheet/break'
41
- require 'axlsx/workbook/worksheet/row_breaks'
42
- require 'axlsx/workbook/worksheet/col_breaks'
43
- require 'axlsx/workbook/workbook_view'
44
- require 'axlsx/workbook/workbook_views'
45
-
46
-
47
- require 'axlsx/workbook/worksheet/worksheet.rb'
48
- require 'axlsx/workbook/shared_strings_table.rb'
49
- require 'axlsx/workbook/defined_name.rb'
50
- require 'axlsx/workbook/defined_names.rb'
51
- require 'axlsx/workbook/worksheet/table_style_info.rb'
52
- require 'axlsx/workbook/worksheet/table.rb'
53
- require 'axlsx/workbook/worksheet/tables.rb'
54
- require 'axlsx/workbook/worksheet/pivot_table_cache_definition.rb'
55
- require 'axlsx/workbook/worksheet/pivot_table.rb'
56
- require 'axlsx/workbook/worksheet/pivot_tables.rb'
57
- require 'axlsx/workbook/worksheet/data_validation.rb'
58
- require 'axlsx/workbook/worksheet/data_validations.rb'
59
- require 'axlsx/workbook/worksheet/sheet_view.rb'
60
- require 'axlsx/workbook/worksheet/sheet_format_pr.rb'
61
- require 'axlsx/workbook/worksheet/pane.rb'
62
- require 'axlsx/workbook/worksheet/selection.rb'
4
+ require 'axlsx/workbook/worksheet/sheet_calc_pr'
5
+ require 'axlsx/workbook/worksheet/auto_filter/auto_filter'
6
+ require 'axlsx/workbook/worksheet/date_time_converter'
7
+ require 'axlsx/workbook/worksheet/protected_range'
8
+ require 'axlsx/workbook/worksheet/protected_ranges'
9
+ require 'axlsx/workbook/worksheet/rich_text_run'
10
+ require 'axlsx/workbook/worksheet/rich_text'
11
+ require 'axlsx/workbook/worksheet/cell_serializer'
12
+ require 'axlsx/workbook/worksheet/cell'
13
+ require 'axlsx/workbook/worksheet/page_margins'
14
+ require 'axlsx/workbook/worksheet/page_set_up_pr'
15
+ require 'axlsx/workbook/worksheet/outline_pr'
16
+ require 'axlsx/workbook/worksheet/page_setup'
17
+ require 'axlsx/workbook/worksheet/header_footer'
18
+ require 'axlsx/workbook/worksheet/print_options'
19
+ require 'axlsx/workbook/worksheet/cfvo'
20
+ require 'axlsx/workbook/worksheet/cfvos'
21
+ require 'axlsx/workbook/worksheet/color_scale'
22
+ require 'axlsx/workbook/worksheet/data_bar'
23
+ require 'axlsx/workbook/worksheet/icon_set'
24
+ require 'axlsx/workbook/worksheet/conditional_formatting'
25
+ require 'axlsx/workbook/worksheet/conditional_formatting_rule'
26
+ require 'axlsx/workbook/worksheet/conditional_formattings'
27
+ require 'axlsx/workbook/worksheet/row'
28
+ require 'axlsx/workbook/worksheet/col'
29
+ require 'axlsx/workbook/worksheet/cols'
30
+ require 'axlsx/workbook/worksheet/comments'
31
+ require 'axlsx/workbook/worksheet/comment'
32
+ require 'axlsx/workbook/worksheet/merged_cells'
33
+ require 'axlsx/workbook/worksheet/sheet_protection'
34
+ require 'axlsx/workbook/worksheet/sheet_pr'
35
+ require 'axlsx/workbook/worksheet/dimension'
36
+ require 'axlsx/workbook/worksheet/sheet_data'
37
+ require 'axlsx/workbook/worksheet/worksheet_drawing'
38
+ require 'axlsx/workbook/worksheet/worksheet_comments'
39
+ require 'axlsx/workbook/worksheet/worksheet_hyperlink'
40
+ require 'axlsx/workbook/worksheet/worksheet_hyperlinks'
41
+ require 'axlsx/workbook/worksheet/break'
42
+ require 'axlsx/workbook/worksheet/row_breaks'
43
+ require 'axlsx/workbook/worksheet/col_breaks'
44
+ require 'axlsx/workbook/workbook_view'
45
+ require 'axlsx/workbook/workbook_views'
46
+ require 'axlsx/workbook/worksheet/worksheet'
47
+ require 'axlsx/workbook/shared_strings_table'
48
+ require 'axlsx/workbook/defined_name'
49
+ require 'axlsx/workbook/defined_names'
50
+ require 'axlsx/workbook/worksheet/table_style_info'
51
+ require 'axlsx/workbook/worksheet/table'
52
+ require 'axlsx/workbook/worksheet/tables'
53
+ require 'axlsx/workbook/worksheet/pivot_table_cache_definition'
54
+ require 'axlsx/workbook/worksheet/pivot_table'
55
+ require 'axlsx/workbook/worksheet/pivot_tables'
56
+ require 'axlsx/workbook/worksheet/data_validation'
57
+ require 'axlsx/workbook/worksheet/data_validations'
58
+ require 'axlsx/workbook/worksheet/sheet_view'
59
+ require 'axlsx/workbook/worksheet/sheet_format_pr'
60
+ require 'axlsx/workbook/worksheet/pane'
61
+ require 'axlsx/workbook/worksheet/selection'
62
+
63
63
  # The Workbook class is an xlsx workbook that manages worksheets, charts, drawings and styles.
64
64
  # The following parts of the Office Open XML spreadsheet specification are not implimented in this version.
65
65
  #
@@ -84,7 +84,6 @@ require 'axlsx/workbook/worksheet/selection.rb'
84
84
  #
85
85
  # *workbookPr is only supported to the extend of date1904
86
86
  class Workbook
87
-
88
87
  BOLD_FONT_MULTIPLIER = 1.5
89
88
  FONT_SCALE_DIVISOR = 10.0
90
89
 
@@ -96,7 +95,7 @@ require 'axlsx/workbook/worksheet/selection.rb'
96
95
 
97
96
  # @see use_shared_strings
98
97
  def use_shared_strings=(v)
99
- Axlsx::validate_boolean(v)
98
+ Axlsx.validate_boolean(v)
100
99
  @use_shared_strings = v
101
100
  end
102
101
 
@@ -105,33 +104,32 @@ require 'axlsx/workbook/worksheet/selection.rb'
105
104
  attr_reader :is_reversed
106
105
 
107
106
  def is_reversed=(v)
108
- Axlsx::validate_boolean(v)
107
+ Axlsx.validate_boolean(v)
109
108
  @is_reversed = v
110
109
  end
111
110
 
112
-
113
- # A collection of worksheets associated with this workbook.
111
+ # A collection of worksheets associated with this workbook.
114
112
  # @note The recommended way to manage worksheets is add_worksheet
115
113
  # @see Workbook#add_worksheet
116
114
  # @see Worksheet
117
115
  # @return [SimpleTypedList]
118
116
  attr_reader :worksheets
119
117
 
120
- # A colllection of charts associated with this workbook
118
+ # A collection of charts associated with this workbook
121
119
  # @note The recommended way to manage charts is Worksheet#add_chart
122
120
  # @see Worksheet#add_chart
123
121
  # @see Chart
124
122
  # @return [SimpleTypedList]
125
123
  attr_reader :charts
126
124
 
127
- # A colllection of images associated with this workbook
125
+ # A collection of images associated with this workbook
128
126
  # @note The recommended way to manage images is Worksheet#add_image
129
127
  # @see Worksheet#add_image
130
128
  # @see Pic
131
129
  # @return [SimpleTypedList]
132
130
  attr_reader :images
133
131
 
134
- # A colllection of drawings associated with this workbook
132
+ # A collection of drawings associated with this workbook
135
133
  # @note The recommended way to manage drawings is Worksheet#add_chart
136
134
  # @see Worksheet#add_chart
137
135
  # @see Drawing
@@ -140,15 +138,14 @@ require 'axlsx/workbook/worksheet/selection.rb'
140
138
 
141
139
  # pretty sure this two are always empty and can be removed.
142
140
 
143
-
144
- # A colllection of tables associated with this workbook
141
+ # A collection of tables associated with this workbook
145
142
  # @note The recommended way to manage drawings is Worksheet#add_table
146
143
  # @see Worksheet#add_table
147
144
  # @see Table
148
145
  # @return [SimpleTypedList]
149
146
  attr_reader :tables
150
147
 
151
- # A colllection of pivot tables associated with this workbook
148
+ # A collection of pivot tables associated with this workbook
152
149
  # @note The recommended way to manage drawings is Worksheet#add_table
153
150
  # @see Worksheet#add_table
154
151
  # @see Table
@@ -174,7 +171,7 @@ require 'axlsx/workbook/worksheet/selection.rb'
174
171
  # @see Comment
175
172
  # @return [Comments]
176
173
  def comments
177
- worksheets.map { |sheet| sheet.comments }.compact
174
+ worksheets.map(&:comments).compact
178
175
  end
179
176
 
180
177
  # The styles associated with this workbook
@@ -200,16 +197,16 @@ require 'axlsx/workbook/worksheet/selection.rb'
200
197
  # A helper to apply styles that were added using `worksheet.add_style`
201
198
  # @return [Boolean]
202
199
  def apply_styles
203
- return false if !styled_cells
200
+ return false unless styled_cells
204
201
 
205
202
  styled_cells.each do |cell|
206
203
  current_style = styles.style_index[cell.style]
207
204
 
208
- if current_style
209
- new_style = Axlsx.hash_deep_merge(current_style, cell.raw_style)
210
- else
211
- new_style = cell.raw_style
212
- end
205
+ new_style = if current_style
206
+ Axlsx.hash_deep_merge(current_style, cell.raw_style)
207
+ else
208
+ cell.raw_style
209
+ end
213
210
 
214
211
  cell.style = styles.add_style(new_style)
215
212
  end
@@ -217,23 +214,21 @@ require 'axlsx/workbook/worksheet/selection.rb'
217
214
  self.styles_applied = true
218
215
  end
219
216
 
220
-
221
217
  # Indicates if the epoc date for serialization should be 1904. If false, 1900 is used.
222
218
  @@date1904 = false
223
219
 
224
-
225
220
  # A quick helper to retrive a worksheet by name
226
221
  # @param [String] name The name of the sheet you are looking for
227
222
  # @return [Worksheet] The sheet found, or nil
228
223
  def sheet_by_name(name)
229
- index = @worksheets.index { |sheet| sheet.name == name }
230
- @worksheets[index] if index
224
+ encoded_name = Axlsx.coder.encode(name)
225
+ @worksheets.find { |sheet| sheet.name == encoded_name }
231
226
  end
232
227
 
233
- # Creates a new Workbook
234
- # The recomended way to work with workbooks is via Package#workbook
235
- # @option options [Boolean] date1904. If this is not specified, date1904 is set to false. Office 2011 for Mac defaults to false.
236
- def initialize(options={})
228
+ # Creates a new Workbook.
229
+ # The recommended way to work with workbooks is via Package#workbook.
230
+ # @option options [Boolean] date1904 If this is not specified, date1904 is set to false. Office 2011 for Mac defaults to false.
231
+ def initialize(options = {})
237
232
  @styles = Styles.new
238
233
  @worksheets = SimpleTypedList.new Worksheet
239
234
  @drawings = SimpleTypedList.new Drawing
@@ -243,13 +238,12 @@ require 'axlsx/workbook/worksheet/selection.rb'
243
238
  @tables = SimpleTypedList.new Table
244
239
  @pivot_tables = SimpleTypedList.new PivotTable
245
240
  @comments = SimpleTypedList.new Comments
246
-
247
-
248
241
  @use_autowidth = true
249
242
  @bold_font_multiplier = BOLD_FONT_MULTIPLIER
250
243
  @font_scale_divisor = FONT_SCALE_DIVISOR
251
244
 
252
- self.date1904= !options[:date1904].nil? && options[:date1904]
245
+ self.escape_formulas = options[:escape_formulas].nil? ? Axlsx.escape_formulas : options[:escape_formulas]
246
+ self.date1904 = !options[:date1904].nil? && options[:date1904]
253
247
  yield self if block_given?
254
248
  end
255
249
 
@@ -258,16 +252,29 @@ require 'axlsx/workbook/worksheet/selection.rb'
258
252
  def date1904() @@date1904; end
259
253
 
260
254
  # see @date1904
261
- def date1904=(v) Axlsx::validate_boolean v; @@date1904 = v; end
255
+ def date1904=(v) Axlsx.validate_boolean v; @@date1904 = v; end
262
256
 
263
257
  # Sets the date1904 attribute to the provided boolean
264
258
  # @return [Boolean]
265
- def self.date1904=(v) Axlsx::validate_boolean v; @@date1904 = v; end
259
+ def self.date1904=(v) Axlsx.validate_boolean v; @@date1904 = v; end
266
260
 
267
261
  # retrieves the date1904 attribute
268
262
  # @return [Boolean]
269
263
  def self.date1904() @@date1904; end
270
264
 
265
+ # Whether to treat values starting with an equals sign as formulas or as literal strings.
266
+ # Allowing user-generated data to be interpreted as formulas is a security risk.
267
+ # See https://www.owasp.org/index.php/CSV_Injection for details.
268
+ # @return [Boolean]
269
+ attr_reader :escape_formulas
270
+
271
+ # Sets whether to treat values starting with an equals sign as formulas or as literal strings.
272
+ # @param [Boolean] value The value to set.
273
+ def escape_formulas=(value)
274
+ Axlsx.validate_boolean(value)
275
+ @escape_formulas = value
276
+ end
277
+
271
278
  # Indicates if the workbook should use autowidths or not.
272
279
  # @note This gem no longer depends on RMagick for autowidth
273
280
  # calculation. Thus the performance benefits of turning this off are
@@ -276,7 +283,7 @@ require 'axlsx/workbook/worksheet/selection.rb'
276
283
  def use_autowidth() @use_autowidth; end
277
284
 
278
285
  # see @use_autowidth
279
- def use_autowidth=(v=true) Axlsx::validate_boolean v; @use_autowidth = v; end
286
+ def use_autowidth=(v = true) Axlsx.validate_boolean v; @use_autowidth = v; end
280
287
 
281
288
  # Font size of bold fonts is multiplied with this
282
289
  # Used for automatic calculation of cell widths with bold text
@@ -284,7 +291,7 @@ require 'axlsx/workbook/worksheet/selection.rb'
284
291
  attr_reader :bold_font_multiplier
285
292
 
286
293
  def bold_font_multiplier=(v)
287
- Axlsx::validate_float v
294
+ Axlsx.validate_float v
288
295
  @bold_font_multiplier = v
289
296
  end
290
297
 
@@ -294,7 +301,7 @@ require 'axlsx/workbook/worksheet/selection.rb'
294
301
  attr_reader :font_scale_divisor
295
302
 
296
303
  def font_scale_divisor=(v)
297
- Axlsx::validate_float v
304
+ Axlsx.validate_float v
298
305
  @font_scale_divisor = v
299
306
  end
300
307
 
@@ -306,7 +313,7 @@ require 'axlsx/workbook/worksheet/selection.rb'
306
313
  # @param [Hash] options Options to pass into the worksheed during initialization.
307
314
  # @option options [String] name The name of the worksheet
308
315
  # @option options [Hash] page_margins The page margins for the worksheet
309
- def insert_worksheet(index=0, options={})
316
+ def insert_worksheet(index = 0, options = {})
310
317
  worksheet = Worksheet.new(self, options)
311
318
  @worksheets.delete_at(@worksheets.size - 1)
312
319
  @worksheets.insert(index, worksheet)
@@ -320,7 +327,7 @@ require 'axlsx/workbook/worksheet/selection.rb'
320
327
  # @option options [String] name The name of the worksheet.
321
328
  # @option options [Hash] page_margins The page margins for the worksheet.
322
329
  # @see Worksheet#initialize
323
- def add_worksheet(options={})
330
+ def add_worksheet(options = {})
324
331
  worksheet = Worksheet.new(self, options)
325
332
  yield worksheet if block_given?
326
333
  worksheet
@@ -330,7 +337,7 @@ require 'axlsx/workbook/worksheet/selection.rb'
330
337
  # @return WorkbookViews
331
338
  # @option options [Hash] options passed into the added WorkbookView
332
339
  # @see WorkbookView#initialize
333
- def add_view(options={})
340
+ def add_view(options = {})
334
341
  views << WorkbookView.new(options)
335
342
  end
336
343
 
@@ -347,14 +354,14 @@ require 'axlsx/workbook/worksheet/selection.rb'
347
354
  def relationships
348
355
  r = Relationships.new
349
356
  @worksheets.each do |sheet|
350
- r << Relationship.new(sheet, WORKSHEET_R, WORKSHEET_PN % (r.size+1))
357
+ r << Relationship.new(sheet, WORKSHEET_R, format(WORKSHEET_PN, r.size + 1))
351
358
  end
352
359
  pivot_tables.each_with_index do |pivot_table, index|
353
- r << Relationship.new(pivot_table.cache_definition, PIVOT_TABLE_CACHE_DEFINITION_R, PIVOT_TABLE_CACHE_DEFINITION_PN % (index+1))
360
+ r << Relationship.new(pivot_table.cache_definition, PIVOT_TABLE_CACHE_DEFINITION_R, format(PIVOT_TABLE_CACHE_DEFINITION_PN, index + 1))
354
361
  end
355
- r << Relationship.new(self, STYLES_R, STYLES_PN)
362
+ r << Relationship.new(self, STYLES_R, STYLES_PN)
356
363
  if use_shared_strings
357
- r << Relationship.new(self, SHARED_STRINGS_R, SHARED_STRINGS_PN)
364
+ r << Relationship.new(self, SHARED_STRINGS_R, SHARED_STRINGS_PN)
358
365
  end
359
366
  r
360
367
  end
@@ -362,7 +369,7 @@ require 'axlsx/workbook/worksheet/selection.rb'
362
369
  # generates a shared string object against all cells in all worksheets.
363
370
  # @return [SharedStringTable]
364
371
  def shared_strings
365
- SharedStringsTable.new(worksheets.collect { |ws| ws.cells }, xml_space)
372
+ SharedStringsTable.new(worksheets.collect(&:cells), xml_space)
366
373
  end
367
374
 
368
375
  # The xml:space attribute for the worksheet.
@@ -380,28 +387,29 @@ require 'axlsx/workbook/worksheet/selection.rb'
380
387
  # @param [Symbol] space must be one of :preserve or :default
381
388
  def xml_space=(space)
382
389
  Axlsx::RestrictionValidator.validate(:xml_space, [:preserve, :default], space)
383
- @xml_space = space;
390
+ @xml_space = space
384
391
  end
385
392
 
386
393
  # returns a range of cells in a worksheet
387
- # @param [String] cell_def The excel style reference defining the worksheet and cells. The range must specify the sheet to
394
+ # @param [String] cell_def The Excel style reference defining the worksheet and cells. The range must specify the sheet to
388
395
  # retrieve the cells from. e.g. range('Sheet1!A1:B2') will return an array of four cells [A1, A2, B1, B2] while range('Sheet1!A1') will return a single Cell.
389
396
  # @return [Cell, Array]
390
397
  def [](cell_def)
391
- sheet_name = cell_def.split('!')[0] if cell_def.match('!')
392
- worksheet = self.worksheets.select { |s| s.name == sheet_name }.first
398
+ sheet_name = cell_def.split('!')[0] if cell_def.include?('!')
399
+ worksheet = worksheets.find { |s| s.name == sheet_name }
393
400
  raise ArgumentError, 'Unknown Sheet' unless sheet_name && worksheet.is_a?(Worksheet)
394
- worksheet[cell_def.gsub(/.+!/,"")]
401
+
402
+ worksheet[cell_def.gsub(/.+!/, "")]
395
403
  end
396
404
 
397
405
  # Serialize the workbook
398
406
  # @param [String] str
399
407
  # @return [String]
400
- def to_xml_string(str='')
401
- add_worksheet(name: 'Sheet1') unless worksheets.size > 0
408
+ def to_xml_string(str = +'')
409
+ add_worksheet(name: 'Sheet1') if worksheets.empty?
402
410
  str << '<?xml version="1.0" encoding="UTF-8"?>'
403
- str << ('<workbook xmlns="' << XML_NS << '" xmlns:r="' << XML_NS_R << '">')
404
- str << ('<workbookPr date1904="' << @@date1904.to_s << '"/>')
411
+ str << '<workbook xmlns="' << XML_NS << '" xmlns:r="' << XML_NS_R << '">'
412
+ str << '<workbookPr date1904="' << @@date1904.to_s << '"/>'
405
413
  views.to_xml_string(str)
406
414
  str << '<sheets>'
407
415
  if is_reversed
@@ -414,12 +422,11 @@ require 'axlsx/workbook/worksheet/selection.rb'
414
422
  unless pivot_tables.empty?
415
423
  str << '<pivotCaches>'
416
424
  pivot_tables.each do |pivot_table|
417
- str << ('<pivotCache cacheId="' << pivot_table.cache_definition.cache_id.to_s << '" r:id="' << pivot_table.cache_definition.rId << '"/>')
425
+ str << '<pivotCache cacheId="' << pivot_table.cache_definition.cache_id.to_s << '" r:id="' << pivot_table.cache_definition.rId << '"/>'
418
426
  end
419
427
  str << '</pivotCaches>'
420
428
  end
421
429
  str << '</workbook>'
422
430
  end
423
-
424
431
  end
425
432
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # <xsd:complexType name="CT_BookView">
2
4
  # <xsd:sequence>
3
5
  # <xsd:element name="extLst" type="CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
@@ -19,19 +21,16 @@
19
21
  # </xsd:complexType>
20
22
 
21
23
  module Axlsx
22
-
23
24
  # A BookView defines the display properties for a workbook.
24
25
  # Units for window widths and other dimensions are expressed in twips.
25
26
  # Twip measurements are portable between different display resolutions.
26
27
  # The formula is (screen pixels) * (20 * 72) / (logical device dpi),
27
28
  # where the logical device dpi can be different for x and y coordinates.
28
29
  class WorkbookView
29
-
30
30
  include Axlsx::SerializedAttributes
31
31
  include Axlsx::OptionsParser
32
32
  include Axlsx::Accessors
33
33
 
34
-
35
34
  # Creates a new BookView object
36
35
  # @param [Hash] options A hash of key/value pairs that will be mapped to this instances attributes.
37
36
  # @option [Symbol] visibility Specifies visible state of the workbook window. The default value for this attribute is :visible.
@@ -47,16 +46,15 @@ module Axlsx
47
46
  # @option [Integer] window_width Specifies the width of the workbook window. The unit of measurement for this value is twips.
48
47
  # @option [Integer] window_height Specifies the height of the workbook window. The unit of measurement for this value is twips.
49
48
  # @option [Boolean] auto_filter_date_grouping Specifies a boolean value that indicates whether to group dates when presenting the user with filtering options in the user interface.
50
- def initialize(options={})
49
+ def initialize(options = {})
51
50
  parse_options options
52
51
  yield self if block_given?
53
52
  end
54
53
 
55
-
56
54
  unsigned_int_attr_accessor :x_window, :y_window, :window_width, :window_height,
57
55
  :tab_ratio, :first_sheet, :active_tab
58
56
 
59
- validated_attr_accessor [:visibility], :validate_view_visibility
57
+ validated_attr_accessor [:visibility], :validate_view_visibility
60
58
 
61
59
  serializable_attributes :visibility, :minimized,
62
60
  :show_horizontal_scroll, :show_vertical_scroll,
@@ -67,14 +65,13 @@ module Axlsx
67
65
  boolean_attr_accessor :minimized, :show_horizontal_scroll, :show_vertical_scroll,
68
66
  :show_sheet_tabs, :auto_filter_date_grouping
69
67
 
70
-
71
68
  # Serialize the WorkbookView
72
69
  # @param [String] str
73
70
  # @return [String]
74
- def to_xml_string(str = '')
75
- str << '<workbookView '
76
- serialized_attributes str
77
- str << '></workbookView>'
71
+ def to_xml_string(str = +'')
72
+ str << '<workbookView '
73
+ serialized_attributes str
74
+ str << '></workbookView>'
78
75
  end
79
76
  end
80
77
  end
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Axlsx
2
4
  # a simple types list of BookView objects
3
5
  class WorkbookViews < SimpleTypedList
4
-
5
6
  # creates the book views object
6
7
  def initialize
7
8
  super WorkbookView
@@ -10,13 +11,12 @@ module Axlsx
10
11
  # Serialize to xml
11
12
  # @param [String] str
12
13
  # @return [String]
13
- def to_xml_string(str = '')
14
+ def to_xml_string(str = +'')
14
15
  return if empty?
16
+
15
17
  str << "<bookViews>"
16
18
  each { |view| view.to_xml_string(str) }
17
19
  str << '</bookViews>'
18
20
  end
19
21
  end
20
22
  end
21
-
22
-
@@ -1,20 +1,22 @@
1
+ # frozen_string_literal: true
1
2
 
2
- require 'axlsx/workbook/worksheet/auto_filter/filter_column.rb'
3
- require 'axlsx/workbook/worksheet/auto_filter/filters.rb'
3
+ require 'axlsx/workbook/worksheet/auto_filter/filter_column'
4
+ require 'axlsx/workbook/worksheet/auto_filter/filters'
5
+ require 'axlsx/workbook/worksheet/auto_filter/sort_state'
4
6
 
5
7
  module Axlsx
6
-
7
- #This class represents an auto filter range in a worksheet
8
+ # This class represents an auto filter range in a worksheet
8
9
  class AutoFilter
9
-
10
10
  # creates a new Autofilter object
11
11
  # @param [Worksheet] worksheet
12
12
  def initialize(worksheet)
13
13
  raise ArgumentError, 'you must provide a worksheet' unless worksheet.is_a?(Worksheet)
14
+
14
15
  @worksheet = worksheet
16
+ @sort_on_generate = true
15
17
  end
16
18
 
17
- attr_reader :worksheet
19
+ attr_reader :worksheet, :sort_on_generate
18
20
 
19
21
  # The range the autofilter should be applied to.
20
22
  # This should be a string like 'A1:B8'
@@ -27,7 +29,8 @@ module Axlsx
27
29
  # @return [String]
28
30
  def defined_name
29
31
  return unless range
30
- Axlsx.cell_range(range.split(':').collect { |name| worksheet.name_to_cell(name)})
32
+
33
+ Axlsx.cell_range(range.split(':').collect { |name| worksheet.name_to_cell(name) })
31
34
  end
32
35
 
33
36
  # A collection of filterColumns for this auto_filter
@@ -47,31 +50,86 @@ module Axlsx
47
50
  columns.last
48
51
  end
49
52
 
50
- # actually performs the filtering of rows who's cells do not
51
- # match the filter.
53
+ # Performs the sorting of the rows based on the sort_state conditions. Then it actually performs
54
+ # the filtering of rows who's cells do not match the filter.
52
55
  def apply
53
56
  first_cell, last_cell = range.split(':')
54
- start_point = Axlsx::name_to_indices(first_cell)
55
- end_point = Axlsx::name_to_indices(last_cell)
57
+ start_point = Axlsx.name_to_indices(first_cell)
58
+ end_point = Axlsx.name_to_indices(last_cell)
56
59
  # The +1 is so we skip the header row with the filter drop downs
57
- rows = worksheet.rows[(start_point.last+1)..end_point.last] || []
60
+ rows = worksheet.rows[(start_point.last + 1)..end_point.last] || []
61
+
62
+ # the sorting of the rows if sort_conditions are available.
63
+ if !sort_state.sort_conditions.empty? && sort_on_generate
64
+ sort_conditions = sort_state.sort_conditions
65
+ sorted_rows = rows.sort do |row1, row2|
66
+ comparison = 0
67
+
68
+ sort_conditions.each do |condition|
69
+ cell_value_row1 = row1.cells[condition.column_index + start_point.first].value
70
+ cell_value_row2 = row2.cells[condition.column_index + start_point.first].value
71
+ custom_list = condition.custom_list
72
+ comparison = if cell_value_row1.nil? || cell_value_row2.nil?
73
+ cell_value_row1.nil? ? 1 : -1
74
+ elsif custom_list.empty?
75
+ condition.order == :asc ? cell_value_row1 <=> cell_value_row2 : cell_value_row2 <=> cell_value_row1
76
+ else
77
+ index1 = custom_list.index(cell_value_row1) || custom_list.size
78
+ index2 = custom_list.index(cell_value_row2) || custom_list.size
79
+
80
+ condition.order == :asc ? index1 <=> index2 : index2 <=> index1
81
+ end
82
+
83
+ break unless comparison.zero?
84
+ end
85
+
86
+ comparison
87
+ end
88
+ insert_index = start_point.last + 1
89
+
90
+ sorted_rows.each do |row|
91
+ # Insert the row at the specified index
92
+ worksheet.rows[insert_index] = row
93
+ insert_index += 1
94
+ end
95
+ end
58
96
 
59
97
  column_offset = start_point.first
60
98
  columns.each do |column|
61
99
  rows.each do |row|
62
100
  next if row.hidden
101
+
63
102
  column.apply(row, column_offset)
64
103
  end
65
104
  end
66
105
  end
106
+
107
+ # the SortState object for this AutoFilter
108
+ # @return [SortState]
109
+ def sort_state
110
+ @sort_state ||= SortState.new self
111
+ end
112
+
113
+ # @param [Boolean] v Flag indicating whether the AutoFilter should sort the rows when generating the
114
+ # file. If false, the sorting rules will need to be applied manually after generating to alter
115
+ # the order of the rows.
116
+ # @return [Boolean]
117
+ def sort_on_generate=(v)
118
+ Axlsx.validate_boolean v
119
+ @sort_on_generate = v
120
+ end
121
+
67
122
  # serialize the object
68
123
  # @return [String]
69
- def to_xml_string(str='')
124
+ def to_xml_string(str = +'')
70
125
  return unless range
126
+
71
127
  str << "<autoFilter ref='#{range}'>"
72
128
  columns.each { |filter_column| filter_column.to_xml_string(str) }
129
+ unless @sort_state.nil?
130
+ @sort_state.to_xml_string(str)
131
+ end
73
132
  str << "</autoFilter>"
74
133
  end
75
-
76
134
  end
77
135
  end