From 036f5883939a91fbc3eb377d968d85500dc3098a Mon Sep 17 00:00:00 2001 From: Alex Rothenberg Date: Tue, 27 Nov 2012 13:45:31 -0500 Subject: 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 --- lib/axlsx.rb | 12 ++ lib/axlsx/workbook/worksheet/pivot_table.rb | 140 ++++++++++++++++++++- .../worksheet/pivot_table_cache_definition.rb | 6 +- 3 files changed, 149 insertions(+), 9 deletions(-) (limited to 'lib') diff --git a/lib/axlsx.rb b/lib/axlsx.rb index 20129b95..91391db5 100644 --- a/lib/axlsx.rb +++ b/lib/axlsx.rb @@ -104,6 +104,18 @@ module Axlsx Axlsx::col_ref(c_index).to_s << (r_index+1).to_s end + def self.range_to_a(range) + range.match(/^(\w+?\d+)\:(\w+?\d+)$/) + start_col, start_row = name_to_indices($1) + end_col, end_row = name_to_indices($2) + (start_row..end_row).to_a.map do |row_num| + (start_col..end_col).to_a.map do |col_num| + "#{col_ref(col_num)}#{row_num+1}" + end + end + end + + # performs the increadible feat of changing snake_case to CamelCase # @param [String] s The snake case string to camelize # @return [String] 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 << '' str << '' str << '' - header_cells_count.times do - str << '' + header_cell_values.each do |cell_value| + str << pivot_field_for(cell_value) end str << '' + if rows.empty? + str << '' + str << ' ' + else + str << '' + rows.each do |row_value| + str << '' + end + str << '' + str << '' + rows.size.times do |i| + str << '' + end + str << '' + end + if columns.empty? + str << '' + else + str << '' + columns.each do |column_value| + str << '' + end + str << '' + end + unless pages.empty? + str << '' + pages.each do |page_value| + str << '' + end + str << '' + end + unless data.empty? + str << '' + data.each do |datum_value| + str << '' + end + str << '' + end str << '' 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 + '' << + '' << + '' + elsif columns.include? cell_ref + '' << + '' << + '' + elsif pages.include? cell_ref + '' << + '' << + '' + elsif data.include? cell_ref + '' << + '' + else + '' << + '' + end + end + + def header_range + range.gsub(/^(\w+?)(\d+)\:(\w+?)\d+$/, '\1\2:\3\2') end end diff --git a/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb b/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb index e70bcc6a..5a6c7442 100644 --- a/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +++ b/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb @@ -30,7 +30,7 @@ module Axlsx end def cache_id - index + index + 1 end # The relation reference id for this table @@ -49,8 +49,8 @@ module Axlsx str << '' str << '' str << '' - pivot_table.header_cells_count.times do |i| - str << '' + pivot_table.header_cells.each do |cell| + str << '' str << '' str << '' str << '' -- cgit v1.2.3