Skip to content

Commit

Permalink
Merge pull request #499 from ehallmark/pivot_table_bugs
Browse files Browse the repository at this point in the history
Pivot table bugs
  • Loading branch information
randym authored Nov 15, 2016
2 parents 8450997 + cbfabd0 commit b0d74cf
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 6 deletions.
9 changes: 9 additions & 0 deletions lib/axlsx/stylesheet/num_fmt.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,14 @@ def to_xml_string(str = '')
serialized_tag('numFmt', str)
end

# Override to avoid removing underscores
def serialized_attributes(str = '', additional_attributes = {})
attributes = declared_attributes.merge! additional_attributes
attributes.each do |key, value|
str << "#{Axlsx.camel(key, false)}=\"#{Axlsx.booleanize(value)}\" "
end
str
end

end
end
33 changes: 28 additions & 5 deletions lib/axlsx/workbook/worksheet/pivot_table.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,20 @@ def initialize(ref, range, sheet, options={})
@data = []
@pages = []
@subtotal = nil
@no_subtotals_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]
attr_accessor :no_subtotals_on_headers

# Style info for the pivot table
# @return[Hash]
attr_accessor :style_info

# The reference to the table data
# @return [String]
attr_reader :ref
Expand Down Expand Up @@ -163,7 +173,7 @@ def to_xml_string(str = '')
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)
str << pivot_field_for(cell_value,!no_subtotals_on_headers.include?(cell_value))
end
str << '</pivotFields>'
if rows.empty?
Expand Down Expand Up @@ -200,12 +210,21 @@ def to_xml_string(str = '')
unless data.empty?
str << "<dataFields count=\"#{data.size}\">"
data.each do |datum_value|
str << "<dataField name='#{@subtotal} of #{datum_value[:ref]}' fld='#{header_index_of(datum_value[:ref])}' baseField='0' baseItem='0'"
# The correct name prefix in ["Sum","Average", etc...]
str << "<dataField name='#{(datum_value[:subtotal]||'')} of #{datum_value[:ref]}' fld='#{header_index_of(datum_value[:ref])}' baseField='0' baseItem='0'"
str << " subtotal='#{datum_value[:subtotal]}' " if datum_value[:subtotal]
str << "/>"
end
str << '</dataFields>'
end
# custom pivot table style
unless style_info.empty?
str << '<pivotTableStyleInfo'
style_info.each do |k,v|
str << ' ' << k.to_s << '="' << v.to_s << '"'
end
str << ' />'
end
str << '</pivotTableDefinition>'
end

Expand Down Expand Up @@ -241,13 +260,17 @@ def header_index_of(value)

private

def pivot_field_for(cell_ref)
def pivot_field_for(cell_ref, subtotal=true)
if rows.include? cell_ref
'<pivotField axis="axisRow" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1">' + '<items count="1"><item t="default"/></items>' + '</pivotField>'
if subtotal
'<pivotField axis="axisRow" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1">' + '<items count="1"><item t="default"/></items>' + '</pivotField>'
else
'<pivotField axis="axisRow" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1" defaultSubtotal="0">' + '</pivotField>'
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>'
elsif pages.include? cell_ref
'<pivotField axis="axisCol" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1">' + '<items count="1"><item t="default"/></items>' + '</pivotField>'
'<pivotField axis="axisPage" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1">' + '<items count="1"><item t="default"/></items>' + '</pivotField>'
elsif data_refs.include? cell_ref
'<pivotField dataField="1" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1">' + '</pivotField>'
else
Expand Down
22 changes: 21 additions & 1 deletion test/workbook/worksheet/tc_pivot_table.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,27 @@ def test_add_pivot_table_with_options_on_data_field
assert_equal([{:ref=>"Sales", :subtotal => 'average'}], pivot_table.data)
end

def test_header_indices
def test_add_pivot_table_with_style_info
style_info_data = { :name=>"PivotStyleMedium9", :showRowHeaders=>"1", :showLastColumn=>"0"}
pivot_table = @ws.add_pivot_table('G5:G6', 'A1:E5', {:style_info=>style_info_data}) do |pt|
pt.rows = ['Year', 'Month']
pt.columns = ['Type']
pt.data = ['Sales']
pt.pages = ['Region']
end
assert_equal(style_info_data, pivot_table.style_info)
shared_test_pivot_table_xml_validity(pivot_table)
end

def test_add_pivot_table_with_row_without_subtotals
pivot_table = @ws.add_pivot_table('G5:G6', 'A1:D5', {:no_subtotals_on_headers=>['Year']}) do |pt|
pt.data = ['Sales']
pt.rows = ['Year','Month']
end
assert_equal(['Year'], pivot_table.no_subtotals_on_headers)
end

def test_header_indices
pivot_table = @ws.add_pivot_table('G5:G6', 'A1:E5')
assert_equal(0, pivot_table.header_index_of('Year' ))
assert_equal(1, pivot_table.header_index_of('Month' ))
Expand Down

0 comments on commit b0d74cf

Please sign in to comment.