axlsx 2.0.1 → 2.1.0.pre

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -3
  3. data/Rakefile +9 -10
  4. data/examples/IMAGE1UP.JPEG +0 -0
  5. data/examples/auto_filter.rb +10 -1
  6. data/examples/conditional_formatting/example_conditional_formatting.rb +3 -3
  7. data/examples/example.rb +72 -4
  8. data/examples/merge_cells.rb +17 -0
  9. data/examples/no_grid_with_borders.rb +18 -0
  10. data/examples/pivot_test.rb +63 -0
  11. data/examples/split.rb +16 -0
  12. data/lib/axlsx.rb +30 -16
  13. data/lib/axlsx/content_type/abstract_content_type.rb +1 -1
  14. data/lib/axlsx/content_type/content_type.rb +1 -1
  15. data/lib/axlsx/doc_props/app.rb +1 -1
  16. data/lib/axlsx/doc_props/core.rb +5 -5
  17. data/lib/axlsx/drawing/axes.rb +1 -1
  18. data/lib/axlsx/drawing/axis.rb +12 -9
  19. data/lib/axlsx/drawing/bar_3D_chart.rb +13 -13
  20. data/lib/axlsx/drawing/bar_series.rb +9 -9
  21. data/lib/axlsx/drawing/bubble_chart.rb +59 -0
  22. data/lib/axlsx/drawing/bubble_series.rb +63 -0
  23. data/lib/axlsx/drawing/cat_axis.rb +5 -5
  24. data/lib/axlsx/drawing/chart.rb +44 -7
  25. data/lib/axlsx/drawing/drawing.rb +3 -1
  26. data/lib/axlsx/drawing/graphic_frame.rb +3 -3
  27. data/lib/axlsx/drawing/hyperlink.rb +1 -3
  28. data/lib/axlsx/drawing/line_3D_chart.rb +2 -2
  29. data/lib/axlsx/drawing/line_chart.rb +10 -10
  30. data/lib/axlsx/drawing/line_series.rb +14 -2
  31. data/lib/axlsx/drawing/marker.rb +1 -1
  32. data/lib/axlsx/drawing/num_data.rb +4 -4
  33. data/lib/axlsx/drawing/num_data_source.rb +6 -6
  34. data/lib/axlsx/drawing/num_val.rb +1 -1
  35. data/lib/axlsx/drawing/one_cell_anchor.rb +1 -1
  36. data/lib/axlsx/drawing/pic.rb +2 -3
  37. data/lib/axlsx/drawing/picture_locking.rb +1 -3
  38. data/lib/axlsx/drawing/pie_3D_chart.rb +5 -6
  39. data/lib/axlsx/drawing/pie_series.rb +6 -6
  40. data/lib/axlsx/drawing/scaling.rb +4 -4
  41. data/lib/axlsx/drawing/scatter_chart.rb +10 -10
  42. data/lib/axlsx/drawing/scatter_series.rb +26 -7
  43. data/lib/axlsx/drawing/ser_axis.rb +2 -2
  44. data/lib/axlsx/drawing/series.rb +3 -3
  45. data/lib/axlsx/drawing/series_title.rb +2 -2
  46. data/lib/axlsx/drawing/str_data.rb +3 -3
  47. data/lib/axlsx/drawing/str_val.rb +1 -1
  48. data/lib/axlsx/drawing/title.rb +3 -3
  49. data/lib/axlsx/drawing/val_axis.rb +1 -1
  50. data/lib/axlsx/drawing/vml_drawing.rb +1 -1
  51. data/lib/axlsx/package.rb +39 -28
  52. data/lib/axlsx/rels/relationship.rb +1 -1
  53. data/lib/axlsx/rels/relationships.rb +2 -2
  54. data/lib/axlsx/stylesheet/border_pr.rb +2 -2
  55. data/lib/axlsx/stylesheet/cell_alignment.rb +1 -3
  56. data/lib/axlsx/stylesheet/cell_protection.rb +1 -3
  57. data/lib/axlsx/stylesheet/cell_style.rb +1 -3
  58. data/lib/axlsx/stylesheet/color.rb +1 -3
  59. data/lib/axlsx/stylesheet/font.rb +1 -1
  60. data/lib/axlsx/stylesheet/gradient_stop.rb +1 -1
  61. data/lib/axlsx/stylesheet/num_fmt.rb +1 -3
  62. data/lib/axlsx/stylesheet/pattern_fill.rb +1 -1
  63. data/lib/axlsx/stylesheet/styles.rb +6 -6
  64. data/lib/axlsx/stylesheet/table_style_element.rb +1 -3
  65. data/lib/axlsx/util/accessors.rb +6 -6
  66. data/lib/axlsx/util/constants.rb +106 -101
  67. data/lib/axlsx/util/options_parser.rb +2 -1
  68. data/lib/axlsx/util/parser.rb +4 -4
  69. data/lib/axlsx/util/serialized_attributes.rb +16 -6
  70. data/lib/axlsx/util/simple_typed_list.rb +28 -52
  71. data/lib/axlsx/util/storage.rb +4 -4
  72. data/lib/axlsx/util/string.rb +7 -0
  73. data/lib/axlsx/util/validators.rb +20 -13
  74. data/lib/axlsx/version.rb +1 -1
  75. data/lib/axlsx/workbook/defined_name.rb +11 -12
  76. data/lib/axlsx/workbook/defined_names.rb +2 -2
  77. data/lib/axlsx/workbook/shared_strings_table.rb +5 -5
  78. data/lib/axlsx/workbook/workbook.rb +19 -12
  79. data/lib/axlsx/workbook/workbook_view.rb +78 -0
  80. data/lib/axlsx/workbook/workbook_views.rb +22 -0
  81. data/lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb +2 -2
  82. data/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +1 -3
  83. data/lib/axlsx/workbook/worksheet/break.rb +1 -3
  84. data/lib/axlsx/workbook/worksheet/cell.rb +128 -73
  85. data/lib/axlsx/workbook/worksheet/cell_serializer.rb +50 -40
  86. data/lib/axlsx/workbook/worksheet/cfvo.rb +1 -3
  87. data/lib/axlsx/workbook/worksheet/cfvos.rb +1 -1
  88. data/lib/axlsx/workbook/worksheet/col.rb +7 -10
  89. data/lib/axlsx/workbook/worksheet/col_breaks.rb +2 -2
  90. data/lib/axlsx/workbook/worksheet/comment.rb +5 -6
  91. data/lib/axlsx/workbook/worksheet/comments.rb +9 -12
  92. data/lib/axlsx/workbook/worksheet/conditional_formatting.rb +1 -1
  93. data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +1 -1
  94. data/lib/axlsx/workbook/worksheet/data_bar.rb +4 -6
  95. data/lib/axlsx/workbook/worksheet/data_validation.rb +6 -4
  96. data/lib/axlsx/workbook/worksheet/dimension.rb +2 -2
  97. data/lib/axlsx/workbook/worksheet/header_footer.rb +6 -8
  98. data/lib/axlsx/workbook/worksheet/icon_set.rb +3 -5
  99. data/lib/axlsx/workbook/worksheet/merged_cells.rb +2 -2
  100. data/lib/axlsx/workbook/worksheet/page_margins.rb +1 -3
  101. data/lib/axlsx/workbook/worksheet/page_set_up_pr.rb +1 -1
  102. data/lib/axlsx/workbook/worksheet/page_setup.rb +21 -23
  103. data/lib/axlsx/workbook/worksheet/pane.rb +1 -3
  104. data/lib/axlsx/workbook/worksheet/pivot_table.rb +17 -24
  105. data/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +4 -4
  106. data/lib/axlsx/workbook/worksheet/print_options.rb +1 -3
  107. data/lib/axlsx/workbook/worksheet/protected_range.rb +1 -3
  108. data/lib/axlsx/workbook/worksheet/protected_ranges.rb +1 -1
  109. data/lib/axlsx/workbook/worksheet/rich_text.rb +35 -0
  110. data/lib/axlsx/workbook/worksheet/rich_text_run.rb +254 -0
  111. data/lib/axlsx/workbook/worksheet/row.rb +33 -51
  112. data/lib/axlsx/workbook/worksheet/row_breaks.rb +2 -2
  113. data/lib/axlsx/workbook/worksheet/selection.rb +1 -3
  114. data/lib/axlsx/workbook/worksheet/sheet_data.rb +3 -1
  115. data/lib/axlsx/workbook/worksheet/sheet_protection.rb +1 -3
  116. data/lib/axlsx/workbook/worksheet/table.rb +6 -6
  117. data/lib/axlsx/workbook/worksheet/table_style_info.rb +1 -3
  118. data/lib/axlsx/workbook/worksheet/tables.rb +1 -1
  119. data/lib/axlsx/workbook/worksheet/worksheet.rb +59 -30
  120. data/lib/axlsx/workbook/worksheet/worksheet_hyperlinks.rb +3 -3
  121. data/test/drawing/tc_axis.rb +27 -0
  122. data/test/drawing/tc_bubble_chart.rb +44 -0
  123. data/test/drawing/tc_bubble_series.rb +21 -0
  124. data/test/drawing/tc_data_source.rb +6 -0
  125. data/test/drawing/tc_line_chart.rb +5 -5
  126. data/test/drawing/tc_line_series.rb +10 -2
  127. data/test/drawing/tc_pic.rb +4 -0
  128. data/test/drawing/tc_scatter_series.rb +25 -1
  129. data/test/tc_helper.rb +1 -1
  130. data/test/tc_package.rb +7 -1
  131. data/test/util/tc_simple_typed_list.rb +1 -2
  132. data/test/workbook/tc_defined_name.rb +12 -4
  133. data/test/workbook/tc_workbook.rb +16 -2
  134. data/test/workbook/tc_workbook_view.rb +50 -0
  135. data/test/workbook/worksheet/auto_filter/tc_filters.rb +1 -1
  136. data/test/workbook/worksheet/tc_break.rb +1 -1
  137. data/test/workbook/worksheet/tc_cell.rb +30 -4
  138. data/test/workbook/worksheet/tc_col.rb +2 -2
  139. data/test/workbook/worksheet/tc_conditional_formatting.rb +2 -2
  140. data/test/workbook/worksheet/tc_data_bar.rb +1 -1
  141. data/test/workbook/worksheet/tc_data_validation.rb +11 -11
  142. data/test/workbook/worksheet/tc_header_footer.rb +2 -2
  143. data/test/workbook/worksheet/tc_icon_set.rb +1 -1
  144. data/test/workbook/worksheet/tc_page_setup.rb +3 -3
  145. data/test/workbook/worksheet/tc_print_options.rb +1 -1
  146. data/test/workbook/worksheet/tc_rich_text.rb +44 -0
  147. data/test/workbook/worksheet/tc_rich_text_run.rb +172 -0
  148. data/test/workbook/worksheet/tc_row.rb +2 -2
  149. data/test/workbook/worksheet/tc_sheet_calc_pr.rb +1 -1
  150. data/test/workbook/worksheet/tc_sheet_format_pr.rb +4 -4
  151. data/test/workbook/worksheet/tc_sheet_protection.rb +5 -5
  152. data/test/workbook/worksheet/tc_sheet_view.rb +4 -4
  153. data/test/workbook/worksheet/tc_worksheet.rb +49 -10
  154. metadata +81 -55
  155. data/test/axlsx.qcachegrind +0 -2226
@@ -3,10 +3,10 @@ module Axlsx
3
3
  # A Row is a single row in a worksheet.
4
4
  # @note The recommended way to manage rows and cells is to use Worksheet#add_row
5
5
  # @see Worksheet#add_row
6
- class Row
7
-
6
+ class Row < SimpleTypedList
8
7
  include SerializedAttributes
9
8
  include Accessors
9
+
10
10
  # No support is provided for the following attributes
11
11
  # spans
12
12
  # thickTop
@@ -28,11 +28,10 @@ module Axlsx
28
28
  # @see Row#array_to_cells
29
29
  # @see Cell
30
30
  def initialize(worksheet, values=[], options={})
31
- @ht = nil
32
31
  self.worksheet = worksheet
33
- @cells = SimpleTypedList.new Cell
34
- @worksheet.rows << self
35
- self.height = options.delete(:height) if options[:height]
32
+ super(Cell, nil, values.size)
33
+ self.height = options.delete(:height)
34
+ worksheet.rows << self
36
35
  array_to_cells(values, options)
37
36
  end
38
37
 
@@ -46,14 +45,10 @@ module Axlsx
46
45
  # @return [Worksheet]
47
46
  attr_reader :worksheet
48
47
 
49
- # The cells this row holds
50
- # @return [SimpleTypedList]
51
- attr_reader :cells
52
-
53
48
  # Row height measured in point size. There is no margin padding on row height.
54
49
  # @return [Float]
55
50
  def height
56
- @ht
51
+ defined?(@ht) ? @ht : nil
57
52
  end
58
53
 
59
54
  # Outlining level of the row, when outlining is on
@@ -77,11 +72,12 @@ module Axlsx
77
72
  Axlsx.validate_unsigned_numeric(v)
78
73
  @outline_level = v
79
74
  end
75
+
80
76
  alias :outlineLevel= :outline_level=
81
77
 
82
78
  # The index of this row in the worksheet
83
79
  # @return [Integer]
84
- def index
80
+ def row_index
85
81
  worksheet.rows.index(self)
86
82
  end
87
83
 
@@ -90,50 +86,48 @@ module Axlsx
90
86
  # @param [String] str The string this rows xml will be appended to.
91
87
  # @return [String]
92
88
  def to_xml_string(r_index, str = '')
93
- str << '<row '
94
- serialized_attributes(str, { :r => r_index + 1 })
95
- str << '>'
96
- @cells.each_with_index { |cell, c_index| cell.to_xml_string(r_index, c_index, str) }
97
- str << '</row>'
89
+ serialized_tag('row', str, :r => r_index + 1) do
90
+ tmp = '' # time / memory tradeoff, lots of calls to rubyzip costs more
91
+ # time..
92
+ each_with_index { |cell, c_index| cell.to_xml_string(r_index, c_index, tmp) }
93
+ str << tmp
94
+ end
98
95
  end
99
96
 
100
- # Adds a single sell to the row based on the data provided and updates the worksheet's autofit data.
97
+ # Adds a single cell to the row based on the data provided and updates the worksheet's autofit data.
101
98
  # @return [Cell]
102
- def add_cell(value="", options={})
99
+ def add_cell(value = '', options = {})
103
100
  c = Cell.new(self, value, options)
104
- worksheet.send(:update_column_info, self.cells, [])
101
+ self << c
102
+ worksheet.send(:update_column_info, self, [])
105
103
  c
106
104
  end
107
105
 
108
106
  # sets the style for every cell in this row
109
107
  def style=(style)
110
- cells.each_with_index do | cell, index |
111
- s = style.is_a?(Array) ? style[index] : style
112
- cell.style = s
108
+ each_with_index do | cell, index |
109
+ cell.style = style.is_a?(Array) ? style[index] : style
113
110
  end
114
111
  end
115
112
 
116
- # returns the cells in this row as an array
117
- # This lets us transpose the rows into columns
118
- # @return [Array]
119
- def to_ary
120
- @cells.to_ary
121
- end
122
-
123
113
  # @see height
124
114
  def height=(v)
125
- Axlsx::validate_unsigned_numeric(v)
126
115
  unless v.nil?
127
- @ht = v
116
+ Axlsx::validate_unsigned_numeric(v)
128
117
  @custom_height = true
118
+ @ht = v
129
119
  end
130
- @ht
120
+ end
121
+
122
+ # return cells
123
+ def cells
124
+ self
131
125
  end
132
126
 
133
127
  private
134
128
 
135
129
  # assigns the owning worksheet for this row
136
- def worksheet=(v) DataTypeValidator.validate "Row.worksheet", Worksheet, v; @worksheet=v; end
130
+ def worksheet=(v) DataTypeValidator.validate :row_worksheet, Worksheet, v; @worksheet=v; end
137
131
 
138
132
  # Converts values, types, and style options into cells and associates them with this row.
139
133
  # A new cell is created for each item in the values array.
@@ -145,26 +139,14 @@ module Axlsx
145
139
  # @option options [Array, Symbol] types
146
140
  # @option options [Array, Integer] style
147
141
  def array_to_cells(values, options={})
148
- values = values
149
- DataTypeValidator.validate 'Row.array_to_cells', Array, values
142
+ DataTypeValidator.validate :array_to_cells, Array, values
150
143
  types, style, formula_values = options.delete(:types), options.delete(:style), options.delete(:formula_values)
151
144
  values.each_with_index do |value, index|
145
+ options[:style] = style.is_a?(Array) ? style[index] : style if style
146
+ options[:type] = types.is_a?(Array) ? types[index] : types if types
147
+ options[:formula_value] = formula_values[index] if formula_values.is_a?(Array)
152
148
 
153
- #WTF IS THIS PAP?
154
- cell_style = style.is_a?(Array) ? style[index] : style
155
- options[:style] = cell_style if cell_style
156
-
157
- cell_type = types.is_a?(Array)? types[index] : types
158
- options[:type] = cell_type if cell_type
159
-
160
- formula_value = formula_values[index] if formula_values.is_a?(Array)
161
- options[:formula_value] = formula_value if formula_value
162
-
163
- Cell.new(self, value, options)
164
-
165
- options.delete(:style)
166
- options.delete(:type)
167
- options.delete(:formula_value)
149
+ self[index] = Cell.new(self, value, options)
168
150
  end
169
151
  end
170
152
  end
@@ -14,7 +14,7 @@ module Axlsx
14
14
  # @see Break
15
15
  def add_break(options)
16
16
  # force feed the excel default
17
- @list << Break.new(options.merge(:max => 16383, :man => true))
17
+ self << Break.new(options.merge(:max => 16383, :man => true))
18
18
  last
19
19
  end
20
20
 
@@ -25,7 +25,7 @@ module Axlsx
25
25
  # </rowBreaks>
26
26
  def to_xml_string(str='')
27
27
  return if empty?
28
- str << '<rowBreaks count="' << @list.size.to_s << '" manualBreakCount="' << @list.size.to_s << '">'
28
+ str << ('<rowBreaks count="' << self.size.to_s << '" manualBreakCount="' << self.size.to_s << '">')
29
29
  each { |brk| brk.to_xml_string(str) }
30
30
  str << '</rowBreaks>'
31
31
  end
@@ -95,9 +95,7 @@ module Axlsx
95
95
  # @param [String] str
96
96
  # @return [String]
97
97
  def to_xml_string(str = '')
98
- str << '<selection '
99
- serialized_attributes str
100
- str << '/>'
98
+ serialized_tag 'selection', str
101
99
  end
102
100
  end
103
101
  end
@@ -17,7 +17,9 @@ module Axlsx
17
17
  # @return [String]
18
18
  def to_xml_string(str = '')
19
19
  str << '<sheetData>'
20
- worksheet.rows.each_with_index{ |row, index| row.to_xml_string(index, str) }
20
+ worksheet.rows.each_with_index do |row, index|
21
+ row.to_xml_string(index, str)
22
+ end
21
23
  str << '</sheetData>'
22
24
  end
23
25
 
@@ -76,9 +76,7 @@ module Axlsx
76
76
  # @param [String] str
77
77
  # @return [String]
78
78
  def to_xml_string(str = '')
79
- str << '<sheetProtection '
80
- serialized_attributes str
81
- str << '/>'
79
+ serialized_tag('sheetProtection', str)
82
80
  end
83
81
 
84
82
  private
@@ -58,7 +58,7 @@ module Axlsx
58
58
  # @param [String, Cell] v
59
59
  # @return [Title]
60
60
  def name=(v)
61
- DataTypeValidator.validate "#{self.class}.name", [String], v
61
+ DataTypeValidator.validate :table_name, [String], v
62
62
  if v.is_a?(String)
63
63
  @name = v
64
64
  end
@@ -75,12 +75,12 @@ module Axlsx
75
75
  # @return [String]
76
76
  def to_xml_string(str = '')
77
77
  str << '<?xml version="1.0" encoding="UTF-8"?>'
78
- str << '<table xmlns="' << XML_NS << '" id="' << (index+1).to_s << '" name="' << @name << '" displayName="' << @name.gsub(/\s/,'_') << '" '
79
- str << 'ref="' << @ref << '" totalsRowShown="0">'
80
- str << '<autoFilter ref="' << @ref << '"/>'
81
- str << '<tableColumns count="' << header_cells.length.to_s << '">'
78
+ str << ('<table xmlns="' << XML_NS << '" id="' << (index+1).to_s << '" name="' << @name << '" displayName="' << @name.gsub(/\s/,'_') << '" ')
79
+ str << ('ref="' << @ref << '" totalsRowShown="0">')
80
+ str << ('<autoFilter ref="' << @ref << '"/>')
81
+ str << ('<tableColumns count="' << header_cells.length.to_s << '">')
82
82
  header_cells.each_with_index do |cell,index|
83
- str << '<tableColumn id ="' << (index+1).to_s << '" name="' << cell.value << '"/>'
83
+ str << ('<tableColumn id ="' << (index+1).to_s << '" name="' << cell.value << '"/>')
84
84
  end
85
85
  str << '</tableColumns>'
86
86
  table_style_info.to_xml_string(str)
@@ -43,9 +43,7 @@ module Axlsx
43
43
  # seralizes this object to an xml string
44
44
  # @param [String] str the string to contact this objects serialization to.
45
45
  def to_xml_string(str = '')
46
- str << '<tableStyleInfo '
47
- serialized_attributes str
48
- str << '/>'
46
+ serialized_tag('tableStyleInfo', str)
49
47
  end
50
48
  end
51
49
  end
@@ -23,7 +23,7 @@ module Axlsx
23
23
  def to_xml_string(str = "")
24
24
  return if empty?
25
25
  str << "<tableParts count='#{size}'>"
26
- @list.each { |table| str << "<tablePart r:id='#{table.rId}'/>" }
26
+ each { |table| str << "<tablePart r:id='#{table.rId}'/>" }
27
27
  str << '</tableParts>'
28
28
  end
29
29
  end
@@ -4,15 +4,11 @@ module Axlsx
4
4
  # The Worksheet class represents a worksheet in the workbook.
5
5
  class Worksheet
6
6
  include Axlsx::OptionsParser
7
-
7
+ include Axlsx::SerializedAttributes
8
8
  # definition of characters which are less than the maximum width of 0-9 in the default font for use in String#count.
9
9
  # This is used for autowidth calculations
10
- # @return [String]
11
- def self.thin_chars
12
- # removed 'e' and 'y' from this list - as a GUESS
13
- @thin_chars ||= "^.acfijklrstxzFIJL()-"
14
- end
15
-
10
+ THIN_CHARS = '^.acfijklrstxzFIJL()-'.freeze
11
+
16
12
  # Creates a new worksheet.
17
13
  # @note the recommended way to manage worksheets is Workbook#add_worksheet
18
14
  # @see Workbook#add_worksheet
@@ -24,12 +20,15 @@ module Axlsx
24
20
  def initialize(wb, options={})
25
21
  self.workbook = wb
26
22
  @sheet_protection = nil
27
-
28
23
  initialize_page_options(options)
29
24
  parse_options options
30
25
  @workbook.worksheets << self
26
+ @sheet_id = index + 1
27
+ yield self if block_given?
31
28
  end
32
29
 
30
+ serializable_attributes :sheet_id, :name, :state
31
+
33
32
  # Initalizes page margin, setup and print options
34
33
  # @param [Hash] options Options passed in from the initializer
35
34
  def initialize_page_options(options)
@@ -44,7 +43,23 @@ module Axlsx
44
43
  # The name of the worksheet
45
44
  # @return [String]
46
45
  def name
47
- @name ||= "Sheet" + (index+1).to_s
46
+ @name ||= "Sheet" + (index+1).to_s
47
+ end
48
+
49
+ # Specifies the visible state of this sheet. Allowed states are
50
+ # :visible, :hidden or :very_hidden. The default value is :visible.
51
+ #
52
+ # Worksheets in the :hidden state can be shown using the sheet formatting properties in excel.
53
+ # :very_hidden sheets should be inaccessible to end users.
54
+ # @param [Symbol] sheet_state The visible state for this sheet.
55
+ def state=(sheet_state)
56
+ RestrictionValidator.validate :worksheet_state, [:visible, :hidden, :very_hidden], sheet_state
57
+ @state = sheet_state
58
+ end
59
+
60
+ # The visibility of this sheet
61
+ def state
62
+ @state ||= :visible
48
63
  end
49
64
 
50
65
  # The sheet calculation properties
@@ -129,7 +144,7 @@ module Axlsx
129
144
  # @return [SimpleTypedList]
130
145
  # @see Worksheet#add_row
131
146
  def rows
132
- @rows ||= SimpleTypedList.new Row
147
+ @rows ||= SimpleTypedList.new Row
133
148
  end
134
149
 
135
150
  # returns the sheet data as columns
@@ -142,7 +157,7 @@ module Axlsx
142
157
  @rows.transpose(&block)
143
158
  end
144
159
 
145
- # An range that excel will apply an auto-filter to "A1:B3"
160
+ # A range that excel will apply an auto-filter to "A1:B3"
146
161
  # This will turn filtering on for the cells in the range.
147
162
  # The first row is considered the header, while subsequent rows are considered to be data.
148
163
  # @return String
@@ -346,7 +361,7 @@ module Axlsx
346
361
  # @param [String] v
347
362
  # @see auto_filter
348
363
  def auto_filter=(v)
349
- DataTypeValidator.validate "Worksheet.auto_filter", String, v
364
+ DataTypeValidator.validate :worksheet_auto_filter, String, v
350
365
  auto_filter.range = v
351
366
  end
352
367
 
@@ -427,10 +442,10 @@ module Axlsx
427
442
  # @option options [Array] widths each member of the widths array will affect how auto_fit behavies.
428
443
  # @option options [Float] height the row's height (in points)
429
444
  def add_row(values=[], options={})
430
- Row.new(self, values, options)
431
- update_column_info @rows.last.cells, options.delete(:widths) || []
432
- yield @rows.last if block_given?
433
- @rows.last
445
+ row = Row.new(self, values, options)
446
+ update_column_info row, options.delete(:widths)
447
+ yield row if block_given?
448
+ row
434
449
  end
435
450
 
436
451
  alias :<< :add_row
@@ -522,7 +537,7 @@ module Axlsx
522
537
  # @example
523
538
  # ws.add_page_break("A4")
524
539
  def add_page_break(cell)
525
- DataTypeValidator.validate "Worksheet#add_page_break cell", [String, Cell], cell
540
+ DataTypeValidator.validate :worksheet_page_break, [String, Cell], cell
526
541
  column_index, row_index = if cell.is_a?(String)
527
542
  Axlsx.name_to_indices(cell)
528
543
  else
@@ -535,7 +550,7 @@ module Axlsx
535
550
  end
536
551
 
537
552
  # This is a helper method that Lets you specify a fixed width for multiple columns in a worksheet in one go.
538
- # Axlsx is sparse, so if you have not set data for a column, you cannot set the width.
553
+ # Note that you must call column_widths AFTER adding data, otherwise the width will not be set successfully.
539
554
  # Setting a fixed column width to nil will revert the behaviour back to calculating the width for you on the next call to add_row.
540
555
  # @example This would set the first and third column widhts but leave the second column in autofit state.
541
556
  # ws.column_widths 7.2, nil, 3
@@ -559,7 +574,7 @@ module Axlsx
559
574
  # @see README.md for an example
560
575
  def col_style(index, style, options={})
561
576
  offset = options.delete(:row_offset) || 0
562
- cells = @rows[(offset..-1)].map { |row| row.cells[index] }.flatten.compact
577
+ cells = @rows[(offset..-1)].map { |row| row[index] }.flatten.compact
563
578
  cells.each { |cell| cell.style = style }
564
579
  end
565
580
 
@@ -577,18 +592,26 @@ module Axlsx
577
592
  cells.each { |cell| cell.style = style }
578
593
  end
579
594
 
595
+ # Returns a sheet node serialization for this sheet in the workbook.
596
+ def to_sheet_node_xml_string(str='')
597
+ add_autofilter_defined_name_to_workbook
598
+ str << '<sheet '
599
+ serialized_attributes str
600
+ str << ('r:id="' << rId << '"></sheet>')
601
+ end
602
+
580
603
  # Serializes the worksheet object to an xml string
581
604
  # This intentionally does not use nokogiri for performance reasons
582
605
  # @return [String]
583
- def to_xml_string
606
+ def to_xml_string str=''
607
+ add_autofilter_defined_name_to_workbook
584
608
  auto_filter.apply if auto_filter.range
585
- str = '<?xml version="1.0" encoding="UTF-8"?>'
609
+ str << '<?xml version="1.0" encoding="UTF-8"?>'
586
610
  str << worksheet_node
587
611
  serializable_parts.each do |item|
588
612
  item.to_xml_string(str) if item
589
613
  end
590
614
  str << '</worksheet>'
591
- Axlsx::sanitize(str)
592
615
  end
593
616
 
594
617
  # The worksheet relationships. This is managed automatically by the worksheet
@@ -622,7 +645,7 @@ module Axlsx
622
645
  def name_to_cell(name)
623
646
  col_index, row_index = *Axlsx::name_to_indices(name)
624
647
  r = rows[row_index]
625
- r.cells[col_index] if r
648
+ r[col_index] if r
626
649
  end
627
650
 
628
651
  # shortcut method to access styles direclty from the worksheet
@@ -675,7 +698,7 @@ module Axlsx
675
698
  end
676
699
 
677
700
  def validate_sheet_name(name)
678
- DataTypeValidator.validate "Worksheet.name", String, name
701
+ DataTypeValidator.validate :worksheet_name, String, name
679
702
  raise ArgumentError, (ERR_SHEET_NAME_TOO_LONG % name) if name.size > 31
680
703
  raise ArgumentError, (ERR_SHEET_NAME_CHARACTER_FORBIDDEN % name) if '[]*/\?:'.chars.any? { |char| name.include? char }
681
704
  name = Axlsx::coder.encode(name)
@@ -695,8 +718,8 @@ module Axlsx
695
718
  def range(*cell_def)
696
719
  first, last = cell_def
697
720
  cells = []
698
- rows[(first.row.index..last.row.index)].each do |r|
699
- r.cells[(first.index..last.index)].each do |c|
721
+ rows[(first.row.row_index..last.row.row_index)].each do |r|
722
+ r[(first.index..last.index)].each do |c|
700
723
  cells << c
701
724
  end
702
725
  end
@@ -734,7 +757,7 @@ module Axlsx
734
757
  # Helper method for parsingout the root node for worksheet
735
758
  # @return [String]
736
759
  def worksheet_node
737
- "<worksheet xmlns=\"%s\" xmlns:r=\"%s\" xml:space=\"#{xml_space}\">" % [XML_NS, XML_NS_R]
760
+ "<worksheet xmlns=\"#{XML_NS}\" xmlns:r=\"#{XML_NS_R}\" xml:space=\"#{xml_space}\">"
738
761
  end
739
762
 
740
763
  def sheet_data
@@ -753,11 +776,12 @@ module Axlsx
753
776
 
754
777
  def workbook=(v) DataTypeValidator.validate "Worksheet.workbook", Workbook, v; @workbook = v; end
755
778
 
756
- def update_column_info(cells, widths=[])
779
+ def update_column_info(cells, widths=nil)
757
780
  cells.each_with_index do |cell, index|
781
+ width = widths ? widths[index] : nil
758
782
  col = find_or_create_column_info(index)
759
- next if widths[index] == :ignore
760
- col.update_width(cell, widths[index], workbook.use_autowidth)
783
+ next if width == :ignore
784
+ col.update_width(cell, width, workbook.use_autowidth)
761
785
  end
762
786
  end
763
787
 
@@ -765,5 +789,10 @@ module Axlsx
765
789
  column_info[index] ||= Col.new(index + 1, index + 1)
766
790
  end
767
791
 
792
+ def add_autofilter_defined_name_to_workbook
793
+ return if !auto_filter.range
794
+ workbook.add_defined_name auto_filter.defined_name, name: '_xlnm._FilterDatabase', local_sheet_id: index, hidden: 1
795
+ end
796
+
768
797
  end
769
798
  end