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,192 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # frozen_string_literal: true
3
+
4
+ require 'write_xlsx/utility/common'
5
+
6
+ module Writexlsx
7
+ class PageSetup # :nodoc:
8
+ include Writexlsx::Utility::Common
9
+
10
+ attr_accessor :margin_left, :margin_right, :margin_top, :margin_bottom # :nodoc:
11
+ attr_accessor :margin_header, :margin_footer # :nodoc:
12
+ attr_accessor :repeat_rows, :repeat_cols, :print_area # :nodoc:
13
+ attr_accessor :hbreaks, :vbreaks, :scale # :nodoc:
14
+ attr_accessor :fit_page, :fit_width, :fit_height, :page_setup_changed # :nodoc:
15
+ attr_writer :across # :nodoc:
16
+ attr_accessor :orientation, :print_options_changed, :black_white # :nodoc:
17
+ attr_accessor :header, :footer, :header_footer_changed, :header_footer_aligns, :header_footer_scales
18
+ attr_writer :page_start
19
+ attr_writer :horizontal_dpi, :vertical_dpi
20
+
21
+ def initialize # :nodoc:
22
+ @margin_left = 0.7
23
+ @margin_right = 0.7
24
+ @margin_top = 0.75
25
+ @margin_bottom = 0.75
26
+ @margin_header = 0.3
27
+ @margin_footer = 0.3
28
+ @repeat_rows = ''
29
+ @repeat_cols = ''
30
+ @print_area = ''
31
+ @hbreaks = []
32
+ @vbreaks = []
33
+ @scale = 100
34
+ @fit_page = false
35
+ @fit_width = nil
36
+ @fit_height = nil
37
+ @page_setup_changed = false
38
+ @across = false
39
+ @orientation = true
40
+ @header_footer_aligns = true
41
+ @header_footer_scales = true
42
+ end
43
+
44
+ def paper=(paper_size)
45
+ if paper_size
46
+ @paper_size = paper_size
47
+ @page_setup_changed = true
48
+ end
49
+ end
50
+
51
+ def center_horizontally
52
+ @print_options_changed = true
53
+ @hcenter = true
54
+ end
55
+
56
+ def center_vertically
57
+ @print_options_changed = true
58
+ @vcenter = true
59
+ end
60
+
61
+ def print_row_col_headers(headers)
62
+ if headers
63
+ @print_headers = true
64
+ @print_options_changed = true
65
+ else
66
+ @print_headers = false
67
+ end
68
+ end
69
+
70
+ def hide_gridlines(option)
71
+ if option == 0 || !option
72
+ @print_gridlines = true
73
+ @print_options_changed = true
74
+ else
75
+ @print_gridlines = false
76
+ end
77
+ end
78
+
79
+ #
80
+ # Write the <pageSetup> element.
81
+ #
82
+ # The following is an example taken from Excel.
83
+ #
84
+ # <pageSetup
85
+ # paperSize="9"
86
+ # scale="110"
87
+ # fitToWidth="2"
88
+ # fitToHeight="2"
89
+ # pageOrder="overThenDown"
90
+ # orientation="portrait"
91
+ # useFirstPageNumber="1"
92
+ # blackAndWhite="1"
93
+ # draft="1"
94
+ # horizontalDpi="200"
95
+ # verticalDpi="200"
96
+ # r:id="rId1"
97
+ # />
98
+ #
99
+ def write_page_setup(writer) # :nodoc:
100
+ return unless @page_setup_changed
101
+
102
+ attributes = []
103
+ attributes << ['paperSize', @paper_size] if @paper_size
104
+ attributes << ['scale', @scale] if @scale != 100
105
+ attributes << ['fitToWidth', @fit_width] if @fit_page && @fit_width != 1
106
+ attributes << ['fitToHeight', @fit_height] if @fit_page && @fit_height != 1
107
+ attributes << %w[pageOrder overThenDown] if @across
108
+ attributes << ['firstPageNumber', @page_start] if @page_start && @page_start > 1
109
+ attributes << ['orientation',
110
+ if @orientation
111
+ 'portrait'
112
+ else
113
+ 'landscape'
114
+ end]
115
+ attributes << ['blackAndWhite', 1] if @black_white
116
+ attributes << ['useFirstPageNumber', 1] if ptrue?(@page_start)
117
+
118
+ # Set the DPI. Mainly only for testing.
119
+ attributes << ['horizontalDpi', @horizontal_dpi] if @horizontal_dpi
120
+ attributes << ['verticalDpi', @vertical_dpi] if @vertical_dpi
121
+
122
+ writer.empty_tag('pageSetup', attributes)
123
+ end
124
+
125
+ #
126
+ # Write the <pageMargins> element.
127
+ #
128
+ def write_page_margins(writer) # :nodoc:
129
+ writer.empty_tag('pageMargins', margin_attributes)
130
+ end
131
+
132
+ #
133
+ # Write the <printOptions> element.
134
+ #
135
+ def write_print_options(writer) # :nodoc:
136
+ return unless @print_options_changed
137
+
138
+ attributes = []
139
+ attributes << ['horizontalCentered', 1] if @hcenter
140
+ attributes << ['verticalCentered', 1] if @vcenter
141
+ attributes << ['headings', 1] if @print_headers
142
+ attributes << ['gridLines', 1] if @print_gridlines
143
+ writer.empty_tag('printOptions', attributes)
144
+ end
145
+
146
+ #
147
+ # Write the <headerFooter> element.
148
+ #
149
+ def write_header_footer(writer, excel2003_style) # :nodoc:
150
+ tag = 'headerFooter'
151
+ attributes = []
152
+ attributes << ['scaleWithDoc', 0] unless ptrue?(@header_footer_scales)
153
+ attributes << ['alignWithMargins', 0] unless ptrue?(@header_footer_aligns)
154
+
155
+ if @header_footer_changed
156
+ writer.tag_elements(tag, attributes) do
157
+ write_odd_header(writer) if @header && @header != ''
158
+ write_odd_footer(writer) if @footer && @footer != ''
159
+ end
160
+ elsif excel2003_style
161
+ writer.empty_tag(tag, attributes)
162
+ end
163
+ end
164
+
165
+ private
166
+
167
+ #
168
+ # Write the <oddHeader> element.
169
+ #
170
+ def write_odd_header(writer) # :nodoc:
171
+ writer.data_element('oddHeader', @header)
172
+ end
173
+
174
+ #
175
+ # Write the <oddFooter> element.
176
+ #
177
+ def write_odd_footer(writer) # :nodoc:
178
+ writer.data_element('oddFooter', @footer)
179
+ end
180
+
181
+ def margin_attributes # :nodoc:
182
+ [
183
+ ['left', @margin_left],
184
+ ['right', @margin_right],
185
+ ['top', @margin_top],
186
+ ['bottom', @margin_bottom],
187
+ ['header', @margin_header],
188
+ ['footer', @margin_footer]
189
+ ]
190
+ end
191
+ end
192
+ end
@@ -1,6 +1,8 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # frozen_string_literal: true
3
3
 
4
+ require 'write_xlsx/utility/chart_formatting'
5
+
4
6
  module Writexlsx
5
7
  ###############################################################################
6
8
  #
@@ -12,7 +14,7 @@ module Writexlsx
12
14
  # Converted to ruby by Hideo NAKAMURA, nakamura.hideo@gmail.com
13
15
  #
14
16
  class Shape
15
- include Writexlsx::Utility
17
+ include Writexlsx::Utility::ChartFormatting
16
18
 
17
19
  attr_reader :edit_as, :drawing
18
20
  attr_reader :tx_box, :fill, :line, :format
@@ -27,106 +29,11 @@ module Writexlsx
27
29
 
28
30
  def initialize(properties = {})
29
31
  @writer = Package::XMLWriterSimple.new
30
- @name = nil
31
- @type = 'rect'
32
-
33
- # Is a Connector shape. 1/0 Value is a hash lookup from type.
34
- @connect = 0
35
-
36
- # Is a Drawing. Always 0, since a single shape never fills an entire sheet.
37
- @drawing = 0
38
-
39
- # OneCell or Absolute: options to move and/or size with cells.
40
- @edit_as = nil
41
-
42
- # Auto-incremented, unless supplied by user.
43
- @id = 0
44
-
45
- # Shape text (usually centered on shape geometry).
46
- @text = 0
47
-
48
- # Shape stencil mode. A copy (child) is created when inserted.
49
- # The link to parent is broken.
50
- @stencil = 1
51
-
52
- # Index to _shapes array when inserted.
53
- @element = -1
54
-
55
- # Shape ID of starting connection, if any.
56
- @start = nil
57
-
58
- # Shape vertex, starts at 0, numbered clockwise from 12 o'clock.
59
- @start_index = nil
60
-
61
- @end = nil
62
- @end_index = nil
63
-
64
- # Number and size of adjustments for shapes (usually connectors).
65
- @adjustments = []
66
-
67
- # Start and end sides. t)op, b)ottom, l)eft, or r)ight.
68
- @start_side = ''
69
- @end_side = ''
70
-
71
- # Flip shape Horizontally. eg. arrow left to arrow right.
72
- @flip_h = 0
73
32
 
74
- # Flip shape Vertically. eg. up arrow to down arrow.
75
- @flip_v = 0
76
-
77
- # shape rotation (in degrees 0-360).
78
- @rotation = 0
79
-
80
- # An alternate way to create a text box, because Excel allows it.
81
- # It is just a rectangle with text.
82
- @tx_box = false
83
-
84
- # Shape outline colour, or 0 for noFill (default black).
85
- @line = '000000'
86
-
87
- # Line type: dash, sysDot, dashDot, lgDash, lgDashDot, lgDashDotDot.
88
- @line_type = ''
89
-
90
- # Line weight (integer).
91
- @line_weight = 1
92
-
93
- # Shape fill colour, or 0 for noFill (default noFill).
94
- @fill = 0
95
-
96
- # Formatting for shape text, if any.
97
- @format = {}
98
-
99
- # copy of colour palette table from Workbook.pm.
100
- @palette = []
101
-
102
- # Vertical alignment: t, ctr, b.
103
- @valign = 'ctr'
104
-
105
- # Alignment: l, ctr, r, just
106
- @align = 'ctr'
107
-
108
- @x_offset = 0
109
- @y_offset = 0
110
-
111
- # Scale factors, which also may be set when the shape is inserted.
112
- @scale_x = 1
113
- @scale_y = 1
114
-
115
- # Default size, which can be modified and/or scaled.
116
- @width = 50
117
- @height = 50
118
-
119
- # Initial assignment. May be modified when prepared.
120
- @column_start = 0
121
- @row_start = 0
122
- @x1 = 0
123
- @y1 = 0
124
- @column_end = 0
125
- @row_end = 0
126
- @x2 = 0
127
- @y2 = 0
128
- @x_abs = 0
129
- @y_abs = 0
33
+ init_basic_attributes
34
+ init_connection_attributes
35
+ init_appearance_attributes
36
+ init_position_attributes
130
37
 
131
38
  set_properties(properties)
132
39
  end
@@ -298,5 +205,95 @@ module Writexlsx
298
205
  @width_emu, @height_emu
299
206
  ]
300
207
  end
208
+
209
+ private
210
+
211
+ def init_basic_attributes
212
+ @name = nil
213
+ @type = 'rect'
214
+
215
+ # Is a Connector shape. 1/0 Value is a hash lookup from type.
216
+ @connect = 0
217
+ # Is a Drawing. Always 0, since a single shape never fills an entire sheet.
218
+ @drawing = 0
219
+ # OneCell or Absolute: options to move and/or size with cells.
220
+ @edit_as = nil
221
+ # Auto-incremented, unless supplied by user.
222
+ @id = 0
223
+ # Shape text (usually centered on shape geometry).
224
+ @text = 0
225
+ # Shape stencil mode. A copy (child) is created when inserted.
226
+ # The link to parent is broken.
227
+ @stencil = 1
228
+ # Index to _shapes array when inserted.
229
+ @element = -1
230
+ # An alternate way to create a text box, because Excel allows it.
231
+ # It is just a rectangle with text.
232
+ @tx_box = false
233
+ # copy of colour palette table from Workbook.pm.
234
+ @palette = []
235
+ end
236
+
237
+ def init_connection_attributes
238
+ # Shape ID of starting connection, if any.
239
+ @start = nil
240
+ # Shape vertex, starts at 0, numbered clockwise from 12 o'clock.
241
+ @start_index = nil
242
+ @end = nil
243
+ @end_index = nil
244
+ # Number and size of adjustments for shapes (usually connectors).
245
+ @adjustments = []
246
+ # Start and end sides. t)op, b)ottom, l)eft, or r)ight.
247
+ @start_side = ''
248
+ @end_side = ''
249
+ end
250
+
251
+ def init_appearance_attributes
252
+ # Flip shape Horizontally. eg. arrow left to arrow right.
253
+ @flip_h = 0
254
+ # Flip shape Vertically. eg. up arrow to down arrow.
255
+ @flip_v = 0
256
+ # shape rotation (in degrees 0-360).
257
+ @rotation = 0
258
+ # Shape outline colour, or 0 for noFill (default black).
259
+ @line = '000000'
260
+ # Line type: dash, sysDot, dashDot, lgDash, lgDashDot, lgDashDotDot.
261
+ @line_type = ''
262
+ # Line weight (integer).
263
+ @line_weight = 1
264
+ # Shape fill colour, or 0 for noFill (default noFill).
265
+ @fill = 0
266
+ # Formatting for shape text, if any.
267
+ @format = {}
268
+ # Vertical alignment: t, ctr, b.
269
+ @valign = 'ctr'
270
+ # Alignment: l, ctr, r, just
271
+ @align = 'ctr'
272
+ end
273
+
274
+ def init_position_attributes
275
+ @x_offset = 0
276
+ @y_offset = 0
277
+
278
+ # Scale factors, which also may be set when the shape is inserted.
279
+ @scale_x = 1
280
+ @scale_y = 1
281
+
282
+ # Default size, which can be modified and/or scaled.
283
+ @width = 50
284
+ @height = 50
285
+
286
+ # Initial assignment. May be modified when prepared.
287
+ @column_start = 0
288
+ @row_start = 0
289
+ @x1 = 0
290
+ @y1 = 0
291
+ @column_end = 0
292
+ @row_end = 0
293
+ @x2 = 0
294
+ @y2 = 0
295
+ @x_abs = 0
296
+ @y_abs = 0
297
+ end
301
298
  end
302
299
  end
@@ -2,11 +2,16 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'delegate'
5
+ require 'write_xlsx/constants'
6
+ require 'write_xlsx/utility/common'
7
+ require 'write_xlsx/utility/xml_primitives'
5
8
  require 'write_xlsx/package/xml_writer_simple'
6
9
 
7
10
  module Writexlsx
8
11
  class Sheets < DelegateClass(Array)
9
- include Writexlsx::Utility
12
+ include Constants
13
+ include Writexlsx::Utility::Common
14
+ include Writexlsx::Utility::XmlPrimitives
10
15
 
11
16
  BASE_NAME = { sheet: 'Sheet', chart: 'Chart' } # :nodoc:
12
17
 
@@ -91,9 +96,9 @@ module Writexlsx
91
96
  def write_comment_files(package_dir)
92
97
  self.select { |sheet| sheet.has_comments? }
93
98
  .each_with_index do |sheet, index|
94
- FileUtils.mkdir_p("#{package_dir}/xl/drawings")
95
- sheet.comments.set_xml_writer("#{package_dir}/xl/comments#{index + 1}.xml")
96
- sheet.comments.assemble_xml_file
99
+ FileUtils.mkdir_p("#{package_dir}/xl/drawings")
100
+ sheet.comments.set_xml_writer("#{package_dir}/xl/comments#{index + 1}.xml")
101
+ sheet.comments.assemble_xml_file
97
102
  end
98
103
  end
99
104
 
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'write_xlsx/utility'
4
+ require 'write_xlsx/utility/common'
5
5
 
6
6
  module Writexlsx
7
7
  ###############################################################################
@@ -14,7 +14,7 @@ module Writexlsx
14
14
  # Converted to ruby by Hideo NAKAMURA, nakamura.hideo@gmail.com
15
15
  #
16
16
  class Sparkline
17
- include Writexlsx::Utility
17
+ include Writexlsx::Utility::Common
18
18
 
19
19
  def initialize(ws, param, sheetname)
20
20
  @color = {}
@@ -0,0 +1,124 @@
1
+ # -*- coding: utf-8 -*-
2
+ # frozen_string_literal: true
3
+
4
+ require 'write_xlsx/col_name'
5
+ require 'write_xlsx/constants'
6
+
7
+ module Writexlsx
8
+ module Utility
9
+ module CellReference
10
+ include Constants
11
+
12
+ #
13
+ # xl_rowcol_to_cell($row, col, row_absolute, col_absolute)
14
+ #
15
+ def xl_rowcol_to_cell(row_or_name, col, row_absolute = false, col_absolute = false)
16
+ if row_or_name.is_a?(Integer)
17
+ row_or_name += 1 # Change from 0-indexed to 1 indexed.
18
+ end
19
+ col_str = xl_col_to_name(col, col_absolute)
20
+ "#{col_str}#{absolute_char(row_absolute)}#{row_or_name}"
21
+ end
22
+
23
+ #
24
+ # Returns: [row, col, row_absolute, col_absolute]
25
+ #
26
+ # The row_absolute and col_absolute parameters aren't documented because they
27
+ # mainly used internally and aren't very useful to the user.
28
+ #
29
+ def xl_cell_to_rowcol(cell)
30
+ cell =~ /(\$?)([A-Z]{1,3})(\$?)(\d+)/
31
+
32
+ col_abs = ::Regexp.last_match(1) != ""
33
+ col = ::Regexp.last_match(2)
34
+ row_abs = ::Regexp.last_match(3) != ""
35
+ row = ::Regexp.last_match(4).to_i
36
+
37
+ # Convert base26 column string to number
38
+ # All your Base are belong to us.
39
+ chars = col.chars
40
+ expn = 0
41
+ col = 0
42
+
43
+ chars.reverse.each do |char|
44
+ col += (char.ord - 'A'.ord + 1) * (26**expn)
45
+ expn += 1
46
+ end
47
+
48
+ # Convert 1-index to zero-index
49
+ row -= 1
50
+ col -= 1
51
+
52
+ [row, col, row_abs, col_abs]
53
+ end
54
+
55
+ def xl_col_to_name(col, col_absolute)
56
+ col_str = ColName.instance.col_str(col)
57
+ if col_absolute
58
+ "#{absolute_char(col_absolute)}#{col_str}"
59
+ else
60
+ # Do not allocate new string
61
+ col_str
62
+ end
63
+ end
64
+
65
+ def xl_range(row_1, row_2, col_1, col_2,
66
+ row_abs_1 = false, row_abs_2 = false, col_abs_1 = false, col_abs_2 = false)
67
+ range1 = xl_rowcol_to_cell(row_1, col_1, row_abs_1, col_abs_1)
68
+ range2 = xl_rowcol_to_cell(row_2, col_2, row_abs_2, col_abs_2)
69
+
70
+ if range1 == range2
71
+ range1
72
+ else
73
+ "#{range1}:#{range2}"
74
+ end
75
+ end
76
+
77
+ def xl_range_formula(sheetname, row_1, row_2, col_1, col_2)
78
+ # Use Excel's conventions and quote the sheet name if it contains any
79
+ # non-word character or if it isn't already quoted.
80
+ sheetname = quote_sheetname(sheetname)
81
+
82
+ range1 = xl_rowcol_to_cell(row_1, col_1, 1, 1)
83
+ range2 = xl_rowcol_to_cell(row_2, col_2, 1, 1)
84
+
85
+ "=#{sheetname}!#{range1}:#{range2}"
86
+ end
87
+
88
+ # Check for a cell reference in A1 notation and substitute row and column
89
+ def row_col_notation(row_or_a1) # :nodoc:
90
+ substitute_cellref(row_or_a1) if row_or_a1.respond_to?(:match) && row_or_a1.to_s =~ /^\D/
91
+ end
92
+
93
+ #
94
+ # Substitute an Excel cell reference in A1 notation for zero based row and
95
+ # column values in an argument list.
96
+ #
97
+ # Ex: ("A4", "Hello") is converted to (3, 0, "Hello").
98
+ #
99
+ def substitute_cellref(cell, *args) # :nodoc:
100
+ normalized_cell = cell.upcase
101
+
102
+ case normalized_cell
103
+ # Convert a column range: 'A:A' or 'B:G'.
104
+ # A range such as A:A is equivalent to A1:65536, so add rows as required
105
+ when /\$?([A-Z]{1,3}):\$?([A-Z]{1,3})/
106
+ row1, col1 = xl_cell_to_rowcol(::Regexp.last_match(1) + '1')
107
+ row2, col2 = xl_cell_to_rowcol(::Regexp.last_match(2) + ROW_MAX.to_s)
108
+ [row1, col1, row2, col2, *args]
109
+ # Convert a cell range: 'A1:B7'
110
+ when /\$?([A-Z]{1,3}\$?\d+):\$?([A-Z]{1,3}\$?\d+)/
111
+ row1, col1 = xl_cell_to_rowcol(::Regexp.last_match(1))
112
+ row2, col2 = xl_cell_to_rowcol(::Regexp.last_match(2))
113
+ [row1, col1, row2, col2, *args]
114
+ # Convert a cell reference: 'A1' or 'AD2000'
115
+ when /\$?([A-Z]{1,3}\$?\d+)/
116
+ row1, col1 = xl_cell_to_rowcol(::Regexp.last_match(1))
117
+ [row1, col1, *args]
118
+ else
119
+ raise("Unknown cell reference #{normalized_cell}")
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end