write_xlsx 0.79.0 → 0.80.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 (71) hide show
  1. checksums.yaml +4 -4
  2. data/Changes +6 -0
  3. data/README.md +1 -1
  4. data/lib/write_xlsx/chart.rb +38 -1
  5. data/lib/write_xlsx/chart/area.rb +4 -0
  6. data/lib/write_xlsx/chart/bar.rb +9 -0
  7. data/lib/write_xlsx/chart/column.rb +9 -0
  8. data/lib/write_xlsx/chart/line.rb +13 -0
  9. data/lib/write_xlsx/chart/pie.rb +10 -0
  10. data/lib/write_xlsx/chart/radar.rb +4 -0
  11. data/lib/write_xlsx/chart/scatter.rb +13 -0
  12. data/lib/write_xlsx/chart/series.rb +38 -26
  13. data/lib/write_xlsx/chart/stock.rb +13 -0
  14. data/lib/write_xlsx/utility.rb +1 -1
  15. data/lib/write_xlsx/version.rb +1 -1
  16. data/lib/write_xlsx/worksheet.rb +11 -4
  17. data/test/chart/test_write_d_lbls.rb +18 -1
  18. data/test/regression/test_chart_data_labels01.rb +47 -0
  19. data/test/regression/test_chart_data_labels02.rb +47 -0
  20. data/test/regression/test_chart_data_labels03.rb +47 -0
  21. data/test/regression/test_chart_data_labels04.rb +47 -0
  22. data/test/regression/test_chart_data_labels05.rb +50 -0
  23. data/test/regression/test_chart_data_labels06.rb +50 -0
  24. data/test/regression/test_chart_data_labels07.rb +40 -0
  25. data/test/regression/test_chart_data_labels08.rb +46 -0
  26. data/test/regression/test_chart_data_labels09.rb +47 -0
  27. data/test/regression/test_chart_data_labels10.rb +47 -0
  28. data/test/regression/test_chart_data_labels11.rb +37 -0
  29. data/test/regression/test_chart_data_labels12.rb +37 -0
  30. data/test/regression/test_chart_data_labels13.rb +37 -0
  31. data/test/regression/test_chart_data_labels14.rb +37 -0
  32. data/test/regression/test_chart_data_labels15.rb +37 -0
  33. data/test/regression/test_chart_data_labels16.rb +40 -0
  34. data/test/regression/test_chart_data_labels17.rb +63 -0
  35. data/test/regression/test_chart_data_labels18.rb +53 -0
  36. data/test/regression/test_chart_data_labels19.rb +53 -0
  37. data/test/regression/test_chart_data_labels20.rb +44 -0
  38. data/test/regression/test_chart_data_labels21.rb +48 -0
  39. data/test/regression/test_chart_data_labels22.rb +47 -0
  40. data/test/regression/test_chart_data_labels23.rb +50 -0
  41. data/test/regression/test_chart_format19.rb +1 -1
  42. data/test/regression/test_quote_name01.rb +48 -0
  43. data/test/regression/test_quote_name03.rb +41 -0
  44. data/test/regression/xlsx_files/chart_data_labels01.xlsx +0 -0
  45. data/test/regression/xlsx_files/chart_data_labels02.xlsx +0 -0
  46. data/test/regression/xlsx_files/chart_data_labels03.xlsx +0 -0
  47. data/test/regression/xlsx_files/chart_data_labels04.xlsx +0 -0
  48. data/test/regression/xlsx_files/chart_data_labels05.xlsx +0 -0
  49. data/test/regression/xlsx_files/chart_data_labels06.xlsx +0 -0
  50. data/test/regression/xlsx_files/chart_data_labels07.xlsx +0 -0
  51. data/test/regression/xlsx_files/chart_data_labels08.xlsx +0 -0
  52. data/test/regression/xlsx_files/chart_data_labels09.xlsx +0 -0
  53. data/test/regression/xlsx_files/chart_data_labels10.xlsx +0 -0
  54. data/test/regression/xlsx_files/chart_data_labels11.xlsx +0 -0
  55. data/test/regression/xlsx_files/chart_data_labels12.xlsx +0 -0
  56. data/test/regression/xlsx_files/chart_data_labels13.xlsx +0 -0
  57. data/test/regression/xlsx_files/chart_data_labels14.xlsx +0 -0
  58. data/test/regression/xlsx_files/chart_data_labels15.xlsx +0 -0
  59. data/test/regression/xlsx_files/chart_data_labels16.xlsx +0 -0
  60. data/test/regression/xlsx_files/chart_data_labels17.xlsx +0 -0
  61. data/test/regression/xlsx_files/chart_data_labels18.xlsx +0 -0
  62. data/test/regression/xlsx_files/chart_data_labels19.xlsx +0 -0
  63. data/test/regression/xlsx_files/chart_data_labels20.xlsx +0 -0
  64. data/test/regression/xlsx_files/chart_data_labels21.xlsx +0 -0
  65. data/test/regression/xlsx_files/chart_data_labels22.xlsx +0 -0
  66. data/test/regression/xlsx_files/chart_data_labels23.xlsx +0 -0
  67. data/test/regression/xlsx_files/chart_data_labels24.xlsx +0 -0
  68. data/test/regression/xlsx_files/quote_name01.xlsx +0 -0
  69. data/test/regression/xlsx_files/quote_name02.xlsx +0 -0
  70. data/test/regression/xlsx_files/quote_name03.xlsx +0 -0
  71. metadata +105 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e671b68b1de5d627fc5e2306b17a157dd669ac0b
4
- data.tar.gz: 9a33233b791e917331d2714bfa1212789ff7d515
3
+ metadata.gz: 9f7b091a25a820d796b03d56e1e599383281513d
4
+ data.tar.gz: 6253c7a5c2dc797c7924593d5e1747f721758899
5
5
  SHA512:
6
- metadata.gz: 2b218047dedb38eb475c41a3dda88d3eefca2d185ea34af3270f6d5ca9ebb884f1e81d3b8f893b16cbb84930fda41f28b2a62c926d2a58b9754c2c0e296204ce
7
- data.tar.gz: d9ea75c34d0510b98d1a9a985fabbe3bcd62a73b8f31eba6b9d334313d1f94e29ffe6392dda2bc12cc84e1d4a778ace0e8ddff6afe530a5c5eb3661aeaa7ef07
6
+ metadata.gz: d4b0e1065e775a4638f962cbb5aa7345a1859f0c4fda350af0119a20c02b1455a7208480d5098283ba83f9ab64e616eed61684a84af0822a7de4a9fe4436be17
7
+ data.tar.gz: 57547d50d45c5961e8827049a0132ff50d392b927f0add7ea5f4bf57974398538d87d4d8bb3ce3d3ed88c36b5bdd81d7379a887cb2382e834d6b3d417429088c
data/Changes CHANGED
@@ -1,4 +1,10 @@
1
1
  Change history of write_xlsx rubygem.
2
+ 2014-11-30 v0.80.0
3
+ Chart Data Label enhancements. Added number formatting, font handling
4
+ (Excel::Writer::XLSX issue #106), separator (Same issue #107) and legend key.
5
+ Added chart specific handling of data label positions since not all
6
+ positions are available for all chart types. Excel::Writer::XLSX Issue #110.
7
+
2
8
  2014-11-29 v0.79.0
3
9
  Added option to add images to headers and footers.
4
10
  Added option to not scale heaader/footer with page.
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  gem to create a new file in the Excel 2007+ XLSX format, and you can use the
6
6
  same interface as writeexcel gem. write_xlsx is converted from Perl's module
7
- [Excel::Writer::XLSX-0.79](https://github.com/jmcnamara/excel-writer-xlsx) .
7
+ [Excel::Writer::XLSX-0.80](https://github.com/jmcnamara/excel-writer-xlsx) .
8
8
 
9
9
  ## Description
10
10
 
@@ -141,6 +141,7 @@ class Chart
141
141
  attr_reader :embedded, :formula_ids, :formula_data # :nodoc:
142
142
  attr_reader :x_scale, :y_scale, :x_offset, :y_offset # :nodoc:
143
143
  attr_reader :width, :height # :nodoc:
144
+ attr_reader :label_positions, :label_position_default
144
145
 
145
146
  #
146
147
  # Factory method for returning chart objects based on their class type.
@@ -1392,6 +1393,20 @@ def write_cat_number_format(axis)
1392
1393
  axis.write_cat_number_format(@writer, @cat_has_num_fmt)
1393
1394
  end
1394
1395
 
1396
+ #
1397
+ # Write the <c:numberFormat> element for data labels.
1398
+ #
1399
+ def write_data_label_number_format(format_code)
1400
+ source_linked = 0
1401
+
1402
+ attributes = [
1403
+ ['formatCode', format_code],
1404
+ ['sourceLinked', source_linked]
1405
+ ]
1406
+
1407
+ @writer.empty_tag('c:numFmt', attributes)
1408
+ end
1409
+
1395
1410
  #
1396
1411
  # Write the <c:majorTickMark> element.
1397
1412
  #
@@ -2232,8 +2247,14 @@ def write_d_lbls(labels) # :nodoc:
2232
2247
  return unless labels
2233
2248
 
2234
2249
  @writer.tag_elements('c:dLbls') do
2250
+ # Write the c:numFmt element.
2251
+ write_data_label_number_format(labels[:num_format]) if labels[:num_format]
2252
+ # Write the data label font elements.
2253
+ write_axis_font(labels[:font]) if labels[:font]
2235
2254
  # Write the c:dLblPos element.
2236
- write_d_lbl_pos(labels[:position]) if labels[:position]
2255
+ write_d_lbl_pos(labels[:position]) if ptrue?(labels[:position])
2256
+ # Write the c:showLegendKey element.
2257
+ write_show_legend_key if labels[:legend_key]
2237
2258
  # Write the c:showVal element.
2238
2259
  write_show_val if labels[:value]
2239
2260
  # Write the c:showCatName element.
@@ -2242,11 +2263,20 @@ def write_d_lbls(labels) # :nodoc:
2242
2263
  write_show_ser_name if labels[:series_name]
2243
2264
  # Write the c:showPercent element.
2244
2265
  write_show_percent if labels[:percentage]
2266
+ # Write the c:separator element.
2267
+ write_separator(labels[:separator]) if labels[:separator]
2245
2268
  # Write the c:showLeaderLines element.
2246
2269
  write_show_leader_lines if labels[:leader_lines]
2247
2270
  end
2248
2271
  end
2249
2272
 
2273
+ #
2274
+ # Write the <c:showLegendKey> element.
2275
+ #
2276
+ def write_show_legend_key
2277
+ @writer.empty_tag('c:showLegendKey', [ ['val', 1] ])
2278
+ end
2279
+
2250
2280
  #
2251
2281
  # Write the <c:showVal> element.
2252
2282
  #
@@ -2275,6 +2305,13 @@ def write_show_percent
2275
2305
  @writer.empty_tag('c:showPercent', [ ['val', 1] ])
2276
2306
  end
2277
2307
 
2308
+ #
2309
+ # Write the <c:separator> element.
2310
+ #
2311
+ def write_separator(data)
2312
+ @writer.data_element('c:separator', data)
2313
+ end
2314
+
2278
2315
  #
2279
2316
  # Write the <c:showLeaderLines> element.
2280
2317
  #
@@ -32,6 +32,10 @@ def initialize(subtype)
32
32
  end
33
33
 
34
34
  set_y_axis
35
+
36
+ # Set the available data label positions for this chart type.
37
+ @label_position_default = 'center'
38
+ @label_positions = { 'center' => 'ctr' }
35
39
  end
36
40
 
37
41
  #
@@ -31,6 +31,15 @@ def initialize(subtype)
31
31
  axis_defaults_set
32
32
  set_x_axis
33
33
  set_y_axis
34
+
35
+ # Set the available data label positions for this chart type.
36
+ @label_position_default = 'outside_end'
37
+ @label_positions = {
38
+ 'center' => 'ctr',
39
+ 'inside_base' => 'inBase',
40
+ 'inside_end' => 'inEnd',
41
+ 'outside_end' => 'outEnd'
42
+ }
34
43
  end
35
44
 
36
45
  #
@@ -39,6 +39,15 @@ def initialize(subtype)
39
39
  end
40
40
 
41
41
  set_y_axis
42
+
43
+ # Set the available data label positions for this chart type.
44
+ @label_position_default = 'outside_end'
45
+ @label_positions = {
46
+ 'center' => 'ctr',
47
+ 'inside_base' => 'inBase',
48
+ 'inside_end' => 'inEnd',
49
+ 'outside_end' => 'outEnd'
50
+ }
42
51
  end
43
52
 
44
53
  #
@@ -24,6 +24,19 @@ def initialize(subtype)
24
24
  super(subtype)
25
25
  @default_marker = Marker.new(:type => 'none')
26
26
  @smooth_allowed = 1
27
+
28
+ # Set the available data label positions for this chart type.
29
+ @label_position_default = 'right'
30
+ @label_positions = {
31
+ 'center' => 'ctr',
32
+ 'right' => 'r',
33
+ 'left' => 'l',
34
+ 'above' => 't',
35
+ 'below' => 'b',
36
+ # For backward compatibility.
37
+ 'top' => 't',
38
+ 'bottom' => 'b'
39
+ }
27
40
  end
28
41
 
29
42
  #
@@ -30,6 +30,16 @@ def initialize(subtype)
30
30
  super(subtype)
31
31
  @vary_data_color = 1
32
32
  @rotation = 0
33
+
34
+ # Set the available data label positions for this chart type.
35
+ @label_position_default = 'best_fit'
36
+ @label_positions = {
37
+ 'center' => 'ctr',
38
+ 'inside_base' => 'inBase',
39
+ 'inside_end' => 'inEnd',
40
+ 'outside_end' => 'outEnd',
41
+ 'best_fit' => 'bestFit'
42
+ }
33
43
  end
34
44
 
35
45
  #
@@ -41,6 +41,10 @@ def initialize(subtype)
41
41
 
42
42
  # Hardcode major_tick_mark for now untill there is an accessor.
43
43
  @y_axis.major_tick_mark = 'cross'
44
+
45
+ # Set the available data label positions for this chart type.
46
+ @label_position_default = 'center'
47
+ @label_positions = { 'center' => 'ctr' }
44
48
  end
45
49
 
46
50
  #
@@ -43,6 +43,19 @@ def initialize(subtype)
43
43
  @horiz_val_axis = 0
44
44
  @val_axis_position = 'b'
45
45
  @smooth_allowed = 1
46
+
47
+ # Set the available data label positions for this chart type.
48
+ @label_position_default = 'right'
49
+ @label_positions = {
50
+ 'center' => 'ctr',
51
+ 'right' => 'r',
52
+ 'left' => 'l',
53
+ 'above' => 't',
54
+ 'below' => 'b',
55
+ # For backward compatibility.
56
+ 'top' => 't',
57
+ 'bottom' => 'b'
58
+ }
46
59
  end
47
60
 
48
61
  #
@@ -168,12 +168,13 @@ class Series
168
168
  attr_accessor :line, :marker
169
169
 
170
170
  def initialize(chart, params = {})
171
+ @chart = chart
171
172
  @values = aref_to_formula(params[:values])
172
173
  @categories = aref_to_formula(params[:categories])
173
174
  @name, @name_formula =
174
175
  chart.process_names(params[:name], params[:name_formula])
175
176
 
176
- set_data_ids(chart, params)
177
+ set_data_ids(params)
177
178
 
178
179
  @line = line_properties(params[:border] || params[:line])
179
180
  @fill = fill_properties(params[:fill])
@@ -182,6 +183,9 @@ def initialize(chart, params = {})
182
183
  @trendline = Trendline.new(params[:trendline]) if params[:trendline]
183
184
  @error_bars = errorbars(params[:x_error_bars], params[:y_error_bars])
184
185
  @points = params[:points].collect { |p| p ? Point.new(p) : p } if params[:points]
186
+
187
+ @label_positions = chart.label_positions
188
+ @label_position_default = chart.label_position_default
185
189
  @labels = labels_properties(params[:data_labels])
186
190
 
187
191
  [:smooth, :invert_if_negative, :x2_axis, :y2_axis].
@@ -214,10 +218,10 @@ def aref_to_formula(data) # :nodoc:
214
218
  xl_range_formula(*data)
215
219
  end
216
220
 
217
- def set_data_ids(chart, params)
218
- @cat_data_id = chart.data_id(@categories, params[:categories_data])
219
- @val_data_id = chart.data_id(@values, params[:values_data])
220
- @name_id = chart.data_id(@name_formula, params[:name_data])
221
+ def set_data_ids(params)
222
+ @cat_data_id = @chart.data_id(@categories, params[:categories_data])
223
+ @val_data_id = @chart.data_id(@values, params[:values_data])
224
+ @name_id = @chart.data_id(@name_formula, params[:name_data])
221
225
  end
222
226
 
223
227
  def errorbars(x, y)
@@ -233,31 +237,39 @@ def errorbars(x, y)
233
237
  def labels_properties(labels) # :nodoc:
234
238
  return nil unless labels
235
239
 
240
+ # Map user defined label positions to Excel positions.
236
241
  position = labels[:position]
237
- if position.nil? || position.empty?
238
- labels.delete(:position)
239
- else
240
- # Map user defined label positions to Excel positions.
241
- labels[:position] = value_or_raise(positions, position, 'label position')
242
+ if ptrue?(position)
243
+ if @label_positions[position]
244
+ if position == @label_position_default
245
+ labels[:position] = nil
246
+ else
247
+ labels[:position] = @label_positions[position]
248
+ end
249
+ else
250
+ raise "Unsupported label position '#{position}' for this chart type"
251
+ end
242
252
  end
243
253
 
244
- labels
245
- end
246
-
247
- def positions
248
- {
249
- :center => 'ctr',
250
- :right => 'r',
251
- :left => 'l',
252
- :top => 't',
253
- :above => 't',
254
- :bottom => 'b',
255
- :below => 'b',
256
- :inside_base => 'inBase',
257
- :inside_end => 'inEnd',
258
- :outside_end => 'outEnd',
259
- :best_fit => 'bestFit'
254
+ # Map the user defined label separator to the Excel separator.
255
+ separators = {
256
+ "," => ", ",
257
+ ";" => "; ",
258
+ "." => ". ",
259
+ "\n" => "\n",
260
+ " " => " "
260
261
  }
262
+ separator = labels[:separator]
263
+ unless separator.nil? || separator.empty?
264
+ raise "unsuppoted label separator #{separator}" unless separators[separator]
265
+ labels[:separator] = separators[separator]
266
+ end
267
+
268
+ if labels[:font]
269
+ labels[:font] = @chart.convert_font_args(labels[:font])
270
+ end
271
+
272
+ labels
261
273
  end
262
274
  end
263
275
  end
@@ -35,6 +35,19 @@ def initialize(subtype)
35
35
  @x2_axis.defaults[:num_format] = 'dd/mm/yyyy'
36
36
  set_x_axis
37
37
  set_x2_axis
38
+
39
+ # Set the available data label positions for this chart type.
40
+ @label_position_default = 'right'
41
+ @label_positions = {
42
+ 'center' => 'ctr',
43
+ 'right' => 'r',
44
+ 'left' => 'l',
45
+ 'above' => 't',
46
+ 'below' => 'b',
47
+ # For backward compatibility.
48
+ 'top' => 't',
49
+ 'bottom' => 'b',
50
+ }
38
51
  end
39
52
 
40
53
  #
@@ -551,7 +551,7 @@ def dash_types
551
551
  end
552
552
 
553
553
  def value_or_raise(hash, key, msg)
554
- raise "Unknown #{msg} '#{key}'" unless hash[key.to_sym]
554
+ raise "Unknown #{msg} '#{key}'" if hash[key.to_sym].nil?
555
555
  hash[key.to_sym]
556
556
  end
557
557
 
@@ -1,5 +1,5 @@
1
1
  require 'write_xlsx/workbook'
2
2
 
3
3
  class WriteXLSX < Writexlsx::Workbook
4
- VERSION = "0.79.0"
4
+ VERSION = "0.80.0"
5
5
  end
@@ -1489,7 +1489,7 @@ def repeat_rows(row_min, row_max = nil)
1489
1489
  area = "$#{row_min}:$#{row_max}"
1490
1490
 
1491
1491
  # Build up the print titles "Sheet1!$1:$2"
1492
- sheetname = quote_sheetname(name)
1492
+ sheetname = quote_sheetname(@name)
1493
1493
  @page_setup.repeat_rows = "#{sheetname}!#{area}"
1494
1494
  end
1495
1495
 
@@ -7515,7 +7515,7 @@ def convert_name_area(row_num_1, col_num_1, row_num_2, col_num_2) #:nodoc:
7515
7515
  end
7516
7516
 
7517
7517
  # Build up the print area range "Sheet1!$A$1:$C$13".
7518
- "#{quote_sheetname(name)}!#{area}"
7518
+ "#{quote_sheetname(@name)}!#{area}"
7519
7519
  end
7520
7520
 
7521
7521
  #
@@ -7524,8 +7524,15 @@ def convert_name_area(row_num_1, col_num_1, row_num_2, col_num_2) #:nodoc:
7524
7524
  # TODO. We need to handle more special cases.
7525
7525
  #
7526
7526
  def quote_sheetname(sheetname) #:nodoc:
7527
- return sheetname if sheetname =~ /^Sheet\d+$/
7528
- return "'#{sheetname}'"
7527
+ # Use Excel's conventions and quote the sheet name if it comtains any
7528
+ # non-word character or if it isn't already quoted.
7529
+ name = sheetname.dup
7530
+ if name =~ /\W/ && !(name =~ /^'/)
7531
+ # Double quote and single quoted strings.
7532
+ name = name.gsub(/'/, "''")
7533
+ name = "'#{name}'"
7534
+ end
7535
+ name
7529
7536
  end
7530
7537
 
7531
7538
  def fit_page? #:nodoc:
@@ -4,7 +4,24 @@
4
4
 
5
5
  class TestWriteDLbls < Test::Unit::TestCase
6
6
  def setup
7
- @chart = Writexlsx::Chart.new('Pie')
7
+ @chart = Writexlsx::Chart.new('Line')
8
+ @chart.instance_variable_set(
9
+ :@label_positions,
10
+ {
11
+ 'center' => 'ctr',
12
+ 'right' => 'r',
13
+ 'left' => 'l',
14
+ 'top' => 't',
15
+ 'above' => 't',
16
+ 'bottom' => 'b',
17
+ 'below' => 'b',
18
+ 'inside_base' => 'inBase',
19
+ 'inside_end' => 'inEnd',
20
+ 'outside_end' => 'outEnd',
21
+ 'best_fit' => 'bestFit'
22
+ }
23
+ )
24
+ @chart.instance_variable_set(:@label_position_default, '')
8
25
  @series = Writexlsx::Chart::Series.new(@chart)
9
26
  end
10
27
 
@@ -0,0 +1,47 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'helper'
3
+
4
+ class TestRegressionChartDataLabels01 < Test::Unit::TestCase
5
+ def setup
6
+ setup_dir_var
7
+ end
8
+
9
+ def teardown
10
+ File.delete(@xlsx) if File.exist?(@xlsx)
11
+ end
12
+
13
+ def test_chart_data_labels01
14
+ @xlsx = 'chart_data_labels01.xlsx'
15
+ workbook = WriteXLSX.new(@xlsx)
16
+ worksheet = workbook.add_worksheet
17
+ chart = workbook.add_chart(:type => 'column', :embedded => 1)
18
+
19
+ # For testing, copy the randomly generated axis ids in the target xlsx file.
20
+ chart.instance_variable_set(:@axis_ids, [45848832, 47718784])
21
+
22
+ data = [
23
+ [1, 2, 3, 4, 5],
24
+ [2, 4, 6, 8, 10],
25
+ [3, 6, 9, 12, 15]
26
+ ]
27
+
28
+ worksheet.write('A1', data)
29
+
30
+ chart.add_series(
31
+ :values => '=Sheet1!$A$1:$A$5',
32
+ :data_labels => { :value => 1, :position => 'outside_end' }
33
+ )
34
+
35
+ chart.add_series(
36
+ :values => '=Sheet1!$B$1:$B$5',
37
+ :data_labels => { :value => 1, :position => 'inside_base' }
38
+ )
39
+
40
+ chart.add_series( :values => '=Sheet1!$C$1:$C$5' )
41
+
42
+ worksheet.insert_chart('E9', chart)
43
+
44
+ workbook.close
45
+ compare_xlsx_for_regression(File.join(@regression_output, @xlsx), @xlsx)
46
+ end
47
+ end