From 4539ffdd6435ce2fce6d3096c1822447cc1c7846 Mon Sep 17 00:00:00 2001 From: sato-s Date: Sun, 12 Feb 2017 16:32:22 +0900 Subject: [PATCH] Range reference to easily use some feature (#504) This patch introduce following methods to easily use auto_filter, table, etc. - Worksheet#top_left_reference - Worksheet#bottom_right_reference - Worksheet#range_reference --- examples/auto_filter.rb | 5 +-- lib/axlsx/workbook/worksheet/worksheet.rb | 47 +++++++++++++++++++++++ test/workbook/worksheet/tc_worksheet.rb | 22 +++++++++++ 3 files changed, 71 insertions(+), 3 deletions(-) diff --git a/examples/auto_filter.rb b/examples/auto_filter.rb index b47082cb..876b46f0 100644 --- a/examples/auto_filter.rb +++ b/examples/auto_filter.rb @@ -5,12 +5,11 @@ require 'axlsx' Axlsx::Package.new do |p| p.workbook.add_worksheet(:name => "Table") do |sheet| - sheet.add_row ["Build Matrix"] sheet.add_row ["Build", "Duration", "Finished", "Rvm"] sheet.add_row ["19.1", "1 min 32 sec", "about 10 hours ago", "1.8.7"] sheet.add_row ["19.2", "1 min 28 sec", "about 10 hours ago", "1.9.2"] sheet.add_row ["19.3", "1 min 35 sec", "about 10 hours ago", "1.9.3"] - sheet.auto_filter = 'A2:D5' + sheet.auto_filter = sheet.range_reference # => "A1:D4" sheet.auto_filter.add_column 3, :filters, :filter_items => ['1.9.2'] end p.workbook.add_worksheet(:name => "Table 2") do |sheet| @@ -19,7 +18,7 @@ sheet.add_row ["19.1", "1 min 32 sec", "about 10 hours ago", "1.8.7"] sheet.add_row ["19.2", "1 min 28 sec", "about 10 hours ago", "1.9.2"] sheet.add_row ["19.3", "1 min 35 sec", "about 10 hours ago", "1.9.3"] - sheet.auto_filter = 'A2:D5' + sheet.auto_filter = "A2:#{sheet.bottom_right_reference}" # => 'A2:D5' sheet.auto_filter.add_column 3, :filters, :filter_items => ['1.9.2'] end end.serialize('auto_filter.xlsx') diff --git a/lib/axlsx/workbook/worksheet/worksheet.rb b/lib/axlsx/workbook/worksheet/worksheet.rb index 031a081f..e4226b14 100644 --- a/lib/axlsx/workbook/worksheet/worksheet.rb +++ b/lib/axlsx/workbook/worksheet/worksheet.rb @@ -682,6 +682,53 @@ def outline_level_columns(start_index, end_index, level = 1, collapsed = true) outline column_info, (start_index..end_index), level, collapsed end + # The excel-style reference of the top-left cell of this worksheet, e.g., A1 + # @return String + def top_left_reference + raise "worksheet has no data" if rows.empty? or rows.first.empty? + rows.first.first.r + end + + # The excel-style reference of the bottom-right cell of this worksheet, e.g., D5 + # This method is useful when you want to apply auto_filter or table to dynamic length data. + # + # @example + # Axlsx::Package.new do |p| + # p.workbook.add_worksheet(:name => "Table 2") do |sheet| + # sheet.add_row ["Build Matrix"] + # sheet.add_row ["Build", "Duration", "Finished", "Rvm"] + # sheet.add_row ["19.1", "1 min 32 sec", "about 10 hours ago", "1.8.7"] + # sheet.add_row ["19.2", "1 min 28 sec", "about 10 hours ago", "1.9.2"] + # sheet.add_row ["19.3", "1 min 35 sec", "about 10 hours ago", "1.9.3"] + # sheet.auto_filter = "A2:#{sheet.bottom_right_reference}" # => 'A2:D5' + # sheet.auto_filter.add_column 3, :filters, :filter_items => ['1.9.2'] + # end + # end + # @return String + def bottom_right_reference + raise "worksheet has no data" if rows.empty? or rows.last.empty? + rows.last.last.r + end + + # The excel-style reference of the range of this worksheet, e.g., A1:D5 + # This method is useful when you just want to apply auto_filter or table to whole worksheet. + # + # @example + # Axlsx::Package.new do |p| + # p.workbook.add_worksheet(:name => "Table") do |sheet| + # sheet.add_row ["Build", "Duration", "Finished", "Rvm"] + # sheet.add_row ["19.1", "1 min 32 sec", "about 10 hours ago", "1.8.7"] + # sheet.add_row ["19.2", "1 min 28 sec", "about 10 hours ago", "1.9.2"] + # sheet.add_row ["19.3", "1 min 35 sec", "about 10 hours ago", "1.9.3"] + # sheet.auto_filter = sheet.range_reference # => "A1:D4" + # sheet.auto_filter.add_column 3, :filters, :filter_items => ['1.9.2'] + # end + # end + # @return String + def range_reference + "#{top_left_reference}:#{bottom_right_reference}" + end + private def xml_space diff --git a/test/workbook/worksheet/tc_worksheet.rb b/test/workbook/worksheet/tc_worksheet.rb index 166850e5..8e901d77 100644 --- a/test/workbook/worksheet/tc_worksheet.rb +++ b/test/workbook/worksheet/tc_worksheet.rb @@ -163,6 +163,28 @@ def test_referencing assert_equal(range.last, @ws.rows.last.cells.last) end + def test_corner_reference + @ws.add_row [1, 2, 3] + @ws.add_row [4, 5, 6] + assert_equal(@ws.top_left_reference, "A1") + assert_equal(@ws.bottom_right_reference, "C2") + end + + def test_corner_reference_raise_exception_if_no_row + assert_raise(RuntimeError, "worksheet has no data"){ @ws.top_left_reference } + assert_raise(RuntimeError, "worksheet has no data"){ @ws.bottom_right_reference } + end + + def test_range_reference + @ws.add_row [1, 2, 3] + @ws.add_row [4, 5, 6] + assert_equal(@ws.range_reference, 'A1:C2') + end + + def test_range_reference_raise_exception_if_no_row + assert_raise(RuntimeError, "worksheet has no data"){ @ws.range_reference } + end + def test_add_row assert(@ws.rows.empty?, "sheet has no rows by default") r = @ws.add_row([1,2,3])