write_xlsx 0.64.1 → 0.65.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/README.rdoc +10 -1
  3. data/examples/conditional_format.rb +251 -18
  4. data/examples/demo.rb +2 -3
  5. data/examples/macros.rb +42 -0
  6. data/examples/outline_collapsed.rb +160 -0
  7. data/examples/republic.png +0 -0
  8. data/examples/shape3.rb +2 -2
  9. data/examples/shape4.rb +5 -5
  10. data/examples/shape5.rb +6 -6
  11. data/examples/shape6.rb +6 -6
  12. data/examples/shape7.rb +11 -11
  13. data/examples/shape8.rb +10 -10
  14. data/examples/shape_all.rb +0 -0
  15. data/examples/vbaProject.bin +0 -0
  16. data/lib/write_xlsx/chart.rb +656 -56
  17. data/lib/write_xlsx/chartsheet.rb +26 -2
  18. data/lib/write_xlsx/format.rb +50 -27
  19. data/lib/write_xlsx/formats.rb +32 -0
  20. data/lib/write_xlsx/package/packager.rb +45 -238
  21. data/lib/write_xlsx/package/table.rb +9 -18
  22. data/lib/write_xlsx/package/xml_writer_simple.rb +26 -9
  23. data/lib/write_xlsx/sheets.rb +223 -0
  24. data/lib/write_xlsx/sparkline.rb +140 -4
  25. data/lib/write_xlsx/version.rb +1 -1
  26. data/lib/write_xlsx/workbook.rb +34 -121
  27. data/lib/write_xlsx/worksheet/data_validation.rb +291 -0
  28. data/lib/write_xlsx/worksheet/hyperlink.rb +111 -0
  29. data/lib/write_xlsx/worksheet/page_setup.rb +170 -0
  30. data/lib/write_xlsx/worksheet.rb +1112 -1334
  31. data/test/helper.rb +1 -1
  32. data/test/package/styles/test_styles_01.rb +1 -10
  33. data/test/package/styles/test_styles_02.rb +1 -10
  34. data/test/package/styles/test_styles_03.rb +1 -10
  35. data/test/package/styles/test_styles_04.rb +1 -10
  36. data/test/package/styles/test_styles_05.rb +1 -10
  37. data/test/package/styles/test_styles_06.rb +1 -10
  38. data/test/package/styles/test_styles_07.rb +1 -10
  39. data/test/package/styles/test_styles_08.rb +1 -10
  40. data/test/package/styles/test_styles_09.rb +1 -10
  41. data/test/perl_output/conditional_format.xlsx +0 -0
  42. data/test/perl_output/outline_collapsed.xlsx +0 -0
  43. data/test/perl_output/protection.xlsx +0 -0
  44. data/test/regression/test_chart_gap01.rb +47 -0
  45. data/test/regression/test_chart_gap02.rb +47 -0
  46. data/test/regression/test_chart_gap03.rb +47 -0
  47. data/test/regression/test_format05.rb +26 -0
  48. data/test/regression/test_rich_string12.rb +32 -0
  49. data/test/regression/xlsx_files/chart_gap01.xlsx +0 -0
  50. data/test/regression/xlsx_files/chart_gap02.xlsx +0 -0
  51. data/test/regression/xlsx_files/chart_gap03.xlsx +0 -0
  52. data/test/regression/xlsx_files/format05.xlsx +0 -0
  53. data/test/regression/xlsx_files/rich_string12.xlsx +0 -0
  54. data/test/test_example_match.rb +253 -20
  55. data/test/worksheet/test_set_column.rb +25 -0
  56. data/test/worksheet/test_worksheet_03.rb +1 -1
  57. data/test/worksheet/test_worksheet_04.rb +1 -1
  58. data/test/worksheet/test_write_array_formula_01.rb +7 -0
  59. data/test/worksheet/test_write_col_breaks.rb +2 -2
  60. data/test/worksheet/test_write_col_info.rb +8 -8
  61. data/test/worksheet/test_write_conditional_formatting.rb +4 -4
  62. data/test/worksheet/test_write_formula_does_not_change_formula_string.rb +18 -0
  63. data/test/worksheet/test_write_header_footer.rb +8 -3
  64. data/test/worksheet/test_write_hyperlink.rb +10 -5
  65. data/test/worksheet/test_write_merge_cells.rb +6 -6
  66. data/test/worksheet/test_write_page_set_up_pr.rb +1 -1
  67. data/test/worksheet/test_write_page_setup.rb +1 -1
  68. data/test/worksheet/test_write_row_breaks.rb +2 -2
  69. data/test/worksheet/test_write_row_element.rb +1 -1
  70. data/test/worksheet/test_write_sheet_pr.rb +2 -2
  71. data/test/worksheet/test_write_sheet_view.rb +0 -9
  72. data/test/worksheet/test_write_url.rb +19 -0
  73. data/test/worksheet/test_write_worksheet_attributes.rb +21 -0
  74. metadata +38 -5
  75. data/lib/write_xlsx/worksheet/print_style.rb +0 -51
  76. data/test/worksheet/test_write_worksheet.rb +0 -19
@@ -9,19 +9,22 @@ require 'write_xlsx/compatibility'
9
9
  require 'write_xlsx/utility'
10
10
  require 'write_xlsx/package/conditional_format'
11
11
  require 'write_xlsx/worksheet/cell_data'
12
- require 'write_xlsx/worksheet/print_style'
12
+ require 'write_xlsx/worksheet/data_validation'
13
+ require 'write_xlsx/worksheet/hyperlink'
14
+ require 'write_xlsx/worksheet/page_setup'
13
15
  require 'tempfile'
14
16
 
15
17
  module Writexlsx
16
18
  #
17
- # A new worksheet is created by calling the add_worksheet() method from a workbook object:
19
+ # A new worksheet is created by calling the add_worksheet() method from a
20
+ # workbook object:
18
21
  #
19
22
  # worksheet1 = workbook.add_worksheet
20
23
  # worksheet2 = workbook.add_worksheet
21
24
  #
22
25
  # The following methods are available through a new worksheet:
23
26
  #
24
- # * write
27
+ # * {#write}[#method-i-write]
25
28
  # * write_number
26
29
  # * write_string
27
30
  # * write_rich_string
@@ -33,7 +36,7 @@ module Writexlsx
33
36
  # * write_formula
34
37
  # * write_comment
35
38
  # * show_comments
36
- # * comments_author=()
39
+ # * {#comments_author=}[#method-i-comments_author-3D]
37
40
  # * insert_image
38
41
  # * insert_chart
39
42
  # * insert_shape
@@ -42,12 +45,12 @@ module Writexlsx
42
45
  # * conditional_formatting
43
46
  # * add_sparkline
44
47
  # * add_table
45
- # * name
46
- # * activate
47
- # * select
48
- # * hide
48
+ # * {#name}[#method-i-name]
49
+ # * {#activate}[#method-i-activate]
50
+ # * {#select}[#method-i-select]
51
+ # * {#hide}[#method-i-hide]
49
52
  # * set_first_sheet
50
- # * protect
53
+ # * {#protect}[#method-i-protect]
51
54
  # * set_selection
52
55
  # * set_row
53
56
  # * set_column
@@ -56,14 +59,52 @@ module Writexlsx
56
59
  # * split_panes
57
60
  # * merge_range
58
61
  # * merge_range_type
59
- # * zoom=()
62
+ # * {#zoom=}[#method-i-zoom-3D]
60
63
  # * right_to_left
61
64
  # * hide_zero
62
- # * tab_color=()
63
- # * autofilter
65
+ # * {#tab_color=}[#method-i-tab_color-3D]
66
+ # * {#autofilter}[#method-i-autofilter]
64
67
  # * filter_column
65
68
  # * filter_column_list
66
69
  #
70
+ # == PAGE SET-UP METHODS
71
+ #
72
+ # Page set-up methods affect the way that a worksheet looks
73
+ # when it is printed. They control features such as page headers and footers
74
+ # and margins. These methods are really just standard worksheet methods.
75
+ #
76
+ # The following methods are available for page set-up:
77
+ #
78
+ # * set_landscape
79
+ # * set_portrait
80
+ # * set_page_view
81
+ # * set_paper
82
+ # * center_horizontally
83
+ # * center_vertically
84
+ # * set_margins
85
+ # * set_header
86
+ # * set_footer
87
+ # * repeat_rows
88
+ # * repeat_columns
89
+ # * hide_gridlines
90
+ # * print_row_col_headers
91
+ # * print_area
92
+ # * print_across
93
+ # * fit_to_pages
94
+ # * set_start_page
95
+ # * set_print_scale
96
+ # * set_h_pagebreaks
97
+ # * set_v_pagebreaks
98
+ #
99
+ # A common requirement when working with WriteXLSX is to apply the same
100
+ # page set-up features to all of the worksheets in a workbook. To do this
101
+ # you can use the sheets() method of the workbook class to access the array
102
+ # of worksheets in a workbook:
103
+ #
104
+ # workbook.sheets.each do |worksheet|
105
+ # worksheet.set_landscape
106
+ # end
107
+ #
67
108
  # ==Cell notation
68
109
  #
69
110
  # WriteXLSX supports two forms of notation to designate the position of cells:
@@ -111,44 +152,6 @@ module Writexlsx
111
152
  # Note: in Excel it is also possible to use a R1C1 notation. This is not
112
153
  # supported by WriteXLSX.
113
154
  #
114
- # == PAGE SET-UP METHODS
115
- #
116
- # Page set-up methods affect the way that a worksheet looks
117
- # when it is printed. They control features such as page headers and footers
118
- # and margins. These methods are really just standard worksheet methods.
119
- #
120
- # The following methods are available for page set-up:
121
- #
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
- #
143
- # A common requirement when working with WriteXLSX is to apply the same
144
- # page set-up features to all of the worksheets in a workbook. To do this
145
- # you can use the sheets() method of the workbook class to access the array
146
- # of worksheets in a workbook:
147
- #
148
- # workbook.sheets.each do |worksheet|
149
- # worksheet.set_landscape
150
- # end
151
- #
152
155
  # == FORMULAS AND FUNCTIONS IN EXCEL
153
156
  #
154
157
  # === Introduction
@@ -277,16 +280,16 @@ module Writexlsx
277
280
  class Worksheet
278
281
  include Writexlsx::Utility
279
282
 
283
+ MAX_DIGIT_WIDTH = 7 # For Calabri 11. # :nodoc:
284
+ PADDING = 5 # :nodoc:
285
+
280
286
  attr_reader :index # :nodoc:
281
287
  attr_reader :charts, :images, :tables, :shapes, :drawing # :nodoc:
282
- attr_reader :external_hyper_links, :external_drawing_links # :nodoc:
283
- attr_reader :external_vml_links, :external_table_links # :nodoc:
284
- attr_reader :external_comment_links, :drawing_links # :nodoc:
285
288
  attr_reader :vml_data_id # :nodoc:
286
289
  attr_reader :autofilter_area # :nodoc:
287
290
  attr_reader :writer, :set_rows, :col_formats # :nodoc:
288
- attr_accessor :vml_shape_id, :rel_count, :hlink_refs # :nodoc:
289
- attr_reader :comments_author # :nodoc:
291
+ attr_reader :vml_shape_id # :nodoc:
292
+ attr_reader :comments, :comments_author # :nodoc:
290
293
  attr_accessor :dxf_priority # :nodoc:
291
294
  attr_reader :vba_codename # :nodoc:
292
295
 
@@ -300,9 +303,7 @@ module Writexlsx
300
303
  @cell_data_table = {}
301
304
  @excel_version = 2007
302
305
 
303
- @print_style = PrintStyle.new
304
-
305
- @print_area = ''
306
+ @page_setup = PageSetup.new
306
307
 
307
308
  @screen_gridlines = true
308
309
  @show_zeros = true
@@ -372,36 +373,36 @@ module Writexlsx
372
373
 
373
374
  def assemble_xml_file #:nodoc:
374
375
  @writer.xml_decl
375
- write_worksheet
376
- write_sheet_pr
377
- write_dimension
378
- write_sheet_views
379
- write_sheet_format_pr
380
- write_cols
381
- write_sheet_data
382
- write_sheet_protection
383
- write_auto_filter
384
- write_merge_cells
385
- write_conditional_formats
386
- write_data_validations
387
- write_hyperlinks
388
- write_print_options
389
- write_page_margins
390
- write_page_setup
391
- write_header_footer
392
- write_row_breaks
393
- write_col_breaks
394
- write_drawings
395
- write_legacy_drawing
396
- write_table_parts
397
- write_ext_sparklines
398
- @writer.end_tag('worksheet')
376
+ @writer.tag_elements('worksheet', write_worksheet_attributes) do
377
+ write_sheet_pr
378
+ write_dimension
379
+ write_sheet_views
380
+ write_sheet_format_pr
381
+ write_cols
382
+ write_sheet_data
383
+ write_sheet_protection
384
+ write_auto_filter
385
+ write_merge_cells
386
+ write_conditional_formats
387
+ write_data_validations
388
+ write_hyperlinks
389
+ write_print_options
390
+ write_page_margins
391
+ write_page_setup
392
+ write_header_footer
393
+ write_row_breaks
394
+ write_col_breaks
395
+ write_drawings
396
+ write_legacy_drawing
397
+ write_table_parts
398
+ write_ext_sparklines
399
+ end
399
400
  @writer.crlf
400
401
  @writer.close
401
402
  end
402
403
 
403
404
  #
404
- # The name() method is used to retrieve the name of a worksheet.
405
+ # The name method is used to retrieve the name of a worksheet.
405
406
  # For example:
406
407
  #
407
408
  # workbook.sheets.each do |sheet|
@@ -410,7 +411,7 @@ module Writexlsx
410
411
  #
411
412
  # For reasons related to the design of WriteXLSX and to the internals
412
413
  # of Excel there is no set_name() method. The only way to set the
413
- # worksheet name is via the add_worksheet() method.
414
+ # worksheet name is via the Workbook#add_worksheet() method.
414
415
  #
415
416
  def name
416
417
  @name
@@ -451,7 +452,7 @@ module Writexlsx
451
452
  # worksheet3.activate
452
453
  #
453
454
  # This is similar to the Excel VBA activate method. More than one worksheet
454
- # can be selected via the select() method, see below, however only one
455
+ # can be selected via the select() method, however only one
455
456
  # worksheet can be active.
456
457
  #
457
458
  # The default active worksheet is the first worksheet.
@@ -531,8 +532,8 @@ module Writexlsx
531
532
  # cell will display the results of a formula but not the formula itself.
532
533
  #
533
534
  # See the protection.rb program in the examples directory of the distro
534
- # for an illustrative example and the set_locked and set_hidden format
535
- # methods in "CELL FORMATTING".
535
+ # for an illustrative example and the +set_locked+ and +set_hidden+ format
536
+ # methods in "CELL FORMATTING", see Format.
536
537
  #
537
538
  # You can optionally add a password to the worksheet protection:
538
539
  #
@@ -548,7 +549,7 @@ module Writexlsx
548
549
  # several man months to implement.
549
550
  #
550
551
  # You can specify which worksheet elements that you which to protect
551
- # by passing a hash_ref with any or all of the following keys:
552
+ # by passing a hash with any or all of the following keys:
552
553
  #
553
554
  # # Default shown.
554
555
  # options = {
@@ -568,6 +569,7 @@ module Writexlsx
568
569
  # :pivot_tables => false,
569
570
  # :select_unlocked_cells => true
570
571
  # }
572
+ #
571
573
  # The default boolean values are shown above. Individual elements
572
574
  # can be protected as follows:
573
575
  #
@@ -607,15 +609,15 @@ module Writexlsx
607
609
 
608
610
  #
609
611
  # :call-seq:
610
- # set_column(firstcol, lastcol, width, format, hidden, level)
612
+ # set_column(firstcol, lastcol, width, format, hidden, level, collapsed)
611
613
  #
612
614
  # This method can be used to change the default properties of a single
613
- # column or a range of columns. All parameters apart from first_col
614
- # and last_col are optional.
615
+ # column or a range of columns. All parameters apart from +first_col+
616
+ # and +last_col+ are optional.
615
617
  #
616
- # If set_column() is applied to a single column the value of first_col
617
- # and last_col should be the same. In the case where last_col is zero
618
- # it is set to the same value as first_col.
618
+ # If set_column() is applied to a single column the value of +first_col+
619
+ # and +last_col+ should be the same. In the case where +last_col+ is zero
620
+ # it is set to the same value as +first_col+.
619
621
  #
620
622
  # It is also possible, and generally clearer, to specify a column range
621
623
  # using the form of A1 notation used for columns. See the note about
@@ -635,21 +637,22 @@ module Writexlsx
635
637
  # only available at runtime from within Excel.
636
638
  #
637
639
  # As usual the format parameter is optional, for additional information,
638
- # see "CELL FORMATTING". If you wish to set the format without changing
639
- # the width you can pass nil as the width parameter:
640
+ # See {"CELL FORMATTING"}[Format.html#label-CELL+FORMATTING].
641
+ # If you wish to set the format without changing the width you can pass
642
+ # nil as the width parameter:
640
643
  #
641
644
  # worksheet.set_column(0, 0, nil, format)
642
645
  #
643
646
  # The format parameter will be applied to any cells in the column that
644
647
  # don't have a format. For example
645
648
  #
646
- # worksheet.set_column( 'A:A', nil, format1 ) # Set format for col 1
647
- # worksheet.write( 'A1', 'Hello' ) # Defaults to format1
648
- # worksheet.write( 'A2', 'Hello', format2 ) # Keeps format2
649
+ # worksheet.set_column('A:A', nil, format1) # Set format for col 1
650
+ # worksheet.write('A1', 'Hello') # Defaults to format1
651
+ # worksheet.write('A2', 'Hello', format2) # Keeps format2
649
652
  #
650
653
  # If you wish to define a column format in this way you should call the
651
- # method before any calls to write(). If you call it afterwards it
652
- # won't have any effect.
654
+ # method before any calls to {#write()}[#method-i-write].
655
+ # If you call it afterwards it won't have any effect.
653
656
  #
654
657
  # A default row format takes precedence over a default column format
655
658
  #
@@ -658,29 +661,30 @@ module Writexlsx
658
661
  # worksheet.write( 'A1', 'Hello' ) # Defaults to format1
659
662
  # worksheet.write( 'A2', 'Hello' ) # Defaults to format2
660
663
  #
661
- # The hidden parameter should be set to 1 if you wish to hide a column.
664
+ # The +hidden+ parameter should be set to 1 if you wish to hide a column.
662
665
  # This can be used, for example, to hide intermediary steps in a
663
666
  # complicated calculation:
664
667
  #
665
668
  # worksheet.set_column( 'D:D', 20, format, 1 )
666
669
  # worksheet.set_column( 'E:E', nil, nil, 1 )
667
670
  #
668
- # The level parameter is used to set the outline level of the column.
669
- # Outlines are described in "OUTLINES AND GROUPING IN EXCEL". Adjacent
670
- # columns with the same outline level are grouped together into a single
671
- # outline.
671
+ # The +level+ parameter is used to set the outline level of the column.
672
+ # Outlines are described in
673
+ # {"OUTLINES AND GROUPING IN EXCEL"}["method-i-set_row-label-OUTLINES+AND+GROUPING+IN+EXCEL"].
674
+ # Adjacent columns with the same outline level are grouped together into
675
+ # a single outline.
672
676
  #
673
677
  # The following example sets an outline level of 1 for columns B to G:
674
678
  #
675
679
  # worksheet.set_column( 'B:G', nil, nil, 0, 1 )
676
680
  #
677
- # The hidden parameter can also be used to hide collapsed outlined
678
- # columns when used in conjunction with the level parameter.
681
+ # The +hidden+ parameter can also be used to hide collapsed outlined
682
+ # columns when used in conjunction with the +level+ parameter.
679
683
  #
680
684
  # worksheet.set_column( 'B:G', nil, nil, 1, 1 )
681
685
  #
682
686
  # For collapsed outlines you should also indicate which row has the
683
- # collapsed + symbol using the optional collapsed parameter.
687
+ # collapsed + symbol using the optional +collapsed+ parameter.
684
688
  #
685
689
  # worksheet.set_column( 'H:H', nil, nil, 0, 0, 1 )
686
690
  #
@@ -688,7 +692,7 @@ module Writexlsx
688
692
  # programs in the examples directory of the distro.
689
693
  #
690
694
  # Excel allows up to 7 outline levels. Therefore the level parameter
691
- # should be in the range 0 <= level <= 7.
695
+ # should be in the range <tt>0 <= level <= 7</tt>.
692
696
  #
693
697
  def set_column(*args)
694
698
  # Check for a cell reference in A1 notation and substitute row and column
@@ -707,7 +711,7 @@ module Writexlsx
707
711
  # Ensure 2nd col is larger than first. Also for KB918419 bug.
708
712
  firstcol, lastcol = lastcol, firstcol if firstcol > lastcol
709
713
 
710
- width, format, hidden, level = data
714
+ width, format, hidden, level, collapsed = data
711
715
 
712
716
  # Check that cols are valid and store max and min values with default row.
713
717
  # NOTE: The check shouldn't modify the row dimensions and should only modify
@@ -728,7 +732,7 @@ module Writexlsx
728
732
  @outline_col_level = level if level > @outline_col_level
729
733
 
730
734
  # Store the column data.
731
- @colinfo.push([firstcol, lastcol] + data)
735
+ @colinfo << [firstcol, lastcol, width, format, hidden, level, collapsed]
732
736
 
733
737
  # Store the column change to allow optimisations.
734
738
  @col_size_changed = 1
@@ -752,10 +756,11 @@ module Writexlsx
752
756
  #
753
757
  # This method can be used to specify which cell or cells are selected
754
758
  # in a worksheet. The most common requirement is to select a single cell,
755
- # in which case last_row and last_col can be omitted. The active cell
756
- # within a selected range is determined by the order in which first and
757
- # last are specified. It is also possible to specify a cell or a range
758
- # using A1 notation. See the note about {"Cell notation"}[#label-Cell+notation].
759
+ # in which case +last_row+ and +last_col+ can be omitted. The active cell
760
+ # within a selected range is determined by the order in which +first+ and
761
+ # +last+ are specified. It is also possible to specify a cell or a range
762
+ # using A1 notation. See the note about
763
+ # {"Cell notation"}[#label-Cell+notation].
759
764
  #
760
765
  # Examples:
761
766
  #
@@ -802,9 +807,9 @@ module Writexlsx
802
807
  # This method can be used to divide a worksheet into horizontal or
803
808
  # vertical regions known as panes and to also "freeze" these panes so
804
809
  # that the splitter bars are not visible. This is the same as the
805
- # Window->Freeze Panes menu command in Excel
810
+ # <tt>Window->Freeze</tt> Panes menu command in Excel
806
811
  #
807
- # The parameters row and col are used to specify the location of
812
+ # The parameters +row+ and +col+ are used to specify the location of
808
813
  # the split. It should be noted that the split is specified at the
809
814
  # top or left of a cell and that the method uses zero based indexing.
810
815
  # Therefore to freeze the first row of a worksheet it is necessary
@@ -812,7 +817,7 @@ module Writexlsx
812
817
  # This might lead you to think that you are using a 1 based index
813
818
  # but this is not the case.
814
819
  #
815
- # You can set one of the row and col parameters as zero if you
820
+ # You can set one of the row and +col+ parameters as zero if you
816
821
  # do not want either a vertical or horizontal split.
817
822
  #
818
823
  # Examples:
@@ -824,14 +829,14 @@ module Writexlsx
824
829
  # worksheet.freeze_panes(1, 2) # Freeze first row and first 2 columns
825
830
  # worksheet.freeze_panes('C2') # Same using A1 notation
826
831
  #
827
- # The parameters top_row and left_col are optional. They are used
832
+ # The parameters +top_row+ and +left_col+ are optional. They are used
828
833
  # to specify the top-most or left-most visible row or column in the
829
834
  # scrolling region of the panes. For example to freeze the first row
830
835
  # and to have the scrolling region begin at row twenty:
831
836
  #
832
837
  # worksheet.freeze_panes(1, 0, 20, 0)
833
838
  #
834
- # You cannot use A1 notation for the top_row and left_col parameters.
839
+ # You cannot use A1 notation for the +top_row+ and +left_col+ parameters.
835
840
  #
836
841
  # See also the panes.rb program in the examples directory of the
837
842
  # distribution.
@@ -852,7 +857,7 @@ module Writexlsx
852
857
 
853
858
  #
854
859
  # :call-seq:
855
- # split_panes(y, x, top_row, left_col, offset_row, offset_col)
860
+ # split_panes(y, x, top_row, left_col)
856
861
  #
857
862
  # Set panes and mark them as split.
858
863
  #--
@@ -869,7 +874,7 @@ module Writexlsx
869
874
  # method in that the splits between the panes will be visible to the user
870
875
  # and each pane will have its own scroll bars.
871
876
  #
872
- # The parameters y and x are used to specify the vertical and horizontal
877
+ # The parameters +y+ and +x+ are used to specify the vertical and horizontal
873
878
  # position of the split. The units for y and x are the same as those
874
879
  # used by Excel to specify row height and column width. However, the
875
880
  # vertical and horizontal units are different from each other. Therefore
@@ -877,10 +882,10 @@ module Writexlsx
877
882
  # and column widths that you have set or the default values which are 15
878
883
  # for a row and 8.43 for a column.
879
884
  #
880
- # You can set one of the y and x parameters as zero if you do not want
881
- # either a vertical or horizontal split. The parameters top_row and left_col
882
- # are optional. They are used to specify the top-most or left-most visible
883
- # row or column in the bottom-right pane.
885
+ # You can set one of the +y+ and +x+ parameters as zero if you do not want
886
+ # either a vertical or horizontal split. The parameters +top_row+ and
887
+ # +left_col+ are optional. They are used to specify the top-most or
888
+ # left-most visible row or column in the bottom-right pane.
884
889
  #
885
890
  # Example:
886
891
  #
@@ -904,16 +909,16 @@ module Writexlsx
904
909
  # need to call this method.
905
910
  #
906
911
  def set_portrait
907
- @print_style.orientation = true
908
- @print_style.page_setup_changed = true
912
+ @page_setup.orientation = true
913
+ @page_setup.page_setup_changed = true
909
914
  end
910
915
 
911
916
  #
912
917
  # Set the page orientation as landscape.
913
918
  #
914
919
  def set_landscape
915
- @print_style.orientation = false
916
- @print_style.page_setup_changed = true
920
+ @page_setup.orientation = false
921
+ @page_setup.page_setup_changed = true
917
922
  end
918
923
 
919
924
  #
@@ -1010,10 +1015,7 @@ module Writexlsx
1010
1015
  # the printer's default paper.
1011
1016
  #
1012
1017
  def paper=(paper_size)
1013
- if paper_size
1014
- @paper_size = paper_size
1015
- @print_style.page_setup_changed = true
1016
- end
1018
+ @page_setup.paper = paper_size
1017
1019
  end
1018
1020
 
1019
1021
  def set_paper(paper_size)
@@ -1173,9 +1175,9 @@ module Writexlsx
1173
1175
  def set_header(string = '', margin = 0.3)
1174
1176
  raise 'Header string must be less than 255 characters' if string.length >= 255
1175
1177
 
1176
- @header = string
1177
- @print_style.margin_header = margin
1178
- @header_footer_changed = true
1178
+ @page_setup.header = string
1179
+ @page_setup.margin_header = margin
1180
+ @page_setup.header_footer_changed = true
1179
1181
  end
1180
1182
 
1181
1183
  #
@@ -1186,25 +1188,23 @@ module Writexlsx
1186
1188
  def set_footer(string = '', margin = 0.3)
1187
1189
  raise 'Footer string must be less than 255 characters' if string.length >= 255
1188
1190
 
1189
- @footer = string
1190
- @print_style.margin_footer = margin
1191
- @header_footer_changed = true
1191
+ @page_setup.footer = string
1192
+ @page_setup.margin_footer = margin
1193
+ @page_setup.header_footer_changed = true
1192
1194
  end
1193
1195
 
1194
1196
  #
1195
1197
  # Center the worksheet data horizontally between the margins on the printed page:
1196
1198
  #
1197
1199
  def center_horizontally
1198
- @print_options_changed = true
1199
- @hcenter = true
1200
+ @page_setup.center_horizontally
1200
1201
  end
1201
1202
 
1202
1203
  #
1203
1204
  # Center the worksheet data vertically between the margins on the printed page:
1204
1205
  #
1205
1206
  def center_vertically
1206
- @print_options_changed = true
1207
- @vcenter = true
1207
+ @page_setup.center_vertically
1208
1208
  end
1209
1209
 
1210
1210
  #
@@ -1257,7 +1257,7 @@ module Writexlsx
1257
1257
  # See margins=()
1258
1258
  #
1259
1259
  def margin_left=(margin)
1260
- @print_style.margin_left = remove_white_space(margin)
1260
+ @page_setup.margin_left = remove_white_space(margin)
1261
1261
  end
1262
1262
 
1263
1263
  #
@@ -1265,7 +1265,7 @@ module Writexlsx
1265
1265
  # See margins=()
1266
1266
  #
1267
1267
  def margin_right=(margin)
1268
- @print_style.margin_right = remove_white_space(margin)
1268
+ @page_setup.margin_right = remove_white_space(margin)
1269
1269
  end
1270
1270
 
1271
1271
  #
@@ -1273,7 +1273,7 @@ module Writexlsx
1273
1273
  # See margins=()
1274
1274
  #
1275
1275
  def margin_top=(margin)
1276
- @print_style.margin_top = remove_white_space(margin)
1276
+ @page_setup.margin_top = remove_white_space(margin)
1277
1277
  end
1278
1278
 
1279
1279
  #
@@ -1281,7 +1281,7 @@ module Writexlsx
1281
1281
  # See margins=()
1282
1282
  #
1283
1283
  def margin_bottom=(margin)
1284
- @print_style.margin_bottom = remove_white_space(margin)
1284
+ @page_setup.margin_bottom = remove_white_space(margin)
1285
1285
  end
1286
1286
 
1287
1287
  #
@@ -1394,11 +1394,11 @@ module Writexlsx
1394
1394
 
1395
1395
  # Build up the print titles "Sheet1!$1:$2"
1396
1396
  sheetname = quote_sheetname(name)
1397
- @print_style.repeat_rows = "#{sheetname}!#{area}"
1397
+ @page_setup.repeat_rows = "#{sheetname}!#{area}"
1398
1398
  end
1399
1399
 
1400
1400
  def print_repeat_rows # :nodoc:
1401
- @print_style.repeat_rows
1401
+ @page_setup.repeat_rows
1402
1402
  end
1403
1403
  #
1404
1404
  # :call-seq:
@@ -1428,11 +1428,11 @@ module Writexlsx
1428
1428
  last_col ||= first_col
1429
1429
 
1430
1430
  area = "#{xl_col_to_name(first_col, 1)}:#{xl_col_to_name(last_col, 1)}"
1431
- @print_style.repeat_cols = "#{quote_sheetname(@name)}!#{area}"
1431
+ @page_setup.repeat_cols = "#{quote_sheetname(@name)}!#{area}"
1432
1432
  end
1433
1433
 
1434
1434
  def print_repeat_cols # :nodoc:
1435
- @print_style.repeat_cols
1435
+ @page_setup.repeat_cols
1436
1436
  end
1437
1437
 
1438
1438
  #
@@ -1448,7 +1448,7 @@ module Writexlsx
1448
1448
  # worksheet2.print_area( 'A:H' ); # Columns A to H if rows have data
1449
1449
  #
1450
1450
  def print_area(*args)
1451
- return @print_area.dup if args.empty?
1451
+ return @page_setup.print_area.dup if args.empty?
1452
1452
  row1, col1, row2, col2 = row_col_notation(args)
1453
1453
  return if [row1, col1, row2, col2].include?(nil)
1454
1454
 
@@ -1458,11 +1458,11 @@ module Writexlsx
1458
1458
  end
1459
1459
 
1460
1460
  # Build up the print area range "=Sheet2!R1C1:R2C1"
1461
- @print_area = convert_name_area(row1, col1, row2, col2)
1461
+ @page_setup.print_area = convert_name_area(row1, col1, row2, col2)
1462
1462
  end
1463
1463
 
1464
1464
  #
1465
- # Set the worksheet zoom factor in the range 10 <= $scale <= 400:
1465
+ # Set the worksheet zoom factor in the range <tt>10 <= scale <= 400</tt>:
1466
1466
  #
1467
1467
  # worksheet1.zoom = 50
1468
1468
  # worksheet2.zoom = 75
@@ -1515,10 +1515,10 @@ module Writexlsx
1515
1515
  scale_val = 100 if scale_val < 10 || scale_val > 400
1516
1516
 
1517
1517
  # Turn off "fit to page" option.
1518
- @print_style.fit_page = false
1518
+ @page_setup.fit_page = false
1519
1519
 
1520
- @print_style.scale = scale_val
1521
- @print_style.page_setup_changed = true
1520
+ @page_setup.scale = scale_val
1521
+ @page_setup.page_setup_changed = true
1522
1522
  end
1523
1523
 
1524
1524
  #
@@ -1581,10 +1581,10 @@ module Writexlsx
1581
1581
  #
1582
1582
  def print_across(across = true)
1583
1583
  if across
1584
- @print_style.across = true
1585
- @print_style.page_setup_changed = true
1584
+ @page_setup.across = true
1585
+ @page_setup.page_setup_changed = true
1586
1586
  else
1587
- @print_style.across = false
1587
+ @page_setup.across = false
1588
1588
  end
1589
1589
  end
1590
1590
 
@@ -1609,7 +1609,7 @@ module Writexlsx
1609
1609
  #
1610
1610
  # Excel makes a distinction between data types such as strings, numbers,
1611
1611
  # blanks, formulas and hyperlinks. To simplify the process of writing
1612
- # data the write() method acts as a general alias for several more
1612
+ # data the {#write()}[#method-i-write] method acts as a general alias for several more
1613
1613
  # specific methods:
1614
1614
  #
1615
1615
  # write_string
@@ -1655,11 +1655,11 @@ module Writexlsx
1655
1655
  #
1656
1656
  # worksheet.write(4, 0, 'Hello', format) # Formatted string
1657
1657
  #
1658
- # The write() method will ignore empty strings or +nil+ tokens unless a
1658
+ # The {#write()}[#method-i-write] method will ignore empty strings or +nil+ tokens unless a
1659
1659
  # format is also supplied. As such you needn't worry about special handling
1660
1660
  # for empty or nil in your data. See also the write_blank() method.
1661
1661
  #
1662
- # One problem with the write() method is that occasionally data looks like
1662
+ # One problem with the {#write()}[#method-i-write] method is that occasionally data looks like
1663
1663
  # a number but you don't want it treated as a number. For example, zip
1664
1664
  # codes or ID numbers often start with a leading zero.
1665
1665
  # If you want to write this data with leading zero(s), use write_string.
@@ -1713,7 +1713,7 @@ module Writexlsx
1713
1713
  # The write_row() method can be used to write a 1D or 2D array of data
1714
1714
  # in one go. This is useful for converting the results of a database
1715
1715
  # query into an Excel worksheet. You must pass a reference to the array
1716
- # of data rather than the array itself. The write() method is then
1716
+ # of data rather than the array itself. The {#write()}[#method-i-write] method is then
1717
1717
  # called for each element of the data. For example:
1718
1718
  #
1719
1719
  # array = ['awk', 'gawk', 'mawk']
@@ -1725,7 +1725,7 @@ module Writexlsx
1725
1725
  # worksheet.write(0, 1, array[1])
1726
1726
  # worksheet.write(0, 2, array[2])
1727
1727
  #
1728
- # Note: For convenience the write() method behaves in the same way as
1728
+ # Note: For convenience the {#write()}[#method-i-write] method behaves in the same way as
1729
1729
  # write_row() if it is passed an array.
1730
1730
  # Therefore the following two method calls are equivalent:
1731
1731
  #
@@ -1844,7 +1844,7 @@ module Writexlsx
1844
1844
  # In either case the appropriate row or column value will still be
1845
1845
  # incremented.
1846
1846
  #
1847
- # As noted above the write() method can be used as a synonym for
1847
+ # As noted above the {#write()}[#method-i-write] method can be used as a synonym for
1848
1848
  # write_row() and write_row() handles nested array refs as columns.
1849
1849
  # Therefore, the following two method calls are equivalent although
1850
1850
  # the more explicit call to write_col() would be preferable for
@@ -1858,7 +1858,6 @@ module Writexlsx
1858
1858
  #
1859
1859
  def write_col(*args)
1860
1860
  row, col, tokens, *options = row_col_notation(args)
1861
- raise "Not an array ref in call to write_col()$!" unless tokens.respond_to?(:to_ary)
1862
1861
 
1863
1862
  tokens.each do |token|
1864
1863
  # write() will deal with any nested arrays
@@ -2071,7 +2070,7 @@ module Writexlsx
2071
2070
  # See the note about {"Cell notation"}[#label-Cell+notation].
2072
2071
  # The +format+ parameter is optional.
2073
2072
  #
2074
- # In general it is sufficient to use the write() method.
2073
+ # In general it is sufficient to use the {#write()}[#method-i-write] method.
2075
2074
  #
2076
2075
  # Note: some versions of Excel 2007 do not display the calculated values
2077
2076
  # of formulas written by WriteXLSX. Applying all available Service Packs
@@ -2103,7 +2102,7 @@ module Writexlsx
2103
2102
  # string segment that Excel can display in a cell is 1000.
2104
2103
  # All 32767 characters can be displayed in the formula bar.
2105
2104
  #
2106
- # In general it is sufficient to use the write() method.
2105
+ # In general it is sufficient to use the {#write()}[#method-i-write] method.
2107
2106
  # However, you may sometimes wish to use the write_string() method
2108
2107
  # to write data that looks like a number but that you don't want
2109
2108
  # treated as a number. For example, zip codes or phone numbers:
@@ -2230,46 +2229,17 @@ module Writexlsx
2230
2229
  row, col, *rich_strings = row_col_notation(args)
2231
2230
  raise WriteXLSXInsufficientArgumentError if [row, col, rich_strings[0]].include?(nil)
2232
2231
 
2233
- # If the last arg is a format we use it as the cell format.
2234
- if rich_strings[-1].respond_to?(:xf_index)
2235
- xf = rich_strings.pop
2236
- else
2237
- xf = nil
2238
- end
2232
+ xf = cell_format_of_rich_string(rich_strings)
2239
2233
 
2240
2234
  # Check that row and col are valid and store max and min values
2241
2235
  check_dimensions(row, col)
2242
2236
  store_row_col_max_min_values(row, col)
2243
2237
 
2244
- # Create a temp XML::Writer object and use it to write the rich string
2245
- # XML to a string.
2246
- writer = Package::XMLWriterSimple.new
2247
-
2248
2238
  fragments, length = rich_strings_fragments(rich_strings)
2249
2239
  # can't allow 2 formats in a row
2250
2240
  return -4 unless fragments
2251
2241
 
2252
- # If the first token is a string start the <r> element.
2253
- writer.start_tag('r') if !fragments[0].respond_to?(:xf_index)
2254
-
2255
- # Write the XML elements for the format string fragments.
2256
- fragments.each do |token|
2257
- if token.respond_to?(:xf_index)
2258
- # Write the font run.
2259
- writer.start_tag('r')
2260
- write_font(writer, token)
2261
- else
2262
- # Write the string fragment part, with whitespace handling.
2263
- attributes = []
2264
-
2265
- attributes << 'xml:space' << 'preserve' if token =~ /^\s/ || token =~ /\s$/
2266
- writer.data_element('t', token, attributes)
2267
- writer.end_tag('r')
2268
- end
2269
- end
2270
-
2271
- # Add the XML string to the shared string table.
2272
- index = shared_string_index(writer.string)
2242
+ index = shared_string_index(xml_str_of_rich_string(fragments))
2273
2243
 
2274
2244
  store_data_to_table(StringCellData.new(self, row, col, index, xf))
2275
2245
  end
@@ -2364,7 +2334,7 @@ module Writexlsx
2364
2334
  else
2365
2335
  check_dimensions(row, col)
2366
2336
  store_row_col_max_min_values(row, col)
2367
- formula.sub!(/^=/, '')
2337
+ formula = formula.sub(/^=/, '')
2368
2338
 
2369
2339
  store_data_to_table(FormulaCellData.new(self, row, col, formula, format, value))
2370
2340
  end
@@ -2385,7 +2355,7 @@ module Writexlsx
2385
2355
  # worksheet.write_array_formula('A1:A1', '{=SUM(B1:C1*B2:C2)}')
2386
2356
  #
2387
2357
  # It this case however it is easier to just use the write_formula()
2388
- # or write() methods:
2358
+ # or {#write()}[#method-i-write] methods:
2389
2359
  #
2390
2360
  # # Same as above but more concise.
2391
2361
  # worksheet.write('A1', '{=SUM(B1:C1*B2:C2)}')
@@ -2434,8 +2404,7 @@ module Writexlsx
2434
2404
  end
2435
2405
 
2436
2406
  # Remove array formula braces and the leading =.
2437
- formula.sub!(/^\{(.*)\}$/, '\1')
2438
- formula.sub!(/^=/, '')
2407
+ formula = formula.sub(/^\{(.*)\}$/, '\1').sub(/^=/, '')
2439
2408
 
2440
2409
  store_data_to_table(FormulaArrayCellData.new(self, row1, col1, formula, xf, range, value))
2441
2410
 
@@ -2448,10 +2417,12 @@ module Writexlsx
2448
2417
  end
2449
2418
  end
2450
2419
 
2420
+ #
2451
2421
  # The outline_settings() method is used to control the appearance of
2452
- # outlines in Excel. Outlines are described in "OUTLINES AND GROUPING IN EXCEL".
2422
+ # outlines in Excel. Outlines are described in
2423
+ # {"OUTLINES AND GROUPING IN EXCEL"}["method-i-set_row-label-OUTLINES+AND+GROUPING+IN+EXCEL"].
2453
2424
  #
2454
- # The visible parameter is used to control whether or not outlines are
2425
+ # The +visible+ parameter is used to control whether or not outlines are
2455
2426
  # visible. Setting this parameter to 0 will cause all outlines on the
2456
2427
  # worksheet to be hidden. They can be unhidden in Excel by means of the
2457
2428
  # "Show Outline Symbols" command button. The default setting is 1 for
@@ -2459,16 +2430,16 @@ module Writexlsx
2459
2430
  #
2460
2431
  # worksheet.outline_settings(0)
2461
2432
  #
2462
- # The symbols_below parameter is used to control whether the row outline
2433
+ # The +symbols_below+ parameter is used to control whether the row outline
2463
2434
  # symbol will appear above or below the outline level bar. The default
2464
2435
  # setting is 1 for symbols to appear below the outline level bar.
2465
2436
  #
2466
- # The symbols_right parameter is used to control whether the column
2437
+ # The +symbols_right+ parameter is used to control whether the column
2467
2438
  # outline symbol will appear to the left or the right of the outline level
2468
2439
  # bar. The default setting is 1 for symbols to appear to the right of
2469
2440
  # the outline level bar.
2470
2441
  #
2471
- # The auto_style parameter is used to control whether the automatic
2442
+ # The +auto_style+parameter is used to control whether the automatic
2472
2443
  # outline generator in Excel uses automatic styles when creating an
2473
2444
  # outline. This has no effect on a file generated by WriteXLSX but it
2474
2445
  # does have an effect on how the worksheet behaves after it is created.
@@ -2504,7 +2475,7 @@ module Writexlsx
2504
2475
  # The hyperlink is comprised of two elements: the visible label and
2505
2476
  # the invisible link. The visible label is the same as the link unless
2506
2477
  # an alternative label is specified. The label parameter is optional.
2507
- # The label is written using the write() method. Therefore it is
2478
+ # The label is written using the {#write()}[#method-i-write] method. Therefore it is
2508
2479
  # possible to write strings, numbers or formulas as labels.
2509
2480
  #
2510
2481
  # The +format+ parameter is also optional, however, without a format
@@ -2551,7 +2522,7 @@ module Writexlsx
2551
2522
  # worksheet.write_url('A13', 'external:..\foo.xlsx#Sheet2!A1', format)
2552
2523
  # worksheet.write_url('A13', 'external:\\\\NET\share\foo.xlsx', format)
2553
2524
  #
2554
- # All of the these URI types are recognised by the write() method, see above.
2525
+ # All of the these URI types are recognised by the {#write()}[#method-i-write] method, see above.
2555
2526
  #
2556
2527
  # Worksheet references are typically of the form Sheet1!A1. You can
2557
2528
  # also refer to a worksheet range using the standard Excel notation:
@@ -2582,102 +2553,26 @@ module Writexlsx
2582
2553
  xf, str = str, xf if str.respond_to?(:xf_index) || !xf.respond_to?(:xf_index)
2583
2554
  raise WriteXLSXInsufficientArgumentError if [row, col, url].include?(nil)
2584
2555
 
2585
- link_type = 1
2586
-
2587
- # Remove the URI scheme from internal links.
2588
- if url =~ /^internal:/
2589
- url.sub!(/^internal:/, '')
2590
- link_type = 2
2591
- # Remove the URI scheme from external links.
2592
- elsif url =~ /^external:/
2593
- url.sub!(/^external:/, '')
2594
- link_type = 3
2595
- end
2596
-
2597
- # The displayed string defaults to the url string.
2598
- str ||= url.dup
2599
-
2600
- # For external links change the directory separator from Unix to Dos.
2601
- if link_type == 3
2602
- url.gsub!(%r|/|, '\\')
2603
- str.gsub!(%r|/|, '\\')
2604
- end
2605
-
2606
- # Strip the mailto header.
2607
- str.sub!(/^mailto:/, '')
2608
-
2609
2556
  # Check that row and col are valid and store max and min values
2610
2557
  check_dimensions(row, col)
2611
2558
  store_row_col_max_min_values(row, col)
2612
2559
 
2613
- # Copy string for use in hyperlink elements.
2614
- url_str = str.dup
2615
-
2616
- # External links to URLs and to other Excel workbooks have slightly
2617
- # different characteristics that we have to account for.
2618
- if link_type == 1
2619
- # Escape URL unless it looks already escaped.
2620
- unless url =~ /%[0-9a-fA-F]{2}/
2621
- # Escape the URL escape symbol.
2622
- url = url.gsub(/%/, "%25")
2623
-
2624
- # Escape whitespae in URL.
2625
- url = url.gsub(/[\s\x00]/, '%20')
2626
-
2627
- # Escape other special characters in URL.
2628
- re = /(["<>\[\]`^{}])/
2629
- while re =~ url
2630
- match = $~[1]
2631
- url = url.sub(re, sprintf("%%%x", match.ord))
2632
- end
2633
- end
2634
-
2635
- # Ordinary URL style external links don't have a "location" string.
2636
- url_str = nil
2637
- elsif link_type == 3
2638
- # External Workbook links need to be modified into the right format.
2639
- # The URL will look something like 'c:\temp\file.xlsx#Sheet!A1'.
2640
- # We need the part to the left of the # as the URL and the part to
2641
- # the right as the "location" string (if it exists).
2642
- url, url_str = url.split(/#/)
2643
-
2644
- # Add the file:/// URI to the url if non-local.
2645
- if url =~ %r![:]! || # Windows style "C:/" link.
2646
- url =~ %r!^\\\\! # Network share.
2647
- url = "file:///#{url}"
2648
- end
2649
-
2650
- # Convert a ./dir/file.xlsx link to dir/file.xlsx.
2651
- url = url.sub(%r!^.\\!, '')
2652
-
2653
- # Treat as a default external link now that the data has been modified.
2654
- link_type = 1
2655
- end
2656
-
2657
- # Excel limits escaped URL to 255 characters.
2658
- if url.bytesize > 255
2659
- raise "URL '#{url}' > 255 characters, it exceeds Excel's limit for URLS."
2660
- end
2560
+ hyperlink = Hyperlink.new(url, str)
2561
+ hyperlink.tip = tip
2661
2562
 
2662
- # Check the limit of URLS per worksheet.
2663
2563
  @hlink_count += 1
2664
2564
 
2665
2565
  if @hlink_count > 65_530
2666
- raise "URL '#{url}' added but number of URLS is over Excel's limit of 65,530 URLS per worksheet."
2566
+ raise "URL '#{hyperlink.url}' added but number of URLS is over Excel's limit of 65,530 URLS per worksheet."
2667
2567
  end
2668
2568
 
2669
2569
  # Write the hyperlink string.
2670
- write_string(row, col, str, xf)
2570
+ write_string(row, col, hyperlink.str, xf)
2671
2571
 
2672
2572
  # Store the hyperlink data in a separate structure.
2673
2573
  @hyperlinks ||= {}
2674
2574
  @hyperlinks[row] ||= {}
2675
- @hyperlinks[row][col] = {
2676
- :_link_type => link_type,
2677
- :_url => url,
2678
- :_str => url_str,
2679
- :_tip => tip
2680
- }
2575
+ @hyperlinks[row][col] = hyperlink
2681
2576
  end
2682
2577
 
2683
2578
  #
@@ -2731,14 +2626,14 @@ module Writexlsx
2731
2626
  # There are two important things to understand about dates and times in Excel:
2732
2627
  #
2733
2628
  # 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.
2629
+ # 2 WriteXLSX doesn't automatically convert date/time strings in {#write()}[#method-i-write] to an Excel date/time.
2735
2630
  #
2736
2631
  # These two points are explained in more detail below along with some
2737
2632
  # suggestions on how to convert times and dates to the required format.
2738
2633
  #
2739
2634
  # === An Excel date/time is a number plus a format
2740
2635
  #
2741
- # If you write a date string with write() then all you will get is a string:
2636
+ # If you write a date string with {#write()}[#method-i-write] then all you will get is a string:
2742
2637
  #
2743
2638
  # worksheet.write('A1', '02/03/04') # !! Writes a string not a date. !!
2744
2639
  #
@@ -2810,7 +2705,7 @@ module Writexlsx
2810
2705
  # 2. Extract the component parts of the date/time using the same regex.
2811
2706
  # 3. Convert the date/time to the ISO8601 format.
2812
2707
  # 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
2708
+ # For a slightly more advanced solution you can modify the {#write()}[#method-i-write] method
2814
2709
  # to handle date formats of your choice via the add_write_handler() method.
2815
2710
  # See the add_write_handler() section of the docs and the
2816
2711
  # write_handler3.rb and write_handler4.rb programs in the examples
@@ -3004,18 +2899,18 @@ module Writexlsx
3004
2899
  # set_row(row [ , height, format, hidden, level, collapsed ] )
3005
2900
  #
3006
2901
  # This method can be used to change the default properties of a row.
3007
- # All parameters apart from row are optional.
2902
+ # All parameters apart from +row+ are optional.
3008
2903
  #
3009
2904
  # The most common use for this method is to change the height of a row:
3010
2905
  #
3011
2906
  # worksheet.set_row(0, 20) # Row 1 height set to 20
3012
2907
  #
3013
2908
  # If you wish to set the format without changing the height you can
3014
- # pass nil as the height parameter:
2909
+ # pass +nil+ as the height parameter:
3015
2910
  #
3016
2911
  # worksheet.set_row(0, nil, format)
3017
2912
  #
3018
- # The format parameter will be applied to any cells in the row that
2913
+ # The +format+ parameter will be applied to any cells in the row that
3019
2914
  # don't have a format. For example
3020
2915
  #
3021
2916
  # worksheet.set_row(0, nil, format1) # Set the format for row 1
@@ -3023,17 +2918,17 @@ module Writexlsx
3023
2918
  # worksheet.write('B1', 'Hello', format2) # Keeps format2
3024
2919
  #
3025
2920
  # If you wish to define a row format in this way you should call the
3026
- # method before any calls to write(). Calling it afterwards will overwrite
2921
+ # method before any calls to {#write()}[#method-i-write]. Calling it afterwards will overwrite
3027
2922
  # any format that was previously specified.
3028
2923
  #
3029
- # The hidden parameter should be set to 1 if you wish to hide a row.
2924
+ # The +hidden+ parameter should be set to 1 if you wish to hide a row.
3030
2925
  # This can be used, for example, to hide intermediary steps in a
3031
2926
  # complicated calculation:
3032
2927
  #
3033
2928
  # worksheet.set_row(0, 20, format, 1)
3034
2929
  # worksheet.set_row(1, nil, nil, 1)
3035
2930
  #
3036
- # The level parameter is used to set the outline level of the row.
2931
+ # The +level+ parameter is used to set the outline level of the row.
3037
2932
  # Outlines are described in "OUTLINES AND GROUPING IN EXCEL". Adjacent
3038
2933
  # rows with the same outline level are grouped together into a single
3039
2934
  # outline.
@@ -3044,22 +2939,110 @@ module Writexlsx
3044
2939
  # worksheet.set_row(1, nil, nil, 0, 1)
3045
2940
  # worksheet.set_row(2, nil, nil, 0, 1)
3046
2941
  #
3047
- # The hidden parameter can also be used to hide collapsed outlined rows
3048
- # when used in conjunction with the level parameter.
2942
+ # The +hidden+ parameter can also be used to hide collapsed outlined rows
2943
+ # when used in conjunction with the +level+ parameter.
3049
2944
  #
3050
2945
  # worksheet.set_row(1, nil, nil, 1, 1)
3051
2946
  # worksheet.set_row(2, nil, nil, 1, 1)
3052
2947
  #
3053
2948
  # For collapsed outlines you should also indicate which row has the
3054
- # collapsed + symbol using the optional collapsed parameter.
2949
+ # collapsed + symbol using the optional +collapsed+ parameter.
3055
2950
  #
3056
2951
  # worksheet.set_row(3, nil, nil, 0, 0, 1)
3057
2952
  #
3058
2953
  # For a more complete example see the outline.rb and outline_collapsed.rb
3059
2954
  # programs in the examples directory of the distro.
3060
2955
  #
3061
- # Excel allows up to 7 outline levels. Therefore the level parameter
3062
- # should be in the range 0 <= level <= 7.
2956
+ # Excel allows up to 7 outline levels. Therefore the +level+ parameter
2957
+ # should be in the range <tt>0 <= level <= 7</tt>.
2958
+ #
2959
+ # == OUTLINES AND GROUPING IN EXCEL
2960
+ #
2961
+ # Excel allows you to group rows or columns so that they can be hidden or
2962
+ # displayed with a single mouse click. This feature is referred to as
2963
+ # outlines.
2964
+ #
2965
+ # Outlines can reduce complex data down to a few salient sub-totals or
2966
+ # summaries.
2967
+ #
2968
+ # This feature is best viewed in Excel but the following is an ASCII
2969
+ # representation of what a worksheet with three outlines might look like.
2970
+ # Rows 3-4 and rows 7-8 are grouped at level 2. Rows 2-9 are grouped at
2971
+ # level 1. The lines at the left hand side are called outline level bars.
2972
+ #
2973
+ # ------------------------------------------
2974
+ # 1 2 3 | | A | B | C | D | ...
2975
+ # ------------------------------------------
2976
+ # _ | 1 | A | | | | ...
2977
+ # | _ | 2 | B | | | | ...
2978
+ # | | | 3 | (C) | | | | ...
2979
+ # | | | 4 | (D) | | | | ...
2980
+ # | - | 5 | E | | | | ...
2981
+ # | _ | 6 | F | | | | ...
2982
+ # | | | 7 | (G) | | | | ...
2983
+ # | | | 8 | (H) | | | | ...
2984
+ # | - | 9 | I | | | | ...
2985
+ # - | . | ... | ... | ... | ... | ...
2986
+ #
2987
+ # Clicking the minus sign on each of the level 2 outlines will collapse
2988
+ # and hide the data as shown in the next figure. The minus sign changes
2989
+ # to a plus sign to indicate that the data in the outline is hidden.
2990
+ #
2991
+ # ------------------------------------------
2992
+ # 1 2 3 | | A | B | C | D | ...
2993
+ # ------------------------------------------
2994
+ # _ | 1 | A | | | | ...
2995
+ # | | 2 | B | | | | ...
2996
+ # | + | 5 | E | | | | ...
2997
+ # | | 6 | F | | | | ...
2998
+ # | + | 9 | I | | | | ...
2999
+ # - | . | ... | ... | ... | ... | ...
3000
+ #
3001
+ # Clicking on the minus sign on the level 1 outline will collapse the
3002
+ # remaining rows as follows:
3003
+ #
3004
+ # ------------------------------------------
3005
+ # 1 2 3 | | A | B | C | D | ...
3006
+ # ------------------------------------------
3007
+ # | 1 | A | | | | ...
3008
+ # + | . | ... | ... | ... | ... | ...
3009
+ #
3010
+ # Grouping in WritXLSX is achieved by setting the outline level via the
3011
+ # set_row() and set_column() worksheet methods:
3012
+ #
3013
+ # set_row(row, height, format, hidden, level, collapsed)
3014
+ # set_column(first_col, last_col, width, format, hidden, level, collapsed)
3015
+ #
3016
+ # The following example sets an outline level of 1 for rows 1 and 2
3017
+ # (zero-indexed) and columns B to G. The parameters $height and $XF are
3018
+ # assigned default values since they are undefined:
3019
+ #
3020
+ # worksheet.set_row(1, nil, nil, 0, 1)
3021
+ # worksheet.set_row(2, nil, nil, 0, 1)
3022
+ # worksheet.set_column('B:G', nil, nil, 0, 1)
3023
+ #
3024
+ # Excel allows up to 7 outline levels. Therefore the +level+ parameter
3025
+ # should be in the range <tt>0 <= $level <= 7</tt>.
3026
+ #
3027
+ # Rows and columns can be collapsed by setting the +hidden+ flag for the
3028
+ # hidden rows/columns and setting the +collapsed+ flag for the row/column
3029
+ # that has the collapsed + symbol:
3030
+ #
3031
+ # worksheet.set_row(1, nil, nil, 1, 1)
3032
+ # worksheet.set_row(2, nil, nil, 1, 1)
3033
+ # worksheet.set_row(3, nil, nil, 0, 0, 1) # Collapsed flag.
3034
+ #
3035
+ # worksheet.set_column('B:G', nil, nil, 1, 1)
3036
+ # worksheet.set_column('H:H', nil, nil, 0, 0, 1) # Collapsed flag.
3037
+ #
3038
+ # Note: Setting the $collapsed flag is particularly important for
3039
+ # compatibility with OpenOffice.org and Gnumeric.
3040
+ #
3041
+ # For a more complete example see the outline.rb and outline_collapsed.rb
3042
+ # programs in the examples directory of the distro.
3043
+ #
3044
+ # Some additional outline properties can be set via the outline_settings()
3045
+ # worksheet method, see above.
3063
3046
  #
3064
3047
  def set_row(*args)
3065
3048
  row = args[0]
@@ -3127,8 +3110,27 @@ module Writexlsx
3127
3110
  #
3128
3111
  # merge_range(first_row, first_col, last_row, last_col, string, format)
3129
3112
  #
3130
- # Merge a range of cells. The first cell should contain the data and the others
3131
- # should be blank. All cells should contain the same format.
3113
+ # Merge a range of cells. The first cell should contain the data and the
3114
+ # others should be blank. All cells should contain the same format.
3115
+ #
3116
+ # The merge_range() method allows you to merge cells that contain other
3117
+ # types of alignment in addition to the merging:
3118
+ #
3119
+ # format = workbook.add_format(
3120
+ # :border => 6,
3121
+ # :valign => 'vcenter',
3122
+ # :align => 'center'
3123
+ # )
3124
+ #
3125
+ # worksheet.merge_range('B3:D4', 'Vertical and horizontal', format)
3126
+ #
3127
+ # merge_range() writes its +token+ argument using the worksheet
3128
+ # {#write()}[#method-i-write] method. Therefore it will handle numbers,
3129
+ # strings, formulas or urls as required. If you need to specify the
3130
+ # required write_*() method use the merge_range_type() method, see below.
3131
+ #
3132
+ # The full possibilities of this method are shown in the merge3.rb to
3133
+ # merge6.rb programs in the examples directory of the distribution.
3132
3134
  #
3133
3135
  def merge_range(*args)
3134
3136
  row_first, col_first, row_last, col_last, string, format, *extra_args = row_col_notation(args)
@@ -3156,7 +3158,39 @@ module Writexlsx
3156
3158
  end
3157
3159
 
3158
3160
  #
3159
- # Same as merge_range() above except the type of write() is specified.
3161
+ # Same as merge_range() above except the type of
3162
+ # {#write()}[#method-i-write] is specified.
3163
+ #
3164
+ # The merge_range() method, see above, uses write() to insert the required
3165
+ # data into to a merged range. However, there may be times where this
3166
+ # isn't what you require so as an alternative the merge_range_type ()
3167
+ # method allows you to specify the type of data you wish to write.
3168
+ # For example:
3169
+ #
3170
+ # worksheet.merge_range_type('number', 'B2:C2', 123, format1)
3171
+ # worksheet.merge_range_type('string', 'B4:C4', 'foo', format2)
3172
+ # worksheet.merge_range_type('formula', 'B6:C6', '=1+2', format3)
3173
+ #
3174
+ # The +type+ must be one of the following, which corresponds to a write_*()
3175
+ # method:
3176
+ #
3177
+ # 'number'
3178
+ # 'string'
3179
+ # 'formula'
3180
+ # 'array_formula'
3181
+ # 'blank'
3182
+ # 'rich_string'
3183
+ # 'date_time'
3184
+ # 'url'
3185
+ #
3186
+ # Any arguments after the range should be whatever the appropriate method
3187
+ # accepts:
3188
+ #
3189
+ # worksheet.merge_range_type('rich_string', 'B8:C8',
3190
+ # 'This is ', bold, 'bold', format4)
3191
+ #
3192
+ # Note, you must always pass a format object as an argument, even if it is
3193
+ # a default format.
3160
3194
  #
3161
3195
  def merge_range_type(type, *args)
3162
3196
  case type
@@ -3215,19 +3249,11 @@ module Writexlsx
3215
3249
  # :call-seq:
3216
3250
  # conditional_formatting(cell_or_cell_range, options)
3217
3251
  #
3218
- # This method handles the interface to Excel conditional formatting.
3219
- #
3220
- # This method contains a lot of parameters and is described in detail in
3221
- # the section below.
3252
+ # Conditional formatting is a feature of Excel which allows you to apply a
3253
+ # format to a cell or a range of cells based on a certain criteria.
3222
3254
  #
3223
- # We allow the format to be called on one cell or a range of cells. The
3224
- # hashref contains the formatting parameters and must be the last param:
3225
- #
3226
- # conditional_formatting(row, col, {...})
3227
- # conditional_formatting(first_row, first_col, last_row, last_col, {...})
3228
- #
3229
- # The conditional_format() method is used to add formatting to a cell
3230
- # or range of cells based on user defined criteria.
3255
+ # For example the following criteria is used to highlight cells >= 50 in
3256
+ # red in the conditional_format.rb example from the distro.
3231
3257
  #
3232
3258
  # worksheet.conditional_formatting('A1:J10',
3233
3259
  # {
@@ -3238,15 +3264,14 @@ module Writexlsx
3238
3264
  # }
3239
3265
  # )
3240
3266
  #
3241
- # See also the conditional_format.rb program in the examples directory of
3242
- # the distro.
3267
+ # http://jmcnamara.github.com/excel-writer-xlsx/images/examples/conditional_example.jpg
3243
3268
  #
3244
3269
  # The conditional_formatting method is used to apply formatting based
3245
3270
  # on user defined criteria to an write_xlsx file.
3246
3271
  #
3247
3272
  # It can be applied to a single cell or a range of cells.
3248
- # You can pass 3 parameters such as (row, col, {...})
3249
- # or 5 parameters such as (first_row, first_col, last_row, last_col, {...}).
3273
+ # You can pass 3 parameters such as (+row+, +col+, {...})
3274
+ # or 5 parameters such as (+first_row+, +first_col+, +last_row+, +last_col+, {...}).
3250
3275
  # You can also use A1 style notation. For example:
3251
3276
  #
3252
3277
  # worksheet.conditional_formatting( 0, 0, {...} )
@@ -3257,6 +3282,7 @@ module Writexlsx
3257
3282
  # worksheet.conditional_formatting( 'A1', {...} )
3258
3283
  # worksheet.conditional_formatting( 'A1:B5', {...} )
3259
3284
  #
3285
+ #
3260
3286
  # Using A1 style notation is is also possible to specify
3261
3287
  # non-contiguous ranges, separated by a comma. For example:
3262
3288
  #
@@ -3272,6 +3298,7 @@ module Writexlsx
3272
3298
  # :value
3273
3299
  # :minimum
3274
3300
  # :maximum
3301
+ #
3275
3302
  # Other, less commonly used parameters are:
3276
3303
  #
3277
3304
  # :min_type
@@ -3284,14 +3311,15 @@ module Writexlsx
3284
3311
  # :mid_color
3285
3312
  # :max_color
3286
3313
  # :bar_color
3314
+ #
3287
3315
  # Additional parameters which are used for specific conditional format types
3288
3316
  # are shown in the relevant sections below.
3289
3317
  #
3290
- # == :type
3318
+ # === :type
3291
3319
  #
3292
3320
  # This parameter is passed in a hash to conditional_formatting.
3293
3321
  #
3294
- # The type parameter is used to set the type of conditional formatting
3322
+ # The +:type+ parameter is used to set the type of conditional formatting
3295
3323
  # that you wish to apply. It is always required and it has no default value.
3296
3324
  # Allowable type values and their associated parameters are:
3297
3325
  #
@@ -3339,10 +3367,11 @@ module Writexlsx
3339
3367
  # 'data_bar' (none)
3340
3368
  #
3341
3369
  # 'formula' :criteria
3370
+ #
3342
3371
  # All conditional formatting types have a format parameter, see below.
3343
3372
  # Other types and parameters such as icon sets will be added in time.
3344
3373
  #
3345
- # == :type => 'cell'
3374
+ # === :type => 'cell'
3346
3375
  #
3347
3376
  # This is the most common conditional formatting type. It is used when
3348
3377
  # a format is applied to a cell based on a simple criterion. For example:
@@ -3366,9 +3395,9 @@ module Writexlsx
3366
3395
  # :format => green_format
3367
3396
  # }
3368
3397
  # )
3369
- # == :criteria
3398
+ # === :criteria
3370
3399
  #
3371
- # The criteria parameter is used to set the criteria by which the cell data
3400
+ # The +:criteria+ parameter is used to set the criteria by which the cell data
3372
3401
  # will be evaluated. It has no default value. The most common criteria
3373
3402
  # as applied to { type => 'cell' } are:
3374
3403
  #
@@ -3380,30 +3409,33 @@ module Writexlsx
3380
3409
  # 'less than' | '<'
3381
3410
  # 'greater than or equal to' | '>='
3382
3411
  # 'less than or equal to' | '<='
3412
+ #
3383
3413
  # You can either use Excel's textual description strings,
3384
3414
  # in the first column above, or the more common symbolic alternatives.
3385
3415
  #
3386
3416
  # Additional criteria which are specific to other conditional format types
3387
3417
  # are shown in the relevant sections below.
3388
3418
  #
3389
- # == :value
3419
+ # === :value
3390
3420
  #
3391
- # The value is generally used along with the criteria parameter to set the
3421
+ # The +:value+ is generally used along with the criteria parameter to set the
3392
3422
  # rule by which the cell data will be evaluated.
3393
3423
  #
3394
3424
  # :type => 'cell',
3395
3425
  # :criteria => '>',
3396
3426
  # :value => 5
3397
3427
  # :format => format
3398
- # The value property can also be an cell reference.
3428
+ #
3429
+ # The +:value+ property can also be an cell reference.
3399
3430
  #
3400
3431
  # :type => 'cell',
3401
3432
  # :criteria => '>',
3402
3433
  # :value => '$C$1',
3403
3434
  # :format => format
3404
- # == :format
3405
3435
  #
3406
- # The format parameter is used to specify the format that will be applied
3436
+ # === :format
3437
+ #
3438
+ # The +:format+ parameter is used to specify the format that will be applied
3407
3439
  # to the cell when the conditional formatting criterion is met.
3408
3440
  # The format is created using the add_format method in the same way as cell
3409
3441
  # formats:
@@ -3418,6 +3450,7 @@ module Writexlsx
3418
3450
  # :format => format
3419
3451
  # }
3420
3452
  # )
3453
+ #
3421
3454
  # The conditional format follows the same rules as in Excel:
3422
3455
  # it is superimposed over the existing cell format and not all font and
3423
3456
  # border properties can be modified. Font properties that can't be modified
@@ -3447,21 +3480,23 @@ module Writexlsx
3447
3480
  # :bg_color => '#C6EFCE',
3448
3481
  # :color => '#006100'
3449
3482
  # )
3450
- # == :minimum
3451
3483
  #
3452
- # The minimum parameter is used to set the lower limiting value when the
3453
- # criteria is either 'between' or 'not between':
3484
+ # === :minimum
3485
+ #
3486
+ # The +:minimum+ parameter is used to set the lower limiting value when the
3487
+ # +:criteria+ is either 'between' or 'not between':
3454
3488
  #
3455
3489
  # :validate => 'integer',
3456
3490
  # :criteria => 'between',
3457
3491
  # :minimum => 1,
3458
3492
  # :maximum => 100
3459
- # == :maximum
3460
3493
  #
3461
- # The maximum parameter is used to set the upper limiting value when the
3462
- # criteria is either 'between' or 'not between'. See the previous example.
3494
+ # === :maximum
3495
+ #
3496
+ # The +:maximum+ parameter is used to set the upper limiting value when the
3497
+ # +:criteria+ is either 'between' or 'not between'. See the previous example.
3463
3498
  #
3464
- # == :type => 'date'
3499
+ # === :type => 'date'
3465
3500
  #
3466
3501
  # The date type is the same as the cell type and uses the same criteria
3467
3502
  # and values. However it allows the value, minimum and maximum properties
@@ -3476,7 +3511,8 @@ module Writexlsx
3476
3511
  # :format => format
3477
3512
  # }
3478
3513
  # )
3479
- # == :type => 'time_period'
3514
+ #
3515
+ # === :type => 'time_period'
3480
3516
  #
3481
3517
  # The time_period type is used to specify Excel's "Dates Occurring" style
3482
3518
  # conditional format.
@@ -3488,6 +3524,7 @@ module Writexlsx
3488
3524
  # :format => format
3489
3525
  # }
3490
3526
  # )
3527
+ #
3491
3528
  # The period is set in the criteria and can have one of the following
3492
3529
  # values:
3493
3530
  #
@@ -3500,7 +3537,8 @@ module Writexlsx
3500
3537
  # :criteria => 'last month',
3501
3538
  # :criteria => 'this month',
3502
3539
  # :criteria => 'next month'
3503
- # == :type => 'text'
3540
+ #
3541
+ # === :type => 'text'
3504
3542
  #
3505
3543
  # The text type is used to specify Excel's "Specific Text" style conditional
3506
3544
  # format. It is used to do simple string matching using the criteria and
@@ -3514,15 +3552,17 @@ module Writexlsx
3514
3552
  # :format => format
3515
3553
  # }
3516
3554
  # )
3555
+ #
3517
3556
  # The criteria can have one of the following values:
3518
3557
  #
3519
3558
  # :criteria => 'containing',
3520
3559
  # :criteria => 'not containing',
3521
3560
  # :criteria => 'begins with',
3522
3561
  # :criteria => 'ends with'
3562
+ #
3523
3563
  # The value parameter should be a string or single character.
3524
3564
  #
3525
- # == :type => 'average'
3565
+ # === :type => 'average'
3526
3566
  #
3527
3567
  # The average type is used to specify Excel's "Average" style conditional
3528
3568
  # format.
@@ -3534,6 +3574,7 @@ module Writexlsx
3534
3574
  # :format => format
3535
3575
  # }
3536
3576
  # )
3577
+ #
3537
3578
  # The type of average for the conditional format range is specified by the
3538
3579
  # criteria:
3539
3580
  #
@@ -3547,7 +3588,8 @@ module Writexlsx
3547
3588
  # :criteria => '2 std dev below',
3548
3589
  # :criteria => '3 std dev above',
3549
3590
  # :criteria => '3 std dev below'
3550
- # == :type => 'duplicate'
3591
+ #
3592
+ # === :type => 'duplicate'
3551
3593
  #
3552
3594
  # The duplicate type is used to highlight duplicate cells in a range:
3553
3595
  #
@@ -3557,7 +3599,8 @@ module Writexlsx
3557
3599
  # :format => format
3558
3600
  # }
3559
3601
  # )
3560
- # == :type => 'unique'
3602
+ #
3603
+ # === :type => 'unique'
3561
3604
  #
3562
3605
  # The unique type is used to highlight unique cells in a range:
3563
3606
  #
@@ -3567,7 +3610,8 @@ module Writexlsx
3567
3610
  # :format => format
3568
3611
  # }
3569
3612
  # )
3570
- # == :type => 'top'
3613
+ #
3614
+ # === :type => 'top'
3571
3615
  #
3572
3616
  # The top type is used to specify the top n values by number or percentage
3573
3617
  # in a range:
@@ -3579,6 +3623,7 @@ module Writexlsx
3579
3623
  # :format => format
3580
3624
  # }
3581
3625
  # )
3626
+ #
3582
3627
  # The criteria can be used to indicate that a percentage condition is
3583
3628
  # required:
3584
3629
  #
@@ -3590,14 +3635,15 @@ module Writexlsx
3590
3635
  # :format => format
3591
3636
  # }
3592
3637
  # )
3593
- # == :type => 'bottom'
3638
+ #
3639
+ # === :type => 'bottom'
3594
3640
  #
3595
3641
  # The bottom type is used to specify the bottom n values by number or
3596
3642
  # percentage in a range.
3597
3643
  #
3598
3644
  # It takes the same parameters as top, see above.
3599
3645
  #
3600
- # == :type => 'blanks'
3646
+ # === :type => 'blanks'
3601
3647
  #
3602
3648
  # The blanks type is used to highlight blank cells in a range:
3603
3649
  #
@@ -3607,7 +3653,8 @@ module Writexlsx
3607
3653
  # :format => format
3608
3654
  # }
3609
3655
  # )
3610
- # == :type => 'no_blanks'
3656
+ #
3657
+ # === :type => 'no_blanks'
3611
3658
  #
3612
3659
  # The no_blanks type is used to highlight non blank cells in a range:
3613
3660
  #
@@ -3617,7 +3664,8 @@ module Writexlsx
3617
3664
  # :format => format
3618
3665
  # }
3619
3666
  # )
3620
- # == :type => 'errors'
3667
+ #
3668
+ # === :type => 'errors'
3621
3669
  #
3622
3670
  # The errors type is used to highlight error cells in a range:
3623
3671
  #
@@ -3627,7 +3675,8 @@ module Writexlsx
3627
3675
  # :format => format
3628
3676
  # }
3629
3677
  # )
3630
- # == :type => 'no_errors'
3678
+ #
3679
+ # === :type => 'no_errors'
3631
3680
  #
3632
3681
  # The no_errors type is used to highlight non error cells in a range:
3633
3682
  #
@@ -3637,7 +3686,8 @@ module Writexlsx
3637
3686
  # :format => format
3638
3687
  # }
3639
3688
  # )
3640
- # == :type => '2_color_scale'
3689
+ #
3690
+ # === :type => '2_color_scale'
3641
3691
  #
3642
3692
  # The 2_color_scale type is used to specify Excel's "2 Color Scale" style
3643
3693
  # conditional format.
@@ -3647,10 +3697,11 @@ module Writexlsx
3647
3697
  # :type => '2_color_scale'
3648
3698
  # }
3649
3699
  # )
3700
+ #
3650
3701
  # At the moment only the default colors and properties can be used. These
3651
3702
  # will be extended in time.
3652
3703
  #
3653
- # == :type => '3_color_scale'
3704
+ # === :type => '3_color_scale'
3654
3705
  #
3655
3706
  # The 3_color_scale type is used to specify Excel's "3 Color Scale" style
3656
3707
  # conditional format.
@@ -3660,10 +3711,11 @@ module Writexlsx
3660
3711
  # :type => '3_color_scale'
3661
3712
  # }
3662
3713
  # )
3714
+ #
3663
3715
  # At the moment only the default colors and properties can be used.
3664
3716
  # These will be extended in time.
3665
3717
  #
3666
- # == :type => 'data_bar'
3718
+ # === :type => 'data_bar'
3667
3719
  #
3668
3720
  # The data_bar type is used to specify Excel's "Data Bar" style conditional
3669
3721
  # format.
@@ -3673,10 +3725,11 @@ module Writexlsx
3673
3725
  # :type => 'data_bar',
3674
3726
  # }
3675
3727
  # )
3728
+ #
3676
3729
  # At the moment only the default colors and properties can be used. These
3677
3730
  # will be extended in time.
3678
3731
  #
3679
- # == :type => 'formula'
3732
+ # === :type => 'formula'
3680
3733
  #
3681
3734
  # The formula type is used to specify a conditional format based on
3682
3735
  # a user defined formula:
@@ -3688,9 +3741,10 @@ module Writexlsx
3688
3741
  # :format => format
3689
3742
  # }
3690
3743
  # )
3744
+ #
3691
3745
  # The formula is specified in the criteria.
3692
3746
  #
3693
- # == :min_type, :mid_type, :max_type
3747
+ # === :min_type, :mid_type, :max_type
3694
3748
  #
3695
3749
  # The min_type and max_type properties are available when the conditional
3696
3750
  # formatting type is 2_color_scale, 3_color_scale or data_bar. The mid_type
@@ -3703,17 +3757,20 @@ module Writexlsx
3703
3757
  # :max_type => 'percent'
3704
3758
  # }
3705
3759
  # )
3760
+ #
3706
3761
  # The available min/mid/max types are:
3707
3762
  #
3708
3763
  # 'num'
3709
3764
  # 'percent'
3710
3765
  # 'percentile'
3711
3766
  # 'formula'
3712
- # == :min_value, :mid_value, :max_value
3713
3767
  #
3714
- # The min_value and max_value properties are available when the conditional
3715
- # formatting type is 2_color_scale, 3_color_scale or data_bar. The mid_value
3716
- # is available for 3_color_scale. The properties are used as follows:
3768
+ # === :min_value, :mid_value, :max_value
3769
+ #
3770
+ # The +:min_value+ and +:max_value+ properties are available when the
3771
+ # conditional formatting type is 2_color_scale, 3_color_scale or
3772
+ # data_bar. The +:mid_value+ is available for 3_color_scale. The properties
3773
+ # are used as follows:
3717
3774
  #
3718
3775
  # worksheet.conditional_formatting( 'A1:A12',
3719
3776
  # {
@@ -3722,7 +3779,8 @@ module Writexlsx
3722
3779
  # :max_value => 90
3723
3780
  # }
3724
3781
  # )
3725
- # == :min_color, :mid_color, :max_color, :bar_color
3782
+ #
3783
+ # === :min_color, :mid_color, :max_color, :bar_color
3726
3784
  #
3727
3785
  # The min_color and max_color properties are available when the conditional
3728
3786
  # formatting type is 2_color_scale, 3_color_scale or data_bar. The mid_color
@@ -3735,10 +3793,11 @@ module Writexlsx
3735
3793
  # :max_color => "#538ED5"
3736
3794
  # }
3737
3795
  # )
3796
+ #
3738
3797
  # The color can be specifies as an Excel::Writer::XLSX color index or,
3739
3798
  # more usefully, as a HTML style RGB hex number, as shown above.
3740
3799
  #
3741
- # == Conditional Formatting Examples
3800
+ # === Conditional Formatting Examples
3742
3801
  #
3743
3802
  # === Example 1. Highlight cells greater than an integer value.
3744
3803
  #
@@ -3838,6 +3897,9 @@ module Writexlsx
3838
3897
  @cond_formats[cond_format.range] << cond_format
3839
3898
  end
3840
3899
 
3900
+ #
3901
+ # :call-seq:
3902
+ # add_table(row1, col1, row2, col2, properties)
3841
3903
  #
3842
3904
  # Add an Excel table to a worksheet.
3843
3905
  #
@@ -3847,16 +3909,312 @@ module Writexlsx
3847
3909
  # worksheet.add_table('B3:F7', { ... } )
3848
3910
  #
3849
3911
  # This method contains a lot of parameters and is described
3850
- # in detail in a separate section "TABLES IN EXCEL".
3912
+ # in detail in a section
3913
+ # {"TABLES IN EXCEL"}[#method-i-add_table-label-TABLES+IN+EXCEL].
3851
3914
  #
3852
3915
  # See also the tables.rb program in the examples directory of the distro
3853
3916
  #
3917
+ # ==TABLES IN EXCEL
3918
+ #
3919
+ # Tables in Excel are a way of grouping a range of cells into a single
3920
+ # entity that has common formatting or that can be referenced from
3921
+ # formulas. Tables can have column headers, autofilters, total rows,
3922
+ # column formulas and default formatting.
3923
+ #
3924
+ # http://jmcnamara.github.com/excel-writer-xlsx/images/examples/tables.jpg
3925
+ #
3926
+ # For more information see "An Overview of Excel Tables"
3927
+ # http://office.microsoft.com/en-us/excel-help/overview-of-excel-tables-HA010048546.aspx.
3928
+ #
3929
+ # Tables are added to a worksheet using the add_table() method:
3930
+ #
3931
+ # worksheet.add_table('B3:F7', parameters)
3932
+ #
3933
+ # The data range can be specified in 'A1' or 'row/col' notation (see also
3934
+ # the note about
3935
+ # {"Cell notation"}[#label-Cell+notation] for more information.
3936
+ #
3937
+ # worksheet.add_table('B3:F7')
3938
+ #
3939
+ # # Same as:
3940
+ # worksheet.add_table(2, 1, 6, 5)
3941
+ #
3942
+ # The last parameter in add_table() should be a hash ref containing the
3943
+ # parameters that describe the table options and data. The available
3944
+ # parameters are:
3945
+ #
3946
+ # :data
3947
+ # :autofilter
3948
+ # :header_row
3949
+ # :banded_columns
3950
+ # :banded_rows
3951
+ # :first_column
3952
+ # :last_column
3953
+ # :style
3954
+ # :total_row
3955
+ # :columns
3956
+ # :name
3957
+ #
3958
+ # The table parameters are detailed below. There are no required parameters
3959
+ # and the hash ref isn't required if no options are specified.
3960
+ #
3961
+ # ===:data
3962
+ #
3963
+ # The +:data+ parameter can be used to specify the data in the cells of the
3964
+ # table.
3965
+ #
3966
+ # data = [
3967
+ # [ 'Apples', 10000, 5000, 8000, 6000 ],
3968
+ # [ 'Pears', 2000, 3000, 4000, 5000 ],
3969
+ # [ 'Bananas', 6000, 6000, 6500, 6000 ],
3970
+ # [ 'Oranges', 500, 300, 200, 700 ]
3971
+ # ]
3972
+ #
3973
+ # worksheet.add_table('B3:F7', :data => data)
3974
+ #
3975
+ # Table data can also be written separately, as an array or individual
3976
+ # cells.
3977
+ #
3978
+ # # These two statements are the same as the single statement above.
3979
+ # worksheet.add_table('B3:F7')
3980
+ # worksheet.write_col('B4', data)
3981
+ #
3982
+ # Writing the cell data separately is occasionally required when you need
3983
+ # to control the write_*() method used to populate the cells or if you
3984
+ # wish to tweak the cell formatting.
3985
+ #
3986
+ # The data structure should be an array ref of array refs holding row data
3987
+ # as shown above.
3988
+ #
3989
+ # ===:header_row
3990
+ #
3991
+ # The +:header_row+ parameter can be used to turn on or off the header row
3992
+ # in the table. It is on by default.
3993
+ #
3994
+ # worksheet.add_table('B4:F7', :header_row => 0) # Turn header off.
3995
+ #
3996
+ # The header row will contain default captions such as Column 1, Column 2,
3997
+ # etc. These captions can be overridden using the +:columns+ parameter
3998
+ # below.
3999
+ #
4000
+ # ===:autofilter
4001
+ #
4002
+ # The +:autofilter+ parameter can be used to turn on or off the autofilter
4003
+ # in the header row. It is on by default.
4004
+ #
4005
+ # worksheet.add_table('B3:F7', :autofilter => 0) # Turn autofilter off.
4006
+ #
4007
+ # The +:autofilter+ is only shown if the +:header_row+ is on. Filters
4008
+ # within the table are not supported.
4009
+ #
4010
+ # ===:banded_rows
4011
+ #
4012
+ # The +:banded_rows+ parameter can be used to used to create rows of
4013
+ # alternating colour in the table. It is on by default.
4014
+ #
4015
+ # worksheet.add_table('B3:F7', :banded_rows => 0)
4016
+ #
4017
+ # ===:banded_columns
4018
+ #
4019
+ # The +:banded_columns+ parameter can be used to used to create columns
4020
+ # of alternating colour in the table. It is off by default.
4021
+ #
4022
+ # worksheet.add_table('B3:F7', :banded_columns => 1)
4023
+ #
4024
+ # ===:first_column
4025
+ #
4026
+ # The +:first_column+ parameter can be used to highlight the first column
4027
+ # of the table. The type of highlighting will depend on the style of the
4028
+ # table. It may be bold text or a different colour. It is off by default.
4029
+ #
4030
+ # worksheet.add_table('B3:F7', :first_column => 1)
4031
+ #
4032
+ # ===:last_column
4033
+ #
4034
+ # The +:last_column+ parameter can be used to highlight the last column
4035
+ # of the table. The type of highlighting will depend on the style of the
4036
+ # table. It may be bold text or a different colour. It is off by default.
4037
+ #
4038
+ # worksheet.add_table('B3:F7', :last_column => 1)
4039
+ #
4040
+ # ===:style
4041
+ #
4042
+ # The +:style+ parameter can be used to set the style of the table.
4043
+ # Standard Excel table format names should be used (with matching
4044
+ # capitalisation):
4045
+ #
4046
+ # worksheet11.add_table(
4047
+ # 'B3:F7',
4048
+ # {
4049
+ # :data => data,
4050
+ # :style => 'Table Style Light 11'
4051
+ # }
4052
+ # )
4053
+ #
4054
+ # The default table style is 'Table Style Medium 9'.
4055
+ #
4056
+ # ===:name
4057
+ #
4058
+ # The +:name+ parameter can be used to set the name of the table.
4059
+ #
4060
+ # By default tables are named Table1, Table2, etc. If you override the
4061
+ # table name you must ensure that it doesn't clash with an existing table
4062
+ # name and that it follows Excel's requirements for table names.
4063
+ #
4064
+ # worksheet.add_table('B3:F7', :name => 'SalesData')
4065
+ #
4066
+ # If you need to know the name of the table, for example to use it in a
4067
+ # formula, you can get it as follows:
4068
+ #
4069
+ # table = worksheet2.add_table('B3:F7')
4070
+ # table_name = table.name
4071
+ #
4072
+ # ===:total_row
4073
+ #
4074
+ # The +:total_row+ parameter can be used to turn on the total row in the
4075
+ # last row of a table. It is distinguished from the other rows by a
4076
+ # different formatting and also with dropdown SUBTOTAL functions.
4077
+ #
4078
+ # worksheet.add_table('B3:F7', :total_row => 1)
4079
+ #
4080
+ # The default total row doesn't have any captions or functions. These must
4081
+ # by specified via the +:columns+ parameter below.
4082
+ #
4083
+ # ===:columns
4084
+ #
4085
+ # The +:columns+ parameter can be used to set properties for columns
4086
+ # within the table.
4087
+ #
4088
+ # The sub-properties that can be set are:
4089
+ #
4090
+ # :header
4091
+ # :formula
4092
+ # :total_string
4093
+ # :total_function
4094
+ # :format
4095
+ #
4096
+ # The column data must be specified as an array of hash. For example to
4097
+ # override the default 'Column n' style table headers:
4098
+ #
4099
+ # worksheet.add_table(
4100
+ # 'B3:F7',
4101
+ # {
4102
+ # :data => data,
4103
+ # :columns => [
4104
+ # { :header => 'Product' },
4105
+ # { :header => 'Quarter 1' },
4106
+ # { :header => 'Quarter 2' },
4107
+ # { :header => 'Quarter 3' },
4108
+ # { :header => 'Quarter 4' }
4109
+ # ]
4110
+ # }
4111
+ # )
4112
+ #
4113
+ # If you don't wish to specify properties for a specific column you pass
4114
+ # an empty hash and the defaults will be applied:
4115
+ #
4116
+ # ...
4117
+ # :columns => [
4118
+ # { :header => 'Product' },
4119
+ # { :header => 'Quarter 1' },
4120
+ # { }, # Defaults to 'Column 3'.
4121
+ # { :header => 'Quarter 3' },
4122
+ # { :header => 'Quarter 4' }
4123
+ # ]
4124
+ # ...
4125
+ #
4126
+ # Column formulas can by applied using the formula column property:
4127
+ #
4128
+ # worksheet8.add_table(
4129
+ # 'B3:G7',
4130
+ # {
4131
+ # :data => data,
4132
+ # :columns => [
4133
+ # { :header => 'Product' },
4134
+ # { :header => 'Quarter 1' },
4135
+ # { :header => 'Quarter 2' },
4136
+ # { :header => 'Quarter 3' },
4137
+ # { :header => 'Quarter 4' },
4138
+ # {
4139
+ # :header => 'Year',
4140
+ # :formula => '=SUM(Table8[@[Quarter 1]:[Quarter 4]])'
4141
+ # }
4142
+ # ]
4143
+ # }
4144
+ # )
4145
+ #
4146
+ # The Excel 2007 [#This Row] and Excel 2010 @ structural references are
4147
+ # supported within the formula.
4148
+ #
4149
+ # As stated above the total_row table parameter turns on the "Total" row
4150
+ # in the table but it doesn't populate it with any defaults. Total
4151
+ # captions and functions must be specified via the columns property and
4152
+ # the total_string and total_function sub properties:
4153
+ #
4154
+ # worksheet10.add_table(
4155
+ # 'B3:F8',
4156
+ # {
4157
+ # :data => data,
4158
+ # :total_row => 1,
4159
+ # :columns => [
4160
+ # { :header => 'Product', total_string => 'Totals' },
4161
+ # { :header => 'Quarter 1', total_function => 'sum' },
4162
+ # { :header => 'Quarter 2', total_function => 'sum' },
4163
+ # { :header => 'Quarter 3', total_function => 'sum' },
4164
+ # { :header => 'Quarter 4', total_function => 'sum' }
4165
+ # ]
4166
+ # }
4167
+ # )
4168
+ #
4169
+ # The supported totals row SUBTOTAL functions are:
4170
+ #
4171
+ # average
4172
+ # count_nums
4173
+ # count
4174
+ # max
4175
+ # min
4176
+ # std_dev
4177
+ # sum
4178
+ # var
4179
+ #
4180
+ # User defined functions or formulas aren't supported.
4181
+ #
4182
+ # Format can also be applied to columns:
4183
+ #
4184
+ # currency_format = workbook.add_format(:num_format => '$#,##0')
4185
+ #
4186
+ # worksheet.add_table(
4187
+ # 'B3:D8',
4188
+ # {
4189
+ # :data => data,
4190
+ # :total_row => 1,
4191
+ # :columns => [
4192
+ # { :header => 'Product', :total_string => 'Totals' },
4193
+ # {
4194
+ # :header => 'Quarter 1',
4195
+ # :total_function => 'sum',
4196
+ # :format => $currency_format
4197
+ # },
4198
+ # {
4199
+ # :header => 'Quarter 2',
4200
+ # :total_function => 'sum',
4201
+ # :format => $currency_format
4202
+ # }
4203
+ # ]
4204
+ # }
4205
+ # )
4206
+ #
4207
+ # Standard WriteXLSX format objects can be used. However, they should be
4208
+ # limited to numerical formats. Overriding other table formatting may
4209
+ # produce inconsistent results.
4210
+ #
3854
4211
  def add_table(*args)
3855
4212
  # Table count is a member of Workbook, global to all Worksheet.
3856
4213
  @workbook.table_count += 1
3857
- table = Package::Table.new(self, @workbook.table_count, *args)
4214
+ id = @workbook.table_count
4215
+ table = Package::Table.new(self, id, *args)
3858
4216
 
3859
- @external_table_links << ['/table', "../tables/table#{table.id}.xml"]
4217
+ @external_table_links << ['/table', "../tables/table#{id}.xml"]
3860
4218
  @tables << table
3861
4219
  table
3862
4220
  end
@@ -3883,6 +4241,8 @@ module Writexlsx
3883
4241
  # }
3884
4242
  # )
3885
4243
  #
4244
+ # http://jmcnamara.github.com/excel-writer-xlsx/images/examples/sparklines1.jpg
4245
+ #
3886
4246
  # Note: Sparklines are a feature of Excel 2010+ only. You can write them
3887
4247
  # to an XLSX file that can be read by Excel 2007 but they won't be
3888
4248
  # displayed.
@@ -3929,108 +4289,135 @@ module Writexlsx
3929
4289
  #
3930
4290
  # This is the cell where the sparkline will be displayed:
3931
4291
  #
3932
- # location => 'F1'
3933
- # The location should be a single cell. (For multiple cells see "Grouped Sparklines" below).
4292
+ # :location => 'F1'
4293
+ #
4294
+ # The location should be a single cell. (For multiple cells see
4295
+ # {"Grouped Sparklines"}[#method-i-add_sparkline-label-Grouped+Sparklines]
4296
+ # below).
3934
4297
  #
3935
- # To specify the location in row-column notation use the xl_rowcol_to_cell() function from the Excel::Writer::XLSX::Utility module.
4298
+ # To specify the location in row-column notation use the
4299
+ # xl_rowcol_to_cell() function from the Writexlsx::Utility module.
3936
4300
  #
3937
- # use Excel::Writer::XLSX::Utility ':rowcol';
4301
+ # include Writexlsx::Utility
3938
4302
  # ...
3939
4303
  # location => xl_rowcol_to_cell( 0, 5 ), # F1
3940
- # range
4304
+ #
4305
+ # ===:range
3941
4306
  #
3942
4307
  # This specifies the cell data range that the sparkline will plot:
3943
4308
  #
3944
- # $worksheet->add_sparkline(
4309
+ # worksheet.add_sparkline(
3945
4310
  # {
3946
- # location => 'F1',
3947
- # range => 'A1:E1',
4311
+ # :location => 'F1',
4312
+ # :range => 'A1:E1'
3948
4313
  # }
3949
- # );
3950
- # The range should be a 2D array. (For 3D arrays of cells see "Grouped Sparklines" below).
4314
+ # )
3951
4315
  #
3952
- # If range is not on the same worksheet you can specify its location using the usual Excel notation:
4316
+ # The range should be a 2D array. (For 3D arrays of cells see
4317
+ # {"Grouped Sparklines"}[#method-i-add_sparkline-label-Grouped+Sparklines]
4318
+ # below).
3953
4319
  #
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:
4320
+ # If range is not on the same worksheet you can specify its location using
4321
+ # the usual Excel notation:
3956
4322
  #
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.
4323
+ # Lrange => 'Sheet1!A1:E1'
3959
4324
  #
3960
- # use Excel::Writer::XLSX::Utility ':rowcol';
3961
- # ...
4325
+ # If the worksheet contains spaces or special characters you should quote
4326
+ # the worksheet name in the same way that Excel does:
4327
+ #
4328
+ # :range => q('Monthly Data'!A1:E1)
4329
+ #
4330
+ # To specify the location in row-column notation use the xl_range() or
4331
+ # xl_range_formula() functions from the Writexlsx::Utility module.
4332
+ #
4333
+ # include Writexlsx::Utility
4334
+ # ...
3962
4335
  # range => xl_range( 1, 1, 0, 4 ), # 'A1:E1'
3963
4336
  # range => xl_range_formula( 'Sheet1', 0, 0, 0, 4 ), # 'Sheet1!A2:E2'
3964
- # type
4337
+ #
4338
+ # ===:type
3965
4339
  #
3966
4340
  # Specifies the type of sparkline. There are 3 available sparkline types:
3967
4341
  #
3968
- # line (default)
3969
- # column
3970
- # win_loss
4342
+ # :line (default)
4343
+ # :column
4344
+ # :win_loss
4345
+ #
3971
4346
  # For example:
3972
4347
  #
3973
4348
  # {
3974
- # location => 'F1',
3975
- # range => 'A1:E1',
3976
- # type => 'column',
4349
+ # :location => 'F1',
4350
+ # :range => 'A1:E1',
4351
+ # :type => 'column'
3977
4352
  # }
3978
- # style
3979
4353
  #
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.
4354
+ # ===:style
4355
+ #
4356
+ # Excel provides 36 built-in Sparkline styles in 6 groups of 6. The style
4357
+ # parameter can be used to replicate these and should be a corresponding
4358
+ # number from 1 .. 36.
3981
4359
  #
3982
4360
  # {
3983
- # location => 'A14',
3984
- # range => 'Sheet2!A2:J2',
3985
- # style => 3,
4361
+ # :location => 'A14',
4362
+ # :range => 'Sheet2!A2:J2',
4363
+ # :style => 3
3986
4364
  # }
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
4365
  #
3989
- # markers
4366
+ # The style number starts in the top left of the style grid and runs left
4367
+ # to right. The default style is 1. It is possible to override colour
4368
+ # elements of the sparklines using the *_color parameters below.
4369
+ #
4370
+ # ===:markers
3990
4371
  #
3991
4372
  # Turn on the markers for line style sparklines.
3992
4373
  #
3993
4374
  # {
3994
- # location => 'A6',
3995
- # range => 'Sheet2!A1:J1',
3996
- # markers => 1,
4375
+ # :location => 'A6',
4376
+ # :range => 'Sheet2!A1:J1',
4377
+ # :markers => 1
3997
4378
  # }
4379
+ #
3998
4380
  # Markers aren't shown in Excel for column and win_loss sparklines.
3999
4381
  #
4000
- # negative_points
4382
+ # ===:negative_points
4001
4383
  #
4002
- # Highlight negative values in a sparkline range. This is usually required with win_loss sparklines.
4384
+ # Highlight negative values in a sparkline range. This is usually required
4385
+ # with win_loss sparklines.
4003
4386
  #
4004
4387
  # {
4005
- # location => 'A21',
4006
- # range => 'Sheet2!A3:J3',
4007
- # type => 'win_loss',
4008
- # negative_points => 1,
4388
+ # :location => 'A21',
4389
+ # :range => 'Sheet2!A3:J3',
4390
+ # :type => 'win_loss',
4391
+ # :negative_points => 1
4009
4392
  # }
4010
- # axis
4393
+ #
4394
+ # ===:axis
4011
4395
  #
4012
4396
  # Display a horizontal axis in the sparkline:
4013
4397
  #
4014
4398
  # {
4015
- # location => 'A10',
4016
- # range => 'Sheet2!A1:J1',
4017
- # axis => 1,
4399
+ # :location => 'A10',
4400
+ # :range => 'Sheet2!A1:J1',
4401
+ # :axis => 1
4018
4402
  # }
4019
- # reverse
4403
+ #
4404
+ # ===:reverse
4020
4405
  #
4021
4406
  # Plot the data from right-to-left instead of the default left-to-right:
4022
4407
  #
4023
4408
  # {
4024
- # location => 'A24',
4025
- # range => 'Sheet2!A4:J4',
4026
- # type => 'column',
4027
- # reverse => 1,
4409
+ # :location => 'A24',
4410
+ # :range => 'Sheet2!A4:J4',
4411
+ # :type => 'column',
4412
+ # :reverse => 1
4028
4413
  # }
4029
- # weight
4414
+ #
4415
+ # ===:weight
4030
4416
  #
4031
4417
  # Adjust the default line weight (thickness) for line style sparklines.
4032
4418
  #
4033
- # weight => 0.25,
4419
+ # :weight => 0.25
4420
+ #
4034
4421
  # The weight value should be one of the following values allowed by Excel:
4035
4422
  #
4036
4423
  # 0.25 0.5 0.75
@@ -4039,107 +4426,110 @@ module Writexlsx
4039
4426
  # 3
4040
4427
  # 4.25
4041
4428
  # 6
4042
- # high_point, low_point, first_point, last_point
4429
+ #
4430
+ # ===:high_point, low_point, first_point, last_point
4043
4431
  #
4044
4432
  # Highlight points in a sparkline range.
4045
4433
  #
4046
- # high_point => 1,
4047
- # low_point => 1,
4048
- # first_point => 1,
4049
- # last_point => 1,
4050
- # max, min
4434
+ # :high_point => 1,
4435
+ # :low_point => 1,
4436
+ # :first_point => 1,
4437
+ # :last_point => 1
4438
+ #
4439
+ # ===:max, min
4051
4440
  #
4052
4441
  # Specify the maximum and minimum vertical axis values:
4053
4442
  #
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:
4443
+ # :max => 0.5,
4444
+ # :min => -0.5
4445
+ #
4446
+ # As a special case you can set the maximum and minimum to be for a group
4447
+ # of sparklines rather than one:
4057
4448
  #
4058
- # max => 'group',
4059
- # See "Grouped Sparklines" below.
4449
+ # max => 'group'
4450
+ # See
4451
+ # {"Grouped Sparklines"}[#method-i-add_sparkline-label-Grouped+Sparklines]
4452
+ # below.
4060
4453
  #
4061
- # empty_cells
4454
+ # ===:empty_cells
4062
4455
  #
4063
4456
  # Define how empty cells are handled in a sparkline.
4064
4457
  #
4065
- # empty_cells => 'zero',
4458
+ # :empty_cells => 'zero',
4459
+ #
4066
4460
  # The available options are:
4067
4461
  #
4068
4462
  # gaps : show empty cells as gaps (the default).
4069
4463
  # zero : plot empty cells as 0.
4070
4464
  # connect: Connect points with a line ("line" type sparklines only).
4071
- # show_hidden
4465
+ #
4466
+ # ===:show_hidden
4072
4467
  #
4073
4468
  # Plot data in hidden rows and columns:
4074
4469
  #
4075
- # show_hidden => 1,
4470
+ # :show_hidden => 1
4471
+ #
4076
4472
  # Note, this option is off by default.
4077
4473
  #
4078
- # date_axis
4474
+ # ===:date_axis
4079
4475
  #
4080
- # Specify an alternative date axis for the sparkline. This is useful if the data being plotted isn't at fixed width intervals:
4476
+ # Specify an alternative date axis for the sparkline. This is useful if
4477
+ # the data being plotted isn't at fixed width intervals:
4081
4478
  #
4082
4479
  # {
4083
- # location => 'F3',
4084
- # range => 'A3:E3',
4085
- # date_axis => 'A4:E4',
4480
+ # :location => 'F3',
4481
+ # :range => 'A3:E3',
4482
+ # :date_axis => 'A4:E4'
4086
4483
  # }
4087
- # The number of cells in the date range should correspond to the number of cells in the data range.
4088
4484
  #
4089
- # series_color
4485
+ # The number of cells in the date range should correspond to the number
4486
+ # of cells in the data range.
4090
4487
  #
4091
- # It is possible to override the colour of a sparkline style using the following parameters:
4488
+ # ===:series_color
4489
+ #
4490
+ # It is possible to override the colour of a sparkline style using the
4491
+ # following parameters:
4492
+ #
4493
+ # :series_color
4494
+ # :negative_color
4495
+ # :markers_color
4496
+ # :first_color
4497
+ # :last_color
4498
+ # :high_color
4499
+ # :low_color
4092
4500
  #
4093
- # series_color
4094
- # negative_color
4095
- # markers_color
4096
- # first_color
4097
- # last_color
4098
- # high_color
4099
- # low_color
4100
4501
  # The color should be specified as a HTML style #rrggbb hex value:
4101
4502
  #
4102
4503
  # {
4103
- # location => 'A18',
4104
- # range => 'Sheet2!A2:J2',
4105
- # type => 'column',
4106
- # series_color => '#E965E0',
4504
+ # :location => 'A18',
4505
+ # :range => 'Sheet2!A2:J2',
4506
+ # :type => 'column',
4507
+ # :series_color => '#E965E0'
4107
4508
  # }
4108
- # Grouped Sparklines
4109
4509
  #
4110
- # The add_sparkline() worksheet method can be used multiple times to write as many sparklines as are required in a worksheet.
4510
+ # ==Grouped Sparklines
4111
4511
  #
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.
4512
+ # The add_sparkline() worksheet method can be used multiple times to write
4513
+ # as many sparklines as are required in a worksheet.
4113
4514
  #
4114
- # In Excel::Writer::XLSX, you can simulate this by passing an array refs of values to location and range:
4515
+ # However, it is sometimes necessary to group contiguous sparklines so that
4516
+ # changes that are applied to one are applied to all. In Excel this is
4517
+ # achieved by selecting a 3D range of cells for the data range and a
4518
+ # 2D range of cells for the location.
4519
+ #
4520
+ # In WriteXLSX, you can simulate this by passing an array of values to
4521
+ # location and range:
4115
4522
  #
4116
4523
  # {
4117
- # location => [ 'A27', 'A28', 'A29' ],
4118
- # range => [ 'Sheet2!A5:J5', 'Sheet2!A6:J6', 'Sheet2!A7:J7' ],
4119
- # markers => 1,
4524
+ # :location => [ 'A27', 'A28', 'A29' ],
4525
+ # :range => [ 'Sheet2!A5:J5', 'Sheet2!A6:J6', 'Sheet2!A7:J7' ],
4526
+ # :markers => 1
4120
4527
  # }
4121
- # Sparkline examples
4122
- #
4123
- # See the sparklines1.pl and sparklines2.pl example programs in the examples directory of the distro.
4124
- #
4125
- # The add_sparkline worksheet method is used to add sparklines to a cell or a range of cells.
4126
4528
  #
4127
- # worksheet.add_sparkline(
4128
- # {
4129
- # :location => 'F2',
4130
- # :range => 'Sheet1!A2:E2',
4131
- # :type => 'column',
4132
- # :style => 12
4133
- # }
4134
- # )
4529
+ # ===Sparkline examples
4135
4530
  #
4136
- # See also the sparklines1.rb and sparklines2.rb example programs in the examples directory of the distro.
4137
- #
4138
- # Note: Sparklines are a feature of Excel 2010+ only.
4139
- # You can write them to an XLSX file that can be read by Excel 2007 but they won't be displayed.
4140
- #
4141
- # Sparklines are a feature of Excel 2010+ which allows you to add small charts to worksheet cells.
4142
- # These are useful for showing visual trends in data in a compact format.
4531
+ # See the sparklines1.rb and sparklines2.rb example programs in the
4532
+ # examples directory of the distro.
4143
4533
  #
4144
4534
  def add_sparkline(param)
4145
4535
  @sparklines << Sparkline.new(self, param, quote_sheetname(@name))
@@ -4331,62 +4721,78 @@ module Writexlsx
4331
4721
  # :length
4332
4722
  # :custom
4333
4723
  #
4334
- # :any is used to specify that the type of data is unrestricted.
4724
+ # +:any+ is used to specify that the type of data is unrestricted.
4335
4725
  # This is the same as not applying a data validation. It is only
4336
4726
  # provided for completeness and isn't used very often in the
4337
4727
  # context of WriteXLSX.
4338
4728
  #
4339
- # :integer restricts the cell to integer values. Excel refers to this
4729
+ # +:integer+ restricts the cell to integer values. Excel refers to this
4340
4730
  # as 'whole number'.
4731
+ #
4341
4732
  # :validate => 'integer',
4342
4733
  # :criteria => '>',
4343
4734
  # :value => 100,
4344
- # :decimal restricts the cell to decimal values.
4735
+ #
4736
+ # +:decimal+ restricts the cell to decimal values.
4737
+ #
4345
4738
  # :validate => 'decimal',
4346
4739
  # :criteria => '>',
4347
4740
  # :value => 38.6,
4348
- # :list restricts the cell to a set of user specified values. These
4741
+ #
4742
+ # +:list+ restricts the cell to a set of user specified values. These
4349
4743
  # can be passed in an array ref or as a cell range (named ranges aren't
4350
4744
  # currently supported):
4745
+ #
4351
4746
  # :validate => 'list',
4352
4747
  # :value => ['open', 'high', 'close'],
4353
4748
  # # Or like this:
4354
4749
  # :value => 'B1:B3',
4750
+ #
4355
4751
  # Excel requires that range references are only to cells on the same
4356
4752
  # worksheet.
4357
4753
  #
4358
- # :date restricts the cell to date values. Dates in Excel are expressed
4754
+ # +:date+ restricts the cell to date values. Dates in Excel are expressed
4359
4755
  # as integer values but you can also pass an ISO860 style string as used
4360
- # in write_date_time(). See also "DATES AND TIME IN EXCEL" for more
4361
- # information about working with Excel's dates.
4756
+ # in write_date_time(). See also
4757
+ # {"DATES AND TIME IN EXCEL"}[#method-i-write_date_time-label-DATES+AND+TIME+IN+EXCEL]
4758
+ # for more information about working with Excel's dates.
4759
+ #
4362
4760
  # :validate => 'date',
4363
4761
  # :criteria => '>',
4364
4762
  # :value => 39653, # 24 July 2008
4365
4763
  # # Or like this:
4366
4764
  # :value => '2008-07-24T',
4367
- # :time restricts the cell to time values. Times in Excel are expressed
4765
+ #
4766
+ # +:time+ restricts the cell to time values. Times in Excel are expressed
4368
4767
  # as decimal values but you can also pass an ISO860 style string as used
4369
- # in write_date_time(). See also "DATES AND TIME IN EXCEL" for more
4370
- # information about working with Excel's times.
4768
+ # in write_date_time(). See also
4769
+ # {"DATES AND TIME IN EXCEL"}[#method-i-write_date_time-label-DATES+AND+TIME+IN+EXCEL]
4770
+ # for more information about working with Excel's times.
4771
+ #
4371
4772
  # :validate => 'time',
4372
4773
  # :criteria => '>',
4373
4774
  # :value => 0.5, # Noon
4374
4775
  # # Or like this:
4375
4776
  # :value => 'T12:00:00',
4376
- # :length restricts the cell data based on an integer string length.
4777
+ #
4778
+ # +:length+ restricts the cell data based on an integer string length.
4377
4779
  # Excel refers to this as 'Text length'.
4780
+ #
4378
4781
  # :validate => 'length',
4379
4782
  # :criteria => '>',
4380
4783
  # :value => 10,
4381
- # :custom restricts the cell based on an external Excel formula
4784
+ #
4785
+ # +:custom+ restricts the cell based on an external Excel formula
4382
4786
  # that returns a TRUE/FALSE value.
4787
+ #
4383
4788
  # :validate => 'custom',
4384
4789
  # :value => '=IF(A10>B10,TRUE,FALSE)',
4790
+ #
4385
4791
  # ===criteria
4386
4792
  #
4387
4793
  # This parameter is passed in a hash ref to data_validation().
4388
4794
  #
4389
- # The criteria parameter is used to set the criteria by which the data
4795
+ # The +:criteria+ parameter is used to set the criteria by which the data
4390
4796
  # in the cell is validated. It is almost always required except for
4391
4797
  # the list and custom validate options. It has no default value.
4392
4798
  # Allowable values are:
@@ -4420,9 +4826,10 @@ module Writexlsx
4420
4826
  #
4421
4827
  # :validate => 'custom',
4422
4828
  # :value => '=IF(A10>B10,TRUE,FALSE)',
4423
- # ===value | minimum | source
4424
4829
  #
4425
- # This parameter is passed in a hash ref to data_validation().
4830
+ # ===:value | :minimum | :source
4831
+ #
4832
+ # This parameter is passed in a hash to data_validation().
4426
4833
  #
4427
4834
  # The value parameter is used to set the limiting value to which the
4428
4835
  # criteria is applied. It is always required and it has no default value.
@@ -4443,54 +4850,59 @@ module Writexlsx
4443
4850
  # # Use 'source'
4444
4851
  # :validate => 'list',
4445
4852
  # :source => '$B$1:$B$3',
4446
- # ===maximum
4853
+ #
4854
+ # ===:maximum
4447
4855
  #
4448
4856
  # This parameter is passed in a hash ref to data_validation().
4449
4857
  #
4450
- # The maximum parameter is used to set the upper limiting value when
4858
+ # The +:maximum: parameter is used to set the upper limiting value when
4451
4859
  # the criteria is either 'between' or 'not between':
4452
4860
  #
4453
4861
  # :validate => 'integer',
4454
4862
  # :criteria => 'between',
4455
4863
  # :minimum => 1,
4456
4864
  # :maximum => 100,
4457
- # ===ignore_blank
4865
+ #
4866
+ # ===:ignore_blank
4458
4867
  #
4459
4868
  # This parameter is passed in a hash ref to data_validation().
4460
4869
  #
4461
- # The ignore_blank parameter is used to toggle on and off the
4870
+ # The +:ignore_blank+ parameter is used to toggle on and off the
4462
4871
  # 'Ignore blank' option in the Excel data validation dialog. When the
4463
4872
  # option is on the data validation is not applied to blank data in the
4464
4873
  # cell. It is on by default.
4465
4874
  #
4466
4875
  # :ignore_blank => 0, # Turn the option off
4467
- # ===dropdown
4876
+ #
4877
+ # ===:dropdown
4468
4878
  #
4469
4879
  # This parameter is passed in a hash ref to data_validation().
4470
4880
  #
4471
- # The dropdown parameter is used to toggle on and off the
4881
+ # The +:dropdown+ parameter is used to toggle on and off the
4472
4882
  # 'In-cell dropdown' option in the Excel data validation dialog.
4473
4883
  # When the option is on a dropdown list will be shown for list validations.
4474
4884
  # It is on by default.
4475
4885
  #
4476
4886
  # :dropdown => 0, # Turn the option off
4477
- # ===input_title
4887
+ #
4888
+ # ===:input_title
4478
4889
  #
4479
4890
  # This parameter is passed in a hash ref to data_validation().
4480
4891
  #
4481
- # The input_title parameter is used to set the title of the input
4892
+ # The +:input_title+ parameter is used to set the title of the input
4482
4893
  # message that is displayed when a cell is entered. It has no default
4483
4894
  # value and is only displayed if the input message is displayed.
4484
4895
  # See the input_message parameter below.
4485
4896
  #
4486
4897
  # :input_title => 'This is the input title',
4898
+ #
4487
4899
  # The maximum title length is 32 characters.
4488
4900
  #
4489
- # ===input_message
4901
+ # ===:input_message
4490
4902
  #
4491
4903
  # This parameter is passed in a hash ref to data_validation().
4492
4904
  #
4493
- # The input_message parameter is used to set the input message that
4905
+ # The +:input_message+ parameter is used to set the input message that
4494
4906
  # is displayed when a cell is entered. It has no default value.
4495
4907
  #
4496
4908
  # :validate => 'integer',
@@ -4507,22 +4919,22 @@ module Writexlsx
4507
4919
  #
4508
4920
  # The maximum message length is 255 characters.
4509
4921
  #
4510
- # ===show_input
4922
+ # ===:show_input
4511
4923
  #
4512
4924
  # This parameter is passed in a hash ref to data_validation().
4513
4925
  #
4514
- # The show_input parameter is used to toggle on and off the 'Show input
4926
+ # The +:show_input+ parameter is used to toggle on and off the 'Show input
4515
4927
  # message when cell is selected' option in the Excel data validation
4516
4928
  # dialog. When the option is off an input message is not displayed even
4517
4929
  # if it has been set using input_message. It is on by default.
4518
4930
  #
4519
4931
  # :show_input => 0, # Turn the option off
4520
4932
  #
4521
- # ===error_title
4933
+ # ===:error_title
4522
4934
  #
4523
4935
  # This parameter is passed in a hash ref to data_validation().
4524
4936
  #
4525
- # The error_title parameter is used to set the title of the error message
4937
+ # The +:error_title+ parameter is used to set the title of the error message
4526
4938
  # that is displayed when the data validation criteria is not met.
4527
4939
  # The default error title is 'Microsoft Excel'.
4528
4940
  #
@@ -4530,11 +4942,11 @@ module Writexlsx
4530
4942
  #
4531
4943
  # The maximum title length is 32 characters.
4532
4944
  #
4533
- # ===error_message
4945
+ # ===:error_message
4534
4946
  #
4535
4947
  # This parameter is passed in a hash ref to data_validation().
4536
4948
  #
4537
- # The error_message parameter is used to set the error message that is
4949
+ # The +:error_message+ parameter is used to set the error message that is
4538
4950
  # displayed when a cell is entered. The default error message is
4539
4951
  # "The value you entered is not valid.\nA user has restricted values
4540
4952
  # that can be entered into the cell.".
@@ -4553,11 +4965,12 @@ module Writexlsx
4553
4965
  #
4554
4966
  # The maximum message length is 255 characters.
4555
4967
  #
4556
- # ===error_type
4968
+ # ===:error_type
4557
4969
  #
4558
4970
  # This parameter is passed in a hash ref to data_validation().
4559
4971
  #
4560
- # The error_type parameter is used to specify the type of error dialog that is displayed. There are 3 options:
4972
+ # The +:error_type+ parameter is used to specify the type of error dialog
4973
+ # that is displayed. There are 3 options:
4561
4974
  #
4562
4975
  # 'stop'
4563
4976
  # 'warning'
@@ -4565,11 +4978,11 @@ module Writexlsx
4565
4978
  #
4566
4979
  # The default is 'stop'.
4567
4980
  #
4568
- # ===show_error
4981
+ # ===:show_error
4569
4982
  #
4570
4983
  # This parameter is passed in a hash ref to data_validation().
4571
4984
  #
4572
- # The show_error parameter is used to toggle on and off the 'Show error
4985
+ # The +:show_error+ parameter is used to toggle on and off the 'Show error
4573
4986
  # alert after invalid data is entered' option in the Excel data validation
4574
4987
  # dialog. When the option is off an error message is not displayed
4575
4988
  # even if it has been set using error_message. It is on by default.
@@ -4578,7 +4991,7 @@ module Writexlsx
4578
4991
  #
4579
4992
  # ===Data Validation Examples
4580
4993
  #
4581
- # ====Example 1. Limiting input to an integer greater than a fixed value.
4994
+ # ===Example 1. Limiting input to an integer greater than a fixed value.
4582
4995
  #
4583
4996
  # worksheet.data_validation('A1',
4584
4997
  # {
@@ -4586,7 +4999,7 @@ module Writexlsx
4586
4999
  # :criteria => '>',
4587
5000
  # :value => 0,
4588
5001
  # });
4589
- # ====Example 2. Limiting input to an integer greater than a fixed value where the value is referenced from a cell.
5002
+ # ===Example 2. Limiting input to an integer greater than a fixed value where the value is referenced from a cell.
4590
5003
  #
4591
5004
  # worksheet.data_validation('A2',
4592
5005
  # {
@@ -4594,7 +5007,7 @@ module Writexlsx
4594
5007
  # :criteria => '>',
4595
5008
  # :value => '=E3',
4596
5009
  # });
4597
- # ====Example 3. Limiting input to a decimal in a fixed range.
5010
+ # ===Example 3. Limiting input to a decimal in a fixed range.
4598
5011
  #
4599
5012
  # worksheet.data_validation('A3',
4600
5013
  # {
@@ -4603,21 +5016,21 @@ module Writexlsx
4603
5016
  # :minimum => 0.1,
4604
5017
  # :maximum => 0.5,
4605
5018
  # });
4606
- # ====Example 4. Limiting input to a value in a dropdown list.
5019
+ # ===Example 4. Limiting input to a value in a dropdown list.
4607
5020
  #
4608
5021
  # worksheet.data_validation('A4',
4609
5022
  # {
4610
5023
  # :validate => 'list',
4611
5024
  # :source => ['open', 'high', 'close'],
4612
5025
  # });
4613
- # ====Example 5. Limiting input to a value in a dropdown list where the list is specified as a cell range.
5026
+ # ===Example 5. Limiting input to a value in a dropdown list where the list is specified as a cell range.
4614
5027
  #
4615
5028
  # worksheet.data_validation('A5',
4616
5029
  # {
4617
5030
  # :validate => 'list',
4618
5031
  # :source => '=$E$4:$G$4',
4619
5032
  # });
4620
- # ====Example 6. Limiting input to a date in a fixed range.
5033
+ # ===Example 6. Limiting input to a date in a fixed range.
4621
5034
  #
4622
5035
  # worksheet.data_validation('A6',
4623
5036
  # {
@@ -4626,7 +5039,7 @@ module Writexlsx
4626
5039
  # :minimum => '2008-01-01T',
4627
5040
  # :maximum => '2008-12-12T',
4628
5041
  # });
4629
- # ====Example 7. Displaying a message when the cell is selected.
5042
+ # ===Example 7. Displaying a message when the cell is selected.
4630
5043
  #
4631
5044
  # worksheet.data_validation('A7',
4632
5045
  # {
@@ -4641,50 +5054,8 @@ module Writexlsx
4641
5054
  # of the distro.
4642
5055
  #
4643
5056
  def data_validation(*args)
4644
- # Check for a cell reference in A1 notation and substitute row and column.
4645
- row1, col1, row2, col2, options = row_col_notation(args)
4646
- if row2.respond_to?(:keys)
4647
- param = row2.dup
4648
- row2, col2 = row1, col1
4649
- elsif options.respond_to?(:keys)
4650
- param = options.dup
4651
- else
4652
- raise WriteXLSXInsufficientArgumentError
4653
- end
4654
- raise WriteXLSXInsufficientArgumentError if [row1, col1, row2, col2, param].include?(nil)
4655
-
4656
- check_dimensions(row1, col1)
4657
- check_dimensions(row2, col2)
4658
-
4659
- check_for_valid_input_params(param)
4660
-
4661
- param[:value] = param[:source] if param[:source]
4662
- param[:value] = param[:minimum] if param[:minimum]
4663
-
4664
- param[:validate] = valid_validation_type[param[:validate].downcase]
4665
- return if param[:validate] == 'none'
4666
- if ['list', 'custom'].include?(param[:validate])
4667
- param[:criteria] = 'between'
4668
- param[:maximum] = nil
4669
- end
4670
-
4671
- check_criteria_required(param)
4672
- check_valid_citeria_types(param)
4673
- param[:criteria] = valid_criteria_type[param[:criteria].downcase]
4674
-
4675
- check_maximum_value_when_criteria_is_between_or_notbetween(param)
4676
- param[:error_type] = param.has_key?(:error_type) ? error_type[param[:error_type].downcase] : 0
4677
-
4678
- convert_date_time_value_if_required(param)
4679
- set_some_defaults(param)
4680
-
4681
- param[:cells] = [[row1, col1, row2, col2]]
4682
-
4683
- # A (for now) undocumented parameter to pass additional cell ranges.
4684
- param[:other_cells].each { |cells| param[:cells] << cells } if param.has_key?(:other_cells)
4685
-
4686
- # Store the validation information until we close the worksheet.
4687
- @validations << param
5057
+ validation = DataValidation.new(*args)
5058
+ @validations << validation unless validation.validate_none?
4688
5059
  end
4689
5060
 
4690
5061
  #
@@ -4711,17 +5082,13 @@ module Writexlsx
4711
5082
  # is true, i.e. only the printed gridlines are hidden.
4712
5083
  #
4713
5084
  def hide_gridlines(option = 1)
4714
- if option == 0 || !option
4715
- @print_gridlines = true # 1 = display, 0 = hide
4716
- @screen_gridlines = true
4717
- @print_options_changed = true
4718
- elsif option == 1
4719
- @print_gridlines = false
4720
- @screen_gridlines = true
4721
- else
4722
- @print_gridlines = false
5085
+ if option == 2
4723
5086
  @screen_gridlines = false
5087
+ else
5088
+ @screen_gridlines = true
4724
5089
  end
5090
+
5091
+ @page_setup.hide_gridlines(option)
4725
5092
  end
4726
5093
 
4727
5094
  # Set the option to print the row and column headers on the printed page.
@@ -4748,13 +5115,14 @@ module Writexlsx
4748
5115
  # Do not confuse these headers with page headers as described in the
4749
5116
  # set_header() section above.
4750
5117
  #
4751
- def print_row_col_headers(headers = 1)
4752
- if headers
4753
- @print_headers = 1
4754
- @print_options_changed = 1
4755
- else
4756
- @print_headers = 0
4757
- end
5118
+ def print_row_col_headers(headers = true)
5119
+ @page_setup.print_row_col_headers(headers)
5120
+ # if headers
5121
+ # @print_headers = 1
5122
+ # @page_setup.print_options_changed = 1
5123
+ # else
5124
+ # @print_headers = 0
5125
+ # end
4758
5126
  end
4759
5127
 
4760
5128
  #
@@ -4785,10 +5153,10 @@ module Writexlsx
4785
5153
  # are defined in the worksheet.
4786
5154
  #
4787
5155
  def fit_to_pages(width = 1, height = 1)
4788
- @print_style.fit_page = true
4789
- @print_style.fit_width = width
4790
- @print_style.fit_height = height
4791
- @print_style.page_setup_changed = true
5156
+ @page_setup.fit_page = true
5157
+ @page_setup.fit_width = width
5158
+ @page_setup.fit_height = height
5159
+ @page_setup.page_setup_changed = true
4792
5160
  end
4793
5161
 
4794
5162
  #
@@ -4834,7 +5202,7 @@ module Writexlsx
4834
5202
  #
4835
5203
  # NOTE: It isn't sufficient to just specify the filter condition.
4836
5204
  # You must also hide any rows that don't match the filter condition.
4837
- # Rows are hidden using the set_row() visible parameter. WriteXLSX cannot
5205
+ # Rows are hidden using the set_row() +visible+ parameter. WriteXLSX cannot
4838
5206
  # do this automatically since it isn't part of the file format.
4839
5207
  # See the autofilter.rb program in the examples directory of the distro
4840
5208
  # for an example.
@@ -4844,7 +5212,7 @@ module Writexlsx
4844
5212
  # worksheet.filter_column('A', 'x > 2000')
4845
5213
  # worksheet.filter_column('B', 'x > 2000 and x < 5000')
4846
5214
  #
4847
- # The column parameter can either be a zero indexed column number or
5215
+ # The +column+ parameter can either be a zero indexed column number or
4848
5216
  # a string column name.
4849
5217
  #
4850
5218
  # The following operators are available:
@@ -4865,7 +5233,7 @@ module Writexlsx
4865
5233
  # the expressions will be interpreted by Excel and not by ruby.
4866
5234
  #
4867
5235
  # An expression can comprise a single statement or two statements
4868
- # separated by the and and or operators. For example:
5236
+ # separated by the +and+ and +or+ operators. For example:
4869
5237
  #
4870
5238
  # 'x < 2000'
4871
5239
  # 'x > 2000'
@@ -4874,7 +5242,7 @@ module Writexlsx
4874
5242
  # 'x == 2000 or x == 5000'
4875
5243
  #
4876
5244
  # Filtering of blank or non-blank data can be achieved by using a value
4877
- # of Blanks or NonBlanks in the expression:
5245
+ # of +Blanks+ or +NonBlanks+ in the expression:
4878
5246
  #
4879
5247
  # 'x == Blanks'
4880
5248
  # 'x == NonBlanks'
@@ -4891,9 +5259,9 @@ module Writexlsx
4891
5259
  # You can also use * to match any character or number and ? to match any
4892
5260
  # single character or number. No other regular expression quantifier is
4893
5261
  # supported by Excel's filters. Excel's regular expression characters can
4894
- # be escaped using ~.
5262
+ # be escaped using +~+.
4895
5263
  #
4896
- # The placeholder variable x in the above examples can be replaced by any
5264
+ # The placeholder variable +x+ in the above examples can be replaced by any
4897
5265
  # simple string. The actual placeholder name is ignored internally so the
4898
5266
  # following are all equivalent:
4899
5267
  #
@@ -4907,7 +5275,7 @@ module Writexlsx
4907
5275
  # See the autofilter.rb program in the examples directory of the distro
4908
5276
  # for a more detailed example.
4909
5277
  #
4910
- # Note Spreadsheet::WriteExcel supports Top 10 style filters. These aren't
5278
+ # Note writeExcel gem supports Top 10 style filters. These aren't
4911
5279
  # currently supported by WriteXLSX but may be added later.
4912
5280
  #
4913
5281
  def filter_column(col, expression)
@@ -5023,7 +5391,7 @@ module Writexlsx
5023
5391
  breaks = args.collect do |brk|
5024
5392
  Array(brk)
5025
5393
  end.flatten
5026
- @print_style.hbreaks += breaks
5394
+ @page_setup.hbreaks += breaks
5027
5395
  end
5028
5396
 
5029
5397
  #
@@ -5048,7 +5416,7 @@ module Writexlsx
5048
5416
  # method it will override all manual page breaks.
5049
5417
  #
5050
5418
  def set_v_pagebreaks(*args)
5051
- @print_style.vbreaks += args
5419
+ @page_setup.vbreaks += args
5052
5420
  end
5053
5421
 
5054
5422
  #
@@ -5292,14 +5660,6 @@ module Writexlsx
5292
5660
  !!@comments_visible
5293
5661
  end
5294
5662
 
5295
- def comments_xml_writer=(file) # :nodoc:
5296
- @comments.set_xml_writer(file)
5297
- end
5298
-
5299
- def comments_assemble_xml_file # :nodoc:
5300
- @comments.assemble_xml_file
5301
- end
5302
-
5303
5663
  def comments_array # :nodoc:
5304
5664
  @comments.sorted_comments
5305
5665
  end
@@ -5324,9 +5684,7 @@ module Writexlsx
5324
5684
  # Write the cell array formula <f> element.
5325
5685
  #
5326
5686
  def write_cell_array_formula(formula, range) #:nodoc:
5327
- attributes = ['t', 'array', 'ref', range]
5328
-
5329
- @writer.data_element('f', formula, attributes)
5687
+ @writer.data_element('f', formula, ['t', 'array', 'ref', range])
5330
5688
  end
5331
5689
 
5332
5690
  def date_1904? #:nodoc:
@@ -5356,6 +5714,20 @@ module Writexlsx
5356
5714
  @buttons_array
5357
5715
  end
5358
5716
 
5717
+ def external_links
5718
+ [
5719
+ @external_hyper_links,
5720
+ @external_drawing_links,
5721
+ @external_vml_links,
5722
+ @external_table_links,
5723
+ @external_comment_links
5724
+ ].reject { |a| a.empty? }
5725
+ end
5726
+
5727
+ def drawing_links
5728
+ [@drawing_links]
5729
+ end
5730
+
5359
5731
  #
5360
5732
  # Turn the HoH that stores the comments into an array for easier handling
5361
5733
  # and set the external links for comments and buttons.
@@ -5384,106 +5756,21 @@ module Writexlsx
5384
5756
  count
5385
5757
  end
5386
5758
 
5387
- private
5388
-
5389
- def check_for_valid_input_params(param)
5390
- check_parameter(param, valid_validation_parameter, 'data_validation')
5391
-
5392
- unless param.has_key?(:validate)
5393
- raise WriteXLSXOptionParameterError, "Parameter :validate is required in data_validation()"
5394
- end
5395
- unless valid_validation_type.has_key?(param[:validate].downcase)
5396
- raise WriteXLSXOptionParameterError,
5397
- "Unknown validation type '#{param[:validate]}' for parameter :validate in data_validation()"
5398
- end
5399
- if param[:error_type] && !error_type.has_key?(param[:error_type].downcase)
5400
- raise WriteXLSXOptionParameterError,
5401
- "Unknown criteria type '#param[:error_type}' for parameter :error_type in data_validation()"
5402
- end
5759
+ def tables_count
5760
+ @tables.size
5403
5761
  end
5404
5762
 
5405
- def check_criteria_required(param)
5406
- unless param.has_key?(:criteria)
5407
- raise WriteXLSXOptionParameterError, "Parameter :criteria is required in data_validation()"
5408
- end
5409
- end
5410
-
5411
- def check_valid_citeria_types(param)
5412
- unless valid_criteria_type.has_key?(param[:criteria].downcase)
5413
- raise WriteXLSXOptionParameterError,
5414
- "Unknown criteria type '#{param[:criteria]}' for parameter :criteria in data_validation()"
5415
- end
5416
- end
5763
+ private
5417
5764
 
5418
- def check_maximum_value_when_criteria_is_between_or_notbetween(param)
5419
- if param[:criteria] == 'between' || param[:criteria] == 'notBetween'
5420
- unless param.has_key?(:maximum)
5421
- raise WriteXLSXOptionParameterError,
5422
- "Parameter :maximum is required in data_validation() when using :between or :not between criteria"
5423
- end
5765
+ def cell_format_of_rich_string(rich_strings)
5766
+ # If the last arg is a format we use it as the cell format.
5767
+ if rich_strings[-1].respond_to?(:xf_index)
5768
+ rich_strings.pop
5424
5769
  else
5425
- param[:maximum] = nil
5426
- end
5427
- end
5428
-
5429
- def error_type
5430
- {'stop' => 0, 'warning' => 1, 'information' => 2}
5431
- end
5432
-
5433
- def convert_date_time_value_if_required(param)
5434
- if param[:validate] == 'date' || param[:validate] == 'time'
5435
- unless convert_date_time_value(param, :value) && convert_date_time_value(param, :maximum)
5436
- raise WriteXLSXOptionParameterError, "Invalid date/time value."
5437
- end
5770
+ nil
5438
5771
  end
5439
5772
  end
5440
5773
 
5441
- def set_some_defaults(param)
5442
- param[:ignore_blank] ||= 1
5443
- param[:dropdown] ||= 1
5444
- param[:show_input] ||= 1
5445
- param[:show_error] ||= 1
5446
- end
5447
-
5448
- # List of valid input parameters.
5449
- def valid_validation_parameter
5450
- [
5451
- :validate,
5452
- :criteria,
5453
- :value,
5454
- :source,
5455
- :minimum,
5456
- :maximum,
5457
- :ignore_blank,
5458
- :dropdown,
5459
- :show_input,
5460
- :input_title,
5461
- :input_message,
5462
- :show_error,
5463
- :error_title,
5464
- :error_message,
5465
- :error_type,
5466
- :other_cells
5467
- ]
5468
- end
5469
-
5470
- def valid_validation_type # :nodoc:
5471
- {
5472
- 'any' => 'none',
5473
- 'any value' => 'none',
5474
- 'whole number' => 'whole',
5475
- 'whole' => 'whole',
5476
- 'integer' => 'whole',
5477
- 'decimal' => 'decimal',
5478
- 'list' => 'list',
5479
- 'date' => 'date',
5480
- 'time' => 'time',
5481
- 'text length' => 'textLength',
5482
- 'length' => 'textLength',
5483
- 'custom' => 'custom'
5484
- }
5485
- end
5486
-
5487
5774
  # Convert the list of format, string tokens to pairs of (format, string)
5488
5775
  # except for the first string fragment which doesn't require a default
5489
5776
  # formatting run. Use the default for strings without a leading format.
@@ -5522,6 +5809,32 @@ module Writexlsx
5522
5809
  [fragments, length]
5523
5810
  end
5524
5811
 
5812
+ def xml_str_of_rich_string(fragments)
5813
+ # Create a temp XML::Writer object and use it to write the rich string
5814
+ # XML to a string.
5815
+ writer = Package::XMLWriterSimple.new
5816
+
5817
+ # If the first token is a string start the <r> element.
5818
+ writer.start_tag('r') if !fragments[0].respond_to?(:xf_index)
5819
+
5820
+ # Write the XML elements for the format string fragments.
5821
+ fragments.each do |token|
5822
+ if token.respond_to?(:xf_index)
5823
+ # Write the font run.
5824
+ writer.start_tag('r')
5825
+ token.write_font(writer, self)
5826
+ else
5827
+ # Write the string fragment part, with whitespace handling.
5828
+ attributes = []
5829
+
5830
+ attributes << 'xml:space' << 'preserve' if token =~ /^\s/ || token =~ /\s$/
5831
+ writer.data_element('t', token, attributes)
5832
+ writer.end_tag('r')
5833
+ end
5834
+ end
5835
+ writer.string
5836
+ end
5837
+
5525
5838
  # Pad out the rest of the area with formatted blank cells.
5526
5839
  def write_formatted_blank_to_area(row_first, row_last, col_first, col_last, format)
5527
5840
  (row_first .. row_last).each do |row|
@@ -5758,9 +6071,6 @@ module Writexlsx
5758
6071
  # we use the default value. If the column is hidden it has a value of zero.
5759
6072
  #
5760
6073
  def size_col(col) #:nodoc:
5761
- max_digit_width = 7 # For Calabri 11.
5762
- padding = 5
5763
-
5764
6074
  # Look up the cell value to see if it has been changed.
5765
6075
  if @col_sizes[col]
5766
6076
  width = @col_sizes[col]
@@ -5771,7 +6081,7 @@ module Writexlsx
5771
6081
  elsif width < 1
5772
6082
  pixels = (width * 12 + 0.5).to_i
5773
6083
  else
5774
- pixels = (width * max_digit_width + 0.5).to_i + padding
6084
+ pixels = (width * MAX_DIGIT_WIDTH + 0.5).to_i + PADDING
5775
6085
  end
5776
6086
  else
5777
6087
  pixels = 64
@@ -6033,35 +6343,31 @@ module Writexlsx
6033
6343
  #
6034
6344
  # Write the <worksheet> element. This is the root element of Worksheet.
6035
6345
  #
6036
- def write_worksheet #:nodoc:
6037
- schema = 'http://schemas.openxmlformats.org/'
6346
+ def write_worksheet_attributes #:nodoc:
6347
+ schema = 'http://schemas.openxmlformats.org/'
6038
6348
  attributes = [
6039
- 'xmlns', schema + 'spreadsheetml/2006/main',
6040
- 'xmlns:r', schema + 'officeDocument/2006/relationships'
6349
+ 'xmlns', "#{schema}spreadsheetml/2006/main",
6350
+ 'xmlns:r', "#{schema}officeDocument/2006/relationships"
6041
6351
  ]
6042
6352
  if @excel_version == 2010
6043
- attributes << 'xmlns:mc' << "#{schema}markup-compatibility/2006"
6044
- attributes << 'xmlns:x14ac' <<
6045
- 'http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac'
6353
+ attributes << 'xmlns:mc' << "#{schema}markup-compatibility/2006"
6354
+ attributes << 'xmlns:x14ac' << "#{OFFICE_URL}spreadsheetml/2009/9/ac"
6046
6355
  attributes << 'mc:Ignorable' << 'x14ac'
6047
6356
  end
6048
- @writer.start_tag('worksheet', attributes)
6357
+ attributes
6049
6358
  end
6050
6359
 
6051
6360
  #
6052
6361
  # Write the <sheetPr> element for Sheet level properties.
6053
6362
  #
6054
6363
  def write_sheet_pr #:nodoc:
6055
- if !fit_page? && !filter_on? && !tab_color? &&
6056
- !outline_changed? && !vba_codename?
6057
- return
6058
- end
6059
- codename = @vba_codename
6364
+ return unless tab_outline_fit? || vba_codename? || filter_on?
6365
+
6060
6366
  attributes = []
6061
- (attributes << 'codeName' << codename) if codename
6062
- (attributes << 'filterMode' << 1) if filter_on?
6367
+ attributes << 'codeName' << @vba_codename if vba_codename?
6368
+ attributes << 'filterMode' << 1 if filter_on?
6063
6369
 
6064
- if fit_page? || tab_color? || outline_changed?
6370
+ if tab_outline_fit?
6065
6371
  @writer.tag_elements('sheetPr', attributes) do
6066
6372
  write_tab_color
6067
6373
  write_outline_pr
@@ -6072,14 +6378,15 @@ module Writexlsx
6072
6378
  end
6073
6379
  end
6074
6380
 
6381
+ def tab_outline_fit?
6382
+ tab_color? || outline_changed? || fit_page?
6383
+ end
6384
+
6075
6385
  #
6076
6386
  # Write the <pageSetUpPr> element.
6077
6387
  #
6078
6388
  def write_page_set_up_pr #:nodoc:
6079
- return unless fit_page?
6080
-
6081
- attributes = ['fitToPage', 1]
6082
- @writer.empty_tag('pageSetUpPr', attributes)
6389
+ @writer.empty_tag('pageSetUpPr', ['fitToPage', 1]) if fit_page?
6083
6390
  end
6084
6391
 
6085
6392
  # Write the <dimension> element. This specifies the range of cells in the
@@ -6111,8 +6418,7 @@ module Writexlsx
6111
6418
  cell_2 = xl_rowcol_to_cell(@dim_rowmax, @dim_colmax)
6112
6419
  ref = cell_1 + ':' + cell_2
6113
6420
  end
6114
- attributes = ['ref', ref]
6115
- @writer.empty_tag('dimension', attributes)
6421
+ @writer.empty_tag('dimension', ['ref', ref])
6116
6422
  end
6117
6423
  #
6118
6424
  # Write the <sheetViews> element.
@@ -6124,7 +6430,7 @@ module Writexlsx
6124
6430
  def write_sheet_view #:nodoc:
6125
6431
  attributes = []
6126
6432
  # Hide screen gridlines if required
6127
- attributes << 'showGridLines' << 0 unless screen_gridlines?
6433
+ attributes << 'showGridLines' << 0 unless @screen_gridlines
6128
6434
 
6129
6435
  # Hide zeroes in cells.
6130
6436
  attributes << 'showZeros' << 0 unless show_zeros?
@@ -6210,14 +6516,18 @@ module Writexlsx
6210
6516
  return if @colinfo.empty?
6211
6517
 
6212
6518
  @writer.tag_elements('cols') do
6213
- @colinfo.each {|col_info| write_col_info(*col_info) }
6519
+ @colinfo.each {|col_info| write_col_info(col_info) }
6214
6520
  end
6215
6521
  end
6216
6522
 
6217
6523
  #
6218
6524
  # Write the <col> element.
6219
6525
  #
6220
- def write_col_info(*args) #:nodoc:
6526
+ def write_col_info(args) #:nodoc:
6527
+ @writer.empty_tag('col', col_info_attributes(args))
6528
+ end
6529
+
6530
+ def col_info_attributes(args)
6221
6531
  min = args[0] || 0 # First formatted column.
6222
6532
  max = args[1] || 0 # Last formatted column.
6223
6533
  width = args[2] # Col width in user units.
@@ -6236,10 +6546,8 @@ module Writexlsx
6236
6546
  end
6237
6547
 
6238
6548
  # Convert column width from user units to character width.
6239
- max_digit_width = 7.0 # For Calabri 11.
6240
- padding = 5.0
6241
6549
  if width && width > 0
6242
- width = ((width * max_digit_width + padding) / max_digit_width * 256).to_i/256.0
6550
+ width = ((width * MAX_DIGIT_WIDTH + PADDING) / MAX_DIGIT_WIDTH.to_f * 256).to_i/256.0
6243
6551
  width = width.to_i if width.to_s =~ /\.0+$/
6244
6552
  end
6245
6553
  attributes = [
@@ -6248,13 +6556,12 @@ module Writexlsx
6248
6556
  'width', width
6249
6557
  ]
6250
6558
 
6251
- (attributes << 'style' << xf_index) if xf_index != 0
6252
- (attributes << 'hidden' << 1) if hidden != 0
6253
- (attributes << 'customWidth' << 1) if custom_width
6254
- (attributes << 'outlineLevel' << level) if level != 0
6255
- (attributes << 'collapsed' << 1) if collapsed != 0
6256
-
6257
- @writer.empty_tag('col', attributes)
6559
+ attributes << 'style' << xf_index if xf_index != 0
6560
+ attributes << 'hidden' << 1 if hidden != 0
6561
+ attributes << 'customWidth' << 1 if custom_width
6562
+ attributes << 'outlineLevel' << level if level != 0
6563
+ attributes << 'collapsed' << 1 if collapsed != 0
6564
+ attributes
6258
6565
  end
6259
6566
 
6260
6567
  #
@@ -6487,14 +6794,11 @@ module Writexlsx
6487
6794
  # Convert column width from user units to pane split width.
6488
6795
  #
6489
6796
  def calculate_x_split_width(width) #:nodoc:
6490
- max_digit_width = 7 # For Calabri 11.
6491
- padding = 5
6492
-
6493
6797
  # Convert to pixels.
6494
6798
  if width < 1
6495
6799
  pixels = int(width * 12 + 0.5)
6496
6800
  else
6497
- pixels = (width * max_digit_width + 0.5).to_i + padding
6801
+ pixels = (width * MAX_DIGIT_WIDTH + 0.5).to_i + PADDING
6498
6802
  end
6499
6803
 
6500
6804
  # Convert to points.
@@ -6511,24 +6815,17 @@ module Writexlsx
6511
6815
  # Write the <sheetCalcPr> element for the worksheet calculation properties.
6512
6816
  #
6513
6817
  def write_sheet_calc_pr #:nodoc:
6514
- full_calc_on_load = 1
6515
-
6516
- attributes = ['fullCalcOnLoad', full_calc_on_load]
6517
-
6518
- @writer.empty_tag('sheetCalcPr', attributes)
6818
+ @writer.empty_tag('sheetCalcPr', ['fullCalcOnLoad', 1])
6519
6819
  end
6520
6820
 
6521
6821
  #
6522
6822
  # Write the <phoneticPr> element.
6523
6823
  #
6524
6824
  def write_phonetic_pr #:nodoc:
6525
- font_id = 1
6526
- type = 'noConversion'
6527
-
6528
6825
  attributes = [
6529
- 'fontId', font_id,
6530
- 'type', type
6531
- ]
6826
+ 'fontId', 1,
6827
+ 'type', 'noConversion'
6828
+ ]
6532
6829
 
6533
6830
  @writer.empty_tag('phoneticPr', attributes)
6534
6831
  end
@@ -6537,55 +6834,14 @@ module Writexlsx
6537
6834
  # Write the <pageMargins> element.
6538
6835
  #
6539
6836
  def write_page_margins #:nodoc:
6540
- @writer.empty_tag('pageMargins', @print_style.attributes)
6837
+ @page_setup.write_page_margins(@writer)
6541
6838
  end
6542
6839
 
6543
6840
  #
6544
6841
  # Write the <pageSetup> element.
6545
6842
  #
6546
- # The following is an example taken from Excel.
6547
- #
6548
- # <pageSetup
6549
- # paperSize="9"
6550
- # scale="110"
6551
- # fitToWidth="2"
6552
- # fitToHeight="2"
6553
- # pageOrder="overThenDown"
6554
- # orientation="portrait"
6555
- # blackAndWhite="1"
6556
- # draft="1"
6557
- # horizontalDpi="200"
6558
- # verticalDpi="200"
6559
- # r:id="rId1"
6560
- # />
6561
- #
6562
6843
  def write_page_setup #:nodoc:
6563
- attributes = []
6564
-
6565
- return unless page_setup_changed?
6566
-
6567
- # Set paper size.
6568
- attributes << 'paperSize' << @paper_size if @paper_size
6569
-
6570
- # Set the scale
6571
- attributes << 'scale' << @print_style.scale if @print_style.scale != 100
6572
-
6573
- # Set the "Fit to page" properties.
6574
- attributes << 'fitToWidth' << @print_style.fit_width if @print_style.fit_page && @print_style.fit_width != 1
6575
-
6576
- attributes << 'fitToHeight' << @print_style.fit_height if @print_style.fit_page && @print_style.fit_height != 1
6577
-
6578
- # Set the page print direction.
6579
- attributes << 'pageOrder' << "overThenDown" if print_across?
6580
-
6581
- # Set page orientation.
6582
- if @print_style.orientation?
6583
- attributes << 'orientation' << 'portrait'
6584
- else
6585
- attributes << 'orientation' << 'landscape'
6586
- end
6587
-
6588
- @writer.empty_tag('pageSetup', attributes)
6844
+ @page_setup.write_page_setup(@writer)
6589
6845
  end
6590
6846
 
6591
6847
  #
@@ -6600,9 +6856,7 @@ module Writexlsx
6600
6856
  def write_some_elements(tag, container)
6601
6857
  return if container.empty?
6602
6858
 
6603
- attributes = ['count', container.size]
6604
-
6605
- @writer.tag_elements(tag, attributes) do
6859
+ @writer.tag_elements(tag, ['count', container.size]) do
6606
6860
  yield
6607
6861
  end
6608
6862
  end
@@ -6616,60 +6870,22 @@ module Writexlsx
6616
6870
  # Convert the merge dimensions to a cell range.
6617
6871
  cell_1 = xl_rowcol_to_cell(row_min, col_min)
6618
6872
  cell_2 = xl_rowcol_to_cell(row_max, col_max)
6619
- ref = "#{cell_1}:#{cell_2}"
6620
-
6621
- attributes = ['ref', ref]
6622
6873
 
6623
- @writer.empty_tag('mergeCell', attributes)
6874
+ @writer.empty_tag('mergeCell', ['ref', "#{cell_1}:#{cell_2}"])
6624
6875
  end
6625
6876
 
6626
6877
  #
6627
6878
  # Write the <printOptions> element.
6628
6879
  #
6629
6880
  def write_print_options #:nodoc:
6630
- attributes = []
6631
-
6632
- return unless print_options_changed?
6633
-
6634
- # Set horizontal centering.
6635
- attributes << 'horizontalCentered' << 1 if hcenter?
6636
-
6637
- # Set vertical centering.
6638
- attributes << 'verticalCentered' << 1 if vcenter?
6639
-
6640
- # Enable row and column headers.
6641
- attributes << 'headings' << 1 if print_headers?
6642
-
6643
- # Set printed gridlines.
6644
- attributes << 'gridLines' << 1 if print_gridlines?
6645
-
6646
- @writer.empty_tag('printOptions', attributes)
6881
+ @page_setup.write_print_options(@writer)
6647
6882
  end
6648
6883
 
6649
6884
  #
6650
6885
  # Write the <headerFooter> element.
6651
6886
  #
6652
6887
  def write_header_footer #:nodoc:
6653
- return unless header_footer_changed?
6654
-
6655
- @writer.tag_elements('headerFooter') do
6656
- write_odd_header if @header && @header != ''
6657
- write_odd_footer if @footer && @footer != ''
6658
- end
6659
- end
6660
-
6661
- #
6662
- # Write the <oddHeader> element.
6663
- #
6664
- def write_odd_header #:nodoc:
6665
- @writer.data_element('oddHeader', @header)
6666
- end
6667
-
6668
- #
6669
- # Write the <oddFooter> element.
6670
- #
6671
- def write_odd_footer #:nodoc:
6672
- @writer.data_element('oddFooter', @footer)
6888
+ @page_setup.write_header_footer(@writer)
6673
6889
  end
6674
6890
 
6675
6891
  #
@@ -6689,10 +6905,10 @@ module Writexlsx
6689
6905
  def write_breaks(tag) # :nodoc:
6690
6906
  case tag
6691
6907
  when 'rowBreaks'
6692
- page_breaks = sort_pagebreaks(*(@print_style.hbreaks))
6908
+ page_breaks = sort_pagebreaks(*(@page_setup.hbreaks))
6693
6909
  max = 16383
6694
6910
  when 'colBreaks'
6695
- page_breaks = sort_pagebreaks(*(@print_style.vbreaks))
6911
+ page_breaks = sort_pagebreaks(*(@page_setup.vbreaks))
6696
6912
  max = 1048575
6697
6913
  else
6698
6914
  raise "Invalid parameter '#{tag}' in write_breaks."
@@ -6763,9 +6979,7 @@ module Writexlsx
6763
6979
  # Write the <filterColumn> element.
6764
6980
  #
6765
6981
  def write_filter_column(col_id, type, *filters) #:nodoc:
6766
- attributes = ['colId', col_id]
6767
-
6768
- @writer.tag_elements('filterColumn', attributes) do
6982
+ @writer.tag_elements('filterColumn', ['colId', col_id]) do
6769
6983
  if type == 1
6770
6984
  # Type == 1 is the new XLSX style filter.
6771
6985
  write_filters(*filters)
@@ -6798,7 +7012,6 @@ module Writexlsx
6798
7012
  @writer.empty_tag('filter', ['val', val])
6799
7013
  end
6800
7014
 
6801
-
6802
7015
  #
6803
7016
  # Write the <customFilters> element.
6804
7017
  #
@@ -6824,7 +7037,6 @@ module Writexlsx
6824
7037
  end
6825
7038
  end
6826
7039
 
6827
-
6828
7040
  #
6829
7041
  # Write the <customFilter> element.
6830
7042
  #
@@ -6861,21 +7073,13 @@ module Writexlsx
6861
7073
  def write_hyperlinks #:nodoc:
6862
7074
  return unless @hyperlinks
6863
7075
 
6864
- # Sort the hyperlinks into row order.
6865
- row_nums = @hyperlinks.keys.sort
6866
-
6867
- # Exit if there are no hyperlinks to process.
6868
- return if row_nums.empty?
6869
-
6870
- # Iterate over the rows.
6871
- row_nums.each do |row_num|
7076
+ @hyperlinks.keys.sort.each do |row_num|
6872
7077
  # Sort the hyperlinks into column order.
6873
7078
  col_nums = @hyperlinks[row_num].keys.sort
6874
7079
  # Iterate over the columns.
6875
7080
  col_nums.each do |col_num|
6876
7081
  # Get the link data for this cell.
6877
- link = @hyperlinks[row_num][col_num]
6878
- link_type = link[:_link_type]
7082
+ link = @hyperlinks[row_num][col_num]
6879
7083
 
6880
7084
  # If the cell isn't a string then we have to add the url as
6881
7085
  # the string to display
@@ -6883,29 +7087,19 @@ module Writexlsx
6883
7087
  ptrue?(@cell_data_table[row_num]) &&
6884
7088
  ptrue?(@cell_data_table[row_num][col_num])
6885
7089
  if @cell_data_table[row_num][col_num].display_url_string?
6886
- display = link[:_url]
6887
- else
6888
- display = nil
7090
+ link.display = link.url_str
6889
7091
  end
6890
7092
  end
6891
7093
 
6892
- if link_type == 1
7094
+ if link.link_type == 1
6893
7095
  # External link with rel file relationship.
6894
7096
  @rel_count += 1
6895
- @hlink_refs << [
6896
- link_type, row_num, col_num,
6897
- @rel_count, link[:_str], display, link[:_tip]
6898
- ]
7097
+ @hlink_refs << [link, row_num, col_num, @rel_count]
6899
7098
  # Links for use by the packager.
6900
- @external_hyper_links << [
6901
- '/hyperlink', link[:_url], 'External'
6902
- ]
7099
+ @external_hyper_links << ['/hyperlink', link.url, 'External']
6903
7100
  else
6904
7101
  # Internal link with rel file relationship.
6905
- @hlink_refs << [
6906
- link_type, row_num, col_num,
6907
- link[:_url], link[:_str], link[:_tip]
6908
- ]
7102
+ @hlink_refs << [link, row_num, col_num]
6909
7103
  end
6910
7104
  end
6911
7105
  end
@@ -6915,12 +7109,11 @@ module Writexlsx
6915
7109
  # Write the hyperlink elements.
6916
7110
  @writer.tag_elements('hyperlinks') do
6917
7111
  @hlink_refs.each do |aref|
6918
- type, *args = aref
6919
-
6920
- if type == 1
6921
- write_hyperlink_external(*args)
6922
- elsif type == 2
6923
- write_hyperlink_internal(*args)
7112
+ case aref[0].link_type
7113
+ when 1
7114
+ write_hyperlink_external(*aref)
7115
+ when 2
7116
+ write_hyperlink_internal(*aref)
6924
7117
  end
6925
7118
  end
6926
7119
  end
@@ -6929,31 +7122,15 @@ module Writexlsx
6929
7122
  #
6930
7123
  # Write the <hyperlink> element for external links.
6931
7124
  #
6932
- def write_hyperlink_external(row, col, id, location = nil, display = nil, tooltip = nil) #:nodoc:
6933
- ref = xl_rowcol_to_cell(row, col)
6934
- r_id = "rId#{id}"
6935
-
6936
- attributes = ['ref', ref, 'r:id', r_id]
6937
-
6938
- attributes << 'location' << location if location
6939
- attributes << 'display' << display if display
6940
- attributes << 'tooltip' << tooltip if tooltip
6941
-
6942
- @writer.empty_tag('hyperlink', attributes)
7125
+ def write_hyperlink_external(link, row, col, id) # :nodoc:
7126
+ @writer.empty_tag('hyperlink', link.write_external_attributes(row, col, id))
6943
7127
  end
6944
7128
 
6945
7129
  #
6946
7130
  # Write the <hyperlink> element for internal links.
6947
7131
  #
6948
- def write_hyperlink_internal(row, col, location, display, tooltip = nil) #:nodoc:
6949
- ref = xl_rowcol_to_cell(row, col)
6950
-
6951
- attributes = ['ref', ref, 'location', location]
6952
-
6953
- attributes << 'tooltip' << tooltip if tooltip
6954
- attributes << 'display' << display
6955
-
6956
- @writer.empty_tag('hyperlink', attributes)
7132
+ def write_hyperlink_internal(link, row, col) #:nodoc:
7133
+ @writer.empty_tag('hyperlink', link.write_internal_attributes(row, col))
6957
7134
  end
6958
7135
 
6959
7136
  #
@@ -6962,8 +7139,7 @@ module Writexlsx
6962
7139
  def write_tab_color #:nodoc:
6963
7140
  return unless tab_color?
6964
7141
 
6965
- attributes = ['rgb', get_palette_color(@tab_color)]
6966
- @writer.empty_tag('tabColor', attributes)
7142
+ @writer.empty_tag('tabColor', ['rgb', get_palette_color(@tab_color)])
6967
7143
  end
6968
7144
 
6969
7145
  #
@@ -7018,109 +7194,31 @@ module Writexlsx
7018
7194
  # Write the <drawing> elements.
7019
7195
  #
7020
7196
  def write_drawings #:nodoc:
7021
- return unless drawing?
7022
- @rel_count += 1
7023
- write_drawing(@rel_count)
7024
- end
7025
-
7026
- #
7027
- # Write the <drawing> element.
7028
- #
7029
- def write_drawing(id) #:nodoc:
7030
- r_id = "rId#{id}"
7031
-
7032
- attributes = ['r:id', r_id]
7033
-
7034
- @writer.empty_tag('drawing', attributes)
7197
+ increment_rel_id_and_write_r_id('drawing') if drawing?
7035
7198
  end
7036
7199
 
7037
7200
  #
7038
7201
  # Write the <legacyDrawing> element.
7039
7202
  #
7040
7203
  def write_legacy_drawing #:nodoc:
7041
- return unless @has_vml
7042
-
7043
- # Increment the relationship id for any drawings or comments.
7044
- @rel_count += 1
7045
- id = @rel_count
7046
-
7047
- attributes = ['r:id', "rId#{id}"]
7048
-
7049
- @writer.empty_tag('legacyDrawing', attributes)
7050
- end
7051
-
7052
- #
7053
- # Write the <font> element.
7054
- #
7055
- def write_font(writer, format) #:nodoc:
7056
- writer.tag_elements('rPr') do
7057
- writer.empty_tag('b') if format.bold?
7058
- writer.empty_tag('i') if format.italic?
7059
- writer.empty_tag('strike') if format.strikeout?
7060
- writer.empty_tag('outline') if format.outline?
7061
- writer.empty_tag('shadow') if format.shadow?
7062
-
7063
- # Handle the underline variants.
7064
- write_underline(writer, format.underline) if format.underline?
7065
-
7066
- write_vert_align(writer, 'superscript') if format.font_script == 1
7067
- write_vert_align(writer, 'subscript') if format.font_script == 2
7068
-
7069
- writer.empty_tag('sz', ['val', format.size])
7070
-
7071
- theme = format.theme
7072
- color = format.color
7073
- if ptrue?(theme)
7074
- write_color(writer, 'theme', theme)
7075
- elsif ptrue?(color)
7076
- color = get_palette_color(color)
7077
- write_color(writer, 'rgb', color)
7078
- else
7079
- write_color(writer, 'theme', 1)
7080
- end
7081
-
7082
- writer.empty_tag('rFont', ['val', format.font])
7083
- writer.empty_tag('family', ['val', format.font_family])
7084
-
7085
- if format.font == 'Calibri' && format.hyperlink == 0
7086
- writer.empty_tag('scheme', ['val', format.font_scheme])
7087
- end
7088
- end
7204
+ increment_rel_id_and_write_r_id('legacyDrawing') if has_vml?
7089
7205
  end
7090
7206
 
7091
7207
  #
7092
7208
  # Write the underline font element.
7093
7209
  #
7094
7210
  def write_underline(writer, underline) #:nodoc:
7095
- attributes = underline_attributes(underline)
7096
- writer.empty_tag('u', attributes)
7097
- end
7098
-
7099
- #
7100
- # Write the <vertAlign> font sub-element.
7101
- #
7102
- def write_vert_align(writer, val) #:nodoc:
7103
- attributes = ['val', val]
7104
-
7105
- writer.empty_tag('vertAlign', attributes)
7211
+ writer.empty_tag('u', underline_attributes(underline))
7106
7212
  end
7107
7213
 
7108
7214
  #
7109
7215
  # Write the <tableParts> element.
7110
7216
  #
7111
7217
  def write_table_parts
7112
- # Return if worksheet doesn't contain any tables.
7113
7218
  return if @tables.empty?
7114
7219
 
7115
- attributes = ['count', @tables.size]
7116
-
7117
- @writer.tag_elements('tableParts', attributes) do
7118
-
7119
- @tables.each do |table|
7120
- # Write the tablePart element.
7121
- @rel_count += 1
7122
- write_table_part(@rel_count)
7123
- end
7220
+ @writer.tag_elements('tableParts', ['count', tables_count]) do
7221
+ tables_count.times { increment_rel_id_and_write_r_id('tablePart') }
7124
7222
  end
7125
7223
  end
7126
7224
 
@@ -7128,215 +7226,50 @@ module Writexlsx
7128
7226
  # Write the <tablePart> element.
7129
7227
  #
7130
7228
  def write_table_part(id)
7131
- r_id = "rId#{id}"
7229
+ @writer.empty_tag('tablePart', ['r:id', "rId#{id}"])
7230
+ end
7132
7231
 
7133
- attributes = ['r:id', r_id]
7232
+ def increment_rel_id_and_write_r_id(tag)
7233
+ @rel_count += 1
7234
+ write_r_id(tag, @rel_count)
7235
+ end
7134
7236
 
7135
- @writer.empty_tag('tablePart', attributes)
7237
+ def write_r_id(tag, id)
7238
+ @writer.empty_tag(tag, ['r:id', "rId#{id}"])
7136
7239
  end
7137
7240
 
7138
7241
  #
7139
7242
  # Write the <extLst> element and sparkline subelements.
7140
7243
  #
7141
7244
  def write_ext_sparklines # :nodoc:
7142
- sparklines = @sparklines
7143
-
7144
- # Return if worksheet doesn't contain any sparklines.
7145
- return if sparklines.empty?
7146
-
7147
- # Write the extLst element.
7148
- @writer.start_tag('extLst')
7149
-
7150
- # Write the ext element.
7151
- write_ext
7152
-
7153
- # Write the x14:sparklineGroups element.
7154
- write_sparkline_groups
7155
-
7156
- # Write the sparkline elements.
7157
- sparklines.reverse.each do |sparkline|
7158
- # Write the x14:sparklineGroup element.
7159
- write_sparkline_group(sparkline)
7160
-
7161
- # Write the x14:colorSeries element.
7162
- write_color_series(sparkline.series_color)
7163
-
7164
- # Write the x14:colorNegative element.
7165
- write_color_negative(sparkline.negative_color)
7166
-
7167
- # Write the x14:colorAxis element.
7168
- write_color_axis
7169
-
7170
- # Write the x14:colorMarkers element.
7171
- write_color_markers(sparkline.markers_color)
7172
-
7173
- # Write the x14:colorFirst element.
7174
- write_color_first(sparkline.first_color)
7175
-
7176
- # Write the x14:colorLast element.
7177
- write_color_last(sparkline.last_color)
7178
-
7179
- # Write the x14:colorHigh element.
7180
- write_color_high(sparkline.high_color)
7181
-
7182
- # Write the x14:colorLow element.
7183
- write_color_low(sparkline.low_color)
7184
-
7185
- if sparkline.date_axis
7186
- @writer.data_element('xm:f', sparkline.date_axis)
7187
- end
7188
-
7189
- write_sparklines(sparkline)
7190
-
7191
- @writer.end_tag('x14:sparklineGroup')
7192
- end
7193
-
7194
- @writer.end_tag('x14:sparklineGroups')
7195
- @writer.end_tag('ext')
7196
- @writer.end_tag('extLst')
7245
+ @writer.tag_elements('extLst') { write_ext } unless @sparklines.empty?
7197
7246
  end
7198
7247
 
7199
- #
7200
- # Write the <x14:sparklines> element and <x14:sparkline> subelements.
7201
- #
7202
- def write_sparklines(sparkline) # :nodoc:
7203
- # Write the sparkline elements.
7204
- @writer.tag_elements('x14:sparklines') do
7205
-
7206
- (0 .. sparkline.count-1).each do |i|
7207
- range = sparkline.ranges[i]
7208
- location = sparkline.locations[i]
7209
-
7210
- @writer.tag_elements('x14:sparkline') do
7211
- @writer.data_element('xm:f', range)
7212
- @writer.data_element('xm:sqref', location)
7213
- end
7214
- end
7248
+ def write_ext
7249
+ @writer.tag_elements('ext', write_ext_attributes) do
7250
+ write_sparkline_groups
7215
7251
  end
7216
7252
  end
7217
7253
 
7218
- #
7219
- # Write the <ext> element.
7220
- #
7221
- def write_ext # :nodoc:
7222
- schema = 'http://schemas.microsoft.com/office/'
7223
- xmlns_x_14 = "#{schema}spreadsheetml/2009/9/main"
7224
- uri = '{05C60535-1F16-4fd2-B633-F4F36F0B64E0}'
7225
-
7226
- attributes = [
7227
- 'xmlns:x14', xmlns_x_14,
7228
- 'uri', uri
7229
- ]
7230
-
7231
- @writer.start_tag('ext', attributes)
7232
- end
7233
-
7234
- #
7235
- # Write the <x14:sparklineGroups> element.
7236
- #
7237
- def write_sparkline_groups # :nodoc:
7238
- xmlns_xm = 'http://schemas.microsoft.com/office/excel/2006/main'
7239
-
7240
- attributes = ['xmlns:xm', xmlns_xm]
7241
-
7242
- @writer.start_tag('x14:sparklineGroups', attributes)
7243
- end
7244
-
7245
- #
7246
- # Write the <x14:sparklineGroup> element.
7247
- #
7248
- # Example for order.
7249
- #
7250
- # <x14:sparklineGroup
7251
- # manualMax="0"
7252
- # manualMin="0"
7253
- # lineWeight="2.25"
7254
- # type="column"
7255
- # dateAxis="1"
7256
- # displayEmptyCellsAs="span"
7257
- # markers="1"
7258
- # high="1"
7259
- # low="1"
7260
- # first="1"
7261
- # last="1"
7262
- # negative="1"
7263
- # displayXAxis="1"
7264
- # displayHidden="1"
7265
- # minAxisType="custom"
7266
- # maxAxisType="custom"
7267
- # rightToLeft="1">
7268
- #
7269
- def write_sparkline_group(sparkline) # :nodoc:
7270
- @writer.start_tag('x14:sparklineGroup', sparkline.group_attributes)
7271
- end
7272
-
7273
- #
7274
- # Helper function for the sparkline color functions below.
7275
- #
7276
- def write_spark_color(element, color) # :nodoc:
7277
- attr = []
7278
-
7279
- attr << 'rgb' << color[:_rgb] if color[:_rgb]
7280
- attr << 'theme' << color[:_theme] if color[:_theme]
7281
- attr << 'tint' << color[:_tint] if color[:_tint]
7282
-
7283
- @writer.empty_tag(element, attr)
7284
- end
7285
-
7286
- #
7287
- # Write the <x14:colorSeries> element.
7288
- #
7289
- def write_color_series(param) # :nodoc:
7290
- write_spark_color('x14:colorSeries', param)
7291
- end
7292
-
7293
- #
7294
- # Write the <x14:colorNegative> element.
7295
- #
7296
- def write_color_negative(param) # :nodoc:
7297
- write_spark_color('x14:colorNegative', param)
7298
- end
7299
-
7300
- #
7301
- # Write the <x14:colorAxis> element.
7302
- #
7303
- def write_color_axis # :nodoc:
7304
- write_spark_color('x14:colorAxis', { :_rgb => 'FF000000'} )
7305
- end
7306
-
7307
- #
7308
- # Write the <x14:colorMarkers> element.
7309
- #
7310
- def write_color_markers(param) # :nodoc:
7311
- write_spark_color('x14:colorMarkers', param)
7312
- end
7313
-
7314
- #
7315
- # Write the <x14:colorFirst> element.
7316
- #
7317
- def write_color_first(param) # :nodoc:
7318
- write_spark_color('x14:colorFirst', param)
7319
- end
7320
-
7321
- #
7322
- # Write the <x14:colorLast> element.
7323
- #
7324
- def write_color_last(param) # :nodoc:
7325
- write_spark_color('x14:colorLast', param)
7254
+ def write_ext_attributes
7255
+ [
7256
+ 'xmlns:x14', "#{OFFICE_URL}spreadsheetml/2009/9/main",
7257
+ 'uri', '{05C60535-1F16-4fd2-B633-F4F36F0B64E0}'
7258
+ ]
7326
7259
  end
7327
7260
 
7328
- #
7329
- # Write the <x14:colorHigh> element.
7330
- #
7331
- def write_color_high(param) # :nodoc:
7332
- write_spark_color('x14:colorHigh', param)
7261
+ def write_sparkline_groups
7262
+ # Write the x14:sparklineGroups element.
7263
+ @writer.tag_elements('x14:sparklineGroups', sparkline_groups_attributes) do
7264
+ # Write the sparkline elements.
7265
+ @sparklines.reverse.each do |sparkline|
7266
+ sparkline.write_sparkline_group(@writer)
7267
+ end
7268
+ end
7333
7269
  end
7334
7270
 
7335
- #
7336
- # Write the <x14:colorLow> element.
7337
- #
7338
- def write_color_low(param) # :nodoc:
7339
- write_spark_color('x14:colorLow', param)
7271
+ def sparkline_groups_attributes # :nodoc:
7272
+ ['xmlns:xm', "#{OFFICE_URL}excel/2006/main"]
7340
7273
  end
7341
7274
 
7342
7275
  #
@@ -7344,87 +7277,10 @@ module Writexlsx
7344
7277
  #
7345
7278
  def write_data_validations #:nodoc:
7346
7279
  write_some_elements('dataValidations', @validations) do
7347
- @validations.each { |validation| write_data_validation(validation) }
7348
- end
7349
- end
7350
-
7351
- #
7352
- # Write the <dataValidation> element.
7353
- #
7354
- def write_data_validation(param) #:nodoc:
7355
- sqref = ''
7356
- attributes = []
7357
-
7358
- # Set the cell range(s) for the data validation.
7359
- param[:cells].each do |cells|
7360
- # Add a space between multiple cell ranges.
7361
- sqref += ' ' if sqref != ''
7362
-
7363
- row_first, col_first, row_last, col_last = cells
7364
-
7365
- # Swap last row/col for first row/col as necessary
7366
- row_first, row_last = row_last, row_first if row_first > row_last
7367
- col_first, col_last = col_last, col_first if col_first > col_last
7368
-
7369
- # If the first and last cell are the same write a single cell.
7370
- if row_first == row_last && col_first == col_last
7371
- sqref += xl_rowcol_to_cell(row_first, col_first)
7372
- else
7373
- sqref += xl_range(row_first, row_last, col_first, col_last)
7374
- end
7375
- end
7376
-
7377
- #use Data::Dumper::Perltidy
7378
- #print Dumper param
7379
-
7380
- attributes << 'type' << param[:validate]
7381
- attributes << 'operator' << param[:criteria] if param[:criteria] != 'between'
7382
-
7383
- if param[:error_type]
7384
- attributes << 'errorStyle' << 'warning' if param[:error_type] == 1
7385
- attributes << 'errorStyle' << 'information' if param[:error_type] == 2
7386
- end
7387
- attributes << 'allowBlank' << 1 if param[:ignore_blank] != 0
7388
- attributes << 'showDropDown' << 1 if param[:dropdown] == 0
7389
- attributes << 'showInputMessage' << 1 if param[:show_input] != 0
7390
- attributes << 'showErrorMessage' << 1 if param[:show_error] != 0
7391
-
7392
- attributes << 'errorTitle' << param[:error_title] if param[:error_title]
7393
- attributes << 'error' << param[:error_message] if param[:error_message]
7394
- attributes << 'promptTitle' << param[:input_title] if param[:input_title]
7395
- attributes << 'prompt' << param[:input_message] if param[:input_message]
7396
- attributes << 'sqref' << sqref
7397
-
7398
- @writer.tag_elements('dataValidation', attributes) do
7399
- # Write the formula1 element.
7400
- write_formula_1(param[:value])
7401
- # Write the formula2 element.
7402
- write_formula_2(param[:maximum]) if param[:maximum]
7280
+ @validations.each { |validation| validation.write_data_validation(@writer) }
7403
7281
  end
7404
7282
  end
7405
7283
 
7406
- #
7407
- # Write the <formula1> element.
7408
- #
7409
- def write_formula_1(formula) #:nodoc:
7410
- # Convert a list array ref into a comma separated string.
7411
- formula = %!"#{formula.join(',')}"! if formula.kind_of?(Array)
7412
-
7413
- formula = formula.sub(/^=/, '') if formula.respond_to?(:sub)
7414
-
7415
- @writer.data_element('formula1', formula)
7416
- end
7417
-
7418
- # write_formula_2()
7419
- #
7420
- # Write the <formula2> element.
7421
- #
7422
- def write_formula_2(formula) #:nodoc:
7423
- formula = formula.sub(/^=/, '') if formula.respond_to?(:sub)
7424
-
7425
- @writer.data_element('formula2', formula)
7426
- end
7427
-
7428
7284
  #
7429
7285
  # Write the Worksheet conditional formats.
7430
7286
  #
@@ -7438,9 +7294,7 @@ module Writexlsx
7438
7294
  # Write the <conditionalFormatting> element.
7439
7295
  #
7440
7296
  def write_conditional_formatting(range, cond_formats) #:nodoc:
7441
- attributes = ['sqref', range]
7442
-
7443
- @writer.tag_elements('conditionalFormatting', attributes) do
7297
+ @writer.tag_elements('conditionalFormatting', ['sqref', range]) do
7444
7298
  cond_formats.each { |cond_format| cond_format.write_cf_rule }
7445
7299
  end
7446
7300
  end
@@ -7511,14 +7365,6 @@ module Writexlsx
7511
7365
  [span_min, span_max]
7512
7366
  end
7513
7367
 
7514
- def xf(format) #:nodoc:
7515
- if format.kind_of?(Format)
7516
- format.xf_index
7517
- else
7518
- 0
7519
- end
7520
- end
7521
-
7522
7368
  #
7523
7369
  # Add a string to the shared string table, if it isn't already there, and
7524
7370
  # return the string index.
@@ -7580,7 +7426,7 @@ module Writexlsx
7580
7426
  end
7581
7427
 
7582
7428
  def fit_page? #:nodoc:
7583
- @print_style.fit_page
7429
+ @page_setup.fit_page
7584
7430
  end
7585
7431
 
7586
7432
  def filter_on? #:nodoc:
@@ -7615,10 +7461,6 @@ module Writexlsx
7615
7461
  !!@show_zeros
7616
7462
  end
7617
7463
 
7618
- def screen_gridlines? #:nodoc:
7619
- !!@screen_gridlines
7620
- end
7621
-
7622
7464
  def protect? #:nodoc:
7623
7465
  !!@protect
7624
7466
  end
@@ -7627,34 +7469,6 @@ module Writexlsx
7627
7469
  !!@autofilter_ref
7628
7470
  end
7629
7471
 
7630
- def print_options_changed? #:nodoc:
7631
- !!@print_options_changed
7632
- end
7633
-
7634
- def hcenter? #:nodoc:
7635
- !!@hcenter
7636
- end
7637
-
7638
- def vcenter? #:nodoc:
7639
- !!@vcenter
7640
- end
7641
-
7642
- def print_headers? #:nodoc:
7643
- !!@print_headers
7644
- end
7645
-
7646
- def print_gridlines? #:nodoc:
7647
- !!@print_gridlines
7648
- end
7649
-
7650
- def page_setup_changed? #:nodoc:
7651
- @print_style.page_setup_changed
7652
- end
7653
-
7654
- def header_footer_changed? #:nodoc:
7655
- !!@header_footer_changed
7656
- end
7657
-
7658
7472
  def drawing? #:nodoc:
7659
7473
  !!@drawing
7660
7474
  end
@@ -7667,32 +7481,6 @@ module Writexlsx
7667
7481
  end
7668
7482
  end
7669
7483
 
7670
- def print_across?
7671
- @print_style.across
7672
- end
7673
-
7674
- # List of valid criteria types.
7675
- def valid_criteria_type # :nodoc:
7676
- {
7677
- 'between' => 'between',
7678
- 'not between' => 'notBetween',
7679
- 'equal to' => 'equal',
7680
- '=' => 'equal',
7681
- '==' => 'equal',
7682
- 'not equal to' => 'notEqual',
7683
- '!=' => 'notEqual',
7684
- '<>' => 'notEqual',
7685
- 'greater than' => 'greaterThan',
7686
- '>' => 'greaterThan',
7687
- 'less than' => 'lessThan',
7688
- '<' => 'lessThan',
7689
- 'greater than or equal to' => 'greaterThanOrEqual',
7690
- '>=' => 'greaterThanOrEqual',
7691
- 'less than or equal to' => 'lessThanOrEqual',
7692
- '<=' => 'lessThanOrEqual'
7693
- }
7694
- end
7695
-
7696
7484
  def set_active_pane_and_cell_selections(row, col, top_row, left_col, active_cell, sqref) # :nodoc:
7697
7485
  if row > 0 && col > 0
7698
7486
  active_pane = 'bottomRight'
@@ -7731,15 +7519,5 @@ module Writexlsx
7731
7519
  end
7732
7520
  col
7733
7521
  end
7734
-
7735
- def convert_date_time_value(param, key) # :nodoc:
7736
- if param[key] && param[key] =~ /T/
7737
- date_time = convert_date_time(param[key])
7738
- param[key] = date_time if date_time
7739
- date_time
7740
- else
7741
- true
7742
- end
7743
- end
7744
7522
  end
7745
7523
  end