summaryrefslogtreecommitdiffhomepage
path: root/lib/axlsx/workbook/worksheet/pivot_table.rb
diff options
context:
space:
mode:
authorJames Lam <[email protected]>2022-07-09 23:13:05 +0200
committerStefan Daschek <[email protected]>2022-07-09 23:14:37 +0200
commitf39e9068803f5cf28a339c67e92ab976c30b00f1 (patch)
tree6040be8b56874c8939f9b1f5613623ed6fb9b8b0 /lib/axlsx/workbook/worksheet/pivot_table.rb
parent3703031ef2cc755fac8c7cb5b403170cda76fa67 (diff)
downloadcaxlsx-f39e9068803f5cf28a339c67e92ab976c30b00f1.tar.gz
caxlsx-f39e9068803f5cf28a339c67e92ab976c30b00f1.zip
Add pivot table option to sort headers (#143)
Diffstat (limited to 'lib/axlsx/workbook/worksheet/pivot_table.rb')
-rw-r--r--lib/axlsx/workbook/worksheet/pivot_table.rb53
1 files changed, 41 insertions, 12 deletions
diff --git a/lib/axlsx/workbook/worksheet/pivot_table.rb b/lib/axlsx/workbook/worksheet/pivot_table.rb
index bc500a8a..60960392 100644
--- a/lib/axlsx/workbook/worksheet/pivot_table.rb
+++ b/lib/axlsx/workbook/worksheet/pivot_table.rb
@@ -26,17 +26,33 @@ module Axlsx
@pages = []
@subtotal = nil
@no_subtotals_on_headers = []
+ @sort_on_headers = {}
@style_info = {}
parse_options options
yield self if block_given?
end
- # Defines the headers in which subtotals are not to be included
- # @return[Array]
+ # Defines the headers in which subtotals are not to be included.
+ # @return [Array]
attr_accessor :no_subtotals_on_headers
+ # Defines the headers in which sort is applied.
+ # Can be an array of headers to sort ascending by default, or a hash for specific control
+ # (with headers as keys, `:ascending` or `:descending` as values).
+ #
+ # Examples: `["year", "month"]` or `{"year" => :descending, "month" => :descending}`
+ # @return [Hash]
+ attr_reader :sort_on_headers
+
+ # (see #sort_on_headers)
+ def sort_on_headers=(headers)
+ headers ||= {}
+ headers = Hash[*headers.map { |h| [h, :ascending] }.flatten] if headers.is_a?(Array)
+ @sort_on_headers = headers
+ end
+
# Style info for the pivot table
- # @return[Hash]
+ # @return [Hash]
attr_accessor :style_info
# The reference to the table data
@@ -178,9 +194,13 @@ module Axlsx
str << ('<location firstDataCol="1" firstDataRow="1" firstHeaderRow="1" ref="' << ref << '"/>')
str << ('<pivotFields count="' << header_cells_count.to_s << '">')
+
header_cell_values.each do |cell_value|
- str << pivot_field_for(cell_value, !no_subtotals_on_headers.include?(cell_value))
+ subtotal = !no_subtotals_on_headers.include?(cell_value)
+ sorttype = sort_on_headers[cell_value]
+ str << pivot_field_for(cell_value, subtotal, sorttype)
end
+
str << '</pivotFields>'
if rows.empty?
str << '<rowFields count="1"><field x="-2"/></rowFields>'
@@ -267,22 +287,31 @@ module Axlsx
private
- def pivot_field_for(cell_ref, subtotal=true)
+ def pivot_field_for(cell_ref, subtotal, sorttype)
+ attributes = %w[compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1"]
+ items_tag = '<items count="1"><item t="default"/></items>'
+ include_items_tag = false
+
if rows.include? cell_ref
+ attributes << 'axis="axisRow"'
+ attributes << "sortType=\"#{sorttype == :descending ? 'descending' : 'ascending'}\"" if sorttype
if subtotal
- '<pivotField axis="axisRow" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1"><items count="1"><item t="default"/></items></pivotField>'
+ include_items_tag = true
else
- '<pivotField axis="axisRow" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1" defaultSubtotal="0"></pivotField>'
+ attributes << 'defaultSubtotal="0"'
end
elsif columns.include? cell_ref
- '<pivotField axis="axisCol" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1"><items count="1"><item t="default"/></items></pivotField>'
+ attributes << 'axis="axisCol"'
+ attributes << "sortType=\"#{sorttype == :descending ? 'descending' : 'ascending'}\"" if sorttype
+ include_items_tag = true
elsif pages.include? cell_ref
- '<pivotField axis="axisPage" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1"><items count="1"><item t="default"/></items></pivotField>'
+ attributes << 'axis="axisPage"'
+ include_items_tag = true
elsif data_refs.include? cell_ref
- '<pivotField dataField="1" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1"></pivotField>'
- else
- '<pivotField compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1"></pivotField>'
+ attributes << 'dataField="1"'
end
+
+ "<pivotField #{attributes.join(' ')}>#{include_items_tag ? items_tag : nil}</pivotField>"
end
def data_refs