summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--lib/axlsx/workbook/workbook.rb21
-rw-r--r--lib/axlsx/workbook/worksheet/worksheet.rb34
-rw-r--r--test/tc_package.rb1
-rw-r--r--test/workbook/tc_workbook.rb14
-rw-r--r--test/workbook/worksheet/tc_worksheet.rb9
5 files changed, 68 insertions, 11 deletions
diff --git a/lib/axlsx/workbook/workbook.rb b/lib/axlsx/workbook/workbook.rb
index 0f70f37f..edd1d0d7 100644
--- a/lib/axlsx/workbook/workbook.rb
+++ b/lib/axlsx/workbook/workbook.rb
@@ -37,7 +37,8 @@ require 'axlsx/workbook/worksheet/worksheet_hyperlinks'
require 'axlsx/workbook/worksheet/break'
require 'axlsx/workbook/worksheet/row_breaks'
require 'axlsx/workbook/worksheet/col_breaks'
-
+require 'axlsx/workbook/workbook_view'
+require 'axlsx/workbook/workbook_views'
require 'axlsx/workbook/worksheet/worksheet.rb'
@@ -139,6 +140,10 @@ require 'axlsx/workbook/worksheet/selection.rb'
# @return [SimpleTypedList]
attr_reader :pivot_tables
+ # A collection of views for this workbook
+ def views
+ @views ||= WorkbookViews.new
+ end
# A collection of defined names for this workbook
# @note The recommended way to manage defined names is Workbook#add_defined_name
@@ -263,6 +268,10 @@ require 'axlsx/workbook/worksheet/selection.rb'
worksheet
end
+ def add_view(options={})
+ views << WorkbookView.new(options)
+ end
+
# Adds a defined name to this workbook
# @return [DefinedName]
# @param [String] formula @see DefinedName
@@ -327,17 +336,13 @@ require 'axlsx/workbook/worksheet/selection.rb'
# @param [String] str
# @return [String]
def to_xml_string(str='')
- add_worksheet unless worksheets.size > 0
+ add_worksheet(name: 'Sheet1') unless worksheets.size > 0
str << '<?xml version="1.0" encoding="UTF-8"?>'
str << '<workbook xmlns="' << XML_NS << '" xmlns:r="' << XML_NS_R << '">'
str << '<workbookPr date1904="' << @@date1904.to_s << '"/>'
+ views.to_xml_string(str)
str << '<sheets>'
- @worksheets.each_with_index do |sheet, index|
- str << '<sheet name="' << sheet.name << '" sheetId="' << (index+1).to_s << '" r:id="' << sheet.rId << '"/>'
- if defined_name = sheet.auto_filter.defined_name
- add_defined_name defined_name, :name => '_xlnm._FilterDatabase', :local_sheet_id => index, :hidden => 1
- end
- end
+ worksheets.each { |sheet| sheet.to_sheet_node_xml_string(str) }
str << '</sheets>'
defined_names.to_xml_string(str)
unless pivot_tables.empty?
diff --git a/lib/axlsx/workbook/worksheet/worksheet.rb b/lib/axlsx/workbook/worksheet/worksheet.rb
index 9937a3f4..2dd5e3af 100644
--- a/lib/axlsx/workbook/worksheet/worksheet.rb
+++ b/lib/axlsx/workbook/worksheet/worksheet.rb
@@ -4,7 +4,7 @@ module Axlsx
# The Worksheet class represents a worksheet in the workbook.
class Worksheet
include Axlsx::OptionsParser
-
+ include Axlsx::SerializedAttributes
# definition of characters which are less than the maximum width of 0-9 in the default font for use in String#count.
# This is used for autowidth calculations
# @return [String]
@@ -24,12 +24,15 @@ module Axlsx
def initialize(wb, options={})
self.workbook = wb
@sheet_protection = nil
-
initialize_page_options(options)
parse_options options
@workbook.worksheets << self
+ @sheet_id = index + 1
+ yield self if block_given?
end
+ serializable_attributes :sheet_id, :name, :state
+
# Initalizes page margin, setup and print options
# @param [Hash] options Options passed in from the initializer
def initialize_page_options(options)
@@ -47,6 +50,22 @@ module Axlsx
@name ||= "Sheet" + (index+1).to_s
end
+ # Specifies the visible state of this sheet. Allowed states are
+ # :visible, :hidden or :very_hidden. The default value is :visible.
+ #
+ # Worksheets in the :hidden state can be shown using the sheet formatting properties in excel.
+ # :very_hidden sheets should be inaccessible to end users.
+ # @param [Symbol] sheet_state The visible state for this sheet.
+ def state=(sheet_state)
+ RestrictionValidator.validate "Worksheet#state", [:visible, :hidden, :very_hidden], sheet_state
+ @state = sheet_state
+ end
+
+ # The visibility of this sheet
+ def state
+ @state ||= :visible
+ end
+
# The sheet calculation properties
# @return [SheetCalcPr]
def sheet_calc_pr
@@ -142,7 +161,7 @@ module Axlsx
@rows.transpose(&block)
end
- # An range that excel will apply an auto-filter to "A1:B3"
+ # A range that excel will apply an auto-filter to "A1:B3"
# This will turn filtering on for the cells in the range.
# The first row is considered the header, while subsequent rows are considered to be data.
# @return String
@@ -348,6 +367,7 @@ module Axlsx
def auto_filter=(v)
DataTypeValidator.validate "Worksheet.auto_filter", String, v
auto_filter.range = v
+ workbook.add_defined_name auto_filter.defined_name, name: '_xlnm.FilterDatabase', local_sheet_id: index, hidden: 1
end
# Accessor for controlling whether leading and trailing spaces in cells are
@@ -577,6 +597,14 @@ module Axlsx
cells.each { |cell| cell.style = style }
end
+ # Returns a sheet node serialization for this sheet in the workbook.
+ def to_sheet_node_xml_string(str='')
+ str << '<sheet '
+ serialized_attributes str
+ str << "r:id='" << rId << "'"
+ str << '></sheet>'
+ end
+
# Serializes the worksheet object to an xml string
# This intentionally does not use nokogiri for performance reasons
# @return [String]
diff --git a/test/tc_package.rb b/test/tc_package.rb
index 4df44ea4..8f0caa46 100644
--- a/test/tc_package.rb
+++ b/test/tc_package.rb
@@ -11,6 +11,7 @@ class TestPackage < Test::Unit::TestCase
ws.outline_level_columns 0, 1
ws.add_hyperlink :ref => ws.rows.first.cells.last, :location => 'https://github.com/randym'
ws.workbook.add_defined_name("#{ws.name}!A1:C2", :name => '_xlnm.Print_Titles', :hidden => true)
+ ws.workbook.add_view active_tab: 1, first_sheet: 0
ws.protect_range('A1:C1')
ws.protect_range(ws.rows.last.cells)
ws.add_comment :author => 'alice', :text => 'Hi Bob', :ref => 'A12'
diff --git a/test/workbook/tc_workbook.rb b/test/workbook/tc_workbook.rb
index 32b6935a..2a51e4bd 100644
--- a/test/workbook/tc_workbook.rb
+++ b/test/workbook/tc_workbook.rb
@@ -53,6 +53,11 @@ class TestWorkbook < Test::Unit::TestCase
assert_equal(1, @wb.defined_names.size)
end
+ def test_add_view
+ @wb.add_view visibility: :hidden, window_width: 800
+ assert_equal(1, @wb.views.size)
+ end
+
def test_shared_strings
assert_equal(@wb.use_shared_strings, nil)
assert_raise(ArgumentError) {@wb.use_shared_strings = 'bpb'}
@@ -116,6 +121,15 @@ class TestWorkbook < Test::Unit::TestCase
assert_equal(doc.xpath('//xmlns:workbook/xmlns:definedNames/xmlns:definedName').inner_text, @wb.worksheets[0].auto_filter.defined_name)
end
+ def test_to_xml_string_book_views
+ @wb.add_worksheet do |sheet|
+ sheet.add_row [1, "two"]
+ end
+ @wb.add_view active_tab: 0, first_sheet: 0
+ doc = Nokogiri::XML(@wb.to_xml_string)
+ assert_equal(1, doc.xpath('//xmlns:workbook/xmlns:bookViews/xmlns:workbookView[@activeTab=0]').size)
+ end
+
def test_to_xml_uses_correct_rIds_for_pivotCache
ws = @wb.add_worksheet
pivot_table = ws.add_pivot_table('G5:G6', 'A1:D5')
diff --git a/test/workbook/worksheet/tc_worksheet.rb b/test/workbook/worksheet/tc_worksheet.rb
index 3782b215..b83613b4 100644
--- a/test/workbook/worksheet/tc_worksheet.rb
+++ b/test/workbook/worksheet/tc_worksheet.rb
@@ -73,6 +73,15 @@ class TestWorksheet < Test::Unit::TestCase
end
end
+ def test_state
+ assert_equal(:visible, @ws.state)
+ end
+
+ def test_state_validation
+ assert_raise(ArgumentError) { @ws.state = :dead }
+ assert_nothing_raised { @ws.state = :very_hidden }
+ end
+
def test_no_autowidth
@ws.workbook.use_autowidth = false
@ws.add_row [1,2,3,4]