caxlsx 3.4.1 → 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 +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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'open3'
2
4
  require 'shellwords'
3
5
 
@@ -23,10 +25,10 @@ module Axlsx
23
25
  # Create a temporary directory for writing files to.
24
26
  #
25
27
  # The directory and its contents are removed at the end of the block.
26
- def open(output, &block)
28
+ def open(output)
27
29
  Dir.mktmpdir do |dir|
28
30
  @dir = dir
29
- block.call(self)
31
+ yield(self)
30
32
  write_file
31
33
  zip_parts(output)
32
34
  end
@@ -38,23 +40,21 @@ module Axlsx
38
40
  @current_file = "#{@dir}/#{entry.name}"
39
41
  @files << entry.name
40
42
  FileUtils.mkdir_p(File.dirname(@current_file))
43
+ @io = File.open(@current_file, "wb")
41
44
  end
42
45
 
43
46
  # Write to a buffer that will be written to the current entry
44
47
  def write(content)
45
- @buffer << content
48
+ @io << content
46
49
  end
47
50
  alias << write
48
51
 
49
52
  private
50
53
 
51
54
  def write_file
52
- if @current_file
53
- @buffer.rewind
54
- File.open(@current_file, "wb") { |f| f.write @buffer.read }
55
- end
55
+ @io.close if @current_file
56
56
  @current_file = nil
57
- @buffer = StringIO.new
57
+ @io = nil
58
58
  end
59
59
 
60
60
  def zip_parts(output)
@@ -63,8 +63,8 @@ module Axlsx
63
63
  escaped_dir = Shellwords.shellescape(@dir)
64
64
  command = "cd #{escaped_dir} && #{@zip_command} #{output} #{inputs}"
65
65
  stdout_and_stderr, status = Open3.capture2e(command)
66
- if !status.success?
67
- raise(ZipError.new(stdout_and_stderr))
66
+ unless status.success?
67
+ raise ZipError, stdout_and_stderr
68
68
  end
69
69
  end
70
70
  end
data/lib/axlsx/version.rb CHANGED
@@ -1,4 +1,6 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Axlsx
2
4
  # The current version
3
- VERSION = "3.4.1"
5
+ VERSION = "4.0.0"
4
6
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # <definedNames>
2
4
  # <definedName name="_xlnm.Print_Titles" localSheetId="0">Sheet1!$1:$1</definedName>
3
5
  # </definedNames>
@@ -107,7 +109,7 @@ module Axlsx
107
109
  # The local sheet index (0-based)
108
110
  # @param [Integer] value the unsigned integer index of the sheet this defined_name applies to.
109
111
  def local_sheet_id=(value)
110
- Axlsx::validate_unsigned_int(value)
112
+ Axlsx.validate_unsigned_int(value)
111
113
  @local_sheet_id = value
112
114
  end
113
115
 
@@ -118,12 +120,12 @@ module Axlsx
118
120
  serializable_attributes :short_cut_key, :status_bar, :help, :description, :custom_menu, :comment,
119
121
  :workbook_parameter, :publish_to_server, :xlm, :vb_proceedure, :function, :hidden, :local_sheet_id
120
122
 
121
- def to_xml_string(str = '')
123
+ def to_xml_string(str = +'')
122
124
  raise ArgumentError, 'you must specify the name for this defined name. Please read the documentation for Axlsx::DefinedName for more details' unless name
123
125
 
124
- str << ('<definedName ' << 'name="' << name << '" ')
126
+ str << '<definedName ' << 'name="' << name << '" '
125
127
  serialized_attributes str
126
- str << ('>' << @formula << '</definedName>')
128
+ str << '>' << @formula << '</definedName>'
127
129
  end
128
130
  end
129
131
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Axlsx
2
4
  # a simple types list of DefinedName objects
3
5
  class DefinedNames < SimpleTypedList
@@ -9,7 +11,7 @@ module Axlsx
9
11
  # Serialize to xml
10
12
  # @param [String] str
11
13
  # @return [String]
12
- def to_xml_string(str = '')
14
+ def to_xml_string(str = +'')
13
15
  return if empty?
14
16
 
15
17
  str << '<definedNames>'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Axlsx
2
4
  # The Shared String Table class is responsible for managing and serializing common strings in a workbook.
3
5
  # While the ECMA-376 spec allows for both inline and shared strings it seems that at least some applications like iWorks Numbers
@@ -34,7 +36,7 @@ module Axlsx
34
36
  @index = 0
35
37
  @xml_space = xml_space
36
38
  @unique_cells = {}
37
- @shared_xml_string = ""
39
+ @shared_xml_string = +''
38
40
  shareable_cells = cells.flatten.select { |cell| cell.plain_string? || cell.contains_rich_text? }
39
41
  @count = shareable_cells.size
40
42
  resolve(shareable_cells)
@@ -43,11 +45,11 @@ module Axlsx
43
45
  # Serializes the object
44
46
  # @param [String] str
45
47
  # @return [String]
46
- def to_xml_string(str = '')
47
- Axlsx::sanitize(@shared_xml_string)
48
- str << ('<?xml version="1.0" encoding="UTF-8"?><sst xmlns="' << XML_NS << '"')
49
- str << (' count="' << @count.to_s << '" uniqueCount="' << unique_count.to_s << '"')
50
- str << (' xml:space="' << xml_space.to_s << '">' << @shared_xml_string << '</sst>')
48
+ def to_xml_string(str = +'')
49
+ Axlsx.sanitize(@shared_xml_string)
50
+ str << '<?xml version="1.0" encoding="UTF-8"?><sst xmlns="' << XML_NS << '"'
51
+ str << ' count="' << @count.to_s << '" uniqueCount="' << unique_count.to_s << '"'
52
+ str << ' xml:space="' << xml_space.to_s << '">' << @shared_xml_string << '</sst>'
51
53
  end
52
54
 
53
55
  private
@@ -1,39 +1,41 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Axlsx
2
- require 'axlsx/workbook/worksheet/sheet_calc_pr.rb'
3
- require 'axlsx/workbook/worksheet/auto_filter/auto_filter.rb'
4
- require 'axlsx/workbook/worksheet/date_time_converter.rb'
5
- require 'axlsx/workbook/worksheet/protected_range.rb'
6
- require 'axlsx/workbook/worksheet/protected_ranges.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'
7
9
  require 'axlsx/workbook/worksheet/rich_text_run'
8
10
  require 'axlsx/workbook/worksheet/rich_text'
9
- require 'axlsx/workbook/worksheet/cell_serializer.rb'
10
- require 'axlsx/workbook/worksheet/cell.rb'
11
- require 'axlsx/workbook/worksheet/page_margins.rb'
12
- require 'axlsx/workbook/worksheet/page_set_up_pr.rb'
13
- require 'axlsx/workbook/worksheet/outline_pr.rb'
14
- require 'axlsx/workbook/worksheet/page_setup.rb'
15
- require 'axlsx/workbook/worksheet/header_footer.rb'
16
- require 'axlsx/workbook/worksheet/print_options.rb'
17
- require 'axlsx/workbook/worksheet/cfvo.rb'
18
- require 'axlsx/workbook/worksheet/cfvos.rb'
19
- require 'axlsx/workbook/worksheet/color_scale.rb'
20
- require 'axlsx/workbook/worksheet/data_bar.rb'
21
- require 'axlsx/workbook/worksheet/icon_set.rb'
22
- require 'axlsx/workbook/worksheet/conditional_formatting.rb'
23
- require 'axlsx/workbook/worksheet/conditional_formatting_rule.rb'
24
- require 'axlsx/workbook/worksheet/conditional_formattings.rb'
25
- require 'axlsx/workbook/worksheet/row.rb'
26
- require 'axlsx/workbook/worksheet/col.rb'
27
- require 'axlsx/workbook/worksheet/cols.rb'
28
- require 'axlsx/workbook/worksheet/comments.rb'
29
- require 'axlsx/workbook/worksheet/comment.rb'
30
- require 'axlsx/workbook/worksheet/merged_cells.rb'
31
- require 'axlsx/workbook/worksheet/sheet_protection.rb'
32
- require 'axlsx/workbook/worksheet/sheet_pr.rb'
33
- require 'axlsx/workbook/worksheet/dimension.rb'
34
- require 'axlsx/workbook/worksheet/sheet_data.rb'
35
- require 'axlsx/workbook/worksheet/worksheet_drawing.rb'
36
- require 'axlsx/workbook/worksheet/worksheet_comments.rb'
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'
37
39
  require 'axlsx/workbook/worksheet/worksheet_hyperlink'
38
40
  require 'axlsx/workbook/worksheet/worksheet_hyperlinks'
39
41
  require 'axlsx/workbook/worksheet/break'
@@ -41,22 +43,22 @@ module Axlsx
41
43
  require 'axlsx/workbook/worksheet/col_breaks'
42
44
  require 'axlsx/workbook/workbook_view'
43
45
  require 'axlsx/workbook/workbook_views'
44
- require 'axlsx/workbook/worksheet/worksheet.rb'
45
- require 'axlsx/workbook/shared_strings_table.rb'
46
- require 'axlsx/workbook/defined_name.rb'
47
- require 'axlsx/workbook/defined_names.rb'
48
- require 'axlsx/workbook/worksheet/table_style_info.rb'
49
- require 'axlsx/workbook/worksheet/table.rb'
50
- require 'axlsx/workbook/worksheet/tables.rb'
51
- require 'axlsx/workbook/worksheet/pivot_table_cache_definition.rb'
52
- require 'axlsx/workbook/worksheet/pivot_table.rb'
53
- require 'axlsx/workbook/worksheet/pivot_tables.rb'
54
- require 'axlsx/workbook/worksheet/data_validation.rb'
55
- require 'axlsx/workbook/worksheet/data_validations.rb'
56
- require 'axlsx/workbook/worksheet/sheet_view.rb'
57
- require 'axlsx/workbook/worksheet/sheet_format_pr.rb'
58
- require 'axlsx/workbook/worksheet/pane.rb'
59
- require 'axlsx/workbook/worksheet/selection.rb'
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'
60
62
 
61
63
  # The Workbook class is an xlsx workbook that manages worksheets, charts, drawings and styles.
62
64
  # The following parts of the Office Open XML spreadsheet specification are not implimented in this version.
@@ -93,7 +95,7 @@ module Axlsx
93
95
 
94
96
  # @see use_shared_strings
95
97
  def use_shared_strings=(v)
96
- Axlsx::validate_boolean(v)
98
+ Axlsx.validate_boolean(v)
97
99
  @use_shared_strings = v
98
100
  end
99
101
 
@@ -102,7 +104,7 @@ module Axlsx
102
104
  attr_reader :is_reversed
103
105
 
104
106
  def is_reversed=(v)
105
- Axlsx::validate_boolean(v)
107
+ Axlsx.validate_boolean(v)
106
108
  @is_reversed = v
107
109
  end
108
110
 
@@ -169,7 +171,7 @@ module Axlsx
169
171
  # @see Comment
170
172
  # @return [Comments]
171
173
  def comments
172
- worksheets.map { |sheet| sheet.comments }.compact
174
+ worksheets.map(&:comments).compact
173
175
  end
174
176
 
175
177
  # The styles associated with this workbook
@@ -195,16 +197,16 @@ module Axlsx
195
197
  # A helper to apply styles that were added using `worksheet.add_style`
196
198
  # @return [Boolean]
197
199
  def apply_styles
198
- return false if !styled_cells
200
+ return false unless styled_cells
199
201
 
200
202
  styled_cells.each do |cell|
201
203
  current_style = styles.style_index[cell.style]
202
204
 
203
- if current_style
204
- new_style = Axlsx.hash_deep_merge(current_style, cell.raw_style)
205
- else
206
- new_style = cell.raw_style
207
- 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
208
210
 
209
211
  cell.style = styles.add_style(new_style)
210
212
  end
@@ -219,8 +221,8 @@ module Axlsx
219
221
  # @param [String] name The name of the sheet you are looking for
220
222
  # @return [Worksheet] The sheet found, or nil
221
223
  def sheet_by_name(name)
222
- index = @worksheets.index { |sheet| sheet.name == name }
223
- @worksheets[index] if index
224
+ encoded_name = Axlsx.coder.encode(name)
225
+ @worksheets.find { |sheet| sheet.name == encoded_name }
224
226
  end
225
227
 
226
228
  # Creates a new Workbook.
@@ -250,11 +252,11 @@ module Axlsx
250
252
  def date1904() @@date1904; end
251
253
 
252
254
  # see @date1904
253
- def date1904=(v) Axlsx::validate_boolean v; @@date1904 = v; end
255
+ def date1904=(v) Axlsx.validate_boolean v; @@date1904 = v; end
254
256
 
255
257
  # Sets the date1904 attribute to the provided boolean
256
258
  # @return [Boolean]
257
- def self.date1904=(v) Axlsx::validate_boolean v; @@date1904 = v; end
259
+ def self.date1904=(v) Axlsx.validate_boolean v; @@date1904 = v; end
258
260
 
259
261
  # retrieves the date1904 attribute
260
262
  # @return [Boolean]
@@ -281,7 +283,7 @@ module Axlsx
281
283
  def use_autowidth() @use_autowidth; end
282
284
 
283
285
  # see @use_autowidth
284
- 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
285
287
 
286
288
  # Font size of bold fonts is multiplied with this
287
289
  # Used for automatic calculation of cell widths with bold text
@@ -289,7 +291,7 @@ module Axlsx
289
291
  attr_reader :bold_font_multiplier
290
292
 
291
293
  def bold_font_multiplier=(v)
292
- Axlsx::validate_float v
294
+ Axlsx.validate_float v
293
295
  @bold_font_multiplier = v
294
296
  end
295
297
 
@@ -299,7 +301,7 @@ module Axlsx
299
301
  attr_reader :font_scale_divisor
300
302
 
301
303
  def font_scale_divisor=(v)
302
- Axlsx::validate_float v
304
+ Axlsx.validate_float v
303
305
  @font_scale_divisor = v
304
306
  end
305
307
 
@@ -352,10 +354,10 @@ module Axlsx
352
354
  def relationships
353
355
  r = Relationships.new
354
356
  @worksheets.each do |sheet|
355
- r << Relationship.new(sheet, WORKSHEET_R, WORKSHEET_PN % (r.size + 1))
357
+ r << Relationship.new(sheet, WORKSHEET_R, format(WORKSHEET_PN, r.size + 1))
356
358
  end
357
359
  pivot_tables.each_with_index do |pivot_table, index|
358
- 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))
359
361
  end
360
362
  r << Relationship.new(self, STYLES_R, STYLES_PN)
361
363
  if use_shared_strings
@@ -367,7 +369,7 @@ module Axlsx
367
369
  # generates a shared string object against all cells in all worksheets.
368
370
  # @return [SharedStringTable]
369
371
  def shared_strings
370
- SharedStringsTable.new(worksheets.collect { |ws| ws.cells }, xml_space)
372
+ SharedStringsTable.new(worksheets.collect(&:cells), xml_space)
371
373
  end
372
374
 
373
375
  # The xml:space attribute for the worksheet.
@@ -389,12 +391,12 @@ module Axlsx
389
391
  end
390
392
 
391
393
  # returns a range of cells in a worksheet
392
- # @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
393
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.
394
396
  # @return [Cell, Array]
395
397
  def [](cell_def)
396
- sheet_name = cell_def.split('!')[0] if cell_def.match('!')
397
- 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 }
398
400
  raise ArgumentError, 'Unknown Sheet' unless sheet_name && worksheet.is_a?(Worksheet)
399
401
 
400
402
  worksheet[cell_def.gsub(/.+!/, "")]
@@ -403,11 +405,11 @@ module Axlsx
403
405
  # Serialize the workbook
404
406
  # @param [String] str
405
407
  # @return [String]
406
- def to_xml_string(str = '')
407
- add_worksheet(name: 'Sheet1') unless worksheets.size > 0
408
+ def to_xml_string(str = +'')
409
+ add_worksheet(name: 'Sheet1') if worksheets.empty?
408
410
  str << '<?xml version="1.0" encoding="UTF-8"?>'
409
- str << ('<workbook xmlns="' << XML_NS << '" xmlns:r="' << XML_NS_R << '">')
410
- str << ('<workbookPr date1904="' << @@date1904.to_s << '"/>')
411
+ str << '<workbook xmlns="' << XML_NS << '" xmlns:r="' << XML_NS_R << '">'
412
+ str << '<workbookPr date1904="' << @@date1904.to_s << '"/>'
411
413
  views.to_xml_string(str)
412
414
  str << '<sheets>'
413
415
  if is_reversed
@@ -420,7 +422,7 @@ module Axlsx
420
422
  unless pivot_tables.empty?
421
423
  str << '<pivotCaches>'
422
424
  pivot_tables.each do |pivot_table|
423
- 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 << '"/>'
424
426
  end
425
427
  str << '</pivotCaches>'
426
428
  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"/>
@@ -66,7 +68,7 @@ module Axlsx
66
68
  # Serialize the WorkbookView
67
69
  # @param [String] str
68
70
  # @return [String]
69
- def to_xml_string(str = '')
71
+ def to_xml_string(str = +'')
70
72
  str << '<workbookView '
71
73
  serialized_attributes str
72
74
  str << '></workbookView>'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Axlsx
2
4
  # a simple types list of BookView objects
3
5
  class WorkbookViews < SimpleTypedList
@@ -9,7 +11,7 @@ module Axlsx
9
11
  # Serialize to xml
10
12
  # @param [String] str
11
13
  # @return [String]
12
- def to_xml_string(str = '')
14
+ def to_xml_string(str = +'')
13
15
  return if empty?
14
16
 
15
17
  str << "<bookViews>"
@@ -1,5 +1,8 @@
1
- require 'axlsx/workbook/worksheet/auto_filter/filter_column.rb'
2
- require 'axlsx/workbook/worksheet/auto_filter/filters.rb'
1
+ # frozen_string_literal: true
2
+
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'
3
6
 
4
7
  module Axlsx
5
8
  # This class represents an auto filter range in a worksheet
@@ -10,9 +13,10 @@ module Axlsx
10
13
  raise ArgumentError, 'you must provide a worksheet' unless worksheet.is_a?(Worksheet)
11
14
 
12
15
  @worksheet = worksheet
16
+ @sort_on_generate = true
13
17
  end
14
18
 
15
- attr_reader :worksheet
19
+ attr_reader :worksheet, :sort_on_generate
16
20
 
17
21
  # The range the autofilter should be applied to.
18
22
  # This should be a string like 'A1:B8'
@@ -46,15 +50,50 @@ module Axlsx
46
50
  columns.last
47
51
  end
48
52
 
49
- # actually performs the filtering of rows who's cells do not
50
- # 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.
51
55
  def apply
52
56
  first_cell, last_cell = range.split(':')
53
- start_point = Axlsx::name_to_indices(first_cell)
54
- 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)
55
59
  # The +1 is so we skip the header row with the filter drop downs
56
60
  rows = worksheet.rows[(start_point.last + 1)..end_point.last] || []
57
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
96
+
58
97
  column_offset = start_point.first
59
98
  columns.each do |column|
60
99
  rows.each do |row|
@@ -65,13 +104,31 @@ module Axlsx
65
104
  end
66
105
  end
67
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
+
68
122
  # serialize the object
69
123
  # @return [String]
70
- def to_xml_string(str = '')
124
+ def to_xml_string(str = +'')
71
125
  return unless range
72
126
 
73
127
  str << "<autoFilter ref='#{range}'>"
74
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
75
132
  str << "</autoFilter>"
76
133
  end
77
134
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Axlsx
2
4
  # The filterColumn collection identifies a particular column in the AutoFilter
3
5
  # range and specifies filter information that has been applied to this column.
@@ -26,7 +28,7 @@ module Axlsx
26
28
  serializable_attributes :col_id, :hidden_button, :show_button
27
29
 
28
30
  # Allowed filters
29
- FILTERS = [:filters] # , :top10, :custom_filters, :dynamic_filters, :color_filters, :icon_filters]
31
+ FILTERS = [:filters].freeze # , :top10, :custom_filters, :dynamic_filters, :color_filters, :icon_filters]
30
32
 
31
33
  # Zero-based index indicating the AutoFilter column to which this filter information applies.
32
34
  # @return [Integer]
@@ -85,8 +87,10 @@ module Axlsx
85
87
  end
86
88
 
87
89
  # Serialize the object to xml
88
- def to_xml_string(str = '')
89
- str << "<filterColumn #{serialized_attributes}>"
90
+ def to_xml_string(str = +'')
91
+ str << '<filterColumn '
92
+ serialized_attributes(str)
93
+ str << '>'
90
94
  @filter.to_xml_string(str)
91
95
  str << "</filterColumn>"
92
96
  end
@@ -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