write_xlsx 1.12.3 → 1.15.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 (118) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +22 -0
  3. data/Changes +23 -0
  4. data/README.md +1 -1
  5. data/lib/write_xlsx/chart/area.rb +2 -2
  6. data/lib/write_xlsx/chart/axis.rb +55 -32
  7. data/lib/write_xlsx/chart/axis_writer.rb +528 -0
  8. data/lib/write_xlsx/chart/bar.rb +2 -2
  9. data/lib/write_xlsx/chart/caption.rb +16 -9
  10. data/lib/write_xlsx/chart/chart_area.rb +121 -0
  11. data/lib/write_xlsx/chart/column.rb +2 -2
  12. data/lib/write_xlsx/chart/d_pt_point_writer.rb +14 -0
  13. data/lib/write_xlsx/chart/doughnut.rb +0 -3
  14. data/lib/write_xlsx/chart/formatting_writer.rb +652 -0
  15. data/lib/write_xlsx/chart/initialization.rb +100 -0
  16. data/lib/write_xlsx/chart/line.rb +4 -3
  17. data/lib/write_xlsx/chart/pie.rb +6 -2
  18. data/lib/write_xlsx/chart/radar.rb +2 -2
  19. data/lib/write_xlsx/chart/scatter.rb +4 -3
  20. data/lib/write_xlsx/chart/series.rb +35 -15
  21. data/lib/write_xlsx/chart/series_data.rb +132 -0
  22. data/lib/write_xlsx/chart/series_writer.rb +318 -0
  23. data/lib/write_xlsx/chart/settings.rb +226 -0
  24. data/lib/write_xlsx/chart/stock.rb +2 -2
  25. data/lib/write_xlsx/chart/table.rb +50 -0
  26. data/lib/write_xlsx/chart/xml_writer.rb +305 -0
  27. data/lib/write_xlsx/chart.rb +286 -2477
  28. data/lib/write_xlsx/chartsheet.rb +35 -83
  29. data/lib/write_xlsx/constants.rb +11 -0
  30. data/lib/write_xlsx/drawing.rb +5 -3
  31. data/lib/write_xlsx/format/alignment_state.rb +39 -0
  32. data/lib/write_xlsx/format/alignment_style.rb +92 -0
  33. data/lib/write_xlsx/format/border_state.rb +47 -0
  34. data/lib/write_xlsx/format/border_style.rb +116 -0
  35. data/lib/write_xlsx/format/fill_state.rb +26 -0
  36. data/lib/write_xlsx/format/fill_style.rb +52 -0
  37. data/lib/write_xlsx/format/font_state.rb +74 -0
  38. data/lib/write_xlsx/format/font_style.rb +172 -0
  39. data/lib/write_xlsx/format/format_state.rb +65 -0
  40. data/lib/write_xlsx/format/number_format_state.rb +20 -0
  41. data/lib/write_xlsx/format/number_format_style.rb +28 -0
  42. data/lib/write_xlsx/format/protection_state.rb +20 -0
  43. data/lib/write_xlsx/format/protection_style.rb +28 -0
  44. data/lib/write_xlsx/format.rb +1093 -426
  45. data/lib/write_xlsx/formats.rb +0 -2
  46. data/lib/write_xlsx/image_property.rb +4 -1
  47. data/lib/write_xlsx/inserted_chart.rb +1 -1
  48. data/lib/write_xlsx/object_positioning.rb +203 -0
  49. data/lib/write_xlsx/package/app.rb +3 -3
  50. data/lib/write_xlsx/package/button.rb +6 -2
  51. data/lib/write_xlsx/package/comments.rb +11 -3
  52. data/lib/write_xlsx/package/conditional_format.rb +7 -3
  53. data/lib/write_xlsx/package/content_types.rb +2 -2
  54. data/lib/write_xlsx/package/core.rb +2 -2
  55. data/lib/write_xlsx/package/custom.rb +3 -2
  56. data/lib/write_xlsx/package/metadata.rb +2 -2
  57. data/lib/write_xlsx/package/packager.rb +0 -3
  58. data/lib/write_xlsx/package/relationships.rb +2 -2
  59. data/lib/write_xlsx/package/rich_value.rb +4 -2
  60. data/lib/write_xlsx/package/rich_value_rel.rb +2 -2
  61. data/lib/write_xlsx/package/rich_value_structure.rb +2 -2
  62. data/lib/write_xlsx/package/rich_value_types.rb +3 -3
  63. data/lib/write_xlsx/package/shared_strings.rb +2 -2
  64. data/lib/write_xlsx/package/styles.rb +13 -9
  65. data/lib/write_xlsx/package/table.rb +8 -2
  66. data/lib/write_xlsx/package/theme.rb +0 -3
  67. data/lib/write_xlsx/package/vml.rb +2 -2
  68. data/lib/write_xlsx/page_setup.rb +192 -0
  69. data/lib/write_xlsx/shape.rb +97 -100
  70. data/lib/write_xlsx/sheets.rb +9 -4
  71. data/lib/write_xlsx/sparkline.rb +2 -2
  72. data/lib/write_xlsx/utility/cell_reference.rb +124 -0
  73. data/lib/write_xlsx/utility/chart_formatting.rb +262 -0
  74. data/lib/write_xlsx/utility/common.rb +44 -0
  75. data/lib/write_xlsx/utility/date_time.rb +113 -0
  76. data/lib/write_xlsx/utility/dimensions.rb +40 -0
  77. data/lib/write_xlsx/utility/drawing.rb +136 -0
  78. data/lib/write_xlsx/utility/rich_text.rb +184 -0
  79. data/lib/write_xlsx/utility/sheetname_quoting.rb +73 -0
  80. data/lib/write_xlsx/utility/string_width.rb +45 -0
  81. data/lib/write_xlsx/utility/url.rb +27 -0
  82. data/lib/write_xlsx/utility/xml_primitives.rb +32 -0
  83. data/lib/write_xlsx/version.rb +1 -1
  84. data/lib/write_xlsx/workbook/chart_data.rb +188 -0
  85. data/lib/write_xlsx/workbook/format_preparation.rb +199 -0
  86. data/lib/write_xlsx/workbook/initialization.rb +223 -0
  87. data/lib/write_xlsx/workbook/package_preparation.rb +231 -0
  88. data/lib/write_xlsx/workbook/workbook_writer.rb +164 -0
  89. data/lib/write_xlsx/workbook.rb +143 -981
  90. data/lib/write_xlsx/worksheet/asset_manager.rb +60 -0
  91. data/lib/write_xlsx/worksheet/autofilter.rb +390 -0
  92. data/lib/write_xlsx/worksheet/cell_data.rb +13 -6
  93. data/lib/write_xlsx/worksheet/cell_data_manager.rb +47 -0
  94. data/lib/write_xlsx/worksheet/cell_data_store.rb +61 -0
  95. data/lib/write_xlsx/worksheet/columns.rb +204 -0
  96. data/lib/write_xlsx/worksheet/comments_support.rb +61 -0
  97. data/lib/write_xlsx/worksheet/conditional_formats.rb +30 -0
  98. data/lib/write_xlsx/worksheet/data_validation.rb +9 -1
  99. data/lib/write_xlsx/worksheet/data_writing.rb +1017 -0
  100. data/lib/write_xlsx/worksheet/drawing_methods.rb +308 -0
  101. data/lib/write_xlsx/worksheet/drawing_preparation.rb +290 -0
  102. data/lib/write_xlsx/worksheet/drawing_relations.rb +76 -0
  103. data/lib/write_xlsx/worksheet/drawing_xml_writer.rb +50 -0
  104. data/lib/write_xlsx/worksheet/formatting.rb +418 -0
  105. data/lib/write_xlsx/worksheet/hyperlink.rb +9 -1
  106. data/lib/write_xlsx/worksheet/initialization.rb +146 -0
  107. data/lib/write_xlsx/worksheet/panes.rb +64 -0
  108. data/lib/write_xlsx/worksheet/print_options.rb +72 -0
  109. data/lib/write_xlsx/worksheet/protection.rb +65 -0
  110. data/lib/write_xlsx/worksheet/rich_text_helpers.rb +78 -0
  111. data/lib/write_xlsx/worksheet/row_col_sizing.rb +69 -0
  112. data/lib/write_xlsx/worksheet/rows.rb +84 -0
  113. data/lib/write_xlsx/worksheet/selection.rb +41 -0
  114. data/lib/write_xlsx/worksheet/xml_writer.rb +1246 -0
  115. data/lib/write_xlsx/worksheet.rb +376 -4530
  116. metadata +66 -4
  117. data/lib/write_xlsx/utility.rb +0 -986
  118. data/lib/write_xlsx/worksheet/page_setup.rb +0 -192
@@ -0,0 +1,100 @@
1
+ # -*- coding: utf-8 -*-
2
+ # frozen_string_literal: true
3
+
4
+ require 'write_xlsx/chart/axis'
5
+ require 'write_xlsx/chart/legend'
6
+
7
+ module Writexlsx
8
+ class Chart
9
+ module Initialization
10
+ private
11
+
12
+ def axis_setup
13
+ @axis_ids = []
14
+ @axis2_ids = []
15
+ @cat_has_num_fmt = false
16
+ @requires_category = 0
17
+ @cat_axis_position = 'b'
18
+ @val_axis_position = 'l'
19
+ @horiz_cat_axis = 0
20
+ @horiz_val_axis = 1
21
+ @x_axis = Axis.new(self)
22
+ @y_axis = Axis.new(self)
23
+ @x2_axis = Axis.new(self)
24
+ @y2_axis = Axis.new(self)
25
+ end
26
+
27
+ def display_setup
28
+ @orientation = 0x0
29
+ @width = 480
30
+ @height = 288
31
+ @x_scale = 1
32
+ @y_scale = 1
33
+ @x_offset = 0
34
+ @y_offset = 0
35
+ @legend = Legend.new
36
+ @smooth_allowed = 0
37
+ @cross_between = 'between'
38
+ @date_category = false
39
+ @show_blanks = 'gap'
40
+ @show_na_as_empty = false
41
+ @show_hidden_data = false
42
+ @show_crosses = true
43
+ end
44
+
45
+ #
46
+ # Setup the default properties for a chart.
47
+ #
48
+ def set_default_properties # :nodoc:
49
+ display_setup
50
+ axis_setup
51
+ set_axis_defaults
52
+
53
+ set_x_axis
54
+ set_y_axis
55
+
56
+ set_x2_axis
57
+ set_y2_axis
58
+ end
59
+
60
+ def set_axis_defaults
61
+ @x_axis.defaults = x_axis_defaults
62
+ @y_axis.defaults = y_axis_defaults
63
+ @x2_axis.defaults = x2_axis_defaults
64
+ @y2_axis.defaults = y2_axis_defaults
65
+ end
66
+
67
+ def x_axis_defaults
68
+ {
69
+ num_format: 'General',
70
+ major_gridlines: { visible: 0 }
71
+ }
72
+ end
73
+
74
+ def y_axis_defaults
75
+ {
76
+ num_format: 'General',
77
+ major_gridlines: { visible: 1 }
78
+ }
79
+ end
80
+
81
+ def x2_axis_defaults
82
+ {
83
+ num_format: 'General',
84
+ label_position: 'none',
85
+ crossing: 'max',
86
+ visible: 0
87
+ }
88
+ end
89
+
90
+ def y2_axis_defaults
91
+ {
92
+ num_format: 'General',
93
+ major_gridlines: { visible: 0 },
94
+ position: 'right',
95
+ visible: 1
96
+ }
97
+ end
98
+ end
99
+ end
100
+ end
@@ -14,13 +14,14 @@
14
14
  #
15
15
 
16
16
  require 'write_xlsx/package/xml_writer_simple'
17
- require 'write_xlsx/utility'
17
+ require 'write_xlsx/utility/xml_primitives'
18
+ require 'write_xlsx/chart/d_pt_point_writer'
18
19
 
19
20
  module Writexlsx
20
21
  class Chart
21
22
  class Line < self
22
- include Writexlsx::Utility
23
- include Writexlsx::WriteDPtPoint
23
+ include Writexlsx::Utility::XmlPrimitives
24
+ include DPtPointWriter
24
25
 
25
26
  def initialize(subtype)
26
27
  super
@@ -15,7 +15,9 @@
15
15
 
16
16
  require 'write_xlsx/package/xml_writer_simple'
17
17
  require 'write_xlsx/chart'
18
- require 'write_xlsx/utility'
18
+ require 'write_xlsx/utility/cell_reference'
19
+ require 'write_xlsx/utility/xml_primitives'
20
+ require 'write_xlsx/utility/sheetname_quoting'
19
21
 
20
22
  module Writexlsx
21
23
  class Chart
@@ -26,7 +28,9 @@ module Writexlsx
26
28
  # chart.set_y_axis
27
29
  #
28
30
  class Pie < self
29
- include Writexlsx::Utility
31
+ include Writexlsx::Utility::CellReference
32
+ include Writexlsx::Utility::XmlPrimitives
33
+ include Writexlsx::Utility::SheetnameQuoting
30
34
 
31
35
  def initialize(subtype)
32
36
  super
@@ -14,7 +14,7 @@
14
14
  #
15
15
 
16
16
  require 'write_xlsx/package/xml_writer_simple'
17
- require 'write_xlsx/utility'
17
+ require 'write_xlsx/utility/xml_primitives'
18
18
 
19
19
  module Writexlsx
20
20
  class Chart
@@ -28,7 +28,7 @@ module Writexlsx
28
28
  # chart = workbook.add_chart( :type => 'column', :subtype => 'stacked' )
29
29
  #
30
30
  class Radar < self
31
- include Writexlsx::Utility
31
+ include Writexlsx::Utility::XmlPrimitives
32
32
 
33
33
  def initialize(subtype)
34
34
  super
@@ -15,13 +15,14 @@
15
15
 
16
16
  require 'write_xlsx/package/xml_writer_simple'
17
17
  require 'write_xlsx/chart'
18
- require 'write_xlsx/utility'
18
+ require 'write_xlsx/utility/xml_primitives'
19
+ require 'write_xlsx/chart/d_pt_point_writer'
19
20
 
20
21
  module Writexlsx
21
22
  class Chart
22
23
  class Scatter < self
23
- include Writexlsx::Utility
24
- include Writexlsx::WriteDPtPoint
24
+ include Writexlsx::Utility::XmlPrimitives
25
+ include DPtPointWriter
25
26
 
26
27
  def initialize(subtype)
27
28
  super
@@ -3,10 +3,17 @@
3
3
 
4
4
  module Writexlsx
5
5
  class Chart
6
+ require 'write_xlsx/utility/common'
7
+ require 'write_xlsx/utility/cell_reference'
8
+ require 'write_xlsx/utility/chart_formatting'
9
+ require 'write_xlsx/utility/rich_text'
10
+ require 'write_xlsx/utility/sheetname_quoting'
6
11
  require 'write_xlsx/gradient'
7
12
 
8
13
  class Chartline
9
- include Writexlsx::Utility
14
+ include Writexlsx::Utility::Common
15
+ include Writexlsx::Utility::ChartFormatting
16
+ include Writexlsx::Utility::RichText
10
17
  include Writexlsx::Gradient
11
18
 
12
19
  attr_reader :line, :fill, :type, :gradient, :pattern
@@ -174,7 +181,7 @@ module Writexlsx
174
181
  end
175
182
 
176
183
  class Errorbars
177
- include Writexlsx::Utility
184
+ include Writexlsx::Utility::ChartFormatting
178
185
 
179
186
  attr_reader :type, :direction, :endcap, :value, :line, :fill
180
187
  attr_reader :plus_values, :minus_values, :plus_data, :minus_data
@@ -223,7 +230,11 @@ module Writexlsx
223
230
  end
224
231
 
225
232
  class Series
226
- include Writexlsx::Utility
233
+ include Writexlsx::Utility::Common
234
+ include Writexlsx::Utility::CellReference
235
+ include Writexlsx::Utility::ChartFormatting
236
+ include Writexlsx::Utility::RichText
237
+ include Writexlsx::Utility::SheetnameQuoting
227
238
  include Writexlsx::Gradient
228
239
 
229
240
  attr_reader :values, :categories, :name, :name_formula, :name_id
@@ -322,19 +333,10 @@ module Writexlsx
322
333
  def labels_properties(labels) # :nodoc:
323
334
  return nil unless labels
324
335
 
336
+ labels = labels.dup
337
+
325
338
  # Map user defined label positions to Excel positions.
326
- position = labels[:position]
327
- if ptrue?(position)
328
- if @label_positions[position]
329
- labels[:position] = if position == @label_position_default
330
- nil
331
- else
332
- @label_positions[position]
333
- end
334
- else
335
- raise "Unsupported label position '#{position}' for this chart type"
336
- end
337
- end
339
+ map_label_position!(labels)
338
340
 
339
341
  # Map the user defined label separator to the Excel separator.
340
342
  separators = {
@@ -400,6 +402,9 @@ module Writexlsx
400
402
 
401
403
  property[:font] = convert_font_args(property[:font]) if property[:font]
402
404
 
405
+ # Map user defined label positions to Excel positions.
406
+ map_label_position!(property)
407
+
403
408
  # Allow 'border' as a synonym for 'line'.
404
409
  line = line_properties(property[:border] || property[:line])
405
410
 
@@ -431,6 +436,21 @@ module Writexlsx
431
436
 
432
437
  labels
433
438
  end
439
+
440
+ def map_label_position!(property)
441
+ position = property[:position]
442
+ return unless ptrue?(position)
443
+
444
+ if @label_positions[position]
445
+ property[:position] = if position == @label_position_default
446
+ nil
447
+ else
448
+ @label_positions[position]
449
+ end
450
+ else
451
+ raise "Unsupported label position '#{position}' for this chart type"
452
+ end
453
+ end
434
454
  end
435
455
  end
436
456
  end
@@ -0,0 +1,132 @@
1
+ # -*- coding: utf-8 -*-
2
+ # frozen_string_literal: true
3
+
4
+ ###############################################################################
5
+ #
6
+ # series_data.rb - series/formula bookkeeping and axis id management
7
+ #
8
+ ###############################################################################
9
+
10
+ module Writexlsx
11
+ class Chart
12
+ module SeriesData
13
+ #
14
+ # Switch name and name_formula parameters if required.
15
+ #
16
+ def process_names(name = nil, name_formula = nil) # :nodoc:
17
+ # Name looks like a formula, use it to set name_formula.
18
+ if name.respond_to?(:to_ary)
19
+ cell = xl_rowcol_to_cell(name[1], name[2], 1, 1)
20
+ name_formula = "#{quote_sheetname(name[0])}!#{cell}"
21
+ name = ''
22
+ elsif name && name =~ /^=[^!]+!\$/
23
+ name_formula = name
24
+ name = ''
25
+ end
26
+
27
+ [name, name_formula]
28
+ end
29
+
30
+ #
31
+ # Assign an id to a each unique series formula or title/axis formula. Repeated
32
+ # formulas such as for categories get the same id. If the series or title
33
+ # has user specified data associated with it then that is also stored. This
34
+ # data is used to populate cached Excel data when creating a chart.
35
+ # If there is no user defined data then it will be populated by the parent
36
+ # workbook in Workbook::_add_chart_data
37
+ #
38
+ def data_id(full_formula, data) # :nodoc:
39
+ return unless full_formula
40
+
41
+ # Strip the leading '=' from the formula.
42
+ formula = full_formula.sub(/^=/, '')
43
+
44
+ # Store the data id in a hash keyed by the formula and store the data
45
+ # in a separate array with the same id.
46
+ if @formula_ids.has_key?(formula)
47
+ # Formula already seen. Return existing id.
48
+ id = @formula_ids[formula]
49
+ # Store user defined data if it isn't already there.
50
+ @formula_data[id] ||= data
51
+ else
52
+ # Haven't seen this formula before.
53
+ id = @formula_ids[formula] = @formula_data.size
54
+ @formula_data << data
55
+ end
56
+
57
+ id
58
+ end
59
+
60
+ private
61
+
62
+ #
63
+ # retun primary/secondary series by :primary_axes flag
64
+ #
65
+ def axes_series(params)
66
+ if params[:primary_axes] == 0
67
+ secondary_axes_series
68
+ else
69
+ primary_axes_series
70
+ end
71
+ end
72
+
73
+ #
74
+ # Find the overall type of the data associated with a series.
75
+ #
76
+ # TODO. Need to handle date type.
77
+ #
78
+ def get_data_type(data) # :nodoc:
79
+ # Check for no data in the series.
80
+ return 'none' unless data
81
+ return 'none' if data.empty?
82
+ return 'multi_str' if data.first.is_a?(Array)
83
+
84
+ # If the token isn't a number assume it is a string.
85
+ data.each do |token|
86
+ next unless token
87
+ return 'str' unless token.is_a?(Numeric)
88
+ end
89
+
90
+ # The series data was all numeric.
91
+ 'num'
92
+ end
93
+
94
+ #
95
+ # Returns series which use the primary axes.
96
+ #
97
+ def get_primary_axes_series
98
+ @series.reject(&:y2_axis)
99
+ end
100
+ alias primary_axes_series get_primary_axes_series
101
+
102
+ #
103
+ # Returns series which use the secondary axes.
104
+ #
105
+ def get_secondary_axes_series
106
+ @series.select(&:y2_axis)
107
+ end
108
+ alias secondary_axes_series get_secondary_axes_series
109
+
110
+ #
111
+ # Add a unique ids for primary or secondary axis.
112
+ #
113
+ def add_axis_ids(params) # :nodoc:
114
+ if ptrue?(params[:primary_axes])
115
+ @axis_ids += ids
116
+ else
117
+ @axis2_ids += ids
118
+ end
119
+ end
120
+
121
+ def ids
122
+ chart_id = 5001 + @id
123
+ axis_count = 1 + @axis2_ids.size + @axis_ids.size
124
+
125
+ id1 = sprintf('%04d%04d', chart_id, axis_count)
126
+ id2 = sprintf('%04d%04d', chart_id, axis_count + 1)
127
+
128
+ [id1, id2]
129
+ end
130
+ end
131
+ end
132
+ end