diff options
| author | Alex Rothenberg <[email protected]> | 2012-11-27 13:45:31 -0500 |
|---|---|---|
| committer | Alex Rothenberg <[email protected]> | 2012-11-27 14:16:55 -0500 |
| commit | 036f5883939a91fbc3eb377d968d85500dc3098a (patch) | |
| tree | 05133197c66091590840da3ed2fe3812eb3143aa /lib/axlsx/workbook/worksheet/pivot_table.rb | |
| parent | 4560bd0a1b8b46bf4d8c0783f9fa12e8ceee714f (diff) | |
| download | caxlsx-036f5883939a91fbc3eb377d968d85500dc3098a.tar.gz caxlsx-036f5883939a91fbc3eb377d968d85500dc3098a.zip | |
Can configure a pivot table when creating it
see examples/pivot_table.rb
wb.add_worksheet(:name => "Data Sheet") do |sheet|
sheet.add_row ['Month', 'Year', 'Type', 'Sales', 'Region']
30.times { sheet.add_row [month, year, type, sales, region] }
sheet.add_pivot_table 'G4:L17', "A1:E31" do |pivot_table|
pivot_table.rows = ['Month', 'Year']
pivot_table.columns = ['Type']
pivot_table.data = ['Sales']
pivot_table.pages = ['Region']
end
end
Diffstat (limited to 'lib/axlsx/workbook/worksheet/pivot_table.rb')
| -rw-r--r-- | lib/axlsx/workbook/worksheet/pivot_table.rb | 140 |
1 files changed, 134 insertions, 6 deletions
diff --git a/lib/axlsx/workbook/worksheet/pivot_table.rb b/lib/axlsx/workbook/worksheet/pivot_table.rb index c4eff8be..d876f777 100644 --- a/lib/axlsx/workbook/worksheet/pivot_table.rb +++ b/lib/axlsx/workbook/worksheet/pivot_table.rb @@ -19,6 +19,10 @@ module Axlsx @sheet = sheet @sheet.workbook.pivot_tables << self @name = "PivotTable#{index+1}" + @rows = [] + @columns = [] + @data = [] + @pages = [] parse_options options yield self if block_given? end @@ -46,6 +50,54 @@ module Axlsx end end + # The rows + # @return [Array] + attr_reader :rows + + def rows=(v) + DataTypeValidator.validate "#{self.class}.rows", [Array], v + v.each do |ref| + DataTypeValidator.validate "#{self.class}.rows[]", [String], ref + end + @rows = v + end + + # The columns + # @return [Array] + attr_reader :columns + + def columns=(v) + DataTypeValidator.validate "#{self.class}.columns", [Array], v + v.each do |ref| + DataTypeValidator.validate "#{self.class}.columns[]", [String], ref + end + @columns = v + end + + # The data + # @return [Array] + attr_reader :data + + def data=(v) + DataTypeValidator.validate "#{self.class}.data", [Array], v + v.each do |ref| + DataTypeValidator.validate "#{self.class}.data[]", [String], ref + end + @data = v + end + + # The pages + # @return [String] + attr_reader :pages + + def pages=(v) + DataTypeValidator.validate "#{self.class}.pages", [Array], v + v.each do |ref| + DataTypeValidator.validate "#{self.class}.pages[]", [String], ref + end + @pages = v + end + # The index of this chart in the workbooks charts collection # @return [Integer] def index @@ -102,19 +154,95 @@ module Axlsx str << '<pivotTableDefinition xmlns="' << XML_NS << '" name="' << name << '" cacheId="' << cache_definition.cache_id.to_s << '" dataOnRows="1" applyNumberFormats="0" applyBorderFormats="0" applyFontFormats="0" applyPatternFormats="0" applyAlignmentFormats="0" applyWidthHeightFormats="1" dataCaption="Data" showMultipleLabel="0" showMemberPropertyTips="0" useAutoFormatting="1" indent="0" compact="0" compactData="0" gridDropZones="1" multipleFieldFilters="0">' str << '<location firstDataCol="1" firstDataRow="1" firstHeaderRow="1" ref="' << ref << '"/>' str << '<pivotFields count="' << header_cells_count.to_s << '">' - header_cells_count.times do - str << '<pivotField compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1"/>' + header_cell_values.each do |cell_value| + str << pivot_field_for(cell_value) end str << '</pivotFields>' + if rows.empty? + str << '<rowFields count="1"><field x="-2"/></rowFields>' + str << '<rowItems count="2"><i><x/></i> <i i="1"><x v="1"/></i></rowItems>' + else + str << '<rowFields count="' << rows.size.to_s << '">' + rows.each do |row_value| + str << '<field x="' << header_index_of(row_value).to_s << '"/>' + end + str << '</rowFields>' + str << '<rowItems count="' << rows.size.to_s << '">' + rows.size.times do |i| + str << '<i/>' + end + str << '</rowItems>' + end + if columns.empty? + str << '<colItems count="1"><i/></colItems>' + else + str << '<colFields count="' << columns.size.to_s << '">' + columns.each do |column_value| + str << '<field x="' << header_index_of(column_value).to_s << '"/>' + end + str << '</colFields>' + end + unless pages.empty? + str << '<pageFields count="' << pages.size.to_s << '">' + pages.each do |page_value| + str << '<pageField fld="' << header_index_of(page_value).to_s << '"/>' + end + str << '</pageFields>' + end + unless data.empty? + str << '<dataFields count="' << data.size.to_s << '">' + data.each do |datum_value| + str << '<dataField name="Sum of ' << datum_value << '" ' << + 'fld="' << header_index_of(datum_value).to_s << '" ' << + 'baseField="0" baseItem="0"/>' + end + str << '</dataFields>' + end str << '</pivotTableDefinition>' end - private + def header_cell_refs + Axlsx::range_to_a(header_range).first + end - # get the header cells (hackish) def header_cells - header = range.gsub(/^(\w+?)(\d+)\:(\w+?)\d+$/, '\1\2:\3\2') - @sheet[header] + @sheet[header_range] + end + + def header_cell_values + header_cells.map(&:value) + end + + def header_index_of(value) + header_cell_values.index(value) + end + + private + + def pivot_field_for(cell_ref) + 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>' + 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>' + elsif data.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>' + end + end + + def header_range + range.gsub(/^(\w+?)(\d+)\:(\w+?)\d+$/, '\1\2:\3\2') end end |
