axlsx 1.2.3 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. data/.yardopts +3 -2
  2. data/CHANGELOG.md +34 -1
  3. data/README.md +26 -37
  4. data/Rakefile +1 -1
  5. data/examples/auto_filter.rb +16 -0
  6. data/examples/auto_filter.xlsx +0 -0
  7. data/examples/example.rb +3 -2
  8. data/examples/example.xlsx +0 -0
  9. data/examples/example_streamed.xlsx +0 -0
  10. data/examples/no-use_autowidth.xlsx +0 -0
  11. data/examples/shared_strings_example.xlsx +0 -0
  12. data/examples/skydrive/real_example.rb +6 -6
  13. data/examples/sprk2012/Screen Shot 2012-09-11 at 10.42.06 PM.png +0 -0
  14. data/examples/sprk2012/Screen Shot 2012-09-11 at 11.07.48 PM.png +0 -0
  15. data/examples/sprk2012/Screen Shot 2012-09-11 at 8.31.50 PM.png +0 -0
  16. data/examples/sprk2012/Screen Shot 2012-09-11 at 9.23.27 PM.png +0 -0
  17. data/examples/sprk2012/Screen Shot 2012-09-11 at 9.32.06 PM.png +0 -0
  18. data/examples/sprk2012/Screen Shot 2012-09-11 at 9.33.35 PM.png +0 -0
  19. data/examples/sprk2012/Screen Shot 2012-09-11 at 9.46.44 PM.png +0 -0
  20. data/examples/sprk2012/Screen Shot 2012-09-12 at 5.07.23 PM.png +0 -0
  21. data/examples/sprk2012/basics.rb +1 -0
  22. data/examples/sprk2012/basics.xlsx +0 -0
  23. data/examples/sprk2012/gravatar.jpeg +0 -0
  24. data/examples/sprk2012/hair_club.jpg +0 -0
  25. data/examples/sprk2012/images.rb +7 -12
  26. data/examples/sprk2012/images.xlsx +0 -0
  27. data/examples/sprk2012/line_chart.rb +56 -0
  28. data/examples/sprk2012/line_chart.xlsx +0 -0
  29. data/examples/sprk2012/sprk2012.key +0 -0
  30. data/examples/sprk2012/styles.rb +13 -12
  31. data/examples/sprk2012/styles.xlsx +0 -0
  32. data/examples/styles.rb +62 -0
  33. data/examples/styles.xlsx +0 -0
  34. data/lib/axlsx.rb +8 -1
  35. data/lib/axlsx/stylesheet/styles.rb +4 -0
  36. data/lib/axlsx/util/constants.rb +90 -5
  37. data/lib/axlsx/util/validators.rb +26 -8
  38. data/lib/axlsx/version.rb +2 -2
  39. data/lib/axlsx/workbook/workbook.rb +4 -1
  40. data/lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb +77 -0
  41. data/lib/axlsx/workbook/worksheet/auto_filter/filter_column.rb +102 -0
  42. data/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +253 -0
  43. data/lib/axlsx/workbook/worksheet/cell.rb +9 -4
  44. data/lib/axlsx/workbook/worksheet/date_time_converter.rb +1 -1
  45. data/lib/axlsx/workbook/worksheet/page_set_up_pr.rb +47 -0
  46. data/lib/axlsx/workbook/worksheet/sheet_calc_pr.rb +49 -0
  47. data/lib/axlsx/workbook/worksheet/sheet_pr.rb +87 -4
  48. data/lib/axlsx/workbook/worksheet/table.rb +8 -1
  49. data/lib/axlsx/workbook/worksheet/table_style_info.rb +68 -0
  50. data/lib/axlsx/workbook/worksheet/worksheet.rb +18 -3
  51. data/test/stylesheet/tc_styles.rb +13 -0
  52. data/test/util/tc_validators.rb +8 -1
  53. data/test/workbook/worksheet/auto_filter/tc_auto_filter.rb +38 -0
  54. data/test/workbook/worksheet/auto_filter/tc_filter_column.rb +76 -0
  55. data/test/workbook/worksheet/auto_filter/tc_filters.rb +50 -0
  56. data/test/workbook/worksheet/tc_cell.rb +5 -0
  57. data/test/workbook/worksheet/tc_page_set_up_pr.rb +15 -0
  58. data/test/workbook/worksheet/tc_sheet_calc_pr.rb +18 -0
  59. data/test/workbook/worksheet/tc_sheet_pr.rb +27 -0
  60. data/test/workbook/worksheet/{table/tc_table.rb → tc_table.rb} +6 -1
  61. data/test/workbook/worksheet/tc_table_style_info.rb +53 -0
  62. data/test/workbook/worksheet/tc_worksheet.rb +17 -3
  63. metadata +45 -7
  64. data/examples/~$extractive.xlsx +0 -0
  65. data/lib/axlsx/workbook/worksheet/auto_filter.rb +0 -35
Binary file
@@ -37,7 +37,12 @@ if !Object.respond_to?(:instance_values)
37
37
  end
38
38
  end
39
39
 
40
- # xlsx generation with charts, images, automated column width, customizable styles and full schema validation. Axlsx excels at helping you generate beautiful Office Open XML Spreadsheet documents without having to understand the entire ECMA specification. Check out the README for some examples of how easy it is. Best of all, you can validate your xlsx file before serialization so you know for sure that anything generated is going to load on your client's machine.
40
+ # xlsx generation with charts, images, automated column width, customizable styles
41
+ # and full schema validation. Axlsx excels at helping you generate beautiful
42
+ # Office Open XML Spreadsheet documents without having to understand the entire
43
+ # ECMA specification. Check out the README for some examples of how easy it is.
44
+ # Best of all, you can validate your xlsx file before serialization so you know
45
+ # for sure that anything generated is going to load on your client's machine.
41
46
  module Axlsx
42
47
 
43
48
  # determines the cell range for the items provided
@@ -65,6 +70,7 @@ module Axlsx
65
70
  # returns the x, y position of a cell
66
71
  def self.name_to_indices(name)
67
72
  raise ArgumentError, 'invalid cell name' unless name.size > 1
73
+ # capitalization?!?
68
74
  v = name[/[A-Z]+/].reverse.chars.reduce({:base=>1, :i=>0}) do |val, c|
69
75
  val[:i] += ((c.bytes.first - 64) * val[:base]); val[:base] *= 26; val
70
76
  end
@@ -95,6 +101,7 @@ module Axlsx
95
101
  # @param [String] s The snake case string to camelize
96
102
  # @return [String]
97
103
  def self.camel(s="", all_caps = true)
104
+ s = s.to_s
98
105
  s = s.capitalize if all_caps
99
106
  s.gsub(/_(.)/){ $1.upcase }
100
107
  end
@@ -279,6 +279,10 @@ module Axlsx
279
279
  # @return [Font|Integer]
280
280
  def parse_font_options(options={})
281
281
  return if (options.keys & [:fg_color, :sz, :b, :i, :u, :strike, :outline, :shadow, :charset, :family, :font_name]).empty?
282
+ fonts.first.instance_values.each do |key, value|
283
+ # Thanks for that 1.8.7 - cant do a simple merge...
284
+ options[key.to_sym] = value unless options.keys.include?(key.to_sym)
285
+ end
282
286
  font = Font.new(options)
283
287
  font.color = Color.new(:rgb => options[:fg_color]) if options[:fg_color]
284
288
  font.name = options[:font_name] if options[:font_name]
@@ -1,4 +1,3 @@
1
- # encoding: UTF-8
2
1
  module Axlsx
3
2
 
4
3
  # XML Encoding
@@ -129,7 +128,7 @@ module Axlsx
129
128
 
130
129
  # digital signature origin content type
131
130
  DIGITAL_SIGNATURE_ORIGIN_CT = "application/vnd.openxmlformats-package.digital-signature-origin"
132
-
131
+
133
132
  # digital signature certificate content type
134
133
  DIGITAL_SIGNATURE_CERTIFICATE_CT = "application/vnd.openxmlformats-package.digital-signature-certificate"
135
134
 
@@ -151,7 +150,7 @@ module Axlsx
151
150
  #drawing content type
152
151
  DRAWING_CT = "application/vnd.openxmlformats-officedocument.drawing+xml"
153
152
 
154
-
153
+
155
154
  # xml content type extensions
156
155
  XML_EX = "xml"
157
156
 
@@ -263,11 +262,14 @@ module Axlsx
263
262
  # error message for RegexValidator
264
263
  ERR_REGEX = "Invalid Data. %s does not match %s."
265
264
 
265
+ # error message for RangeValidator
266
+ ERR_RANGE = "Invalid Data. %s must be between %s and %s, (inclusive:%s) you gave: %s"
267
+
266
268
  # error message for sheets that use a name which is longer than 31 bytes
267
269
  ERR_SHEET_NAME_TOO_LONG = "Your worksheet name '%s' is too long. Worksheet names must be 31 characters (bytes) or less"
268
-
270
+
269
271
  # error message for sheets that use a name which includes a colon
270
-
272
+
271
273
  ERR_SHEET_NAME_COLON_FORBIDDEN = "Your worksheet name '%s' contains a colon, which is not allowed by MS Excel and will cause repair warnings. Please change the name of your sheet."
272
274
 
273
275
  # error message for duplicate sheet names
@@ -284,4 +286,87 @@ module Axlsx
284
286
 
285
287
  # error message for non 'integerish' value
286
288
  ERR_INTEGERISH = "You value must be, or be castable via to_i, an Integer. You provided %s"
289
+
290
+ # Regex to match forbidden control characters
291
+ # The following will be automatically stripped from worksheets.
292
+ #
293
+ # x00 Null
294
+ # x01 Start Of Heading
295
+ # x02 Start Of Text
296
+ # x03End Of Text
297
+ # x04 End Of Transmission
298
+ # x05 Enquiry
299
+ # x06 Acknowledge
300
+ # x07 Bell
301
+ # x08 Backspace
302
+ # x0B Line Tabulation
303
+ # x0C Form Feed
304
+ # x0E Shift Out
305
+ # x0F Shift In
306
+ # x10 Data Link Escape
307
+ # x11 Device Control One
308
+ # x12 Device Control Two
309
+ # x13 Device Control Three
310
+ # x14 Device Control Four
311
+ # x15 Negative Acknowledge
312
+ # x16 Synchronous Idle
313
+ # x17 End Of Transmission Block
314
+ # x18 Cancel
315
+ # x19 End Of Medium
316
+ # x1A Substitute
317
+ # x1B Escape
318
+ # x1C Information Separator Four
319
+ # x1D Information Separator Three
320
+ # x1E Information Separator Two
321
+ # x1F Information Separator One
322
+ #
323
+ # The following are not dealt with.
324
+ # If you have this in your data, expect excel to blow up!
325
+ #
326
+ # x7F Delete
327
+ # x80 Control 0080
328
+ # x81 Control 0081
329
+ # x82 Break Permitted Here
330
+ # x83 No Break Here
331
+ # x84 Control 0084
332
+ # x85 Next Line (Nel)
333
+ # x86 Start Of Selected Area
334
+ # x87 End Of Selected Area
335
+ # x88 Character Tabulation Set
336
+ # x89 Character Tabulation With Justification
337
+ # x8A Line Tabulation Set
338
+ # x8B Partial Line Forward
339
+ # x8C Partial Line Backward
340
+ # x8D Reverse Line Feed
341
+ # x8E Single Shift Two
342
+ # x8F Single Shift Three
343
+ # x90 Device Control String
344
+ # x91 Private Use One
345
+ # x92 Private Use Two
346
+ # x93 Set Transmit State
347
+ # x94 Cancel Character
348
+ # x95 Message Waiting
349
+ # x96 Start Of Guarded Area
350
+ # x97 End Of Guarded Area
351
+ # x98 Start Of String
352
+ # x99 Control 0099
353
+ # x9A Single Character Introducer
354
+ # x9B Control Sequence Introducer
355
+ # x9C String Terminator
356
+ # x9D Operating System Command
357
+ # x9E Privacy Message
358
+ # x9F Application Program Command
359
+ #
360
+ # The following are allowed:
361
+ #
362
+ # x0A Line Feed (Lf)
363
+ # x0D Carriage Return (Cr)
364
+ # x09 Character Tabulation
365
+ # @see http://www.codetable.net/asciikeycodes
366
+ pattern = "[\x0-\x08\x0B\x0C\x0E-\x1F]"
367
+ pattern= pattern.respond_to?(:encode) ? pattern.encode('UTF-8') : pattern
368
+
369
+ # The regular expression used to remove control characters from worksheets
370
+ CONTROL_CHAR_REGEX = Regexp.new(pattern, 'n')
371
+
287
372
  end
@@ -14,6 +14,24 @@ module Axlsx
14
14
  end
15
15
  end
16
16
 
17
+ # Validate that the value provided is between a specific range
18
+ # Note that no data conversions will be done for you!
19
+ # Comparisons will be made using < and > or <= and <= when the inclusive parameter is true
20
+ class RangeValidator
21
+ # @param [String] name The name of what is being validated
22
+ # @param [Any] min The minimum allowed value
23
+ # @param [Any] max The maximum allowed value
24
+ # @param [Any] value The value to be validated
25
+ # @param [Boolean] inclusive Flag indicating if the comparison should be inclusive.
26
+ def self.validate(name, min, max, value, inclusive = true)
27
+ passes = if inclusive
28
+ min <= value && value <= max
29
+ else
30
+ min < value && value < max
31
+ end
32
+ raise ArgumentError, (ERR_RANGE % [value.inspect, min.to_s, max.to_s, inclusive]) unless passes
33
+ end
34
+ end
17
35
  # Validates the value against the regular expression provided.
18
36
  class RegexValidator
19
37
  # @param [String] name The name of what is being validated. This is included in the output when the value is invalid
@@ -73,7 +91,7 @@ module Axlsx
73
91
  # @raise [ArgumentError] raised if the value is not a Fixnun, Integer, Float value greater or equal to 0
74
92
  # @return [Boolean] true if the data is valid
75
93
  def self.validate_unsigned_numeric(v)
76
- DataTypeValidator.validate("Invalid column width", [Fixnum, Integer, Float], v, lambda { |arg| arg.respond_to?(:>=) && arg >= 0 })
94
+ DataTypeValidator.validate("Invalid column width", [Fixnum, Integer, Float], v, lambda { |arg| arg.respond_to?(:>=) && arg.to_i >= 0 })
77
95
  end
78
96
 
79
97
  # Requires that the value is a Fixnum or Integer
@@ -112,7 +130,7 @@ module Axlsx
112
130
  def self.validate_scale_10_400(v)
113
131
  DataTypeValidator.validate "page_scale", [Fixnum, Integer], v, lambda { |arg| arg >= 10 && arg <= 400 }
114
132
  end
115
-
133
+
116
134
  # Requires that the value is an integer ranging from 10 to 400 or 0.
117
135
  def self.validate_scale_0_10_400(v)
118
136
  DataTypeValidator.validate "page_scale", [Fixnum, Integer], v, lambda { |arg| arg == 0 || (arg >= 10 && arg <= 400) }
@@ -129,7 +147,7 @@ module Axlsx
129
147
  # @param [Any] v The value validated
130
148
  def self.validate_pattern_type(v)
131
149
  RestrictionValidator.validate :pattern_type, [:none, :solid, :mediumGray, :darkGray, :lightGray, :darkHorizontal, :darkVertical, :darkDown, :darkUp, :darkGrid,
132
- :darkTrellis, :lightHorizontal, :lightVertical, :lightDown, :lightUp, :lightGrid, :lightTrellis, :gray125, :gray0625], v
150
+ :darkTrellis, :lightHorizontal, :lightVertical, :lightDown, :lightUp, :lightGrid, :lightTrellis, :gray125, :gray0625], v
133
151
  end
134
152
 
135
153
  # Requires that the value is one of the ST_TimePeriod types
@@ -226,7 +244,7 @@ module Axlsx
226
244
  def self.validate_data_validation_error_style(v)
227
245
  RestrictionValidator.validate :validate_data_validation_error_style, [:information, :stop, :warning], v
228
246
  end
229
-
247
+
230
248
  # Requires that the value is valid data validation operator.
231
249
  # valid operators must be one of lessThan, lessThanOrEqual, equal,
232
250
  # notEqual, greaterThanOrEqual, greaterThan, between, notBetween
@@ -234,28 +252,28 @@ module Axlsx
234
252
  def self.validate_data_validation_operator(v)
235
253
  RestrictionValidator.validate :data_validation_operator, [:lessThan, :lessThanOrEqual, :equal, :notEqual, :greaterThanOrEqual, :greaterThan, :between, :notBetween], v
236
254
  end
237
-
255
+
238
256
  # Requires that the value is valid data validation type.
239
257
  # valid types must be one of custom, data, decimal, list, none, textLength, time, whole
240
258
  # @param [Any] v The value validated
241
259
  def self.validate_data_validation_type(v)
242
260
  RestrictionValidator.validate :data_validation_type, [:custom, :data, :decimal, :list, :none, :textLength, :time, :whole], v
243
261
  end
244
-
262
+
245
263
  # Requires that the value is a valid sheet view type.
246
264
  # valid types must be one of normal, page_break_preview, page_layout
247
265
  # @param [Any] v The value validated
248
266
  def self.validate_sheet_view_type(v)
249
267
  RestrictionValidator.validate :sheet_view_type, [:normal, :page_break_preview, :page_layout], v
250
268
  end
251
-
269
+
252
270
  # Requires that the value is a valid active pane type.
253
271
  # valid types must be one of bottom_left, bottom_right, top_left, top_right
254
272
  # @param [Any] v The value validated
255
273
  def self.validate_pane_type(v)
256
274
  RestrictionValidator.validate :active_pane_type, [:bottom_left, :bottom_right, :top_left, :top_right], v
257
275
  end
258
-
276
+
259
277
  # Requires that the value is a valid split state type.
260
278
  # valid types must be one of frozen, frozen_split, split
261
279
  # @param [Any] v The value validated
@@ -1,5 +1,5 @@
1
- # encoding: UTF-8
2
1
  module Axlsx
2
+
3
3
  # The current version
4
- VERSION="1.2.3"
4
+ VERSION = "1.3.1"
5
5
  end
@@ -1,11 +1,13 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  module Axlsx
3
- require 'axlsx/workbook/worksheet/auto_filter.rb'
3
+ require 'axlsx/workbook/worksheet/sheet_calc_pr.rb'
4
+ require 'axlsx/workbook/worksheet/auto_filter/auto_filter.rb'
4
5
  require 'axlsx/workbook/worksheet/date_time_converter.rb'
5
6
  require 'axlsx/workbook/worksheet/protected_range.rb'
6
7
  require 'axlsx/workbook/worksheet/protected_ranges.rb'
7
8
  require 'axlsx/workbook/worksheet/cell.rb'
8
9
  require 'axlsx/workbook/worksheet/page_margins.rb'
10
+ require 'axlsx/workbook/worksheet/page_set_up_pr.rb'
9
11
  require 'axlsx/workbook/worksheet/page_setup.rb'
10
12
  require 'axlsx/workbook/worksheet/print_options.rb'
11
13
  require 'axlsx/workbook/worksheet/cfvo.rb'
@@ -33,6 +35,7 @@ require 'axlsx/workbook/worksheet/worksheet.rb'
33
35
  require 'axlsx/workbook/shared_strings_table.rb'
34
36
  require 'axlsx/workbook/defined_name.rb'
35
37
  require 'axlsx/workbook/defined_names.rb'
38
+ require 'axlsx/workbook/worksheet/table_style_info.rb'
36
39
  require 'axlsx/workbook/worksheet/table.rb'
37
40
  require 'axlsx/workbook/worksheet/tables.rb'
38
41
  require 'axlsx/workbook/worksheet/data_validation.rb'
@@ -0,0 +1,77 @@
1
+
2
+ require 'axlsx/workbook/worksheet/auto_filter/filter_column.rb'
3
+ require 'axlsx/workbook/worksheet/auto_filter/filters.rb'
4
+
5
+ module Axlsx
6
+
7
+ #This class represents an auto filter range in a worksheet
8
+ class AutoFilter
9
+
10
+ # creates a new Autofilter object
11
+ # @param [Worksheet] worksheet
12
+ def initialize(worksheet)
13
+ raise ArgumentError, 'you must provide a worksheet' unless worksheet.is_a?(Worksheet)
14
+ @worksheet = worksheet
15
+ end
16
+
17
+ attr_reader :worksheet
18
+
19
+ # The range the autofilter should be applied to.
20
+ # This should be a string like 'A1:B8'
21
+ # @return [String]
22
+ attr_accessor :range
23
+
24
+ # the formula for the defined name required for this auto filter
25
+ # This prepends the worksheet name to the absolute cell reference
26
+ # e.g. A1:B2 -> 'Sheet1'!$A$1:$B$2
27
+ # @return [String]
28
+ def defined_name
29
+ return unless range
30
+ Axlsx.cell_range(range.split(':').collect { |name| worksheet.name_to_cell(name)})
31
+ end
32
+
33
+ # A collection of filterColumns for this auto_filter
34
+ # @return [SimpleTypedList]
35
+ def columns
36
+ @columns ||= SimpleTypedList.new FilterColumn
37
+ end
38
+
39
+ # Adds a filter column. This is the recommended way to create and manage filter columns for your autofilter.
40
+ # In addition to the require id and type parameters, options will be passed to the filter column during instantiation.
41
+ # @param [String] col_id Zero-based index indicating the AutoFilter column to which this filter information applies.
42
+ # @param [Symbol] filter_type A symbol representing one of the supported filter types.
43
+ # @param [Hash] options a hash of options to pass into the generated filter
44
+ # @return [FilterColumn]
45
+ def add_column(col_id, filter_type, options = {})
46
+ columns << FilterColumn.new(col_id, filter_type, options)
47
+ columns.last
48
+ end
49
+
50
+ # actually performs the filtering of rows who's cells do not
51
+ # match the filter.
52
+ def apply
53
+ first_cell, last_cell = range.split(':')
54
+ start_point = Axlsx::name_to_indices(first_cell)
55
+ end_point = Axlsx::name_to_indices(last_cell)
56
+ # The +1 is so we skip the header row with the filter drop downs
57
+ rows = worksheet.rows[(start_point.last+1)..end_point.last] || []
58
+
59
+ column_offset = start_point.first
60
+ columns.each do |column|
61
+ rows.each do |row|
62
+ next if row.hidden
63
+ column.apply(row, column_offset)
64
+ end
65
+ end
66
+ end
67
+ # serialize the object
68
+ # @return [String]
69
+ def to_xml_string(str='')
70
+ return unless range
71
+ str << "<autoFilter ref='#{range}'>"
72
+ columns.each { |filter_column| filter_column.to_xml_string(str) }
73
+ str << "</autoFilter>"
74
+ end
75
+
76
+ end
77
+ end
@@ -0,0 +1,102 @@
1
+ module Axlsx
2
+ # The filterColumn collection identifies a particular column in the AutoFilter
3
+ # range and specifies filter information that has been applied to this column.
4
+ # If a column in the AutoFilter range has no criteria specified,
5
+ # then there is no corresponding filterColumn collection expressed for that column.
6
+ class FilterColumn
7
+
8
+ # Allowed filters
9
+ FILTERS = [:filters] #, :top10, :custom_filters, :dynamic_filters, :color_filters, :icon_filters]
10
+
11
+ # Creates a new FilterColumn object
12
+ # @note This class yeilds its filter object as that is where the vast majority of processing will be done
13
+ # @param [Integer|Cell] col_id The zero based index for the column to which this filter will be applied
14
+ # @param [Symbol] filter_type The symbolized class name of the filter to apply to this column.
15
+ # @param [Hash] options options for this object and the filter
16
+ # @option [Boolean] hidden_button @see hidden_button
17
+ # @option [Boolean] show_button @see show_button
18
+ def initialize(col_id, filter_type, options = {})
19
+ RestrictionValidator.validate 'FilterColumn.filter', FILTERS, filter_type
20
+ #Axlsx::validate_unsigned_int(col_id)
21
+ self.col_id = col_id
22
+ options.each do |o|
23
+ self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
24
+ end
25
+ @filter = Axlsx.const_get(Axlsx.camel(filter_type)).new(options)
26
+ yield @filter if block_given?
27
+ end
28
+
29
+ # Zero-based index indicating the AutoFilter column to which this filter information applies.
30
+ # @return [Integer]
31
+ attr_reader :col_id
32
+
33
+ # The actual filter being dealt with here
34
+ # This could be any one of the allowed filter types
35
+ attr_reader :filter
36
+
37
+ # Flag indicating whether the filter button is visible.
38
+ # When the cell containing the filter button is merged with another cell,
39
+ # the filter button can be hidden, and not drawn.
40
+ # @return [Boolean]
41
+ def show_button
42
+ @show_button ||= true
43
+ end
44
+
45
+ # Flag indicating whether the AutoFilter button for this column is hidden.
46
+ # @return [Boolean]
47
+ def hidden_button
48
+ @hidden_button ||= false
49
+ end
50
+
51
+ # Sets the col_id attribute for this filter column.
52
+ # @param [Integer | Cell] column_index The zero based index of the column to which this filter applies.
53
+ # When you specify a cell, the column index will be read off the cell
54
+ # @return [Integer]
55
+ def col_id=(column_index)
56
+ column_index = column_index.col if column_index.is_a?(Cell)
57
+ Axlsx.validate_unsigned_int column_index
58
+ @col_id = column_index
59
+ end
60
+
61
+ # Apply the filters for this column
62
+ # @param [Array] row A row from a worksheet that needs to be
63
+ # filtered.
64
+ def apply(row, offset)
65
+ row.hidden = @filter.apply(row.cells[offset+col_id.to_i])
66
+ end
67
+ # @param [Boolean] hidden Flag indicating whether the AutoFilter button for this column is hidden.
68
+ # @return [Boolean]
69
+ def hidden_button=(hidden)
70
+ Axlsx.validate_boolean hidden
71
+ @hidden_button = hidden
72
+ end
73
+
74
+ # Flag indicating whether the AutoFilter button is show. This is
75
+ # undocumented in the spec, but exists in the schema file as an
76
+ # optional attribute.
77
+ # @param [Boolean] show Show or hide the button
78
+ # @return [Boolean]
79
+ def show_button=(show)
80
+ Axlsx.validate_boolean show
81
+ @show_botton = show
82
+ end
83
+
84
+ # Serialize the object to xml
85
+ def to_xml_string(str='')
86
+ str << "<filterColumn #{serialized_attributes}>"
87
+ @filter.to_xml_string(str)
88
+ str << "</filterColumn>"
89
+ end
90
+
91
+ private
92
+
93
+ def serialized_attributes(str='')
94
+ instance_values.each do |key, value|
95
+ if %(show_button hidden_button col_id).include? key.to_s
96
+ str << "#{Axlsx.camel(key, false)}='#{value}' "
97
+ end
98
+ end
99
+ str
100
+ end
101
+ end
102
+ end