diff options
| author | Randy Morgan <[email protected]> | 2012-09-26 14:42:00 +0900 |
|---|---|---|
| committer | Randy Morgan <[email protected]> | 2012-09-26 14:42:00 +0900 |
| commit | 7ae8e76838c5ccf921de032a8d7bfa6e1017d007 (patch) | |
| tree | 5e16ff075e7b261b60c891097f25215fb24906ea | |
| parent | 178335010128df34a7d0a0a6492e3e9bf1e94b99 (diff) | |
| download | caxlsx-7ae8e76838c5ccf921de032a8d7bfa6e1017d007.tar.gz caxlsx-7ae8e76838c5ccf921de032a8d7bfa6e1017d007.zip | |
pre-release readme updates and more work on auto_filter preset values
| -rw-r--r-- | README.md | 4 | ||||
| -rw-r--r-- | examples/auto_filter.rb | 16 | ||||
| -rwxr-xr-x | examples/example.rb | 4 | ||||
| -rw-r--r-- | lib/axlsx/util/validators.rb | 2 | ||||
| -rw-r--r-- | lib/axlsx/workbook/worksheet/auto_filter/filter_column.rb | 21 | ||||
| -rw-r--r-- | lib/axlsx/workbook/worksheet/auto_filter/filters.rb | 10 | ||||
| -rw-r--r-- | lib/axlsx/workbook/worksheet/sheet_pr.rb | 135 | ||||
| -rw-r--r-- | test/workbook/worksheet/auto_filter/tc_filter_column.rb | 67 |
8 files changed, 245 insertions, 14 deletions
@@ -150,6 +150,7 @@ This gem has 100% test coverage using test/unit. To execute tests for this gem, #Change log --------- - **September.??.12**: 1.2.4 + - added stored autowidth filter values and date grouping items - Improved support for autowidth when custom styles are applied - Added support for table style info that lets you take advantage of all the predefined table styles. @@ -252,6 +253,9 @@ done without the help of the people below. [straydogstudio](https://github.com/straydocstudio) - For making an AWESOME axlsx templating gem for rails. [MitchellAJ](https://github.com/MitchellAJ) - For catching a bug in font_size calculations, finding some old code in an example and above all for reporting all of that brilliantly + +[ebenoist](https://github.com/ebenoist) - For taking control of control characters and keeping what is between the lines, between the lines. + #Copyright and License ---------- diff --git a/examples/auto_filter.rb b/examples/auto_filter.rb new file mode 100644 index 00000000..fcfe2e90 --- /dev/null +++ b/examples/auto_filter.rb @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby -w -s +# -*- coding: utf-8 -*- + +$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib" +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.add_column 3, :filters, :filter_items => ['1.9.2'] + end +end.serialize('auto_filter.xlsx') diff --git a/examples/example.rb b/examples/example.rb index 3af276d5..9ba1ab73 100755 --- a/examples/example.rb +++ b/examples/example.rb @@ -309,13 +309,13 @@ end ##Tables #```ruby -wb.add_worksheet(:name => "Table", :style_info => { :name => "TableStyleMedium23" }) do |sheet| +wb.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.add_table "A2:D5", :name => 'Build Matrix' + sheet.add_table "A2:D5", :name => 'Build Matrix', :style_info => { :name => "TableStyleMedium23" } end #``` diff --git a/lib/axlsx/util/validators.rb b/lib/axlsx/util/validators.rb index 142f6dde..417de908 100644 --- a/lib/axlsx/util/validators.rb +++ b/lib/axlsx/util/validators.rb @@ -91,7 +91,7 @@ module Axlsx # @raise [ArgumentError] raised if the value is not a Fixnun, Integer, Float value greater or equal to 0 # @return [Boolean] true if the data is valid def self.validate_unsigned_numeric(v) - DataTypeValidator.validate("Invalid column width", [Fixnum, Integer, Float], v, lambda { |arg| arg.respond_to?(:>=) && arg >= 0 }) + DataTypeValidator.validate("Invalid column width", [Fixnum, Integer, Float], v, lambda { |arg| arg.respond_to?(:>=) && arg.to_i >= 0 }) end # Requires that the value is a Fixnum or Integer diff --git a/lib/axlsx/workbook/worksheet/auto_filter/filter_column.rb b/lib/axlsx/workbook/worksheet/auto_filter/filter_column.rb index 3de6d6a6..b55ee884 100644 --- a/lib/axlsx/workbook/worksheet/auto_filter/filter_column.rb +++ b/lib/axlsx/workbook/worksheet/auto_filter/filter_column.rb @@ -17,17 +17,22 @@ module Axlsx # @option [Boolean] show_button @see show_button def initialize(col_id, filter_type, options = {}) RestrictionValidator.validate 'FilterColumn.filter', FILTERS, filter_type + #Axlsx::validate_unsigned_int(col_id) self.col_id = col_id options.each do |o| self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}=" end - @filter = Axlsx.const_get(Axlsx.camel(filter_type)) + @filter = Axlsx.const_get(Axlsx.camel(filter_type)).new(options) yield @filter if block_given? end # Zero-based index indicating the AutoFilter column to which this filter information applies. # @return [Integer] attr_reader :col_id + + # The actual filter being dealt with here + # This could be any one of the allowed filter types + attr_reader :filter # Flag indicating whether the filter button is visible. # When the cell containing the filter button is merged with another cell, @@ -56,13 +61,23 @@ module Axlsx # @param [Boolean] hidden Flag indicating whether the AutoFilter button for this column is hidden. # @return [Boolean] def hidden_button=(hidden) - DataValidater.validate_boolean hidden + Axlsx.validate_boolean hidden @hidden_button = hidden end + # Flag indicating whether the AutoFilter button is show. This is + # undocumented in the spec, but exists in the schema file as an + # optional attribute. + # @param [Boolean] show Show or hide the button + # @return [Boolean] + def show_button=(show) + Axlsx.validate_boolean show + @show_botton = show + end + # Serialize the object to xml def to_xml_string(str='') - str << "<filterColumn colId='#{@col_id}' hiddenButton='#{@hidden_button}' showButton='#{@show_button}'>" + str << "<filterColumn colId='#{@col_id}' hiddenButton='#{hidden_button}' showButton='#{show_button}'>" @filter.to_xml_string(str) str << "</filterColumn>" end diff --git a/lib/axlsx/workbook/worksheet/auto_filter/filters.rb b/lib/axlsx/workbook/worksheet/auto_filter/filters.rb index d754f433..a71e999c 100644 --- a/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +++ b/lib/axlsx/workbook/worksheet/auto_filter/filters.rb @@ -62,12 +62,16 @@ module Axlsx # Serialize the object to xml def to_xml_string(str = '') - str << "<filters blank='#{@blank}' calendarType='#{@calendar_type}'>" - @filters.each { |filter| filter.to_xml_string(str) } - @date_group_items.each { |date_group_item| date_group_item.to_xml_string(str) } + str << "<filters blank='#{blank}' calendarType='#{calendar_type}'>" + filter_items.each { |filter| filter.to_xml_string(str) } + date_group_items.each { |date_group_item| date_group_item.to_xml_string(str) } str << '</filters>' end + # not entirely happy with this. + # filter_items should be a simple typed list that overrides << etc + # to create Filter objects from the inserted values. However this + # is most likely so rarely used...(really? do you know that?) def filter_items=(values) values.each do |value| filter_items << Filter.new(value) diff --git a/lib/axlsx/workbook/worksheet/sheet_pr.rb b/lib/axlsx/workbook/worksheet/sheet_pr.rb index 6f03bf5b..710d3cc1 100644 --- a/lib/axlsx/workbook/worksheet/sheet_pr.rb +++ b/lib/axlsx/workbook/worksheet/sheet_pr.rb @@ -1,9 +1,37 @@ module Axlsx - +#<xsd:complexType name="CT_SheetPr"> +#<xsd:sequence> +#<xsd:element name="tabColor" type="CT_Color" minOccurs="0" maxOccurs="1"/> +#<xsd:element name="outlinePr" type="CT_OutlinePr" minOccurs="0" maxOccurs="1"/> +#<xsd:element name="pageSetUpPr" type="CT_PageSetUpPr" minOccurs="0" maxOccurs="1"/> +#</xsd:sequence> +#<xsd:attribute name="syncHorizontal" type="xsd:boolean" use="optional" default="false"/> +#<xsd:attribute name="syncVertical" type="xsd:boolean" use="optional" default="false"/> +#<xsd:attribute name="syncRef" type="ST_Ref" use="optional"/> +#<xsd:attribute name="transitionEvaluation" type="xsd:boolean" use="optional" default="false"/> +#<xsd:attribute name="transitionEntry" type="xsd:boolean" use="optional" default="false"/> +#<xsd:attribute name="published" type="xsd:boolean" use="optional" default="true"/> +#<xsd:attribute name="codeName" type="xsd:string" use="optional"/> +#<xsd:attribute name="filterMode" type="xsd:boolean" use="optional" default="false"/> +#<xsd:attribute name="enableFormatConditionsCalculation" type="xsd:boolean" use="optional" default="true"/> +#</xsd:complexType> # The SheetPr class manages serialization fo a worksheet's sheetPr element. # Only fit_to_page is implemented class SheetPr + + # These attributes are all boolean so I'm doing a bit of a hand + # waving magic show to set up the attriubte accessors + # + BOOLEAN_ATTRIBUTES = [:sync_horizontal, + :sync_vertical, + :transtion_evaluation, + :transition_entry, + :published, + :filter_mode, + :enable_format_conditions_calculation] + + # Creates a new SheetPr object # @param [Worksheet] worksheet The worksheet that owns this SheetPr object def initialize(worksheet) @@ -11,14 +39,115 @@ module Axlsx @worksheet = worksheet end + # Dynamically create accessors for boolean attriubtes + BOOLEAN_ATTRIBUTES.each do |attr| + class_eval %{ + # The #{attr} attribute reader + # @return [Boolean] + attr_reader :#{attr} + + # The #{attr} writer + # @param [Boolean] value The value to assign to #{attr} + # @return [Boolean] + def #{attr}=(value) + Axlsx::validate_boolean(value) + @#{attr} = value + end + } + end + + # Anchor point for worksheet's window. + # @return [String] + attr_reader :code_name + + # Specifies a stable name of the sheet, which should not change over time, + # and does not change from user input. This name should be used by code + # to reference a particular sheet. + # @return [String] + attr_reader :sync_ref + + # The worksheet these properties apply to! + # @return [Worksheet] attr_reader :worksheet + # @see code_name + # @param [String] name + def code_name=(name) + @code_name = name + end + + # @see sync_ref + # @param [String] ref A cell reference (e.g. "A1") + def sync_ref=(ref) + @sync_ref = ref + end + # Serialize the object # @param [String] str serialized output will be appended to this object if provided. # @return [String] def to_xml_string(str = '') - return unless worksheet.fit_to_page? - str << "<sheetPr><pageSetUpPr fitToPage=\"%s\"></pageSetUpPr></sheetPr>" % worksheet.fit_to_page? + update_properties + str << "<sheetPr #{serialized_attributes}>" + page_setup_pr.to_xml_string(str) + str << "</sheetPr>" + end + + def page_setup_pr + @page_setup_pr ||= PageSetUpPr.new + end + + private + + def serialized_attributes(str = '') + instance_values.each do |key, value| + unless %(worksheet page_setup_pr).include? key + str << "#{Axlsx.camel(key, false)}='#{value}' " + end + end + str + end + + + def update_properties + page_setup_pr.fit_to_page = worksheet.fit_to_page? + filter_mode = worksheet.auto_filter.columns.size > 0 + end + end + + + class PageSetUpPr + + # creates a new page setup properties object + # @param [Hash] options + # @option [Boolean] fit_to_page Flag indicating whether the sheet displays Automatic Page Breaks. + # @option [Boolean] auto_page_breaks Flag indicating whether the Fit to Page print option is enabled. + def initialize(options = {}) + options.each do |key, value| + self.send("#{key}=",value) if self.respond_to?("#{key}=") + end + end + + # Flag indicating whether the sheet displays Automatic Page Breaks. + # @param [Boolean] value + # @return [Boolean] + def fit_to_page=(value) + Axlsx.validate_boolean value + @fit_to_page = value + end + + # Flag indicating whether the Fit to Page print option is enabled. + # @param [Boolean] value + # @return [Boolean] + def auto_page_breaks=(value) + Alxsx.validate_boolean value + @auto_page_breaks = value + end + + # serialize to xml + def to_xml_string(str='') + str << '<pageSetUpPr ' + instance_values.each { |key, value| str << "#{Axlsx.camel(key, false)}='#{value}' " } + str << '></pageSetUpPr>' end end end diff --git a/test/workbook/worksheet/auto_filter/tc_filter_column.rb b/test/workbook/worksheet/auto_filter/tc_filter_column.rb index b3ffed88..ec74316c 100644 --- a/test/workbook/worksheet/auto_filter/tc_filter_column.rb +++ b/test/workbook/worksheet/auto_filter/tc_filter_column.rb @@ -3,11 +3,74 @@ require 'tc_helper.rb' class TestFilterColumn < Test::Unit::TestCase def setup + @filter_column = Axlsx::FilterColumn.new(0, :filters, :filter_items => [200]) + end + + + def test_initialize_col_id + assert_raise ArgumentError do + Axlsx::FilterColumn.new(0, :bobs_house_of_filter) + end + assert_raise ArgumentError do + Axlsx::FilterColumn.new(:penut, :filters) + end + end + + def test_initailize_filter_type + assert @filter_column.filter.is_a?(Axlsx::Filters) + assert_equal 1, @filter_column.filter.filter_items.size + end + + def test_initialize_filter_type_filters_with_options + assert_equal 200, @filter_column.filter.filter_items.first.val + end + + def test_initialize_with_block + filter_column = Axlsx::FilterColumn.new(0, :filters) do |filters| + filters.filter_items = [700, 100, 5] + end + assert_equal 3, filter_column.filter.filter_items.size + assert_equal 700, filter_column.filter.filter_items.first.val + assert_equal 5, filter_column.filter.filter_items.last.val + end + def test_default_show_button + assert_equal true, @filter_column.show_button end + def test_default_hidden_button + assert_equal false, @filter_column.hidden_button + end + + def test_show_button + assert_raise ArgumentError do + @filter_column.show_button = :foo + end + assert_nothing_raised { @filter_column.show_button = false } + end + + def test_hidden_button + assert_raise ArgumentError do + @filter_column.hidden_button = :hoge + end + assert_nothing_raised { @filter_column.hidden_button = true } + end + + def test_col_id= + assert_raise ArgumentError do + @filter_column.col_id = :bar + end + assert_nothing_raised { @filter_column.col_id = 7 } + end + + def test_to_xml_string + doc = Nokogiri::XML(@filter_column.to_xml_string) + assert doc.xpath("//filterColumn[@colId=#{@filter_column.col_id}]") + assert doc.xpath("//filterColumn[@hiddenButton=#{@filter_column.hidden_button}]") + assert doc.xpath("//filterColumn[@showButton=#{@filter_column.show_button}]") + + - def test_do_it_later - assert true + assert doc.xpath("//filterColumn/filters") end end |
