write_xlsx 0.62.0 → 0.64.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. data/README.rdoc +14 -1
  2. data/examples/chart_data_tools.rb +215 -0
  3. data/examples/chart_pie.rb +36 -5
  4. data/examples/sparklines2.rb +1 -1
  5. data/examples/tab_colors.rb +3 -3
  6. data/lib/write_xlsx/chart.rb +559 -516
  7. data/lib/write_xlsx/chart/area.rb +4 -1
  8. data/lib/write_xlsx/chart/axis.rb +132 -0
  9. data/lib/write_xlsx/chart/bar.rb +17 -9
  10. data/lib/write_xlsx/chart/column.rb +9 -1
  11. data/lib/write_xlsx/chart/line.rb +24 -0
  12. data/lib/write_xlsx/chart/radar.rb +2 -2
  13. data/lib/write_xlsx/chart/scatter.rb +19 -0
  14. data/lib/write_xlsx/chart/stock.rb +10 -3
  15. data/lib/write_xlsx/drawing.rb +43 -44
  16. data/lib/write_xlsx/package/vml.rb +21 -14
  17. data/lib/write_xlsx/shape.rb +173 -22
  18. data/lib/write_xlsx/sparkline.rb +524 -0
  19. data/lib/write_xlsx/version.rb +1 -1
  20. data/lib/write_xlsx/workbook.rb +183 -115
  21. data/lib/write_xlsx/worksheet.rb +821 -1073
  22. data/lib/write_xlsx/worksheet/cell_data.rb +132 -0
  23. data/lib/write_xlsx/worksheet/print_style.rb +51 -0
  24. data/test/chart/test_add_series.rb +31 -6
  25. data/test/chart/test_write_d_lbls.rb +18 -18
  26. data/test/chart/test_write_number_format.rb +20 -24
  27. data/test/drawing/test_drawing_shape_01.rb +1 -1
  28. data/test/drawing/test_drawing_shape_02.rb +2 -2
  29. data/test/drawing/test_drawing_shape_03.rb +5 -5
  30. data/test/drawing/test_drawing_shape_04.rb +3 -3
  31. data/test/drawing/test_drawing_shape_05.rb +4 -4
  32. data/test/drawing/test_drawing_shape_07.rb +2 -2
  33. data/test/perl_output/chart_data_tools.xlsx +0 -0
  34. data/test/perl_output/chart_pie.xlsx +0 -0
  35. data/test/regression/disabled_test_vml04.rb +2 -2
  36. data/test/regression/test_chart_drop_lines01.rb +46 -0
  37. data/test/regression/test_chart_drop_lines02.rb +51 -0
  38. data/test/regression/test_chart_drop_lines03.rb +46 -0
  39. data/test/regression/test_chart_drop_lines04.rb +64 -0
  40. data/test/regression/test_chart_errorbars01.rb +47 -0
  41. data/test/regression/test_chart_errorbars02.rb +57 -0
  42. data/test/regression/test_chart_errorbars03.rb +53 -0
  43. data/test/regression/test_chart_errorbars04.rb +48 -0
  44. data/test/regression/test_chart_errorbars05.rb +47 -0
  45. data/test/regression/test_chart_errorbars06.rb +47 -0
  46. data/test/regression/test_chart_errorbars07.rb +66 -0
  47. data/test/regression/test_chart_font02.rb +1 -1
  48. data/test/regression/test_chart_font06.rb +1 -1
  49. data/test/regression/test_chart_gridlines04.rb +2 -1
  50. data/test/regression/test_chart_gridlines08.rb +2 -1
  51. data/test/regression/test_chart_points01.rb +37 -0
  52. data/test/regression/test_chart_points02.rb +40 -0
  53. data/test/regression/test_chart_points03.rb +42 -0
  54. data/test/regression/test_chart_points04.rb +52 -0
  55. data/test/regression/test_chart_points05.rb +49 -0
  56. data/test/regression/test_chart_points06.rb +49 -0
  57. data/test/regression/test_chartsheet05.rb +1 -1
  58. data/test/regression/test_chartsheet06.rb +1 -1
  59. data/test/regression/test_comment01.rb +1 -1
  60. data/test/regression/test_comment02.rb +1 -1
  61. data/test/regression/test_comment03.rb +1 -1
  62. data/test/regression/test_comment04.rb +2 -2
  63. data/test/regression/test_comment06.rb +1 -1
  64. data/test/regression/test_comment07.rb +1 -1
  65. data/test/regression/test_comment08.rb +1 -1
  66. data/test/regression/test_comment09.rb +1 -1
  67. data/test/regression/test_comment10.rb +1 -1
  68. data/test/regression/test_default_row04.rb +1 -1
  69. data/test/regression/test_escapes02.rb +1 -1
  70. data/test/regression/test_hyperlink15.rb +2 -2
  71. data/test/regression/test_shape_connect01.rb +6 -6
  72. data/test/regression/test_shape_connect02.rb +6 -6
  73. data/test/regression/test_shape_connect03.rb +11 -11
  74. data/test/regression/test_shape_connect04.rb +10 -10
  75. data/test/regression/test_shape_scale01.rb +2 -2
  76. data/test/regression/test_shape_stencil01.rb +3 -3
  77. data/test/regression/test_tab_color01.rb +1 -1
  78. data/test/regression/test_table04.rb +1 -1
  79. data/test/regression/test_table05.rb +1 -1
  80. data/test/regression/test_table06.rb +1 -1
  81. data/test/regression/test_vml01.rb +1 -1
  82. data/test/regression/test_vml02.rb +1 -1
  83. data/test/regression/test_vml03.rb +2 -2
  84. data/test/regression/xlsx_files/chart_drop_lines01.xlsx +0 -0
  85. data/test/regression/xlsx_files/chart_drop_lines02.xlsx +0 -0
  86. data/test/regression/xlsx_files/chart_drop_lines03.xlsx +0 -0
  87. data/test/regression/xlsx_files/chart_drop_lines04.xlsx +0 -0
  88. data/test/regression/xlsx_files/chart_errorbars01.xlsx +0 -0
  89. data/test/regression/xlsx_files/chart_errorbars02.xlsx +0 -0
  90. data/test/regression/xlsx_files/chart_errorbars03.xlsx +0 -0
  91. data/test/regression/xlsx_files/chart_errorbars04.xlsx +0 -0
  92. data/test/regression/xlsx_files/chart_errorbars05.xlsx +0 -0
  93. data/test/regression/xlsx_files/chart_errorbars06.xlsx +0 -0
  94. data/test/regression/xlsx_files/chart_errorbars07.xlsx +0 -0
  95. data/test/regression/xlsx_files/chart_points01.xlsx +0 -0
  96. data/test/regression/xlsx_files/chart_points02.xlsx +0 -0
  97. data/test/regression/xlsx_files/chart_points03.xlsx +0 -0
  98. data/test/regression/xlsx_files/chart_points04.xlsx +0 -0
  99. data/test/regression/xlsx_files/chart_points05.xlsx +0 -0
  100. data/test/regression/xlsx_files/chart_points06.xlsx +0 -0
  101. data/test/regression/xlsx_files/chart_stock02.xlsx +0 -0
  102. data/test/test_example_match.rb +278 -57
  103. data/test/worksheet/test_convert_date_time_02.rb +427 -433
  104. data/test/worksheet/test_convert_date_time_03.rb +1 -1
  105. data/test/worksheet/test_write_sheet_pr.rb +2 -2
  106. data/test/worksheet/test_write_sheet_view1.rb +2 -2
  107. metadata +80 -10
@@ -4,9 +4,12 @@
4
4
  require 'write_xlsx/colors'
5
5
  require 'write_xlsx/format'
6
6
  require 'write_xlsx/drawing'
7
+ require 'write_xlsx/sparkline'
7
8
  require 'write_xlsx/compatibility'
8
9
  require 'write_xlsx/utility'
9
10
  require 'write_xlsx/package/conditional_format'
11
+ require 'write_xlsx/worksheet/cell_data'
12
+ require 'write_xlsx/worksheet/print_style'
10
13
  require 'tempfile'
11
14
 
12
15
  module Writexlsx
@@ -18,48 +21,48 @@ module Writexlsx
18
21
  #
19
22
  # The following methods are available through a new worksheet:
20
23
  #
21
- # write
22
- # write_number
23
- # write_string
24
- # write_rich_string
25
- # write_blank
26
- # write_row
27
- # write_col
28
- # write_date_time
29
- # write_url
30
- # write_url_range
31
- # write_formula
32
- # write_comment
33
- # show_comments
34
- # set_comments_author
35
- # insert_image
36
- # insert_chart
37
- # insert_shape
38
- # data_validation
39
- # conditional_formatting
40
- # add_sparkline
41
- # add_table
42
- # name
43
- # activate
44
- # select
45
- # hide
46
- # set_first_sheet
47
- # protect
48
- # set_selection
49
- # set_row
50
- # set_column
51
- # outline_settings
52
- # freeze_panes
53
- # split_panes
54
- # merge_range
55
- # merge_range_type
56
- # set_zoom
57
- # right_to_left
58
- # hide_zero
59
- # set_tab_color
60
- # autofilter
61
- # filter_column
62
- # filter_column_list
24
+ # * write
25
+ # * write_number
26
+ # * write_string
27
+ # * write_rich_string
28
+ # * write_blank
29
+ # * write_row
30
+ # * write_col
31
+ # * write_date_time
32
+ # * write_url
33
+ # * write_formula
34
+ # * write_comment
35
+ # * show_comments
36
+ # * comments_author=()
37
+ # * insert_image
38
+ # * insert_chart
39
+ # * insert_shape
40
+ # * insert_button
41
+ # * data_validation
42
+ # * conditional_formatting
43
+ # * add_sparkline
44
+ # * add_table
45
+ # * name
46
+ # * activate
47
+ # * select
48
+ # * hide
49
+ # * set_first_sheet
50
+ # * protect
51
+ # * set_selection
52
+ # * set_row
53
+ # * set_column
54
+ # * outline_settings
55
+ # * freeze_panes
56
+ # * split_panes
57
+ # * merge_range
58
+ # * merge_range_type
59
+ # * zoom=()
60
+ # * right_to_left
61
+ # * hide_zero
62
+ # * tab_color=()
63
+ # * autofilter
64
+ # * filter_column
65
+ # * filter_column_list
63
66
  #
64
67
  # ==Cell notation
65
68
  #
@@ -105,35 +108,38 @@ module Writexlsx
105
108
  # following sections are given in terms of row-column notation. In all cases
106
109
  # it is also possible to use A1 notation.
107
110
  #
111
+ # Note: in Excel it is also possible to use a R1C1 notation. This is not
112
+ # supported by WriteXLSX.
113
+ #
108
114
  # == PAGE SET-UP METHODS
109
115
  #
110
116
  # Page set-up methods affect the way that a worksheet looks
111
117
  # when it is printed. They control features such as page headers and footers
112
118
  # and margins. These methods are really just standard worksheet methods.
113
- # They are documented here in a separate section for the sake of clarity.
114
119
  #
115
120
  # The following methods are available for page set-up:
116
121
  #
117
- # set_landscape()
118
- # set_portrait()
119
- # set_page_view()
120
- # set_paper()
121
- # center_horizontally()
122
- # center_vertically()
123
- # set_margins()
124
- # set_header()
125
- # set_footer()
126
- # repeat_rows()
127
- # repeat_columns()
128
- # hide_gridlines()
129
- # print_row_col_headers()
130
- # print_area()
131
- # print_across()
132
- # fit_to_pages()
133
- # set_start_page()
134
- # set_print_scale()
135
- # set_h_pagebreaks()
136
- # set_v_pagebreaks()
122
+ # * set_landscape
123
+ # * set_portrait
124
+ # * set_page_view
125
+ # * set_paper
126
+ # * center_horizontally
127
+ # * center_vertically
128
+ # * set_margins
129
+ # * set_header
130
+ # * set_footer
131
+ # * repeat_rows
132
+ # * repeat_columns
133
+ # * hide_gridlines
134
+ # * print_row_col_headers
135
+ # * print_area
136
+ # * print_across
137
+ # * fit_to_pages
138
+ # * set_start_page
139
+ # * set_print_scale
140
+ # * set_h_pagebreaks
141
+ # * set_v_pagebreaks
142
+ #
137
143
  # A common requirement when working with WriteXLSX is to apply the same
138
144
  # page set-up features to all of the worksheets in a workbook. To do this
139
145
  # you can use the sheets() method of the workbook class to access the array
@@ -143,182 +149,134 @@ module Writexlsx
143
149
  # worksheet.set_landscape
144
150
  # end
145
151
  #
152
+ # == FORMULAS AND FUNCTIONS IN EXCEL
153
+ #
154
+ # === Introduction
155
+ #
156
+ # The following is a brief introduction to formulas and functions in Excel
157
+ # and WriteXLSX.
158
+ #
159
+ # A formula is a string that begins with an equals sign:
160
+ #
161
+ # '=A1+B1'
162
+ # '=AVERAGE(1, 2, 3)'
163
+ #
164
+ # The formula can contain numbers, strings, boolean values, cell references,
165
+ # cell ranges and functions. Named ranges are not supported. Formulas should
166
+ # be written as they appear in Excel, that is cells and functions must be
167
+ # in uppercase.
168
+ #
169
+ # Cells in Excel are referenced using the A1 notation system where the column
170
+ # is designated by a letter and the row by a number. Columns range from +A+
171
+ # to +XFD+ i.e. 0 to 16384, rows range from 1 to 1048576.
172
+ # The Writexlsx::Utility module that is included in the distro contains
173
+ # helper functions for dealing with A1 notation, for example:
174
+ #
175
+ # require 'write_xlsx'
176
+ #
177
+ # include Writexlsx::Utility
178
+ #
179
+ # row, col = xl_cell_to_rowcol('C2') # (1, 2)
180
+ # str = xl_rowcol_to_cell(1, 2) # C2
181
+ #
182
+ # The Excel +$+ notation in cell references is also supported. This allows
183
+ # you to specify whether a row or column is relative or absolute. This only
184
+ # has an effect if the cell is copied. The following examples show relative
185
+ # and absolute values.
186
+ #
187
+ # '=A1' # Column and row are relative
188
+ # '=$A1' # Column is absolute and row is relative
189
+ # '=A$1' # Column is relative and row is absolute
190
+ # '=$A$1' # Column and row are absolute
191
+ #
192
+ # Formulas can also refer to cells in other worksheets of the current
193
+ # workbook. For example:
194
+ #
195
+ # '=Sheet2!A1'
196
+ # '=Sheet2!A1:A5'
197
+ # '=Sheet2:Sheet3!A1'
198
+ # '=Sheet2:Sheet3!A1:A5'
199
+ # %Q{='Test Data'!A1}
200
+ # %Q{='Test Data1:Test Data2'!A1}
201
+ #
202
+ # The sheet reference and the cell reference are separated by +!+ the
203
+ # exclamation mark symbol. If worksheet names contain spaces, commas or
204
+ # parentheses then Excel requires that the name is enclosed in single
205
+ # quotes as shown in the last two examples above. In order to avoid using
206
+ # a lot of escape characters you can use the quote operator +%Q{}+ to
207
+ # protect the quotes. Only valid sheet names that have been added using the
208
+ # add_worksheet() method can be used in formulas. You cannot reference
209
+ # external workbooks.
210
+ #
211
+ # The following table lists the operators that are available in Excel's
212
+ # formulas. The majority of the operators are the same as Ruby's,
213
+ # differences are indicated:
214
+ #
215
+ # Arithmetic operators:
216
+ # =====================
217
+ # Operator Meaning Example
218
+ # + Addition 1+2
219
+ # - Subtraction 2-1
220
+ # * Multiplication 2*3
221
+ # / Division 1/4
222
+ # ^ Exponentiation 2^3 # Equivalent to **
223
+ # - Unary minus -(1+2)
224
+ # % Percent (Not modulus) 13%
225
+ #
226
+ #
227
+ # Comparison operators:
228
+ # =====================
229
+ # Operator Meaning Example
230
+ # = Equal to A1 = B1 # Equivalent to ==
231
+ # <> Not equal to A1 <> B1 # Equivalent to !=
232
+ # > Greater than A1 > B1
233
+ # < Less than A1 < B1
234
+ # >= Greater than or equal to A1 >= B1
235
+ # <= Less than or equal to A1 <= B1
236
+ #
237
+ #
238
+ # String operator:
239
+ # ================
240
+ # Operator Meaning Example
241
+ # & Concatenation "Hello " & "World!" # [1]
242
+ #
243
+ #
244
+ # Reference operators:
245
+ # ====================
246
+ # Operator Meaning Example
247
+ # : Range operator A1:A4 # [2]
248
+ # , Union operator SUM(1, 2+2, B3) # [3]
249
+ #
250
+ #
251
+ # Notes:
252
+ # [1]: Equivalent to "Hello " + "World!" in Ruby.
253
+ # [2]: This range is equivalent to cells A1, A2, A3 and A4.
254
+ # [3]: The comma behaves like the list separator in Perl.
255
+ #
256
+ # The range and comma operators can have different symbols in non-English
257
+ # versions of Excel. These may be supported in a later version of WriteXLSX.
258
+ # In the meantime European users of Excel take note:
259
+ #
260
+ # worksheet.write('A1', '=SUM(1; 2; 3)') # Wrong!!
261
+ # worksheet.write('A1', '=SUM(1, 2, 3)') # Okay
262
+ #
263
+ # For a general introduction to Excel's formulas and an explanation of the
264
+ # syntax of the function refer to the Excel help files or the following:
265
+ # http://office.microsoft.com/en-us/assistance/CH062528031033.aspx.
266
+ #
267
+ # If your formula doesn't work in Excel::Writer::XLSX try the following:
268
+ #
269
+ # 1. Verify that the formula works in Excel.
270
+ # 2. Ensure that cell references and formula names are in uppercase.
271
+ # 3. Ensure that you are using ':' as the range operator, A1:A4.
272
+ # 4. Ensure that you are using ',' as the union operator, SUM(1,2,3).
273
+ # 5. If you verify that the formula works in Gnumeric, OpenOffice.org
274
+ # or LibreOffice, make sure to note items 2-4 above, since these
275
+ # applications are more flexible than Excel with formula syntax.
276
+ #
146
277
  class Worksheet
147
278
  include Writexlsx::Utility
148
279
 
149
- class CellData # :nodoc:
150
- include Writexlsx::Utility
151
-
152
- attr_reader :row, :col, :token, :xf
153
- attr_reader :result, :range, :link_type, :url, :tip
154
-
155
- #
156
- # attributes for the <cell> element. This is the innermost loop so efficiency is
157
- # important where possible.
158
- #
159
- def cell_attributes #:nodoc:
160
- xf_index = xf ? xf.get_xf_index : 0
161
- attributes = ['r', xl_rowcol_to_cell(row, col)]
162
-
163
- # Add the cell format index.
164
- if xf_index != 0
165
- attributes << 's' << xf_index
166
- elsif @worksheet.set_rows[row] && @worksheet.set_rows[row][1]
167
- row_xf = @worksheet.set_rows[row][1]
168
- attributes << 's' << row_xf.get_xf_index
169
- elsif @worksheet.col_formats[col]
170
- col_xf = @worksheet.col_formats[col]
171
- attributes << 's' << col_xf.get_xf_index
172
- end
173
- attributes
174
- end
175
-
176
- def display_url_string?
177
- true
178
- end
179
- end
180
-
181
- class NumberCellData < CellData # :nodoc:
182
- def initialize(worksheet, row, col, num, xf)
183
- @worksheet = worksheet
184
- @row, @col, @token, @xf = row, col, num, xf
185
- end
186
-
187
- def data
188
- @token
189
- end
190
-
191
- def write_cell
192
- @worksheet.writer.tag_elements('c', cell_attributes) do
193
- @worksheet.write_cell_value(token)
194
- end
195
- end
196
- end
197
-
198
- class StringCellData < CellData # :nodoc:
199
- def initialize(worksheet, row, col, index, xf)
200
- @worksheet = worksheet
201
- @row, @col, @token, @xf = row, col, index, xf
202
- end
203
-
204
- def data
205
- { :sst_id => token }
206
- end
207
-
208
- def write_cell
209
- attributes = cell_attributes
210
- attributes << 't' << 's'
211
- @worksheet.writer.tag_elements('c', attributes) do
212
- @worksheet.write_cell_value(token)
213
- end
214
- end
215
-
216
- def display_url_string?
217
- false
218
- end
219
- end
220
-
221
- class FormulaCellData < CellData # :nodoc:
222
- def initialize(worksheet, row, col, formula, xf, result)
223
- @worksheet = worksheet
224
- @row, @col, @token, @xf, @result = row, col, formula, xf, result
225
- end
226
-
227
- def data
228
- @result || 0
229
- end
230
-
231
- def write_cell
232
- attributes = cell_attributes
233
- if @result && !(@result.to_s =~ /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/)
234
- attributes << 't' << 'str'
235
- end
236
- @worksheet.writer.tag_elements('c', attributes) do
237
- @worksheet.write_cell_formula(token)
238
- @worksheet.write_cell_value(result || 0)
239
- end
240
- end
241
- end
242
-
243
- class FormulaArrayCellData < CellData # :nodoc:
244
- def initialize(worksheet, row, col, formula, xf, range, result)
245
- @worksheet = worksheet
246
- @row, @col, @token, @xf, @range, @result = row, col, formula, xf, range, result
247
- end
248
-
249
- def data
250
- @result || 0
251
- end
252
-
253
- def write_cell
254
- @worksheet.writer.tag_elements('c', cell_attributes) do
255
- @worksheet.write_cell_array_formula(token, range)
256
- @worksheet.write_cell_value(result)
257
- end
258
- end
259
- end
260
-
261
- class BlankCellData < CellData # :nodoc:
262
- def initialize(worksheet, row, col, index, xf)
263
- @worksheet = worksheet
264
- @row, @col, @xf = row, col, xf
265
- end
266
-
267
- def data
268
- ''
269
- end
270
-
271
- def write_cell
272
- @worksheet.writer.empty_tag('c', cell_attributes)
273
- end
274
- end
275
-
276
- class PrintStyle # :nodoc:
277
- attr_accessor :margin_left, :margin_right, :margin_top, :margin_bottom # :nodoc:
278
- attr_accessor :margin_header, :margin_footer # :nodoc:
279
- attr_accessor :repeat_rows, :repeat_cols, :print_area # :nodoc:
280
- attr_accessor :hbreaks, :vbreaks, :scale # :nodoc:
281
- attr_accessor :fit_page, :fit_width, :fit_height, :page_setup_changed # :nodoc:
282
- attr_accessor :across # :nodoc:
283
- attr_accessor :orientation # :nodoc:
284
-
285
- def initialize # :nodoc:
286
- @margin_left = 0.7
287
- @margin_right = 0.7
288
- @margin_top = 0.75
289
- @margin_bottom = 0.75
290
- @margin_header = 0.3
291
- @margin_footer = 0.3
292
- @repeat_rows = ''
293
- @repeat_cols = ''
294
- @print_area = ''
295
- @hbreaks = []
296
- @vbreaks = []
297
- @scale = 100
298
- @fit_page = false
299
- @fit_width = nil
300
- @fit_height = nil
301
- @page_setup_changed = false
302
- @across = false
303
- @orientation = true
304
- end
305
-
306
- def attributes # :nodoc:
307
- [
308
- 'left', @margin_left,
309
- 'right', @margin_right,
310
- 'top', @margin_top,
311
- 'bottom', @margin_bottom,
312
- 'header', @margin_header,
313
- 'footer', @margin_footer
314
- ]
315
- end
316
-
317
- def orientation?
318
- !!@orientation
319
- end
320
- end
321
-
322
280
  attr_reader :index # :nodoc:
323
281
  attr_reader :charts, :images, :tables, :shapes, :drawing # :nodoc:
324
282
  attr_reader :external_hyper_links, :external_drawing_links # :nodoc:
@@ -390,7 +348,6 @@ def initialize(workbook, index, name) #:nodoc:
390
348
  @shapes = []
391
349
  @shape_hash = {}
392
350
 
393
- @zoom = 100
394
351
  @outline_row_level = 0
395
352
  @outline_col_level = 0
396
353
 
@@ -662,7 +619,7 @@ def protect_default_settings # :nodoc:
662
619
  #
663
620
  # It is also possible, and generally clearer, to specify a column range
664
621
  # using the form of A1 notation used for columns. See the note about
665
- # "Cell notation".
622
+ # {"Cell notation"}[#label-Cell+notation].
666
623
  #
667
624
  # Examples:
668
625
  #
@@ -798,7 +755,7 @@ def set_column(*args)
798
755
  # in which case last_row and last_col can be omitted. The active cell
799
756
  # within a selected range is determined by the order in which first and
800
757
  # last are specified. It is also possible to specify a cell or a range
801
- # using A1 notation. See the note about "Cell notation".
758
+ # using A1 notation. See the note about {"Cell notation"}[#label-Cell+notation].
802
759
  #
803
760
  # Examples:
804
761
  #
@@ -969,20 +926,27 @@ def set_page_view(flag = true)
969
926
  #
970
927
  # Set the colour of the worksheet tab.
971
928
  #
972
- # The set_tab_color() method is used to change the colour of the worksheet
929
+ # The tab_color=() method is used to change the colour of the worksheet
973
930
  # tab. This feature is only available in Excel 2002 and later. You can use
974
931
  # one of the standard colour names provided by the Format object or a
975
- # colour index. See "COLOURS IN EXCEL" and the set_custom_color() method.
932
+ # colour index.
933
+ # See "COLOURS IN EXCEL" and the set_custom_color() method.
976
934
  #
977
- # worksheet1.set_tab_color('red')
978
- # worksheet2.set_tab_color(0x0C)
935
+ # worksheet1.tab_color = 'red'
936
+ # worksheet2.tab_color = 0x0C
979
937
  #
980
938
  # See the tab_colors.rb program in the examples directory of the distro.
981
939
  #
982
- def set_tab_color(color)
940
+ def tab_color=(color)
983
941
  @tab_color = Colors.new.get_color(color)
984
942
  end
985
943
 
944
+ # This method is deprecated. use tab_color=().
945
+ def set_tab_color(color)
946
+ put_deprecate_message("#{self}.set_tab_color")
947
+ self.tab_color = color
948
+ end
949
+
986
950
  #
987
951
  # Set the paper type. Ex. 1 = US Letter, 9 = A4
988
952
  #
@@ -1448,7 +1412,7 @@ def print_repeat_rows # :nodoc:
1448
1412
  # method. The parameters first_column and last_column are zero based.
1449
1413
  # The last_column parameter is optional if you only wish to specify
1450
1414
  # one column. You can also specify the columns using A1 column
1451
- # notation, see the note about "Cell notation".
1415
+ # notation, see the note about {"Cell notation"}[#label-Cell+notation].
1452
1416
  #
1453
1417
  # worksheet1.repeat_columns(0) # Repeat the first column
1454
1418
  # worksheet2.repeat_columns(0, 1) # Repeat the first two columns
@@ -1477,7 +1441,7 @@ def print_repeat_cols # :nodoc:
1477
1441
  #
1478
1442
  # This method is used to specify the area of the worksheet that will
1479
1443
  # be printed. All four parameters must be specified. You can also use
1480
- # A1 notation, see the note about "Cell notation".
1444
+ # A1 notation, see the note about {"Cell notation"}[#label-Cell+notation].
1481
1445
  #
1482
1446
  # worksheet1.print_area( 'A1:H20' ); # Cells A1 to H20
1483
1447
  # worksheet2.print_area( 0, 0, 19, 7 ); # The same
@@ -1498,16 +1462,33 @@ def print_area(*args)
1498
1462
  end
1499
1463
 
1500
1464
  #
1501
- # Set the worksheet zoom factor.
1465
+ # Set the worksheet zoom factor in the range 10 <= $scale <= 400:
1466
+ #
1467
+ # worksheet1.zoom = 50
1468
+ # worksheet2.zoom = 75
1469
+ # worksheet3.zoom = 300
1470
+ # worksheet4.zoom = 400
1502
1471
  #
1503
- def set_zoom(scale = 100)
1472
+ # The default zoom factor is 100. You cannot zoom to "Selection" because
1473
+ # it is calculated by Excel at run-time.
1474
+ #
1475
+ # Note, zoom=() does not affect the scale of the printed page.
1476
+ # For that you should use print_scale=().
1477
+ #
1478
+ def zoom=(scale)
1504
1479
  # Confine the scale to Excel's range
1505
1480
  if scale < 10 or scale > 400
1506
1481
  # carp "Zoom factor scale outside range: 10 <= zoom <= 400"
1507
- scale = 100
1482
+ @zoom = 100
1483
+ else
1484
+ @zoom = scale.to_i
1508
1485
  end
1486
+ end
1509
1487
 
1510
- @zoom = scale.to_i
1488
+ # This method is deprecated. use zoom=().
1489
+ def set_zoom(scale)
1490
+ put_deprecate_message("#{self}.set_zoom")
1491
+ self.zoom = scale
1511
1492
  end
1512
1493
 
1513
1494
  #
@@ -1521,7 +1502,7 @@ def set_zoom(scale = 100)
1521
1502
  #
1522
1503
  # The default scale factor is 100. Note, print_scale=() does not
1523
1504
  # affect the scale of the visible page in Excel. For that you should
1524
- # use set_zoom().
1505
+ # use zoom=().
1525
1506
  #
1526
1507
  # Note also that although it is valid to use both fit_to_pages() and
1527
1508
  # print_scale=() on the same worksheet only one of these options
@@ -1639,8 +1620,8 @@ def set_start_page(page_start)
1639
1620
  # write_row
1640
1621
  # write_col
1641
1622
  #
1642
- # The general rule is that if the data looks like a something then
1643
- # a something is written. Here are some examples in both row-column
1623
+ # The general rule is that if the data looks like a _something_ then
1624
+ # a _something_ is written. Here are some examples in both row-column
1644
1625
  # and A1 notation:
1645
1626
  #
1646
1627
  # # Same as:
@@ -1664,7 +1645,8 @@ def set_start_page(page_start)
1664
1645
  # # Write an array formula. Not available in writeexcel gem.
1665
1646
  # worksheet.write('A16', '{=SUM(A1:B1*A2:B2)}' ) # write_formula()
1666
1647
  #
1667
- # The format parameter is optional. It should be a valid Format object.
1648
+ # The +format+ parameter is optional. It should be a valid Format object,
1649
+ # See {"CELL FORMATTING"}[Format.html#label-CELL+FORMATTING]:
1668
1650
  #
1669
1651
  # format = workbook.add_format
1670
1652
  # format.set_bold
@@ -1673,9 +1655,9 @@ def set_start_page(page_start)
1673
1655
  #
1674
1656
  # worksheet.write(4, 0, 'Hello', format) # Formatted string
1675
1657
  #
1676
- # The write() method will ignore empty strings or nil tokens unless a format
1677
- # is also supplied. As such you needn't worry about special handling for
1678
- # empty or nil in your data. See also the write_blank() method.
1658
+ # The write() method will ignore empty strings or +nil+ tokens unless a
1659
+ # format is also supplied. As such you needn't worry about special handling
1660
+ # for empty or nil in your data. See also the write_blank() method.
1679
1661
  #
1680
1662
  # One problem with the write() method is that occasionally data looks like
1681
1663
  # a number but you don't want it treated as a number. For example, zip
@@ -1744,13 +1726,13 @@ def write(*args)
1744
1726
  # worksheet.write(0, 2, array[2])
1745
1727
  #
1746
1728
  # Note: For convenience the write() method behaves in the same way as
1747
- # write_row() if it is passed an array reference.
1729
+ # write_row() if it is passed an array.
1748
1730
  # Therefore the following two method calls are equivalent:
1749
1731
  #
1750
1732
  # worksheet.write_row('A1', array) # Write a row of data
1751
1733
  # worksheet.write( 'A1', array) # Same thing
1752
1734
  #
1753
- # As with all of the write methods the format parameter is optional.
1735
+ # As with all of the write methods the +format+ parameter is optional.
1754
1736
  # If a format is specified it is applied to all the elements of the
1755
1737
  # data array.
1756
1738
  #
@@ -1764,6 +1746,7 @@ def write(*args)
1764
1746
  # ]
1765
1747
  #
1766
1748
  # worksheet.write_row('A1', eec)
1749
+ #
1767
1750
  # Would produce a worksheet as follows:
1768
1751
  #
1769
1752
  # -----------------------------------------------------------
@@ -1779,16 +1762,11 @@ def write(*args)
1779
1762
  # To write the data in a row-column order refer to the write_col()
1780
1763
  # method below.
1781
1764
  #
1782
- # Any nil in the data will be ignored unless a format is applied to
1765
+ # Any +nil+ in the data will be ignored unless a format is applied to
1783
1766
  # the data, in which case a formatted blank cell will be written.
1784
1767
  # In either case the appropriate row or column value will still
1785
1768
  # be incremented.
1786
1769
  #
1787
- # The write_row() method returns the first error encountered when
1788
- # writing the elements of the data or zero if no errors were
1789
- # encountered. See the return values described for the write()
1790
- # method.
1791
- #
1792
1770
  # See also the write_arrays.rb program in the examples directory
1793
1771
  # of the distro.
1794
1772
  #
@@ -1831,7 +1809,7 @@ def write_row(*args)
1831
1809
  # worksheet.write(1, 0, array[1])
1832
1810
  # worksheet.write(2, 0, array[2])
1833
1811
  #
1834
- # As with all of the write methods the format parameter is optional.
1812
+ # As with all of the write methods the +format+ parameter is optional.
1835
1813
  # If a format is specified it is applied to all the elements of the
1836
1814
  # data array.
1837
1815
  #
@@ -1861,7 +1839,7 @@ def write_row(*args)
1861
1839
  # To write the data in a column-row order refer to the write_row()
1862
1840
  # method above.
1863
1841
  #
1864
- # Any nil in the data will be ignored unless a format is applied to
1842
+ # Any +nil+ in the data will be ignored unless a format is applied to
1865
1843
  # the data, in which case a formatted blank cell will be written.
1866
1844
  # In either case the appropriate row or column value will still be
1867
1845
  # incremented.
@@ -1875,10 +1853,6 @@ def write_row(*args)
1875
1853
  # worksheet.write_col('A1', array ) # Write a column of data
1876
1854
  # worksheet.write( 'A1', [ array ] ) # Same thing
1877
1855
  #
1878
- # The write_col() method returns the first error encountered when
1879
- # writing the elements of the data or zero if no errors were encountered.
1880
- # See the return values described for the write() method above.
1881
- #
1882
1856
  # See also the write_arrays.rb program in the examples directory of
1883
1857
  # the distro.
1884
1858
  #
@@ -1899,9 +1873,6 @@ def write_col(*args)
1899
1873
  #
1900
1874
  # Write a comment to the specified row and column (zero indexed).
1901
1875
  #
1902
- # write_comment methods return:
1903
- # Returns 0 : normal termination
1904
- #
1905
1876
  # The write_comment() method is used to add a comment to a cell.
1906
1877
  # A cell comment is indicated in Excel by a small red triangle in the
1907
1878
  # upper right-hand corner of the cell. Moving the cursor over the red
@@ -1913,15 +1884,15 @@ def write_col(*args)
1913
1884
  # worksheet.write_comment(2, 2, 'This is a comment.')
1914
1885
  #
1915
1886
  # As usual you can replace the row and column parameters with an A1
1916
- # cell reference. See the note about "Cell notation".
1887
+ # cell reference. See the note about {"Cell notation"}[#label-Cell+notation].
1917
1888
  #
1918
1889
  # worksheet.write( 'C3', 'Hello')
1919
1890
  # worksheet.write_comment('C3', 'This is a comment.')
1920
1891
  #
1921
1892
  # The write_comment() method will also handle strings in UTF-8 format.
1922
1893
  #
1923
- # worksheet.write_comment('C3', "\x{263a}") # Smiley
1924
- # worksheet.write_comment('C4', 'Comment ca va?')
1894
+ # worksheet.write_comment('C3', "日本")
1895
+ # worksheet.write_comment('C4', 'Comment ça va')
1925
1896
  #
1926
1897
  # In addition to the basic 3 argument form of write_comment() you can
1927
1898
  # pass in several optional key/value pairs to control the format of
@@ -1958,9 +1929,9 @@ def write_col(*args)
1958
1929
  # worksheet.write_comment('C3', 'Atonement', :author => 'Ian McEwan')
1959
1930
  #
1960
1931
  # The default author for all cell comments can be set using the
1961
- # set_comments_author() method.
1932
+ # comments_author=() method.
1962
1933
  #
1963
- # worksheet.set_comments_author('Ruby')
1934
+ # worksheet.comments_author = 'Ruby'
1964
1935
  #
1965
1936
  # ===Option: visible
1966
1937
  #
@@ -2057,13 +2028,13 @@ def write_col(*args)
2057
2028
  #
2058
2029
  # You can apply as many of these options as you require.
2059
2030
  #
2060
- # Note about using options that adjust the position of the cell comment
2061
- # such as start_cell, start_row, start_col, x_offset and y_offset:
2031
+ # <b>Note about using options that adjust the position of the cell comment
2032
+ # such as start_cell, start_row, start_col, x_offset and y_offset</b>:
2062
2033
  # Excel only displays offset cell comments when they are displayed as
2063
2034
  # "visible". Excel does not display hidden cells as moved when you
2064
2035
  # mouse over them.
2065
2036
  #
2066
- # Note about row height and comments. If you specify the height of a
2037
+ # <b>Note about row height and comments</b>. If you specify the height of a
2067
2038
  # row that contains a comment then WriteXLSX will adjust the
2068
2039
  # height of the comment to maintain the default or user specified
2069
2040
  # dimensions. However, the height of a row can also be adjusted
@@ -2097,8 +2068,8 @@ def write_comment(*args)
2097
2068
  # worksheet.write_number(0, 0, 123456)
2098
2069
  # worksheet.write_number('A2', 2.3451)
2099
2070
  #
2100
- # See the note about "Cell notation".
2101
- # The format parameter is optional.
2071
+ # See the note about {"Cell notation"}[#label-Cell+notation].
2072
+ # The +format+ parameter is optional.
2102
2073
  #
2103
2074
  # In general it is sufficient to use the write() method.
2104
2075
  #
@@ -2123,7 +2094,7 @@ def write_number(*args)
2123
2094
  # write_string(row, column, string [, format ] )
2124
2095
  #
2125
2096
  # Write a string to the specified row and column (zero indexed).
2126
- # format is optional.
2097
+ # +format+ is optional.
2127
2098
  #
2128
2099
  # worksheet.write_string(0, 0, 'Your text here')
2129
2100
  # worksheet.write_string('A2', 'or here')
@@ -2169,9 +2140,7 @@ def write_string(*args)
2169
2140
  # The method receives string fragments prefixed by format objects. The final
2170
2141
  # format object is used as the cell format.
2171
2142
  #
2172
- # write_rich_string methods return:
2173
- #
2174
- # For example to write the string "This is bold and this is italic"
2143
+ # For example to write the string "This is *bold* and this is _italic_"
2175
2144
  # you would use the following:
2176
2145
  #
2177
2146
  # bold = workbook.add_format(:bold => 1)
@@ -2180,7 +2149,7 @@ def write_string(*args)
2180
2149
  # worksheet.write_rich_string('A1',
2181
2150
  # 'This is ', bold, 'bold', ' and this is ', italic, 'italic')
2182
2151
  #
2183
- # The basic rule is to break the string into fragments and put a format
2152
+ # The basic rule is to break the string into fragments and put a +format+
2184
2153
  # object before the fragment that you want to format. For example:
2185
2154
  #
2186
2155
  # # Unformatted string.
@@ -2195,8 +2164,9 @@ def write_string(*args)
2195
2164
  # # In WriteXLSX.
2196
2165
  # worksheet.write_rich_string('A1',
2197
2166
  # 'This is an ', format, 'example', ' string')
2198
- # String fragments that don't have a format are given a default
2199
- # format. So for example when writing the string "Some bold text"
2167
+ #
2168
+ # String fragments that don't have a format are given a default format.
2169
+ # So for example when writing the string "Some *bold* text"
2200
2170
  # you would use the first example below but it would be equivalent
2201
2171
  # to the second:
2202
2172
  #
@@ -2250,8 +2220,10 @@ def write_string(*args)
2250
2220
  # worksheet.write_rich_string('A7',
2251
2221
  # italic, 'j = k', super, '(n-1)', center)
2252
2222
  #
2223
+ # "http://jmcnamara.github.com/excel-writer-xlsx/images/examples/rich_strings.jpg"
2224
+ #
2253
2225
  # As with write_sting() the maximum string size is 32767 characters.
2254
- # See also the note about "Cell notation".
2226
+ # See also the note about {"Cell notation"}[#label-Cell+notation].
2255
2227
  #
2256
2228
  def write_rich_string(*args)
2257
2229
  # Check for a cell reference in A1 notation and substitute row and column
@@ -2310,6 +2282,11 @@ def write_rich_string(*args)
2310
2282
  # A blank cell is used to specify formatting without adding a string
2311
2283
  # or a number.
2312
2284
  #
2285
+ # worksheet.write_blank(0, 0, format)
2286
+ #
2287
+ # This method is used to add formatting to cell which doesn't contain a
2288
+ # string or number value.
2289
+ #
2313
2290
  # A blank cell without a format serves no purpose. Therefore, we don't write
2314
2291
  # a BLANK record unless a format is specified. This is mainly an optimisation
2315
2292
  # for the write_row() and write_col() methods.
@@ -2325,9 +2302,9 @@ def write_rich_string(*args)
2325
2302
  # worksheet.write('A2', nil ) # Ignored
2326
2303
  #
2327
2304
  # This seemingly uninteresting fact means that you can write arrays of
2328
- # data without special treatment for nil or empty string values.
2305
+ # data without special treatment for +nil+ or empty string values.
2329
2306
  #
2330
- # See the note about "Cell notation".
2307
+ # See the note about {"Cell notation"}[#label-Cell+notation].
2331
2308
  #
2332
2309
  def write_blank(*args)
2333
2310
  # Check for a cell reference in A1 notation and substitute row and column
@@ -2348,7 +2325,7 @@ def write_blank(*args)
2348
2325
  # :call-seq:
2349
2326
  # write_formula(row, column, formula [ , format [ , value ] ] )
2350
2327
  #
2351
- # Write a formula or function to the cell specified by row and column:
2328
+ # Write a formula or function to the cell specified by +row+ and +column+:
2352
2329
  #
2353
2330
  # worksheet.write_formula(0, 0, '=$B$3 + B4')
2354
2331
  # worksheet.write_formula(1, 0, '=SIN(PI()/4)')
@@ -2356,19 +2333,21 @@ def write_blank(*args)
2356
2333
  # worksheet.write_formula('A4', '=IF(A3>1,"Yes", "No")')
2357
2334
  # worksheet.write_formula('A5', '=AVERAGE(1, 2, 3, 4)')
2358
2335
  # worksheet.write_formula('A6', '=DATEVALUE("1-Jan-2001")')
2336
+ #
2359
2337
  # Array formulas are also supported:
2360
2338
  #
2361
2339
  # worksheet.write_formula('A7', '{=SUM(A1:B1*A2:B2)}')
2362
2340
  #
2363
2341
  # See also the write_array_formula() method.
2364
2342
  #
2365
- # See the note about "Cell notation". For more information about
2366
- # writing Excel formulas see "FORMULAS AND FUNCTIONS IN EXCEL"
2343
+ # See the note about {"Cell notation"}[#label-Cell+notation].
2344
+ # For more information about writing Excel formulas see
2345
+ # {"FORMULAS AND FUNCTIONS IN EXCEL"}[#label-FORMULAS+AND+FUNCTIONS+IN+EXCEL]
2367
2346
  #
2368
2347
  # If required, it is also possible to specify the calculated value
2369
2348
  # of the formula. This is occasionally necessary when working with
2370
2349
  # non-Excel applications that don't calculate the value of the
2371
- # formula. The calculated value is added at the end of the argument list:
2350
+ # formula. The calculated +value+ is added at the end of the argument list:
2372
2351
  #
2373
2352
  # worksheet.write('A1', '=2+2', format, 4)
2374
2353
  #
@@ -2395,16 +2374,13 @@ def write_formula(*args)
2395
2374
  # :call-seq:
2396
2375
  # write_array_formula(row1, col1, row2, col2, formula [ , format [ , value ] ] )
2397
2376
  #
2398
- # Write an array formula to the specified row and column (zero indexed).
2399
- #
2400
- # format is optional.
2401
- #
2402
- # In Excel an array formula is a formula that performs a calculation
2403
- # on a set of values. It can return a single value or a range of values.
2377
+ # Write an array formula to a cell range. In Excel an array formula is a
2378
+ # formula that performs a calculation on a set of values. It can return
2379
+ # a single value or a range of values.
2404
2380
  #
2405
2381
  # An array formula is indicated by a pair of braces around the
2406
- # formula: {=SUM(A1:B1*A2:B2)}. If the array formula returns a single
2407
- # value then the first and last parameters should be the same:
2382
+ # formula: +{=SUM(A1:B1*A2:B2)}+. If the array formula returns a single
2383
+ # value then the +first_+ and +last_+ parameters should be the same:
2408
2384
  #
2409
2385
  # worksheet.write_array_formula('A1:A1', '{=SUM(B1:C1*B2:C2)}')
2410
2386
  #
@@ -2522,19 +2498,16 @@ def store_formula(string)
2522
2498
 
2523
2499
  #
2524
2500
  # :call-seq:
2525
- # write_url(row, column, url [ , format, string, tool_tip ] )
2501
+ # write_url(row, column, url [ , format, label ] )
2526
2502
  #
2527
- # Write a hyperlink to a URL in the cell specified by row and column.
2503
+ # Write a hyperlink to a URL in the cell specified by +row+ and +column+.
2528
2504
  # The hyperlink is comprised of two elements: the visible label and
2529
2505
  # the invisible link. The visible label is the same as the link unless
2530
2506
  # an alternative label is specified. The label parameter is optional.
2531
2507
  # The label is written using the write() method. Therefore it is
2532
2508
  # possible to write strings, numbers or formulas as labels.
2533
2509
  #
2534
- # The hyperlink can be to a http, ftp, mail, internal sheet, or external
2535
- # directory url.
2536
- #
2537
- # The format parameter is also optional, however, without a format
2510
+ # The +format+ parameter is also optional, however, without a format
2538
2511
  # the link won't look like a format.
2539
2512
  #
2540
2513
  # The suggested format is:
@@ -2548,11 +2521,22 @@ def store_formula(string)
2548
2521
  # There are four web style URI's supported:
2549
2522
  # http://, https://, ftp:// and mailto::
2550
2523
  #
2551
- # worksheet.write_url(0, 0, 'ftp://www.ruby.org/', format)
2552
- # worksheet.write_url(1, 0, 'http://www.ruby.com/', format, 'Ruby')
2553
- # worksheet.write_url('A3', 'http://www.ruby.com/', format)
2524
+ # worksheet.write_url(0, 0, 'ftp://www.ruby-lang.org/', format)
2525
+ # worksheet.write_url('A3', 'http://www.ruby-lang.org/', format)
2554
2526
  # worksheet.write_url('A4', 'mailto:foo@bar.com', format)
2555
2527
  #
2528
+ # You can display an alternative string using the +label+ parameter:
2529
+ #
2530
+ # worksheet.write_url(1, 0, 'http://www.ruby-lang.org/', format, 'Ruby')
2531
+ #
2532
+ # If you wish to have some other cell data such as a number or a formula
2533
+ # you can overwrite the cell using another call to write_*():
2534
+ #
2535
+ # worksheet.write_url('A1', 'http://www.ruby-lang.org/')
2536
+ #
2537
+ # # Overwrite the URL string with a formula. The cell is still a link.
2538
+ # worksheet.write_formula('A1', '=1+1', format)
2539
+ #
2556
2540
  # There are two local URIs supported: internal: and external:.
2557
2541
  # These are used for hyperlinks to internal worksheet references or
2558
2542
  # external workbook and worksheet references:
@@ -2571,19 +2555,26 @@ def store_formula(string)
2571
2555
  #
2572
2556
  # Worksheet references are typically of the form Sheet1!A1. You can
2573
2557
  # also refer to a worksheet range using the standard Excel notation:
2574
- # Sheet1!A1:B2.
2558
+ # +Sheet1!A1:B2+.
2575
2559
  #
2576
2560
  # In external links the workbook and worksheet name must be separated
2577
- # by the # character: external:Workbook.xlsx#Sheet1!A1'.
2561
+ # by the # character: +external:Workbook.xlsx#Sheet1!A1+.
2578
2562
  #
2579
2563
  # You can also link to a named range in the target worksheet. For
2580
- # example say you have a named range called my_name in the workbook
2581
- # c:\temp\foo.xlsx you could link to it as follows:
2564
+ # example say you have a named range called +my_name+ in the workbook
2565
+ # +c:\temp\foo.xlsx+ you could link to it as follows:
2582
2566
  #
2583
2567
  # worksheet.write_url('A14', 'external:c:\temp\foo.xlsx#my_name')
2584
2568
  #
2585
2569
  # Excel requires that worksheet names containing spaces or non
2586
- # alphanumeric characters are single quoted as follows 'Sales Data'!A1.
2570
+ # alphanumeric characters are single quoted as follows +'Sales Data'!A1+.
2571
+ #
2572
+ # Note: WriteXLSX will escape the following characters in URLs as required
2573
+ # by Excel: \s " < > \ [ ] ` ^ { } unless the URL already contains +%xx+
2574
+ # style escapes. In which case it is assumed that the URL was escaped
2575
+ # correctly by the user and will by passed directly to Excel.
2576
+ #
2577
+ # See also, the note about {"Cell notation"}[#label-Cell+notation].
2587
2578
  #
2588
2579
  def write_url(*args)
2589
2580
  # Check for a cell reference in A1 notation and substitute row and column
@@ -2701,14 +2692,14 @@ def write_url(*args)
2701
2692
  #
2702
2693
  # worksheet.write_date_time('A1', '2004-05-13T23:20', date_format)
2703
2694
  #
2704
- # The date_string should be in the following format:
2695
+ # The +date_string+ should be in the following format:
2705
2696
  #
2706
2697
  # yyyy-mm-ddThh:mm:ss.sss
2707
2698
  #
2708
2699
  # This conforms to an ISO8601 date but it should be noted that the
2709
2700
  # full range of ISO8601 formats are not supported.
2710
2701
  #
2711
- # The following variations on the date_string parameter are permitted:
2702
+ # The following variations on the +date_string+ parameter are permitted:
2712
2703
  #
2713
2704
  # yyyy-mm-ddThh:mm:ss.sss # Standard format
2714
2705
  # yyyy-mm-ddT # No time
@@ -2719,8 +2710,10 @@ def write_url(*args)
2719
2710
  #
2720
2711
  # Note that the T is required in all cases.
2721
2712
  #
2722
- # A date should always have a format, otherwise it will appear
2723
- # as a number, see "DATES AND TIME IN EXCEL" and "CELL FORMATTING".
2713
+ # A date should always have a +format+, otherwise it will appear
2714
+ # as a number, see
2715
+ # {"DATES AND TIME IN EXCEL"}[#method-i-write_date_time-label-DATES+AND+TIME+IN+EXCEL]
2716
+ # and {"CELL FORMATTING"}[#label-CELL+FORMATTING].
2724
2717
  # Here is a typical example:
2725
2718
  #
2726
2719
  # date_format = workbook.add_format(:num_format => 'mm/dd/yy')
@@ -2732,6 +2725,105 @@ def write_url(*args)
2732
2725
  #
2733
2726
  # See also the date_time.rb program in the examples directory of the distro.
2734
2727
  #
2728
+ #
2729
+ # == DATES AND TIME IN EXCEL
2730
+ #
2731
+ # There are two important things to understand about dates and times in Excel:
2732
+ #
2733
+ # 1 A date/time in Excel is a real number plus an Excel number format.
2734
+ # 2 WriteXLSX doesn't automatically convert date/time strings in write() to an Excel date/time.
2735
+ #
2736
+ # These two points are explained in more detail below along with some
2737
+ # suggestions on how to convert times and dates to the required format.
2738
+ #
2739
+ # === An Excel date/time is a number plus a format
2740
+ #
2741
+ # If you write a date string with write() then all you will get is a string:
2742
+ #
2743
+ # worksheet.write('A1', '02/03/04') # !! Writes a string not a date. !!
2744
+ #
2745
+ # Dates and times in Excel are represented by real numbers, for example
2746
+ # "Jan 1 2001 12:30 AM" is represented by the number 36892.521.
2747
+ #
2748
+ # The integer part of the number stores the number of days since the epoch
2749
+ # and the fractional part stores the percentage of the day.
2750
+ #
2751
+ # A date or time in Excel is just like any other number. To have the number
2752
+ # display as a date you must apply an Excel number format to it.
2753
+ # Here are some examples.
2754
+ #
2755
+ # #!/usr/bin/ruby -w
2756
+ #
2757
+ # require 'write_xlsx'
2758
+ #
2759
+ # workbook = WriteXLSX.new('date_examples.xlsx')
2760
+ # worksheet = workbook>add_worksheet
2761
+ #
2762
+ # worksheet.set_column('A:A', 30) # For extra visibility.
2763
+ #
2764
+ # number = 39506.5
2765
+ #
2766
+ # worksheet.write('A1', number) # 39506.5
2767
+ #
2768
+ # format2 = workbook.add_format(:num_format => 'dd/mm/yy')
2769
+ # worksheet.write('A2', number, format2) # 28/02/08
2770
+ #
2771
+ # format3 = workbook.add_format(:num_format => 'mm/dd/yy')
2772
+ # worksheet.write('A3', number, format3) # 02/28/08
2773
+ #
2774
+ # format4 = workbook.add_format(:num_format => 'd-m-yyyy')
2775
+ # worksheet.write('A4', number, format4) # 28-2-2008
2776
+ #
2777
+ # format5 = workbook.add_format(:num_format => 'dd/mm/yy hh:mm')
2778
+ # worksheet.write('A5', number, format5) # 28/02/08 12:00
2779
+ #
2780
+ # format6 = workbook.add_format(:num_format => 'd mmm yyyy')
2781
+ # worksheet.write('A6', number, format6) # 28 Feb 2008
2782
+ #
2783
+ # format7 = workbook.add_format(:num_format => 'mmm d yyyy hh:mm AM/PM')
2784
+ # worksheet.write('A7', number , format7) # Feb 28 2008 12:00 PM
2785
+ #
2786
+ # WriteXLSX doesn't automatically convert date/time strings
2787
+ #
2788
+ # WriteXLSX doesn't automatically convert input date strings into Excel's
2789
+ # formatted date numbers due to the large number of possible date formats
2790
+ # and also due to the possibility of misinterpretation.
2791
+ #
2792
+ # For example, does 02/03/04 mean March 2 2004, February 3 2004 or
2793
+ # even March 4 2002.
2794
+ #
2795
+ # Therefore, in order to handle dates you will have to convert them to
2796
+ # numbers and apply an Excel format. Some methods for converting dates are
2797
+ # listed in the next section.
2798
+ #
2799
+ # The most direct way is to convert your dates to the ISO8601
2800
+ # yyyy-mm-ddThh:mm:ss.sss date format and use the write_date_time()
2801
+ # worksheet method:
2802
+ #
2803
+ # worksheet.write_date_time('A2', '2001-01-01T12:20', format)
2804
+ #
2805
+ # See the write_date_time() section of the documentation for more details.
2806
+ #
2807
+ # A general methodology for handling date strings with write_date_time() is:
2808
+ #
2809
+ # 1. Identify incoming date/time strings with a regex.
2810
+ # 2. Extract the component parts of the date/time using the same regex.
2811
+ # 3. Convert the date/time to the ISO8601 format.
2812
+ # 4. Write the date/time using write_date_time() and a number format.
2813
+ # For a slightly more advanced solution you can modify the write() method
2814
+ # to handle date formats of your choice via the add_write_handler() method.
2815
+ # See the add_write_handler() section of the docs and the
2816
+ # write_handler3.rb and write_handler4.rb programs in the examples
2817
+ # directory of the distro.
2818
+ #
2819
+ # Converting dates and times to an Excel date or time
2820
+ #
2821
+ # The write_date_time() method above is just one way of handling dates and
2822
+ # times.
2823
+ #
2824
+ # You can also use the convert_date_time() worksheet method to convert
2825
+ # from an ISO8601 style date string to an Excel date and time number.
2826
+ #
2735
2827
  def write_date_time(*args)
2736
2828
  # Check for a cell reference in A1 notation and substitute row and column
2737
2829
  row, col, str, xf = row_col_notation(args)
@@ -2755,10 +2847,6 @@ def write_date_time(*args)
2755
2847
  # :call-seq:
2756
2848
  # insert_chart(row, column, chart [ , x, y, x_scale, y_scale ] )
2757
2849
  #
2758
- # Insert a chart into a worksheet. The chart argument should be a Chart
2759
- # object or else it is assumed to be a filename of an external binary file.
2760
- # The latter is for backwards compatibility.
2761
- #
2762
2850
  # This method can be used to insert a Chart object into a worksheet.
2763
2851
  # The Chart must be created by the add_chart() Workbook method and
2764
2852
  # it must have the embedded option set.
@@ -2775,10 +2863,10 @@ def write_date_time(*args)
2775
2863
  # Writexlsx::Chart for details on how to configure it. See also the
2776
2864
  # chart_*.rb programs in the examples directory of the distro.
2777
2865
  #
2778
- # The x, y, x_scale and y_scale parameters are optional.
2866
+ # The +x+, +y+, +x_scale+ and +y_scale+ parameters are optional.
2779
2867
  #
2780
- # The parameters x and y can be used to specify an offset from the top
2781
- # left hand corner of the cell specified by row and column. The offset
2868
+ # The parameters +x+ and +y+ can be used to specify an offset from the top
2869
+ # left hand corner of the cell specified by +row+ and +column+. The offset
2782
2870
  # values are in pixels.
2783
2871
  #
2784
2872
  # worksheet1.insert_chart('E2', chart, 3, 3)
@@ -2813,11 +2901,10 @@ def insert_chart(*args)
2813
2901
 
2814
2902
  #
2815
2903
  # :call-seq:
2816
- # insert_image(row, column, filename [ , x, y, x_scale, y_scale ] )
2904
+ # insert_image(row, column, filename, x=0, y=0, x_scale=1, y_scale=1)
2905
+ #
2906
+ # Partially supported. Currently only works for 96 dpi images.
2817
2907
  #
2818
- # Partially supported. Currently only works for 96 dpi images. This
2819
- # will be fixed in an upcoming release.
2820
- #--
2821
2908
  # This method can be used to insert a image into a worksheet. The image
2822
2909
  # can be in PNG, JPEG or BMP format. The x, y, x_scale and y_scale
2823
2910
  # parameters are optional.
@@ -2826,8 +2913,8 @@ def insert_chart(*args)
2826
2913
  # worksheet2.insert_image('A1', '../images/ruby.bmp')
2827
2914
  # worksheet3.insert_image('A1', '.c:\images\ruby.bmp')
2828
2915
  #
2829
- # The parameters x and y can be used to specify an offset from the top
2830
- # left hand corner of the cell specified by row and column. The offset
2916
+ # The parameters +x+ and +y+ can be used to specify an offset from the top
2917
+ # left hand corner of the cell specified by +row+ and +column+. The offset
2831
2918
  # values are in pixels.
2832
2919
  #
2833
2920
  # worksheet1.insert_image('A1', 'ruby.bmp', 32, 10)
@@ -2836,14 +2923,12 @@ def insert_chart(*args)
2836
2923
  # cell. This can be occasionally useful if you wish to align two or more
2837
2924
  # images relative to the same cell.
2838
2925
  #
2839
- # The parameters x_scale and y_scale can be used to scale the inserted
2926
+ # The parameters +x_scale+ and +y_scale+ can be used to scale the inserted
2840
2927
  # image horizontally and vertically:
2841
2928
  #
2842
2929
  # # Scale the inserted image: width x 2.0, height x 0.8
2843
2930
  # worksheet.insert_image('A1', 'perl.bmp', 0, 0, 2, 0.8)
2844
2931
  #
2845
- # See also the images.rb program in the examples directory of the distro.
2846
- #
2847
2932
  # Note: you must call set_row() or set_column() before insert_image()
2848
2933
  # if you wish to change the default dimensions of any of the rows or
2849
2934
  # columns that the image occupies. The height of a row can also change
@@ -2854,7 +2939,6 @@ def insert_chart(*args)
2854
2939
  #
2855
2940
  # BMP images must be 24 bit, true colour, bitmaps. In general it is
2856
2941
  # best to avoid BMP images since they aren't compressed.
2857
- #++
2858
2942
  #
2859
2943
  def insert_image(*args)
2860
2944
  # Check for a cell reference in A1 notation and substitute row and column.
@@ -3777,9 +3861,267 @@ def add_table(*args)
3777
3861
  table
3778
3862
  end
3779
3863
 
3864
+ #
3865
+ # :call-seq:
3866
+ # add_sparkline(properties)
3780
3867
  #
3781
3868
  # Add sparklines to the worksheet.
3782
3869
  #
3870
+ # Sparklines are a feature of Excel 2010+ which allows you to add small
3871
+ # charts to worksheet cells. These are useful for showing visual trends
3872
+ # in data in a compact format.
3873
+ #
3874
+ # In WriteXLSX Sparklines can be added to cells using the add_sparkline()
3875
+ # worksheet method:
3876
+ #
3877
+ # worksheet.add_sparkline(
3878
+ # {
3879
+ # :location => 'F2',
3880
+ # :range => 'Sheet1!A2:E2',
3881
+ # :type => 'column',
3882
+ # :style => 12
3883
+ # }
3884
+ # )
3885
+ #
3886
+ # Note: Sparklines are a feature of Excel 2010+ only. You can write them
3887
+ # to an XLSX file that can be read by Excel 2007 but they won't be
3888
+ # displayed.
3889
+ #
3890
+ # The add_sparkline() worksheet method is used to add sparklines to a
3891
+ # cell or a range of cells.
3892
+ #
3893
+ # The parameters to add_sparkline() must be passed in a hash.
3894
+ # The main sparkline parameters are:
3895
+ #
3896
+ # :location (required)
3897
+ # :range (required)
3898
+ # :type
3899
+ # :style
3900
+ #
3901
+ # :markers
3902
+ # :negative_points
3903
+ # :axis
3904
+ # :reverse
3905
+ # Other, less commonly used parameters are:
3906
+ #
3907
+ # :high_point
3908
+ # :low_point
3909
+ # :first_point
3910
+ # :last_point
3911
+ # :max
3912
+ # :min
3913
+ # :empty_cells
3914
+ # :show_hidden
3915
+ # :date_axis
3916
+ # :weight
3917
+ #
3918
+ # :series_color
3919
+ # :negative_color
3920
+ # :markers_color
3921
+ # :first_color
3922
+ # :last_color
3923
+ # :high_color
3924
+ # :low_color
3925
+ #
3926
+ # These parameters are explained in the sections below:
3927
+ #
3928
+ # ===:location
3929
+ #
3930
+ # This is the cell where the sparkline will be displayed:
3931
+ #
3932
+ # location => 'F1'
3933
+ # The location should be a single cell. (For multiple cells see "Grouped Sparklines" below).
3934
+ #
3935
+ # To specify the location in row-column notation use the xl_rowcol_to_cell() function from the Excel::Writer::XLSX::Utility module.
3936
+ #
3937
+ # use Excel::Writer::XLSX::Utility ':rowcol';
3938
+ # ...
3939
+ # location => xl_rowcol_to_cell( 0, 5 ), # F1
3940
+ # range
3941
+ #
3942
+ # This specifies the cell data range that the sparkline will plot:
3943
+ #
3944
+ # $worksheet->add_sparkline(
3945
+ # {
3946
+ # location => 'F1',
3947
+ # range => 'A1:E1',
3948
+ # }
3949
+ # );
3950
+ # The range should be a 2D array. (For 3D arrays of cells see "Grouped Sparklines" below).
3951
+ #
3952
+ # If range is not on the same worksheet you can specify its location using the usual Excel notation:
3953
+ #
3954
+ # range => 'Sheet1!A1:E1',
3955
+ # If the worksheet contains spaces or special characters you should quote the worksheet name in the same way that Excel does:
3956
+ #
3957
+ # range => q('Monthly Data'!A1:E1),
3958
+ # To specify the location in row-column notation use the xl_range() or xl_range_formula() functions from the Excel::Writer::XLSX::Utility module.
3959
+ #
3960
+ # use Excel::Writer::XLSX::Utility ':rowcol';
3961
+ # ...
3962
+ # range => xl_range( 1, 1, 0, 4 ), # 'A1:E1'
3963
+ # range => xl_range_formula( 'Sheet1', 0, 0, 0, 4 ), # 'Sheet1!A2:E2'
3964
+ # type
3965
+ #
3966
+ # Specifies the type of sparkline. There are 3 available sparkline types:
3967
+ #
3968
+ # line (default)
3969
+ # column
3970
+ # win_loss
3971
+ # For example:
3972
+ #
3973
+ # {
3974
+ # location => 'F1',
3975
+ # range => 'A1:E1',
3976
+ # type => 'column',
3977
+ # }
3978
+ # style
3979
+ #
3980
+ # Excel provides 36 built-in Sparkline styles in 6 groups of 6. The style parameter can be used to replicate these and should be a corresponding number from 1 .. 36.
3981
+ #
3982
+ # {
3983
+ # location => 'A14',
3984
+ # range => 'Sheet2!A2:J2',
3985
+ # style => 3,
3986
+ # }
3987
+ # The style number starts in the top left of the style grid and runs left to right. The default style is 1. It is possible to override colour elements of the sparklines using the *_color parameters below.
3988
+ #
3989
+ # markers
3990
+ #
3991
+ # Turn on the markers for line style sparklines.
3992
+ #
3993
+ # {
3994
+ # location => 'A6',
3995
+ # range => 'Sheet2!A1:J1',
3996
+ # markers => 1,
3997
+ # }
3998
+ # Markers aren't shown in Excel for column and win_loss sparklines.
3999
+ #
4000
+ # negative_points
4001
+ #
4002
+ # Highlight negative values in a sparkline range. This is usually required with win_loss sparklines.
4003
+ #
4004
+ # {
4005
+ # location => 'A21',
4006
+ # range => 'Sheet2!A3:J3',
4007
+ # type => 'win_loss',
4008
+ # negative_points => 1,
4009
+ # }
4010
+ # axis
4011
+ #
4012
+ # Display a horizontal axis in the sparkline:
4013
+ #
4014
+ # {
4015
+ # location => 'A10',
4016
+ # range => 'Sheet2!A1:J1',
4017
+ # axis => 1,
4018
+ # }
4019
+ # reverse
4020
+ #
4021
+ # Plot the data from right-to-left instead of the default left-to-right:
4022
+ #
4023
+ # {
4024
+ # location => 'A24',
4025
+ # range => 'Sheet2!A4:J4',
4026
+ # type => 'column',
4027
+ # reverse => 1,
4028
+ # }
4029
+ # weight
4030
+ #
4031
+ # Adjust the default line weight (thickness) for line style sparklines.
4032
+ #
4033
+ # weight => 0.25,
4034
+ # The weight value should be one of the following values allowed by Excel:
4035
+ #
4036
+ # 0.25 0.5 0.75
4037
+ # 1 1.25
4038
+ # 2.25
4039
+ # 3
4040
+ # 4.25
4041
+ # 6
4042
+ # high_point, low_point, first_point, last_point
4043
+ #
4044
+ # Highlight points in a sparkline range.
4045
+ #
4046
+ # high_point => 1,
4047
+ # low_point => 1,
4048
+ # first_point => 1,
4049
+ # last_point => 1,
4050
+ # max, min
4051
+ #
4052
+ # Specify the maximum and minimum vertical axis values:
4053
+ #
4054
+ # max => 0.5,
4055
+ # min => -0.5,
4056
+ # As a special case you can set the maximum and minimum to be for a group of sparklines rather than one:
4057
+ #
4058
+ # max => 'group',
4059
+ # See "Grouped Sparklines" below.
4060
+ #
4061
+ # empty_cells
4062
+ #
4063
+ # Define how empty cells are handled in a sparkline.
4064
+ #
4065
+ # empty_cells => 'zero',
4066
+ # The available options are:
4067
+ #
4068
+ # gaps : show empty cells as gaps (the default).
4069
+ # zero : plot empty cells as 0.
4070
+ # connect: Connect points with a line ("line" type sparklines only).
4071
+ # show_hidden
4072
+ #
4073
+ # Plot data in hidden rows and columns:
4074
+ #
4075
+ # show_hidden => 1,
4076
+ # Note, this option is off by default.
4077
+ #
4078
+ # date_axis
4079
+ #
4080
+ # Specify an alternative date axis for the sparkline. This is useful if the data being plotted isn't at fixed width intervals:
4081
+ #
4082
+ # {
4083
+ # location => 'F3',
4084
+ # range => 'A3:E3',
4085
+ # date_axis => 'A4:E4',
4086
+ # }
4087
+ # The number of cells in the date range should correspond to the number of cells in the data range.
4088
+ #
4089
+ # series_color
4090
+ #
4091
+ # It is possible to override the colour of a sparkline style using the following parameters:
4092
+ #
4093
+ # series_color
4094
+ # negative_color
4095
+ # markers_color
4096
+ # first_color
4097
+ # last_color
4098
+ # high_color
4099
+ # low_color
4100
+ # The color should be specified as a HTML style #rrggbb hex value:
4101
+ #
4102
+ # {
4103
+ # location => 'A18',
4104
+ # range => 'Sheet2!A2:J2',
4105
+ # type => 'column',
4106
+ # series_color => '#E965E0',
4107
+ # }
4108
+ # Grouped Sparklines
4109
+ #
4110
+ # The add_sparkline() worksheet method can be used multiple times to write as many sparklines as are required in a worksheet.
4111
+ #
4112
+ # However, it is sometimes necessary to group contiguous sparklines so that changes that are applied to one are applied to all. In Excel this is achieved by selecting a 3D range of cells for the data range and a 2D range of cells for the location.
4113
+ #
4114
+ # In Excel::Writer::XLSX, you can simulate this by passing an array refs of values to location and range:
4115
+ #
4116
+ # {
4117
+ # location => [ 'A27', 'A28', 'A29' ],
4118
+ # range => [ 'Sheet2!A5:J5', 'Sheet2!A6:J6', 'Sheet2!A7:J7' ],
4119
+ # markers => 1,
4120
+ # }
4121
+ # Sparkline examples
4122
+ #
4123
+ # See the sparklines1.pl and sparklines2.pl example programs in the examples directory of the distro.
4124
+ #
3783
4125
  # The add_sparkline worksheet method is used to add sparklines to a cell or a range of cells.
3784
4126
  #
3785
4127
  # worksheet.add_sparkline(
@@ -3800,112 +4142,91 @@ def add_table(*args)
3800
4142
  # These are useful for showing visual trends in data in a compact format.
3801
4143
  #
3802
4144
  def add_sparkline(param)
3803
- sparkline = {}
3804
-
3805
- # Check for valid input parameters.
3806
- param.each_key do |k|
3807
- unless valid_sparkline_parameter[k]
3808
- raise "Unknown parameter '#{k}' in add_sparkline()"
3809
- end
3810
- end
3811
- [:location, :range].each do |required_key|
3812
- unless param[required_key]
3813
- raise "Parameter '#{required_key}' is required in add_sparkline()"
3814
- end
3815
- end
3816
-
3817
- # Handle the sparkline type.
3818
- type = param[:type] || 'line'
3819
- unless ['line', 'column', 'win_loss'].include?(type)
3820
- raise "Parameter ':type' must be 'line', 'column' or 'win_loss' in add_sparkline()"
3821
- end
3822
- type = 'stacked' if type == 'win_loss'
3823
- sparkline[:_type] = type
3824
-
3825
- # We handle single location/range values or array refs of values.
3826
- sparkline[:_locations] = [param[:location]].flatten
3827
- sparkline[:_ranges] = [param[:range]].flatten
3828
-
3829
- if sparkline[:_ranges].size != sparkline[:_locations].size
3830
- raise "Must have the same number of location and range parameters in add_sparkline()"
3831
- end
3832
-
3833
- # Store the count.
3834
- sparkline[:_count] = sparkline[:_locations].size
3835
-
3836
- # Get the worksheet name for the range conversion below.
3837
- sheetname = quote_sheetname(@name)
3838
-
3839
- # Cleanup the input ranges.
3840
- sparkline[:_ranges].collect! do |range|
3841
- # Remove the absolute reference $ symbols.
3842
- range = range.gsub(/\$/, '')
3843
- # Convert a simple range into a full Sheet1!A1:D1 range.
3844
- range = "#{sheetname}!#{range}" unless range =~ /!/
3845
- range
3846
- end
3847
-
3848
- # Cleanup the input locations.
3849
- sparkline[:_locations].collect! { |location| location.gsub(/\$/, '') }
3850
-
3851
- # Map options.
3852
- sparkline[:_high] = param[:high_point]
3853
- sparkline[:_low] = param[:low_point]
3854
- sparkline[:_negative] = param[:negative_points]
3855
- sparkline[:_first] = param[:first_point]
3856
- sparkline[:_last] = param[:last_point]
3857
- sparkline[:_markers] = param[:markers]
3858
- sparkline[:_min] = param[:min]
3859
- sparkline[:_max] = param[:max]
3860
- sparkline[:_axis] = param[:axis]
3861
- sparkline[:_reverse] = param[:reverse]
3862
- sparkline[:_hidden] = param[:show_hidden]
3863
- sparkline[:_weight] = param[:weight]
3864
-
3865
- # Map empty cells options.
3866
- empty = param[:empty_cells] || ''
3867
- sparkline[:_empty] = case empty
3868
- when 'zero'
3869
- 0
3870
- when 'connect'
3871
- 'span'
3872
- else
3873
- 'gap'
3874
- end
3875
-
3876
- # Map the date axis range.
3877
- date_range = param[:date_axis]
3878
- if ptrue?(date_range) && !(date_range =~ /!/)
3879
- date_range = "#{sheetname}!#{date_range}"
3880
- end
3881
- sparkline[:_date_axis] = date_range
3882
-
3883
- # Set the sparkline styles.
3884
- style_id = param[:style] || 0
3885
- style = spark_styles[style_id]
3886
-
3887
- sparkline[:_series_color] = style[:series]
3888
- sparkline[:_negative_color] = style[:negative]
3889
- sparkline[:_markers_color] = style[:markers]
3890
- sparkline[:_first_color] = style[:first]
3891
- sparkline[:_last_color] = style[:last]
3892
- sparkline[:_high_color] = style[:high]
3893
- sparkline[:_low_color] = style[:low]
3894
-
3895
- # Override the style colours with user defined colors.
3896
- set_spark_color(sparkline, param, :series_color)
3897
- set_spark_color(sparkline, param, :negative_color)
3898
- set_spark_color(sparkline, param, :markers_color)
3899
- set_spark_color(sparkline, param, :first_color)
3900
- set_spark_color(sparkline, param, :last_color)
3901
- set_spark_color(sparkline, param, :high_color)
3902
- set_spark_color(sparkline, param, :low_color)
3903
-
3904
- @sparklines << sparkline
4145
+ @sparklines << Sparkline.new(self, param, quote_sheetname(@name))
3905
4146
  end
3906
4147
 
3907
4148
  #
3908
- # Insert a button form object into the worksheet.
4149
+ # :call-seq:
4150
+ # insert_button(row, col, properties)
4151
+ #
4152
+ # The insert_button() method can be used to insert an Excel form button
4153
+ # into a worksheet.
4154
+ #
4155
+ # This method is generally only useful when used in conjunction with
4156
+ # the Workbook add_vba_project() method to tie the button to a macro
4157
+ # from an embedded VBA project:
4158
+ #
4159
+ # workbook = WriteXLSX.new('file.xlsm')
4160
+ # ...
4161
+ # workbook.add_vba_project('./vbaProject.bin')
4162
+ #
4163
+ # worksheet.insert_button('C2', { :macro => 'my_macro' } )
4164
+ #
4165
+ # The properties of the button that can be set are:
4166
+ #
4167
+ # :macro
4168
+ # :caption
4169
+ # :width
4170
+ # :height
4171
+ # :x_scale
4172
+ # :y_scale
4173
+ # :x_offset
4174
+ # :y_offset
4175
+ #
4176
+ # === Option: macro
4177
+ # This option is used to set the macro that the button will invoke when
4178
+ # the user clicks on it. The macro should be included using the
4179
+ # Workbook#add_vba_project() method shown above.
4180
+ #
4181
+ # worksheet.insert_button('C2', { :macro => 'my_macro' } )
4182
+ #
4183
+ # The default macro is +ButtonX_Click+ where X is the button number.
4184
+ #
4185
+ # ===Option: caption
4186
+ # This option is used to set the caption on the button. The default is
4187
+ # <tt>Button X</tt> where X is the button number.
4188
+ #
4189
+ # worksheet.insert_button('C2', { :macro => 'my_macro', :caption => 'Hello' })
4190
+ #
4191
+ # ===Option: width
4192
+ # This option is used to set the width of the button in pixels.
4193
+ #
4194
+ # worksheet.insert_button('C2', { :macro => 'my_macro', :width => 128 })
4195
+ #
4196
+ # The default button width is 64 pixels which is the width of a default cell.
4197
+ #
4198
+ # ===Option: height
4199
+ # This option is used to set the height of the button in pixels.
4200
+ #
4201
+ # worksheet.insert_button('C2', { :macro => 'my_macro', :height => 40 })
4202
+ #
4203
+ # The default button height is 20 pixels which is the height of a default cell.
4204
+ #
4205
+ # ===Option: x_scale
4206
+ # This option is used to set the width of the button as a factor of the
4207
+ # default width.
4208
+ #
4209
+ # worksheet.insert_button('C2', { :macro => 'my_macro', :x_scale => 2.0 })
4210
+ #
4211
+ # ===Option: y_scale
4212
+ # This option is used to set the height of the button as a factor of the
4213
+ # default height.
4214
+ #
4215
+ # worksheet.insert_button('C2', { :macro => 'my_macro', y_:scale => 2.0 } )
4216
+ #
4217
+ # ===Option: x_offset
4218
+ # This option is used to change the x offset, in pixels, of a button
4219
+ # within a cell:
4220
+ #
4221
+ # worksheet.insert_button('C2', { :macro => 'my_macro', :x_offset => 2 })
4222
+ #
4223
+ # ===Option: y_offset
4224
+ # This option is used to change the y offset, in pixels, of a comment
4225
+ # within a cell.
4226
+ #
4227
+ # Note: Button is the only Excel form element that is available in
4228
+ # WriteXLSX. Form elements represent a lot of work to implement and the
4229
+ # underlying VML syntax isn't very much fun.
3909
4230
  #
3910
4231
  def insert_button(*args)
3911
4232
  @buttons_array << button_params(*(row_col_notation(args)))
@@ -3959,7 +4280,8 @@ def insert_button(*args)
3959
4280
  #
3960
4281
  # worksheet.data_validation( 'A1', {...} )
3961
4282
  # worksheet.data_validation( 'A1:B5', {...} )
3962
- # See also the note about "Cell notation" for more information.
4283
+ #
4284
+ # See also the note about {"Cell notation"}[#label-Cell+notation] for more information.
3963
4285
  #
3964
4286
  # The last parameter in data_validation() must be a hash ref containing
3965
4287
  # the parameters that describe the type and style of the data validation.
@@ -4729,8 +5051,6 @@ def set_v_pagebreaks(*args)
4729
5051
  @print_style.vbreaks += args
4730
5052
  end
4731
5053
 
4732
- #
4733
- # Make any comments in the worksheet visible.
4734
5054
  #
4735
5055
  # This method is used to make all cell comments visible when a worksheet
4736
5056
  # is opened.
@@ -4738,7 +5058,7 @@ def set_v_pagebreaks(*args)
4738
5058
  # worksheet.show_comments
4739
5059
  #
4740
5060
  # Individual comments can be made visible using the visible parameter of
4741
- # the write_comment method (see above):
5061
+ # the write_comment method:
4742
5062
  #
4743
5063
  # worksheet.write_comment('C3', 'Hello', :visible => 1)
4744
5064
  #
@@ -4752,12 +5072,10 @@ def show_comments(visible = true)
4752
5072
  @comments_visible = visible
4753
5073
  end
4754
5074
 
4755
- #
4756
- # Set the default author of the cell comments.
4757
5075
  #
4758
5076
  # This method is used to set the default author of all cell comments.
4759
5077
  #
4760
- # worksheet.set_comments_author('Ruby')
5078
+ # worksheet.comments_author = 'Ruby'
4761
5079
  #
4762
5080
  # Individual comment authors can be set using the author parameter
4763
5081
  # of the write_comment method.
@@ -4765,8 +5083,14 @@ def show_comments(visible = true)
4765
5083
  # The default comment author is an empty string, '',
4766
5084
  # if no author is specified.
4767
5085
  #
4768
- def set_comments_author(author = '')
4769
- @comments_author = author if author
5086
+ def comments_author=(author)
5087
+ @comments_author = author || ''
5088
+ end
5089
+
5090
+ # This method is deprecated. use comments_author=().
5091
+ def set_comments_author(author)
5092
+ put_deprecate_message("#{self}.set_comments_author")
5093
+ self.comments_author = author
4770
5094
  end
4771
5095
 
4772
5096
  def comments_count # :nodoc:
@@ -5428,44 +5752,6 @@ def position_object_emus(col_start, row_start, x1, y1, width, height, is_drawing
5428
5752
  [col_start, row_start, x1, y1, col_end, row_end, x2, y2, x_abs, y_abs]
5429
5753
  end
5430
5754
 
5431
- #
5432
- # Calculate the vertices that define the position of a shape object within
5433
- # the worksheet in EMUs. Save the vertices with the object.
5434
- #
5435
- # The vertices are expressed as English Metric Units (EMUs). There are 12,700
5436
- # EMUs per point. Therefore, 12,700 * 3 /4 = 9,525 EMUs per pixel.
5437
- #
5438
- def position_shape_emus(shape)
5439
- col_start, row_start, x1, y1, col_end, row_end, x2, y2, x_abs, y_abs =
5440
- position_object_pixels(
5441
- shape[:column_start],
5442
- shape[:row_start],
5443
- shape[:x_offset],
5444
- shape[:y_offset],
5445
- shape[:width] * shape[:scale_x],
5446
- shape[:height] * shape[:scale_y],
5447
- shape[:drawing]
5448
- )
5449
-
5450
- # Now that x2/y2 have been calculated with a potentially negative
5451
- # width/height we use the absolute value and convert to EMUs.
5452
- shape[:width_emu] = (shape[:width] * 9_525).abs.to_i
5453
- shape[:height_emu] = (shape[:height] * 9_525).abs.to_i
5454
-
5455
- shape[:column_start] = col_start.to_i
5456
- shape[:row_start] = row_start.to_i
5457
- shape[:column_end] = col_end.to_i
5458
- shape[:row_end] = row_end.to_i
5459
-
5460
- # Convert the pixel values to EMUs. See above.
5461
- shape[:x1] = (x1 * 9_525).to_i
5462
- shape[:y1] = (y1 * 9_525).to_i
5463
- shape[:x2] = (x2 * 9_525).to_i
5464
- shape[:y2] = (y2 * 9_525).to_i
5465
- shape[:x_abs] = (x_abs * 9_525).to_i
5466
- shape[:y_abs] = (y_abs * 9_525).to_i
5467
- end
5468
-
5469
5755
  #
5470
5756
  # Convert the width of a cell from user's units to pixels. Excel rounds the
5471
5757
  # column width to the nearest pixel. If the width hasn't been set by the user
@@ -5550,6 +5836,9 @@ def prepare_image(index, image_id, drawing_id, width, height, name, image_type)
5550
5836
  end
5551
5837
  public :prepare_image
5552
5838
 
5839
+ #
5840
+ # :call-seq:
5841
+ # insert_shape(row, col, shape [ , x, y, x_scale, y_scale ] )
5553
5842
  #
5554
5843
  # Insert a shape into the worksheet.
5555
5844
  #
@@ -5566,22 +5855,23 @@ def prepare_image(index, image_id, drawing_id, width, height, name, image_type)
5566
5855
  # worksheet.insert_shape('E2', shape)
5567
5856
  #
5568
5857
  # See add_shape() for details on how to create the Shape object
5569
- # and Excel::Writer::XLSX::Shape for details on how to configure it.
5858
+ # and Writexlsx::Shape for details on how to configure it.
5570
5859
  #
5571
- # The x, y, x_scale and y_scale parameters are optional.
5860
+ # The +x+, +y+, +x_scale+ and +y_scale+ parameters are optional.
5572
5861
  #
5573
- # The parameters x and y can be used to specify an offset
5574
- # from the top left hand corner of the cell specified by row and col.
5862
+ # The parameters +x+ and +y+ can be used to specify an offset
5863
+ # from the top left hand corner of the cell specified by +row+ and +col+.
5575
5864
  # The offset values are in pixels.
5576
5865
  #
5577
5866
  # worksheet1.insert_shape('E2', chart, 3, 3)
5578
5867
  #
5579
- # The parameters x_scale and y_scale can be used to scale the
5868
+ # The parameters +x_scale+ and +y_scale+ can be used to scale the
5580
5869
  # inserted shape horizontally and vertically:
5581
5870
  #
5582
5871
  # # Scale the width by 120% and the height by 150%
5583
5872
  # worksheet.insert_shape('E2', shape, 0, 0, 1.2, 1.5)
5584
- # See also the shape*.pl programs in the examples directory of the distro.
5873
+ #
5874
+ # See also the shape*.rb programs in the examples directory of the distro.
5585
5875
  #
5586
5876
  def insert_shape(*args)
5587
5877
  # Check for a cell reference in A1 notation and substitute row and column.
@@ -5591,20 +5881,13 @@ def insert_shape(*args)
5591
5881
  raise "Insufficient arguments in insert_shape()"
5592
5882
  end
5593
5883
 
5594
- # Set the shape properties
5595
- shape[:row_start] = row_start
5596
- shape[:column_start] = column_start
5597
- shape[:x_offset] = x_offset || 0
5598
- shape[:y_offset] = y_offset || 0
5599
-
5600
- # Override shape scale if supplied as an argument. Otherwise, use the
5601
- # existing shape scale factors.
5602
- shape[:scale_x] = x_scale if x_scale
5603
- shape[:scale_y] = y_scale if y_scale
5604
-
5884
+ shape.set_position(
5885
+ row_start, column_start, x_offset, y_offset,
5886
+ x_scale, y_scale
5887
+ )
5605
5888
  # Assign a shape ID.
5606
5889
  while true
5607
- id = shape[:id] || 0
5890
+ id = shape.id || 0
5608
5891
  used = @shape_hash[id]
5609
5892
 
5610
5893
  # Test if shape ID is already used. Otherwise assign a new one.
@@ -5612,38 +5895,29 @@ def insert_shape(*args)
5612
5895
  break
5613
5896
  else
5614
5897
  @last_shape_id += 1
5615
- shape[:id] = @last_shape_id
5898
+ shape.id = @last_shape_id
5616
5899
  end
5617
5900
  end
5618
5901
 
5619
- shape[:element] = @shapes.size
5620
-
5621
5902
  # Allow lookup of entry into shape array by shape ID.
5622
- @shape_hash[shape[:id]] = shape[:element]
5903
+ @shape_hash[shape.id] = shape.element = @shapes.size
5623
5904
 
5624
- # Create link to Worksheet color palette.
5625
- shape[:palette] = @workbook.palette
5626
-
5627
- if ptrue?(shape[:stencil])
5905
+ if ptrue?(shape.stencil)
5628
5906
  # Insert a copy of the shape, not a reference so that the shape is
5629
5907
  # used as a stencil. Previously stamped copies don't get modified
5630
5908
  # if the stencil is modified.
5631
5909
  insert = shape.dup
5632
-
5633
- # For connectors change x/y coords based on location of connected shapes.
5634
- auto_locate_connectors(insert)
5635
-
5636
- @shapes << insert
5637
- insert
5638
5910
  else
5639
- # For connectors change x/y coords based on location of connected shapes.
5640
- auto_locate_connectors(shape)
5641
-
5642
- # Insert a link to the shape on the list of shapes. Connection to
5643
- # the parent shape is maintained.
5644
- @shapes << shape
5645
- return shape
5911
+ insert = shape
5646
5912
  end
5913
+
5914
+ # For connectors change x/y coords based on location of connected shapes.
5915
+ insert.auto_locate_connectors(@shapes, @shape_hash)
5916
+
5917
+ # Insert a link to the shape on the list of shapes. Connection to
5918
+ # the parent shape is maintained.
5919
+ @shapes << insert
5920
+ insert
5647
5921
  end
5648
5922
  public :insert_shape
5649
5923
 
@@ -5652,7 +5926,6 @@ def insert_shape(*args)
5652
5926
  #
5653
5927
  def prepare_shape(index, drawing_id)
5654
5928
  shape = @shapes[index]
5655
- drawing_type = 3
5656
5929
 
5657
5930
  # Create a Drawing object to use with worksheet unless one already exists.
5658
5931
  unless drawing?
@@ -5662,121 +5935,14 @@ def prepare_shape(index, drawing_id)
5662
5935
  end
5663
5936
 
5664
5937
  # Validate the he shape against various rules.
5665
- validate_shape(shape, index)
5666
- position_shape_emus(shape)
5667
-
5668
- dimensions = [
5669
- shape[:column_start], shape[:row_start],
5670
- shape[:x1], shape[:y1],
5671
- shape[:column_end], shape[:row_end],
5672
- shape[:x2], shape[:y2],
5673
- shape[:x_abs], shape[:y_abs],
5674
- shape[:width_emu], shape[:height_emu]
5675
- ]
5938
+ shape.validate(index)
5939
+ shape.calc_position_emus(self)
5676
5940
 
5677
- drawing.add_drawing_object(drawing_type, dimensions, shape[:name], shape)
5941
+ drawing_type = 3
5942
+ drawing.add_drawing_object(drawing_type, shape.dimensions, shape.name, shape)
5678
5943
  end
5679
5944
  public :prepare_shape
5680
5945
 
5681
- #
5682
- # Re-size connector shapes if they are connected to other shapes.
5683
- #
5684
- def auto_locate_connectors(shape)
5685
- # Valid connector shapes.
5686
- connector_shapes = {
5687
- :straightConnector => 1,
5688
- :Connector => 1,
5689
- :bentConnector => 1,
5690
- :curvedConnector => 1,
5691
- :line => 1
5692
- }
5693
-
5694
- shape_base = shape[:type].chop.to_sym # Remove the number of segments from end of type.
5695
- shape[:connect] = connector_shapes[shape_base] ? 1 : 0
5696
- return if shape[:connect] == 0
5697
-
5698
- # Both ends have to be connected to size it.
5699
- return if shape[:start] == 0 && shape[:end] == 0
5700
-
5701
- # Both ends need to provide info about where to connect.
5702
- return if shape[:start_side] == 0 && shape[:end_side] == 0
5703
-
5704
- sid = shape[:start]
5705
- eid = shape[:end]
5706
-
5707
- slink_id = @shape_hash[sid] || 0
5708
- sls = @shapes.fetch(slink_id, Hash.new(0))
5709
- elink_id = @shape_hash[eid] || 0
5710
- els = @shapes.fetch(elink_id, Hash.new(0))
5711
-
5712
- # Assume shape connections are to the middle of an object, and
5713
- # not a corner (for now).
5714
- connect_type = shape[:start_side] + shape[:end_side]
5715
- smidx = sls[:x_offset] + sls[:width] / 2
5716
- emidx = els[:x_offset] + els[:width] / 2
5717
- smidy = sls[:y_offset] + sls[:height] / 2
5718
- emidy = els[:y_offset] + els[:height] / 2
5719
- netx = (smidx - emidx).abs
5720
- nety = (smidy - emidy).abs
5721
-
5722
- if connect_type == 'bt'
5723
- sy = sls[:y_offset] + sls[:height]
5724
- ey = els[:y_offset]
5725
-
5726
- shape[:width] = (emidx - smidx).to_i.abs
5727
- shape[:x_offset] = [smidx, emidx].min.to_i
5728
- shape[:height] =
5729
- (els[:y_offset] - (sls[:y_offset] + sls[:height])).to_i.abs
5730
- shape[:y_offset] =
5731
- [sls[:y_offset] + sls[:height], els[:y_offset]].min.to_i
5732
- shape[:flip_h] = smidx < emidx ? 1 : 0
5733
- shape[:rotation] = 90
5734
-
5735
- if sy > ey
5736
- shape[:flip_v] = 1
5737
-
5738
- # Create 3 adjustments for an end shape vertically above a
5739
- # start shape. Adjustments count from the upper left object.
5740
- if shape[:adjustments].empty?
5741
- shape[:adjustments] = [-10, 50, 110]
5742
- end
5743
- shape[:type] = 'bentConnector5'
5744
- end
5745
- elsif connect_type == 'rl'
5746
- shape[:width] =
5747
- (els[:x_offset] - (sls[:x_offset] + sls[:width])).to_i.abs
5748
- shape[:height] = (emidy - smidy).to_i.abs
5749
- shape[:x_offset] =
5750
- [sls[:x_offset] + sls[:width], els[:x_offset]].min
5751
- shape[:y_offset] = [smidy, emidy].min
5752
-
5753
- shape[:flip_h] = 1 if smidx < emidx && smidy > emidy
5754
- shape[:flip_h] = 1 if smidx > emidx && smidy < emidy
5755
-
5756
- if smidx > emidx
5757
- # Create 3 adjustments for an end shape to the left of a
5758
- # start shape.
5759
- if shape[:adjustments].empty?
5760
- shape[:adjustments] = [-10, 50, 110]
5761
- end
5762
- shape[:type] = 'bentConnector5'
5763
- end
5764
- end
5765
- end
5766
-
5767
- #
5768
- # Check shape attributes to ensure they are valid.
5769
- #
5770
- def validate_shape(shape, index)
5771
- unless %w[l ctr r just].include?(shape[:align])
5772
- raise "Shape #{index} (#{shape[:type]}) alignment (#{shape[:align]}) not in ['l', 'ctr', 'r', 'just']\n"
5773
- end
5774
-
5775
- unless %w[t ctr b].include?(shape[:valign])
5776
- raise "Shape #{index} (#{shape[:type]}) vertical alignment (#{shape[:valign]}) not in ['t', 'ctr', 'v']\n"
5777
- end
5778
- end
5779
-
5780
5946
  #
5781
5947
  # This method handles the parameters passed to insert_button as well as
5782
5948
  # calculating the comment object position and vertices.
@@ -6969,385 +7135,6 @@ def write_table_part(id)
6969
7135
  @writer.empty_tag('tablePart', attributes)
6970
7136
  end
6971
7137
 
6972
- def spark_styles # :nodoc:
6973
- [
6974
- { # 0
6975
- :series => { :_theme => "4", :_tint => "-0.499984740745262" },
6976
- :negative => { :_theme => "5" },
6977
- :markers => { :_theme => "4", :_tint => "-0.499984740745262" },
6978
- :first => { :_theme => "4", :_tint => "0.39997558519241921" },
6979
- :last => { :_theme => "4", :_tint => "0.39997558519241921" },
6980
- :high => { :_theme => "4" },
6981
- :low => { :_theme => "4" }
6982
- },
6983
- { # 1
6984
- :series => { :_theme => "4", :_tint => "-0.499984740745262" },
6985
- :negative => { :_theme => "5" },
6986
- :markers => { :_theme => "4", :_tint => "-0.499984740745262" },
6987
- :first => { :_theme => "4", :_tint => "0.39997558519241921" },
6988
- :last => { :_theme => "4", :_tint => "0.39997558519241921" },
6989
- :high => { :_theme => "4" },
6990
- :low => { :_theme => "4" }
6991
- },
6992
- { # 2
6993
- :series => { :_theme => "5", :_tint => "-0.499984740745262" },
6994
- :negative => { :_theme => "6" },
6995
- :markers => { :_theme => "5", :_tint => "-0.499984740745262" },
6996
- :first => { :_theme => "5", :_tint => "0.39997558519241921" },
6997
- :last => { :_theme => "5", :_tint => "0.39997558519241921" },
6998
- :high => { :_theme => "5" },
6999
- :low => { :_theme => "5" }
7000
- },
7001
- { # 3
7002
- :series => { :_theme => "6", :_tint => "-0.499984740745262" },
7003
- :negative => { :_theme => "7" },
7004
- :markers => { :_theme => "6", :_tint => "-0.499984740745262" },
7005
- :first => { :_theme => "6", :_tint => "0.39997558519241921" },
7006
- :last => { :_theme => "6", :_tint => "0.39997558519241921" },
7007
- :high => { :_theme => "6" },
7008
- :low => { :_theme => "6" }
7009
- },
7010
- { # 4
7011
- :series => { :_theme => "7", :_tint => "-0.499984740745262" },
7012
- :negative => { :_theme => "8" },
7013
- :markers => { :_theme => "7", :_tint => "-0.499984740745262" },
7014
- :first => { :_theme => "7", :_tint => "0.39997558519241921" },
7015
- :last => { :_theme => "7", :_tint => "0.39997558519241921" },
7016
- :high => { :_theme => "7" },
7017
- :low => { :_theme => "7" }
7018
- },
7019
- { # 5
7020
- :series => { :_theme => "8", :_tint => "-0.499984740745262" },
7021
- :negative => { :_theme => "9" },
7022
- :markers => { :_theme => "8", :_tint => "-0.499984740745262" },
7023
- :first => { :_theme => "8", :_tint => "0.39997558519241921" },
7024
- :last => { :_theme => "8", :_tint => "0.39997558519241921" },
7025
- :high => { :_theme => "8" },
7026
- :low => { :_theme => "8" }
7027
- },
7028
- { # 6
7029
- :series => { :_theme => "9", :_tint => "-0.499984740745262" },
7030
- :negative => { :_theme => "4" },
7031
- :markers => { :_theme => "9", :_tint => "-0.499984740745262" },
7032
- :first => { :_theme => "9", :_tint => "0.39997558519241921" },
7033
- :last => { :_theme => "9", :_tint => "0.39997558519241921" },
7034
- :high => { :_theme => "9" },
7035
- :low => { :_theme => "9" }
7036
- },
7037
- { # 7
7038
- :series => { :_theme => "4", :_tint => "-0.249977111117893" },
7039
- :negative => { :_theme => "5" },
7040
- :markers => { :_theme => "5", :_tint => "-0.249977111117893" },
7041
- :first => { :_theme => "5", :_tint => "-0.249977111117893" },
7042
- :last => { :_theme => "5", :_tint => "-0.249977111117893" },
7043
- :high => { :_theme => "5", :_tint => "-0.249977111117893" },
7044
- :low => { :_theme => "5", :_tint => "-0.249977111117893" }
7045
- },
7046
- { # 8
7047
- :series => { :_theme => "5", :_tint => "-0.249977111117893" },
7048
- :negative => { :_theme => "6" },
7049
- :markers => { :_theme => "6", :_tint => "-0.249977111117893" },
7050
- :first => { :_theme => "6", :_tint => "-0.249977111117893" },
7051
- :last => { :_theme => "6", :_tint => "-0.249977111117893" },
7052
- :high => { :_theme => "6", :_tint => "-0.249977111117893" },
7053
- :low => { :_theme => "6", :_tint => "-0.249977111117893" }
7054
- },
7055
- { # 9
7056
- :series => { :_theme => "6", :_tint => "-0.249977111117893" },
7057
- :negative => { :_theme => "7" },
7058
- :markers => { :_theme => "7", :_tint => "-0.249977111117893" },
7059
- :first => { :_theme => "7", :_tint => "-0.249977111117893" },
7060
- :last => { :_theme => "7", :_tint => "-0.249977111117893" },
7061
- :high => { :_theme => "7", :_tint => "-0.249977111117893" },
7062
- :low => { :_theme => "7", :_tint => "-0.249977111117893" }
7063
- },
7064
- { # 10
7065
- :series => { :_theme => "7", :_tint => "-0.249977111117893" },
7066
- :negative => { :_theme => "8" },
7067
- :markers => { :_theme => "8", :_tint => "-0.249977111117893" },
7068
- :first => { :_theme => "8", :_tint => "-0.249977111117893" },
7069
- :last => { :_theme => "8", :_tint => "-0.249977111117893" },
7070
- :high => { :_theme => "8", :_tint => "-0.249977111117893" },
7071
- :low => { :_theme => "8", :_tint => "-0.249977111117893" }
7072
- },
7073
- { # 11
7074
- :series => { :_theme => "8", :_tint => "-0.249977111117893" },
7075
- :negative => { :_theme => "9" },
7076
- :markers => { :_theme => "9", :_tint => "-0.249977111117893" },
7077
- :first => { :_theme => "9", :_tint => "-0.249977111117893" },
7078
- :last => { :_theme => "9", :_tint => "-0.249977111117893" },
7079
- :high => { :_theme => "9", :_tint => "-0.249977111117893" },
7080
- :low => { :_theme => "9", :_tint => "-0.249977111117893" }
7081
- },
7082
- { # 12
7083
- :series => { :_theme => "9", :_tint => "-0.249977111117893" },
7084
- :negative => { :_theme => "4" },
7085
- :markers => { :_theme => "4", :_tint => "-0.249977111117893" },
7086
- :first => { :_theme => "4", :_tint => "-0.249977111117893" },
7087
- :last => { :_theme => "4", :_tint => "-0.249977111117893" },
7088
- :high => { :_theme => "4", :_tint => "-0.249977111117893" },
7089
- :low => { :_theme => "4", :_tint => "-0.249977111117893" }
7090
- },
7091
- { # 13
7092
- :series => { :_theme => "4" },
7093
- :negative => { :_theme => "5" },
7094
- :markers => { :_theme => "4", :_tint => "-0.249977111117893" },
7095
- :first => { :_theme => "4", :_tint => "-0.249977111117893" },
7096
- :last => { :_theme => "4", :_tint => "-0.249977111117893" },
7097
- :high => { :_theme => "4", :_tint => "-0.249977111117893" },
7098
- :low => { :_theme => "4", :_tint => "-0.249977111117893" }
7099
- },
7100
- { # 14
7101
- :series => { :_theme => "5" },
7102
- :negative => { :_theme => "6" },
7103
- :markers => { :_theme => "5", :_tint => "-0.249977111117893" },
7104
- :first => { :_theme => "5", :_tint => "-0.249977111117893" },
7105
- :last => { :_theme => "5", :_tint => "-0.249977111117893" },
7106
- :high => { :_theme => "5", :_tint => "-0.249977111117893" },
7107
- :low => { :_theme => "5", :_tint => "-0.249977111117893" }
7108
- },
7109
- { # 15
7110
- :series => { :_theme => "6" },
7111
- :negative => { :_theme => "7" },
7112
- :markers => { :_theme => "6", :_tint => "-0.249977111117893" },
7113
- :first => { :_theme => "6", :_tint => "-0.249977111117893" },
7114
- :last => { :_theme => "6", :_tint => "-0.249977111117893" },
7115
- :high => { :_theme => "6", :_tint => "-0.249977111117893" },
7116
- :low => { :_theme => "6", :_tint => "-0.249977111117893" }
7117
- },
7118
- { # 16
7119
- :series => { :_theme => "7" },
7120
- :negative => { :_theme => "8" },
7121
- :markers => { :_theme => "7", :_tint => "-0.249977111117893" },
7122
- :first => { :_theme => "7", :_tint => "-0.249977111117893" },
7123
- :last => { :_theme => "7", :_tint => "-0.249977111117893" },
7124
- :high => { :_theme => "7", :_tint => "-0.249977111117893" },
7125
- :low => { :_theme => "7", :_tint => "-0.249977111117893" }
7126
- },
7127
- { # 17
7128
- :series => { :_theme => "8" },
7129
- :negative => { :_theme => "9" },
7130
- :markers => { :_theme => "8", :_tint => "-0.249977111117893" },
7131
- :first => { :_theme => "8", :_tint => "-0.249977111117893" },
7132
- :last => { :_theme => "8", :_tint => "-0.249977111117893" },
7133
- :high => { :_theme => "8", :_tint => "-0.249977111117893" },
7134
- :low => { :_theme => "8", :_tint => "-0.249977111117893" }
7135
- },
7136
- { # 18
7137
- :series => { :_theme => "9" },
7138
- :negative => { :_theme => "4" },
7139
- :markers => { :_theme => "9", :_tint => "-0.249977111117893" },
7140
- :first => { :_theme => "9", :_tint => "-0.249977111117893" },
7141
- :last => { :_theme => "9", :_tint => "-0.249977111117893" },
7142
- :high => { :_theme => "9", :_tint => "-0.249977111117893" },
7143
- :low => { :_theme => "9", :_tint => "-0.249977111117893" }
7144
- },
7145
- { # 19
7146
- :series => { :_theme => "4", :_tint => "0.39997558519241921" },
7147
- :negative => { :_theme => "0", :_tint => "-0.499984740745262" },
7148
- :markers => { :_theme => "4", :_tint => "0.79998168889431442" },
7149
- :first => { :_theme => "4", :_tint => "-0.249977111117893" },
7150
- :last => { :_theme => "4", :_tint => "-0.249977111117893" },
7151
- :high => { :_theme => "4", :_tint => "-0.499984740745262" },
7152
- :low => { :_theme => "4", :_tint => "-0.499984740745262" }
7153
- },
7154
- { # 20
7155
- :series => { :_theme => "5", :_tint => "0.39997558519241921" },
7156
- :negative => { :_theme => "0", :_tint => "-0.499984740745262" },
7157
- :markers => { :_theme => "5", :_tint => "0.79998168889431442" },
7158
- :first => { :_theme => "5", :_tint => "-0.249977111117893" },
7159
- :last => { :_theme => "5", :_tint => "-0.249977111117893" },
7160
- :high => { :_theme => "5", :_tint => "-0.499984740745262" },
7161
- :low => { :_theme => "5", :_tint => "-0.499984740745262" }
7162
- },
7163
- { # 21
7164
- :series => { :_theme => "6", :_tint => "0.39997558519241921" },
7165
- :negative => { :_theme => "0", :_tint => "-0.499984740745262" },
7166
- :markers => { :_theme => "6", :_tint => "0.79998168889431442" },
7167
- :first => { :_theme => "6", :_tint => "-0.249977111117893" },
7168
- :last => { :_theme => "6", :_tint => "-0.249977111117893" },
7169
- :high => { :_theme => "6", :_tint => "-0.499984740745262" },
7170
- :low => { :_theme => "6", :_tint => "-0.499984740745262" }
7171
- },
7172
- { # 22
7173
- :series => { :_theme => "7", :_tint => "0.39997558519241921" },
7174
- :negative => { :_theme => "0", :_tint => "-0.499984740745262" },
7175
- :markers => { :_theme => "7", :_tint => "0.79998168889431442" },
7176
- :first => { :_theme => "7", :_tint => "-0.249977111117893" },
7177
- :last => { :_theme => "7", :_tint => "-0.249977111117893" },
7178
- :high => { :_theme => "7", :_tint => "-0.499984740745262" },
7179
- :low => { :_theme => "7", :_tint => "-0.499984740745262" }
7180
- },
7181
- { # 23
7182
- :series => { :_theme => "8", :_tint => "0.39997558519241921" },
7183
- :negative => { :_theme => "0", :_tint => "-0.499984740745262" },
7184
- :markers => { :_theme => "8", :_tint => "0.79998168889431442" },
7185
- :first => { :_theme => "8", :_tint => "-0.249977111117893" },
7186
- :last => { :_theme => "8", :_tint => "-0.249977111117893" },
7187
- :high => { :_theme => "8", :_tint => "-0.499984740745262" },
7188
- :low => { :_theme => "8", :_tint => "-0.499984740745262" }
7189
- },
7190
- { # 24
7191
- :series => { :_theme => "9", :_tint => "0.39997558519241921" },
7192
- :negative => { :_theme => "0", :_tint => "-0.499984740745262" },
7193
- :markers => { :_theme => "9", :_tint => "0.79998168889431442" },
7194
- :first => { :_theme => "9", :_tint => "-0.249977111117893" },
7195
- :last => { :_theme => "9", :_tint => "-0.249977111117893" },
7196
- :high => { :_theme => "9", :_tint => "-0.499984740745262" },
7197
- :low => { :_theme => "9", :_tint => "-0.499984740745262" }
7198
- },
7199
- { # 25
7200
- :series => { :_theme => "1", :_tint => "0.499984740745262" },
7201
- :negative => { :_theme => "1", :_tint => "0.249977111117893" },
7202
- :markers => { :_theme => "1", :_tint => "0.249977111117893" },
7203
- :first => { :_theme => "1", :_tint => "0.249977111117893" },
7204
- :last => { :_theme => "1", :_tint => "0.249977111117893" },
7205
- :high => { :_theme => "1", :_tint => "0.249977111117893" },
7206
- :low => { :_theme => "1", :_tint => "0.249977111117893" }
7207
- },
7208
- { # 26
7209
- :series => { :_theme => "1", :_tint => "0.34998626667073579" },
7210
- :negative => { :_theme => "0", :_tint => "-0.249977111117893" },
7211
- :markers => { :_theme => "0", :_tint => "-0.249977111117893" },
7212
- :first => { :_theme => "0", :_tint => "-0.249977111117893" },
7213
- :last => { :_theme => "0", :_tint => "-0.249977111117893" },
7214
- :high => { :_theme => "0", :_tint => "-0.249977111117893" },
7215
- :low => { :_theme => "0", :_tint => "-0.249977111117893" }
7216
- },
7217
- { # 27
7218
- :series => { :_rgb => "FF323232" },
7219
- :negative => { :_rgb => "FFD00000" },
7220
- :markers => { :_rgb => "FFD00000" },
7221
- :first => { :_rgb => "FFD00000" },
7222
- :last => { :_rgb => "FFD00000" },
7223
- :high => { :_rgb => "FFD00000" },
7224
- :low => { :_rgb => "FFD00000" }
7225
- },
7226
- { # 28
7227
- :series => { :_rgb => "FF000000" },
7228
- :negative => { :_rgb => "FF0070C0" },
7229
- :markers => { :_rgb => "FF0070C0" },
7230
- :first => { :_rgb => "FF0070C0" },
7231
- :last => { :_rgb => "FF0070C0" },
7232
- :high => { :_rgb => "FF0070C0" },
7233
- :low => { :_rgb => "FF0070C0" }
7234
- },
7235
- { # 29
7236
- :series => { :_rgb => "FF376092" },
7237
- :negative => { :_rgb => "FFD00000" },
7238
- :markers => { :_rgb => "FFD00000" },
7239
- :first => { :_rgb => "FFD00000" },
7240
- :last => { :_rgb => "FFD00000" },
7241
- :high => { :_rgb => "FFD00000" },
7242
- :low => { :_rgb => "FFD00000" }
7243
- },
7244
- { # 30
7245
- :series => { :_rgb => "FF0070C0" },
7246
- :negative => { :_rgb => "FF000000" },
7247
- :markers => { :_rgb => "FF000000" },
7248
- :first => { :_rgb => "FF000000" },
7249
- :last => { :_rgb => "FF000000" },
7250
- :high => { :_rgb => "FF000000" },
7251
- :low => { :_rgb => "FF000000" }
7252
- },
7253
- { # 31
7254
- :series => { :_rgb => "FF5F5F5F" },
7255
- :negative => { :_rgb => "FFFFB620" },
7256
- :markers => { :_rgb => "FFD70077" },
7257
- :first => { :_rgb => "FF5687C2" },
7258
- :last => { :_rgb => "FF359CEB" },
7259
- :high => { :_rgb => "FF56BE79" },
7260
- :low => { :_rgb => "FFFF5055" }
7261
- },
7262
- { # 32
7263
- :series => { :_rgb => "FF5687C2" },
7264
- :negative => { :_rgb => "FFFFB620" },
7265
- :markers => { :_rgb => "FFD70077" },
7266
- :first => { :_rgb => "FF777777" },
7267
- :last => { :_rgb => "FF359CEB" },
7268
- :high => { :_rgb => "FF56BE79" },
7269
- :low => { :_rgb => "FFFF5055" }
7270
- },
7271
- { # 33
7272
- :series => { :_rgb => "FFC6EFCE" },
7273
- :negative => { :_rgb => "FFFFC7CE" },
7274
- :markers => { :_rgb => "FF8CADD6" },
7275
- :first => { :_rgb => "FFFFDC47" },
7276
- :last => { :_rgb => "FFFFEB9C" },
7277
- :high => { :_rgb => "FF60D276" },
7278
- :low => { :_rgb => "FFFF5367" }
7279
- },
7280
- { # 34
7281
- :series => { :_rgb => "FF00B050" },
7282
- :negative => { :_rgb => "FFFF0000" },
7283
- :markers => { :_rgb => "FF0070C0" },
7284
- :first => { :_rgb => "FFFFC000" },
7285
- :last => { :_rgb => "FFFFC000" },
7286
- :high => { :_rgb => "FF00B050" },
7287
- :low => { :_rgb => "FFFF0000" }
7288
- },
7289
- { # 35
7290
- :series => { :_theme => "3" },
7291
- :negative => { :_theme => "9" },
7292
- :markers => { :_theme => "8" },
7293
- :first => { :_theme => "4" },
7294
- :last => { :_theme => "5" },
7295
- :high => { :_theme => "6" },
7296
- :low => { :_theme => "7" }
7297
- },
7298
- { # 36
7299
- :series => { :_theme => "1" },
7300
- :negative => { :_theme => "9" },
7301
- :markers => { :_theme => "8" },
7302
- :first => { :_theme => "4" },
7303
- :last => { :_theme => "5" },
7304
- :high => { :_theme => "6" },
7305
- :low => { :_theme => "7" }
7306
- }
7307
- ]
7308
- end
7309
-
7310
- def valid_sparkline_parameter # :nodoc:
7311
- {
7312
- :location => 1,
7313
- :range => 1,
7314
- :type => 1,
7315
- :high_point => 1,
7316
- :low_point => 1,
7317
- :negative_points => 1,
7318
- :first_point => 1,
7319
- :last_point => 1,
7320
- :markers => 1,
7321
- :style => 1,
7322
- :series_color => 1,
7323
- :negative_color => 1,
7324
- :markers_color => 1,
7325
- :first_color => 1,
7326
- :last_color => 1,
7327
- :high_color => 1,
7328
- :low_color => 1,
7329
- :max => 1,
7330
- :min => 1,
7331
- :axis => 1,
7332
- :reverse => 1,
7333
- :empty_cells => 1,
7334
- :show_hidden => 1,
7335
- :date_axis => 1,
7336
- :weight => 1
7337
- }
7338
- end
7339
-
7340
- #
7341
- #
7342
- #
7343
- def set_spark_color(sparkline, param, user_color) # :nodoc:
7344
- spark_color = "_#{user_color}".to_sym
7345
-
7346
- return unless ptrue?(param[user_color])
7347
-
7348
- sparkline[spark_color] =
7349
- { :_rgb => get_palette_color(param[user_color]) }
7350
- end
7351
7138
  #
7352
7139
  # Write the <extLst> element and sparkline subelements.
7353
7140
  #
@@ -7372,31 +7159,31 @@ def write_ext_sparklines # :nodoc:
7372
7159
  write_sparkline_group(sparkline)
7373
7160
 
7374
7161
  # Write the x14:colorSeries element.
7375
- write_color_series(sparkline[:_series_color])
7162
+ write_color_series(sparkline.series_color)
7376
7163
 
7377
7164
  # Write the x14:colorNegative element.
7378
- write_color_negative(sparkline[:_negative_color])
7165
+ write_color_negative(sparkline.negative_color)
7379
7166
 
7380
7167
  # Write the x14:colorAxis element.
7381
7168
  write_color_axis
7382
7169
 
7383
7170
  # Write the x14:colorMarkers element.
7384
- write_color_markers(sparkline[:_markers_color])
7171
+ write_color_markers(sparkline.markers_color)
7385
7172
 
7386
7173
  # Write the x14:colorFirst element.
7387
- write_color_first(sparkline[:_first_color])
7174
+ write_color_first(sparkline.first_color)
7388
7175
 
7389
7176
  # Write the x14:colorLast element.
7390
- write_color_last(sparkline[:_last_color] )
7177
+ write_color_last(sparkline.last_color)
7391
7178
 
7392
7179
  # Write the x14:colorHigh element.
7393
- write_color_high(sparkline[:_high_color])
7180
+ write_color_high(sparkline.high_color)
7394
7181
 
7395
7182
  # Write the x14:colorLow element.
7396
- write_color_low(sparkline[:_low_color])
7183
+ write_color_low(sparkline.low_color)
7397
7184
 
7398
- if sparkline[:_date_axis]
7399
- @writer.data_element('xm:f', sparkline[:_date_axis])
7185
+ if sparkline.date_axis
7186
+ @writer.data_element('xm:f', sparkline.date_axis)
7400
7187
  end
7401
7188
 
7402
7189
  write_sparklines(sparkline)
@@ -7416,9 +7203,9 @@ def write_sparklines(sparkline) # :nodoc:
7416
7203
  # Write the sparkline elements.
7417
7204
  @writer.tag_elements('x14:sparklines') do
7418
7205
 
7419
- (0 .. sparkline[:_count]-1).each do |i|
7420
- range = sparkline[:_ranges][i]
7421
- location = sparkline[:_locations][i]
7206
+ (0 .. sparkline.count-1).each do |i|
7207
+ range = sparkline.ranges[i]
7208
+ location = sparkline.locations[i]
7422
7209
 
7423
7210
  @writer.tag_elements('x14:sparkline') do
7424
7211
  @writer.data_element('xm:f', range)
@@ -7480,46 +7267,7 @@ def write_sparkline_groups # :nodoc:
7480
7267
  # rightToLeft="1">
7481
7268
  #
7482
7269
  def write_sparkline_group(sparkline) # :nodoc:
7483
- @writer.start_tag(
7484
- 'x14:sparklineGroup',
7485
- attributes_from_sparkline(sparkline)
7486
- )
7487
- end
7488
-
7489
- def attributes_from_sparkline(opts) # :nodoc:
7490
- opts[:_cust_max] = cust_max_min(opts[:_max]) if opts[:_max]
7491
- opts[:_cust_min] = cust_max_min(opts[:_min]) if opts[:_min]
7492
-
7493
- opts[:_cust_max] = cust_max_min(opts[:_max]) if opts[:_max]
7494
- opts[:_cust_min] = cust_max_min(opts[:_min]) if opts[:_min]
7495
-
7496
- a = []
7497
- a << 'manualMax' << opts[:_max] if opts[:_max] && opts[:_max] != 'group'
7498
- a << 'manualMin' << opts[:_min] if opts[:_min] && opts[:_min] != 'group'
7499
-
7500
- # Ignore the default type attribute (line).
7501
- a << 'type' << opts[:_type] if opts[:_type] != 'line'
7502
-
7503
- a << 'lineWeight' << opts[:_weight] if opts[:_weight]
7504
- a << 'dateAxis' << 1 if opts[:_date_axis]
7505
- a << 'displayEmptyCellsAs' << opts[:_empty] if ptrue?(opts[:_empty])
7506
-
7507
- a << 'markers' << 1 if opts[:_markers]
7508
- a << 'high' << 1 if opts[:_high]
7509
- a << 'low' << 1 if opts[:_low]
7510
- a << 'first' << 1 if opts[:_first]
7511
- a << 'last' << 1 if opts[:_last]
7512
- a << 'negative' << 1 if opts[:_negative]
7513
- a << 'displayXAxis' << 1 if opts[:_axis]
7514
- a << 'displayHidden' << 1 if opts[:_hidden]
7515
- a << 'minAxisType' << opts[:_cust_min] if opts[:_cust_min]
7516
- a << 'maxAxisType' << opts[:_cust_max] if opts[:_cust_max]
7517
- a << 'rightToLeft' << 1 if opts[:_reverse]
7518
- a
7519
- end
7520
-
7521
- def cust_max_min(max_min) # :nodoc:
7522
- max_min == 'group' ? 'group' : 'custom'
7270
+ @writer.start_tag('x14:sparklineGroup', sparkline.group_attributes)
7523
7271
  end
7524
7272
 
7525
7273
  #