Class: Axlsx::AutoFilter

Inherits:
Object
  • Object
show all
Defined in:
lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb

Overview

This class represents an auto filter range in a worksheet

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(worksheet) ⇒ AutoFilter

creates a new Autofilter object

Parameters:

Raises:

  • (ArgumentError)


12
13
14
15
16
17
# File 'lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb', line 12

def initialize(worksheet)
  raise ArgumentError, 'you must provide a worksheet' unless worksheet.is_a?(Worksheet)

  @worksheet = worksheet
  @sort_on_generate = true
end

Instance Attribute Details

#rangeString

The range the autofilter should be applied to. This should be a string like 'A1:B8'

Returns:

  • (String)


24
25
26
# File 'lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb', line 24

def range
  @range
end

#sort_on_generateObject

Returns the value of attribute sort_on_generate.



19
20
21
# File 'lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb', line 19

def sort_on_generate
  @sort_on_generate
end

#worksheetObject (readonly)

Returns the value of attribute worksheet.



19
20
21
# File 'lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb', line 19

def worksheet
  @worksheet
end

Instance Method Details

#add_column(col_id, filter_type, options = {}) ⇒ FilterColumn

Adds a filter column. This is the recommended way to create and manage filter columns for your autofilter. In addition to the require id and type parameters, options will be passed to the filter column during instantiation.

Parameters:

  • col_id (String)

    Zero-based index indicating the AutoFilter column to which this filter information applies.

  • filter_type (Symbol)

    A symbol representing one of the supported filter types.

  • options (Hash) (defaults to: {})

    a hash of options to pass into the generated filter

Returns:



48
49
50
51
# File 'lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb', line 48

def add_column(col_id, filter_type, options = {})
  columns << FilterColumn.new(col_id, filter_type, options)
  columns.last
end

#applyObject

Performs the sorting of the rows based on the sort_state conditions. Then it actually performs the filtering of rows who's cells do not match the filter.



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb', line 55

def apply
  first_cell, last_cell = range.split(':')
  start_point = Axlsx.name_to_indices(first_cell)
  end_point = Axlsx.name_to_indices(last_cell)
  # The +1 is so we skip the header row with the filter drop downs
  rows = worksheet.rows[(start_point.last + 1)..end_point.last] || []

  # the sorting of the rows if sort_conditions are available.
  if !sort_state.sort_conditions.empty? && sort_on_generate
    sort_conditions = sort_state.sort_conditions
    sorted_rows = rows.sort do |row1, row2|
      comparison = 0

      sort_conditions.each do |condition|
        cell_value_row1 = row1.cells[condition.column_index + start_point.first].value
        cell_value_row2 = row2.cells[condition.column_index + start_point.first].value
        custom_list = condition.custom_list
        comparison = if cell_value_row1.nil? || cell_value_row2.nil?
                       cell_value_row1.nil? ? 1 : -1
                     elsif custom_list.empty?
                       condition.order == :asc ? cell_value_row1 <=> cell_value_row2 : cell_value_row2 <=> cell_value_row1
                     else
                       index1 = custom_list.index(cell_value_row1) || custom_list.size
                       index2 = custom_list.index(cell_value_row2) || custom_list.size

                       condition.order == :asc ? index1 <=> index2 : index2 <=> index1
                     end

        break unless comparison.zero?
      end

      comparison
    end
    insert_index = start_point.last + 1

    sorted_rows.each do |row|
      # Insert the row at the specified index
      worksheet.rows[insert_index] = row
      insert_index += 1
    end
  end

  column_offset = start_point.first
  columns.each do |column|
    rows.each do |row|
      next if row.hidden

      column.apply(row, column_offset)
    end
  end
end

#columnsSimpleTypedList

A collection of filterColumns for this auto_filter

Returns:

  • (SimpleTypedList)


38
39
40
# File 'lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb', line 38

def columns
  @columns ||= SimpleTypedList.new FilterColumn
end

#defined_nameString

the formula for the defined name required for this auto filter This prepends the worksheet name to the absolute cell reference e.g. A1:B2 -> 'Sheet1'!$A$1:$B$2

Returns:

  • (String)


30
31
32
33
34
# File 'lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb', line 30

def defined_name
  return unless range

  Axlsx.cell_range(range.split(':').collect { |name| worksheet.name_to_cell(name) })
end

#sort_stateSortState

the SortState object for this AutoFilter

Returns:



109
110
111
# File 'lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb', line 109

def sort_state
  @sort_state ||= SortState.new self
end

#to_xml_string(str = +'')) ⇒ String

serialize the object

Returns:

  • (String)


124
125
126
127
128
129
130
131
132
133
# File 'lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb', line 124

def to_xml_string(str = +'')
  return unless range

  str << "<autoFilter ref='#{range}'>"
  columns.each { |filter_column| filter_column.to_xml_string(str) }
  unless @sort_state.nil?
    @sort_state.to_xml_string(str)
  end
  str << "</autoFilter>"
end