Permalink
Browse files

pre-release readme updates and more work on auto_filter preset values

  • Loading branch information...
1 parent 1783350 commit 7ae8e76838c5ccf921de032a8d7bfa6e1017d007 @randym committed Sep 26, 2012
View
4 README.md
@@ -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
----------
View
16 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')
View
4 examples/example.rb
@@ -309,13 +309,13 @@
##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
#```
View
2 lib/axlsx/util/validators.rb
@@ -91,7 +91,7 @@ def self.validate_unsigned_int(v)
# @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
View
21 lib/axlsx/workbook/worksheet/auto_filter/filter_column.rb
@@ -17,17 +17,22 @@ class FilterColumn
# @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 @@ def col_id=(column_index)
# @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
View
10 lib/axlsx/workbook/worksheet/auto_filter/filters.rb
@@ -62,12 +62,16 @@ def blank=(use_blank)
# 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)
View
135 lib/axlsx/workbook/worksheet/sheet_pr.rb
@@ -1,24 +1,153 @@
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)
raise ArgumentError, "you must provide a worksheet" unless worksheet.is_a?(Worksheet)
@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
View
67 test/workbook/worksheet/auto_filter/tc_filter_column.rb
@@ -3,11 +3,74 @@
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

0 comments on commit 7ae8e76

Please sign in to comment.