axlsx 1.2.0 → 1.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. data/.yardopts +3 -2
  2. data/CHANGELOG.md +34 -1
  3. data/README.md +47 -33
  4. data/Rakefile +1 -1
  5. data/examples/auto_filter.rb +16 -0
  6. data/examples/basic_charts.rb +4 -0
  7. data/examples/colored_links.rb +59 -0
  8. data/examples/doc/_index.html +88 -0
  9. data/examples/doc/class_list.html +53 -0
  10. data/examples/doc/css/common.css +1 -0
  11. data/examples/doc/css/full_list.css +57 -0
  12. data/examples/doc/css/style.css +328 -0
  13. data/examples/doc/file_list.html +52 -0
  14. data/examples/doc/frames.html +28 -0
  15. data/examples/doc/index.html +88 -0
  16. data/examples/doc/js/app.js +214 -0
  17. data/examples/doc/js/full_list.js +173 -0
  18. data/examples/doc/js/jquery.js +4 -0
  19. data/examples/doc/method_list.html +52 -0
  20. data/examples/doc/top-level-namespace.html +102 -0
  21. data/examples/example.rb +447 -257
  22. data/examples/finance.rb +82 -0
  23. data/examples/hyperlinks.rb +23 -0
  24. data/examples/page_setup.rb +11 -0
  25. data/examples/skydrive/axlsx.csv +1 -0
  26. data/examples/skydrive/axlsx.xlsx +0 -0
  27. data/examples/skydrive/real_example.rb +8 -8
  28. data/examples/sprk2012/Screen Shot 2012-09-11 at 10.42.06 PM.png +0 -0
  29. data/examples/sprk2012/Screen Shot 2012-09-11 at 11.07.48 PM.png +0 -0
  30. data/examples/sprk2012/Screen Shot 2012-09-11 at 8.31.50 PM.png +0 -0
  31. data/examples/sprk2012/Screen Shot 2012-09-11 at 9.23.27 PM.png +0 -0
  32. data/examples/sprk2012/Screen Shot 2012-09-11 at 9.32.06 PM.png +0 -0
  33. data/examples/sprk2012/Screen Shot 2012-09-11 at 9.33.35 PM.png +0 -0
  34. data/examples/sprk2012/Screen Shot 2012-09-11 at 9.46.44 PM.png +0 -0
  35. data/examples/sprk2012/Screen Shot 2012-09-12 at 5.07.23 PM.png +0 -0
  36. data/examples/sprk2012/basics.rb +11 -0
  37. data/examples/sprk2012/basics.xlsx +0 -0
  38. data/examples/sprk2012/gravatar.jpeg +0 -0
  39. data/examples/sprk2012/hair_club.jpg +0 -0
  40. data/examples/sprk2012/images.rb +9 -0
  41. data/examples/{example.xlsx → sprk2012/images.xlsx} +0 -0
  42. data/examples/sprk2012/line_chart.rb +56 -0
  43. data/examples/sprk2012/line_chart.xlsx +0 -0
  44. data/examples/sprk2012/sprk2012.key +0 -0
  45. data/examples/sprk2012/styles.rb +20 -0
  46. data/examples/sprk2012/styles.xlsx +0 -0
  47. data/examples/styles.rb +62 -0
  48. data/lib/axlsx/content_type/abstract_content_type.rb +32 -0
  49. data/lib/axlsx/content_type/content_type.rb +1 -1
  50. data/lib/axlsx/content_type/default.rb +6 -37
  51. data/lib/axlsx/content_type/override.rb +6 -38
  52. data/lib/axlsx/doc_props/app.rb +10 -7
  53. data/lib/axlsx/drawing/axis.rb +4 -4
  54. data/lib/axlsx/drawing/chart.rb +2 -3
  55. data/lib/axlsx/drawing/d_lbls.rb +21 -31
  56. data/lib/axlsx/drawing/drawing.rb +6 -0
  57. data/lib/axlsx/drawing/hyperlink.rb +40 -32
  58. data/lib/axlsx/drawing/marker.rb +13 -13
  59. data/lib/axlsx/drawing/num_data.rb +6 -6
  60. data/lib/axlsx/drawing/num_data_source.rb +17 -16
  61. data/lib/axlsx/drawing/one_cell_anchor.rb +20 -22
  62. data/lib/axlsx/drawing/pic.rb +25 -27
  63. data/lib/axlsx/drawing/picture_locking.rb +12 -44
  64. data/lib/axlsx/drawing/scaling.rb +13 -13
  65. data/lib/axlsx/drawing/scatter_chart.rb +3 -3
  66. data/lib/axlsx/drawing/series.rb +3 -6
  67. data/lib/axlsx/drawing/str_data.rb +3 -3
  68. data/lib/axlsx/drawing/str_val.rb +7 -8
  69. data/lib/axlsx/drawing/view_3D.rb +52 -38
  70. data/lib/axlsx/drawing/vml_shape.rb +23 -23
  71. data/lib/axlsx/package.rb +14 -17
  72. data/lib/axlsx/stylesheet/border.rb +29 -20
  73. data/lib/axlsx/stylesheet/border_pr.rb +5 -4
  74. data/lib/axlsx/stylesheet/cell_alignment.rb +55 -29
  75. data/lib/axlsx/stylesheet/cell_protection.rb +7 -4
  76. data/lib/axlsx/stylesheet/cell_style.rb +19 -14
  77. data/lib/axlsx/stylesheet/color.rb +19 -16
  78. data/lib/axlsx/stylesheet/dxf.rb +4 -4
  79. data/lib/axlsx/stylesheet/font.rb +22 -22
  80. data/lib/axlsx/stylesheet/gradient_fill.rb +45 -21
  81. data/lib/axlsx/stylesheet/num_fmt.rb +22 -13
  82. data/lib/axlsx/stylesheet/pattern_fill.rb +12 -21
  83. data/lib/axlsx/stylesheet/styles.rb +11 -2
  84. data/lib/axlsx/stylesheet/table_style.rb +17 -16
  85. data/lib/axlsx/stylesheet/table_style_element.rb +15 -11
  86. data/lib/axlsx/stylesheet/table_styles.rb +14 -11
  87. data/lib/axlsx/stylesheet/xf.rb +28 -26
  88. data/lib/axlsx/util/accessors.rb +49 -0
  89. data/lib/axlsx/util/constants.rb +105 -4
  90. data/lib/axlsx/util/options_parser.rb +15 -0
  91. data/lib/axlsx/util/serialized_attributes.rb +46 -0
  92. data/lib/axlsx/util/simple_typed_list.rb +16 -2
  93. data/lib/axlsx/util/validators.rb +33 -8
  94. data/lib/axlsx/version.rb +2 -2
  95. data/lib/axlsx/workbook/defined_name.rb +13 -58
  96. data/lib/axlsx/workbook/workbook.rb +33 -2
  97. data/lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb +77 -0
  98. data/lib/axlsx/workbook/worksheet/auto_filter/filter_column.rb +94 -0
  99. data/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +246 -0
  100. data/lib/axlsx/workbook/worksheet/cell.rb +82 -45
  101. data/lib/axlsx/workbook/worksheet/cfvo.rb +15 -15
  102. data/lib/axlsx/workbook/worksheet/cfvos.rb +18 -0
  103. data/lib/axlsx/workbook/worksheet/col.rb +34 -27
  104. data/lib/axlsx/workbook/worksheet/color_scale.rb +7 -13
  105. data/lib/axlsx/workbook/worksheet/comment.rb +14 -11
  106. data/lib/axlsx/workbook/worksheet/conditional_formatting.rb +11 -11
  107. data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +27 -25
  108. data/lib/axlsx/workbook/worksheet/data_bar.rb +44 -34
  109. data/lib/axlsx/workbook/worksheet/data_validation.rb +61 -62
  110. data/lib/axlsx/workbook/worksheet/date_time_converter.rb +1 -1
  111. data/lib/axlsx/workbook/worksheet/dimension.rb +0 -1
  112. data/lib/axlsx/workbook/worksheet/icon_set.rb +20 -20
  113. data/lib/axlsx/workbook/worksheet/page_margins.rb +21 -19
  114. data/lib/axlsx/workbook/worksheet/page_set_up_pr.rb +44 -0
  115. data/lib/axlsx/workbook/worksheet/page_setup.rb +152 -23
  116. data/lib/axlsx/workbook/worksheet/pane.rb +48 -51
  117. data/lib/axlsx/workbook/worksheet/print_options.rb +8 -30
  118. data/lib/axlsx/workbook/worksheet/protected_range.rb +16 -13
  119. data/lib/axlsx/workbook/worksheet/row.rb +48 -81
  120. data/lib/axlsx/workbook/worksheet/selection.rb +30 -38
  121. data/lib/axlsx/workbook/worksheet/sheet_calc_pr.rb +29 -0
  122. data/lib/axlsx/workbook/worksheet/sheet_pr.rb +49 -4
  123. data/lib/axlsx/workbook/worksheet/sheet_protection.rb +51 -155
  124. data/lib/axlsx/workbook/worksheet/sheet_view.rb +68 -234
  125. data/lib/axlsx/workbook/worksheet/table.rb +22 -17
  126. data/lib/axlsx/workbook/worksheet/table_style_info.rb +51 -0
  127. data/lib/axlsx/workbook/worksheet/worksheet.rb +51 -14
  128. data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +1 -1
  129. data/lib/axlsx/workbook/worksheet/worksheet_hyperlink.rb +79 -0
  130. data/lib/axlsx/workbook/worksheet/worksheet_hyperlinks.rb +38 -0
  131. data/lib/axlsx.rb +19 -5
  132. data/test/content_type/tc_default.rb +0 -11
  133. data/test/content_type/tc_override.rb +0 -13
  134. data/test/drawing/tc_d_lbls.rb +14 -4
  135. data/test/stylesheet/tc_styles.rb +13 -0
  136. data/test/tc_axlsx.rb +20 -2
  137. data/test/tc_package.rb +1 -0
  138. data/test/util/tc_validators.rb +22 -1
  139. data/test/workbook/tc_defined_name.rb +2 -2
  140. data/test/workbook/tc_workbook.rb +15 -0
  141. data/test/workbook/worksheet/auto_filter/tc_auto_filter.rb +38 -0
  142. data/test/workbook/worksheet/auto_filter/tc_filter_column.rb +76 -0
  143. data/test/workbook/worksheet/auto_filter/tc_filters.rb +50 -0
  144. data/test/workbook/worksheet/tc_cell.rb +35 -5
  145. data/test/workbook/worksheet/tc_col.rb +11 -1
  146. data/test/workbook/worksheet/tc_page_set_up_pr.rb +15 -0
  147. data/test/workbook/worksheet/tc_page_setup.rb +6 -1
  148. data/test/workbook/worksheet/tc_pane.rb +5 -45
  149. data/test/workbook/worksheet/tc_row.rb +4 -4
  150. data/test/workbook/worksheet/tc_selection.rb +9 -48
  151. data/test/workbook/worksheet/tc_sheet_calc_pr.rb +18 -0
  152. data/test/workbook/worksheet/tc_sheet_pr.rb +27 -0
  153. data/test/workbook/worksheet/{table/tc_table.rb → tc_table.rb} +6 -1
  154. data/test/workbook/worksheet/tc_table_style_info.rb +53 -0
  155. data/test/workbook/worksheet/tc_worksheet.rb +17 -3
  156. data/test/workbook/worksheet/tc_worksheet_hyperlink.rb +64 -0
  157. metadata +74 -10
  158. data/examples/example_streamed.xlsx +0 -0
  159. data/examples/no-use_autowidth.xlsx +0 -0
  160. data/examples/shared_strings_example.xlsx +0 -0
  161. data/lib/axlsx/workbook/worksheet/auto_filter.rb +0 -34
@@ -0,0 +1,79 @@
1
+ module Axlsx
2
+
3
+ # A worksheet hyperlink object. Note that this is not the same as a drawing hyperlink object.
4
+ class WorksheetHyperlink
5
+
6
+ include Axlsx::OptionsParser
7
+ include Axlsx::Accessors
8
+ include Axlsx::SerializedAttributes
9
+ # Creates a new hyperlink object.
10
+ # @note the preferred way to add hyperlinks to your worksheet is the Worksheet#add_hyperlink method
11
+ # @param [Worksheet] worksheet the Worksheet that owns this hyperlink
12
+ # @param [Hash] options options to use when creating this hyperlink
13
+ # @option [String] display Display string, if different from string in string table. This is a property on the hyperlink object, but does not need to appear in the spreadsheet application UI.
14
+ # @option [String] location Location within target. If target is a workbook (or this workbook) this shall refer to a sheet and cell or a defined name. Can also be an HTML anchor if target is HTML file.
15
+ # @option [String] tooltip The tip to display when the user positions the mouse cursor over this hyperlink
16
+ # @option [Symbol] target This is :external by default. If you set it to anything else, the location is interpreted to be the current workbook.
17
+ # @option [String|Cell] ref The location of this hyperlink in the worksheet
18
+ def initialize(worksheet, options={})
19
+ DataTypeValidator.validate "Hyperlink.worksheet", [Worksheet], worksheet
20
+ @worksheet = worksheet
21
+ @target = :external
22
+ parse_options options
23
+ yield self if block_given?
24
+ end
25
+
26
+ string_attr_accessor :display, :location, :tooltip
27
+
28
+ serializable_attributes :display, :tooltip, :ref
29
+
30
+ #Cell location of hyperlink on worksheet.
31
+ # @return [String]
32
+ attr_reader :ref
33
+
34
+ # Sets the target for this hyperlink. Anything other than :external instructs the library to treat the location as an in-workbook reference.
35
+ # @param [Symbol] target
36
+ def target=(target)
37
+ @target = target
38
+ end
39
+
40
+ # Sets the cell location of this hyperlink in the worksheet
41
+ # @param [String|Cell] cell_reference The string reference or cell that defines where this hyperlink shows in the worksheet.
42
+ def ref=(cell_reference)
43
+ cell_reference = cell_reference.r if cell_reference.is_a?(Cell)
44
+ Axlsx::validate_string cell_reference
45
+ @ref = cell_reference
46
+ end
47
+
48
+ # The relationship required by this hyperlink when the taget is :external
49
+ # @return [Relationship]
50
+ def relationship
51
+ return unless @target == :external
52
+ Relationship.new HYPERLINK_R, location, :target_mode => :External
53
+ end
54
+
55
+ # The id of the relationship for this object
56
+ # @return [String]
57
+ def id
58
+ return unless @target == :external
59
+ "rId#{(@worksheet.relationships_index_of(self)+1)}"
60
+ end
61
+
62
+ # Seralize the object
63
+ # @param [String] str
64
+ # @return [String]
65
+ def to_xml_string(str='')
66
+ str << '<hyperlink '
67
+ serialized_attributes str, location_or_id
68
+ str << '/>'
69
+ end
70
+
71
+ # The values to be used in serialization based on the target.
72
+ # location should only be specified for non-external targets.
73
+ # r:id should only be specified for external targets.
74
+ # @return [Hash]
75
+ def location_or_id
76
+ @target == :external ? { :"r:id" => id } : { :location => location }
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,38 @@
1
+ module Axlsx
2
+
3
+ #A collection of hyperlink objects for a worksheet
4
+ class WorksheetHyperlinks < SimpleTypedList
5
+
6
+ # Creates a new Hyperlinks collection
7
+ # @param [Worksheet] worksheet the worksheet that owns these hyperlinks
8
+ def initialize(worksheet)
9
+ DataTypeValidator.validate "Hyperlinks.worksheet", [Worksheet], worksheet
10
+ @worksheet = worksheet
11
+ super WorksheetHyperlink
12
+ end
13
+
14
+ # Creates and adds a new hyperlink based on the options provided
15
+ # @see WorksheetHyperlink#initialize
16
+ # @return [WorksheetHyperlink]
17
+ def add(options)
18
+ @list << WorksheetHyperlink.new(@worksheet, options)
19
+ @list.last
20
+ end
21
+
22
+ # The relationships required by this collection's hyperlinks
23
+ # @return Array
24
+ def relationships
25
+ return [] if empty?
26
+ map { |hyperlink| hyperlink.relationship }
27
+ end
28
+
29
+ # seralize the collection of hyperlinks
30
+ # @return [String]
31
+ def to_xml_string(str='')
32
+ return if empty?
33
+ str << '<hyperlinks>'
34
+ @list.each { |hyperlink| hyperlink.to_xml_string(str) }
35
+ str << '</hyperlinks>'
36
+ end
37
+ end
38
+ end
data/lib/axlsx.rb CHANGED
@@ -5,7 +5,9 @@ require 'axlsx/version.rb'
5
5
  require 'axlsx/util/simple_typed_list.rb'
6
6
  require 'axlsx/util/constants.rb'
7
7
  require 'axlsx/util/validators.rb'
8
-
8
+ require 'axlsx/util/accessors.rb'
9
+ require 'axlsx/util/serialized_attributes'
10
+ require 'axlsx/util/options_parser'
9
11
  # to be included with parsable intitites.
10
12
  #require 'axlsx/util/parser.rb'
11
13
 
@@ -37,15 +39,25 @@ if !Object.respond_to?(:instance_values)
37
39
  end
38
40
  end
39
41
 
40
- # xlsx generation with charts, images, automated column width, customizable styles and full schema validation. Axlsx excels at helping you generate beautiful Office Open XML Spreadsheet documents without having to understand the entire ECMA specification. Check out the README for some examples of how easy it is. Best of all, you can validate your xlsx file before serialization so you know for sure that anything generated is going to load on your client's machine.
42
+ # xlsx generation with charts, images, automated column width, customizable styles
43
+ # and full schema validation. Axlsx excels at helping you generate beautiful
44
+ # Office Open XML Spreadsheet documents without having to understand the entire
45
+ # ECMA specification. Check out the README for some examples of how easy it is.
46
+ # Best of all, you can validate your xlsx file before serialization so you know
47
+ # for sure that anything generated is going to load on your client's machine.
41
48
  module Axlsx
42
49
 
43
50
  # determines the cell range for the items provided
44
51
  def self.cell_range(cells, absolute=true)
45
52
  return "" unless cells.first.is_a? Cell
46
- sort_cells(cells)
53
+ cells = sort_cells(cells)
47
54
  reference = "#{cells.first.reference(absolute)}:#{cells.last.reference(absolute)}"
48
- absolute ? "'#{cells.first.row.worksheet.name}'!#{reference}" : reference
55
+ if absolute
56
+ escaped_name = cells.first.row.worksheet.name.gsub "&apos;", "''"
57
+ "'#{escaped_name}'!#{reference}"
58
+ else
59
+ reference
60
+ end
49
61
  end
50
62
 
51
63
  # sorts the array of cells provided to start from the minimum x,y to
@@ -61,10 +73,11 @@ module Axlsx
61
73
  def self.coder
62
74
  @@coder ||= ::HTMLEntities.new
63
75
  end
64
-
76
+
65
77
  # returns the x, y position of a cell
66
78
  def self.name_to_indices(name)
67
79
  raise ArgumentError, 'invalid cell name' unless name.size > 1
80
+ # capitalization?!?
68
81
  v = name[/[A-Z]+/].reverse.chars.reduce({:base=>1, :i=>0}) do |val, c|
69
82
  val[:i] += ((c.bytes.first - 64) * val[:base]); val[:base] *= 26; val
70
83
  end
@@ -95,6 +108,7 @@ module Axlsx
95
108
  # @param [String] s The snake case string to camelize
96
109
  # @return [String]
97
110
  def self.camel(s="", all_caps = true)
111
+ s = s.to_s
98
112
  s = s.capitalize if all_caps
99
113
  s.gsub(/_(.)/){ $1.upcase }
100
114
  end
@@ -3,14 +3,6 @@ require 'tc_helper.rb'
3
3
 
4
4
  class TestDefault < Test::Unit::TestCase
5
5
 
6
- def test_initialization_requires_Extension_and_ContentType
7
- assert_raise(ArgumentError, "raises argument error if Extension and/or ContentType are not specified") { Axlsx::Default.new }
8
- assert_raise(ArgumentError, "raises argument error if Extension and/or ContentType are not specified") { Axlsx::Default.new :Extension=>"xml" }
9
- assert_raise(ArgumentError, "raises argument error if Extension and/or ContentType are not specified") { Axlsx::Default.new :ContentType=>"asdf" }
10
-
11
- assert_nothing_raised {Axlsx::Default.new :Extension=>"foo", :ContentType=>Axlsx::XML_CT}
12
-
13
- end
14
6
  def test_content_type_restriction
15
7
  assert_raise(ArgumentError, "raises argument error if invlalid ContentType is") { Axlsx::Default.new :ContentType=>"asdf" }
16
8
  end
@@ -20,8 +12,5 @@ class TestDefault < Test::Unit::TestCase
20
12
  doc = Nokogiri::XML(type.to_xml_string)
21
13
  assert_equal(doc.xpath("Default[@ContentType='#{Axlsx::XML_CT}']").size, 1)
22
14
  assert_equal(doc.xpath("Default[@Extension='xml']").size, 1)
23
-
24
15
  end
25
-
26
-
27
16
  end
@@ -1,16 +1,6 @@
1
- # -*- coding: utf-8 -*-
2
1
  require 'tc_helper.rb'
3
-
4
2
  class TestOverride < Test::Unit::TestCase
5
3
 
6
- def test_initialization_requires_Extension_and_ContentType
7
- err = "requires PartName and ContentType options"
8
- assert_raise(ArgumentError, err) { Axlsx::Override.new }
9
- assert_raise(ArgumentError, err) { Axlsx::Override.new :PartName=>"xml" }
10
- assert_raise(ArgumentError, err) { Axlsx::Override.new :ContentType=>"asdf" }
11
- assert_nothing_raised {Axlsx::Override.new :PartName=>"foo", :ContentType=>Axlsx::CHART_CT}
12
- end
13
-
14
4
  def test_content_type_restriction
15
5
  assert_raise(ArgumentError, "requires known content type") { Axlsx::Override.new :ContentType=>"asdf" }
16
6
  end
@@ -20,8 +10,5 @@ class TestOverride < Test::Unit::TestCase
20
10
  doc = Nokogiri::XML(type.to_xml_string)
21
11
  assert_equal(doc.xpath("Override[@ContentType='#{Axlsx::CHART_CT}']").size, 1)
22
12
  assert_equal(doc.xpath("Override[@PartName='somechart.xml']").size, 1)
23
-
24
13
  end
25
-
26
-
27
14
  end
@@ -4,19 +4,29 @@ class TestDLbls < Test::Unit::TestCase
4
4
 
5
5
  def setup
6
6
  @d_lbls = Axlsx::DLbls.new(Axlsx::Pie3DChart)
7
+ @boolean_attributes =[:show_legend_key,
8
+ :show_val,
9
+ :show_cat_name,
10
+ :show_ser_name,
11
+ :show_percent,
12
+ :show_bubble_size,
13
+ :show_leader_lines]
7
14
  end
8
15
 
9
16
  def test_initialization
10
17
  assert_equal(:bestFit, @d_lbls.d_lbl_pos)
11
- Axlsx::DLbls::BOOLEAN_ATTRIBUTES.each do |attr|
18
+ @boolean_attributes.each do |attr|
12
19
  assert_equal(false, @d_lbls.send(attr))
13
20
  end
14
21
  end
15
22
 
16
23
  def test_initialization_with_optoins
17
- options_hash = Hash[*[Axlsx::DLbls::BOOLEAN_ATTRIBUTES.map { |name| [name, true] }] ]
24
+
25
+ options_hash = Hash[*[@boolean_attributes.map { |name| [name, true] }] ]
26
+
18
27
  d_lbls = Axlsx::DLbls.new(Axlsx::Pie3DChart, options_hash.merge( { :d_lbl_pos => :t }))
19
- Axlsx::DLbls::BOOLEAN_ATTRIBUTES.each do |attr|
28
+
29
+ @boolean_attributes.each do |attr|
20
30
  assert_equal(true, d_lbls.send(attr), "boolean attributes set by options")
21
31
  end
22
32
  assert_equal(:t, d_lbls.d_lbl_pos, "d_lbl_pos set by options")
@@ -27,7 +37,7 @@ class TestDLbls < Test::Unit::TestCase
27
37
  end
28
38
 
29
39
  def test_boolean_attributes
30
- Axlsx::DLbls::BOOLEAN_ATTRIBUTES.each do |attr|
40
+ @boolean_attributes.each do |attr|
31
41
  assert_raise(ArgumentError, "rejects non boolean value for #{attr}") { @d_lbls.send("#{attr}=", :foo) }
32
42
  assert_nothing_raised("accepts boolean value for #{attr}") { @d_lbls.send("#{attr}=", true) }
33
43
  assert_nothing_raised("accepts boolean value for #{attr}") { @d_lbls.send("#{attr}=", false) }
@@ -105,6 +105,19 @@ class TestStyles < Test::Unit::TestCase
105
105
  assert(@styles.parse_alignment_options(:alignment => {}).is_a?(Axlsx::CellAlignment))
106
106
  end
107
107
 
108
+ def test_parse_font_using_defaults
109
+ original = @styles.fonts.first
110
+ @styles.add_style :b => 1, :sz => 99
111
+ created = @styles.fonts.last
112
+ original_attributes = original.instance_values
113
+ assert_equal(1, created.b)
114
+ assert_equal(99, created.sz)
115
+ copied = original_attributes.reject{ |key, value| %w(b sz).include? key }
116
+ copied.each do |key, value|
117
+ assert_equal(created.instance_values[key], value)
118
+ end
119
+ end
120
+
108
121
  def test_parse_font_options
109
122
  options = {
110
123
  :fg_color => "FF050505",
data/test/tc_axlsx.rb CHANGED
@@ -14,8 +14,26 @@ class TestAxlsx < Test::Unit::TestCase
14
14
  }
15
15
  end
16
16
 
17
- def test_cell_range
18
- #To do
17
+ def test_cell_range_empty_if_no_cell
18
+ assert_equal(Axlsx.cell_range([]), "")
19
+ end
20
+
21
+ def test_cell_range_relative
22
+ p = Axlsx::Package.new
23
+ ws = p.workbook.add_worksheet
24
+ row = ws.add_row
25
+ c1 = row.add_cell
26
+ c2 = row.add_cell
27
+ assert_equal(Axlsx.cell_range([c2, c1], false), "A1:B1")
28
+ end
29
+
30
+ def test_cell_range_absolute
31
+ p = Axlsx::Package.new
32
+ ws = p.workbook.add_worksheet :name => "Sheet <'>\" 1"
33
+ row = ws.add_row
34
+ c1 = row.add_cell
35
+ c2 = row.add_cell
36
+ assert_equal(Axlsx.cell_range([c2, c1], true), "'Sheet &lt;''&gt;&quot; 1'!$A$1:$B$1")
19
37
  end
20
38
 
21
39
  def test_name_to_indices
data/test/tc_package.rb CHANGED
@@ -7,6 +7,7 @@ class TestPackage < Test::Unit::TestCase
7
7
  ws = @package.workbook.add_worksheet
8
8
  ws.add_row ['Can', 'we', 'build it?']
9
9
  ws.add_row ['Yes!', 'We', 'can!']
10
+ ws.add_hyperlink :ref => ws.rows.first.cells.last, :location => 'https://github.com/randym'
10
11
  ws.workbook.add_defined_name("#{ws.name}!A1:C2", :name => '_xlnm.Print_Titles', :hidden => true)
11
12
  ws.protect_range('A1:C1')
12
13
  ws.protect_range(ws.rows.last.cells)
@@ -158,4 +158,25 @@ class TestValidators < Test::Unit::TestCase
158
158
  assert_raise(ArgumentError) { Axlsx.validate_split_state_type 'frozen_split' }
159
159
  assert_raise(ArgumentError) { Axlsx.validate_split_state_type 0 }
160
160
  end
161
- end
161
+
162
+ def test_validate_family
163
+ assert_raise(ArgumentError) { Axlsx.validate_family 0 }
164
+ (1..5).each do |item|
165
+ assert_nothing_raised { Axlsx.validate_family item }
166
+ end
167
+ end
168
+
169
+ def test_validate_u
170
+ assert_raise(ArgumentError) { Axlsx.validate_cell_u :hoge }
171
+ [:none, :single, :double, :singleAccounting, :doubleAccounting].each do |sym|
172
+ assert_nothing_raised { Axlsx.validate_cell_u sym }
173
+ end
174
+ end
175
+
176
+ def test_range_validation
177
+ # exclusive
178
+ assert_raise(ArgumentError) { Axlsx::RangeValidator.validate('foo', 1, 10, 10, false) }
179
+ # inclusive by default
180
+ assert_nothing_raised { Axlsx::RangeValidator.validate('foo', 1, 10, 10) }
181
+ end
182
+ end
@@ -10,14 +10,14 @@ class TestDefinedNames < Test::Unit::TestCase
10
10
  end
11
11
 
12
12
  def test_string_attributes
13
- Axlsx::DefinedName::STRING_ATTRIBUTES.each do |attr|
13
+ %w(short_cut_key status_bar help description custom_menu comment).each do |attr|
14
14
  assert_raise(ArgumentError, 'only strings allowed in string attributes') { @dn.send("#{attr}=", 1) }
15
15
  assert_nothing_raised { @dn.send("#{attr}=", '_xlnm.Sheet_Title') }
16
16
  end
17
17
  end
18
18
 
19
19
  def test_boolean_attributes
20
- Axlsx::DefinedName::BOOLEAN_ATTRIBUTES.each do |attr|
20
+ %w(workbook_parameter publish_to_server xlm vb_proceedure function hidden).each do |attr|
21
21
  assert_raise(ArgumentError, 'only booleanish allowed in string attributes') { @dn.send("#{attr}=", 'foo') }
22
22
  assert_nothing_raised { @dn.send("#{attr}=", 1) }
23
23
  end
@@ -16,6 +16,13 @@ class TestWorkbook < Test::Unit::TestCase
16
16
  assert_equal(@wb.use_autowidth, false)
17
17
  end
18
18
 
19
+
20
+ def test_sheet_by_name_retrieval
21
+ @wb.add_worksheet(:name=>'foo')
22
+ @wb.add_worksheet(:name=>'bar')
23
+ assert_equal('foo', @wb.sheet_by_name('foo').name)
24
+
25
+ end
19
26
  def test_date1904
20
27
  assert_equal(Axlsx::Workbook.date1904, @wb.date1904)
21
28
  @wb.date1904 = :false
@@ -42,6 +49,14 @@ class TestWorkbook < Test::Unit::TestCase
42
49
  assert_equal(@wb.worksheets.first, ws, "the worksheet returned is the worksheet added")
43
50
  assert_equal(ws.name, "bob", "name option gets passed to worksheet")
44
51
  end
52
+
53
+ def test_insert_worksheet
54
+ @wb.add_worksheet(:name => 'A')
55
+ @wb.add_worksheet(:name => 'B')
56
+ ws3 = @wb.insert_worksheet(0, :name => 'C')
57
+ assert_equal(ws3.name, @wb.worksheets.first.name)
58
+ end
59
+
45
60
  def test_relationships
46
61
  #current relationship size is 1 due to style relation
47
62
  assert(@wb.relationships.size == 1)
@@ -0,0 +1,38 @@
1
+ require 'tc_helper.rb'
2
+
3
+ class TestAutoFilter < Test::Unit::TestCase
4
+
5
+ def setup
6
+ ws = Axlsx::Package.new.workbook.add_worksheet
7
+ 3.times { |index| ws.add_row [1*index,2*index,3*index] }
8
+ @auto_filter = ws.auto_filter
9
+ @auto_filter.range = 'A1:C3'
10
+ @auto_filter.add_column 0, :filters, :filter_items => [1]
11
+ end
12
+
13
+ def test_defined_name
14
+ assert_equal("'Sheet1'!$A$1:$C$3", @auto_filter.defined_name)
15
+ end
16
+
17
+ def test_to_xml_string
18
+ doc = Nokogiri::XML(@auto_filter.to_xml_string)
19
+ assert(doc.xpath("autoFilter[@ref='#{@auto_filter.range}']"))
20
+ end
21
+
22
+ def test_columns
23
+ assert @auto_filter.columns.is_a?(Axlsx::SimpleTypedList)
24
+ assert_equal @auto_filter.columns.allowed_types, [Axlsx::FilterColumn]
25
+ end
26
+
27
+ def test_add_column
28
+ @auto_filter.add_column(0, :filters) do |column|
29
+ assert column.is_a? FilterColumn
30
+ end
31
+ end
32
+
33
+ def test_applya
34
+ assert_equal nil, @auto_filter.worksheet.rows.last.hidden
35
+ @auto_filter.apply
36
+ assert_equal true, @auto_filter.worksheet.rows.last.hidden
37
+ end
38
+ end
@@ -0,0 +1,76 @@
1
+ require 'tc_helper.rb'
2
+
3
+ class TestFilterColumn < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @filter_column = Axlsx::FilterColumn.new(0, :filters, :filter_items => [200])
7
+ end
8
+
9
+
10
+ def test_initialize_col_id
11
+ assert_raise ArgumentError do
12
+ Axlsx::FilterColumn.new(0, :bobs_house_of_filter)
13
+ end
14
+ assert_raise ArgumentError do
15
+ Axlsx::FilterColumn.new(:penut, :filters)
16
+ end
17
+ end
18
+
19
+ def test_initailize_filter_type
20
+ assert @filter_column.filter.is_a?(Axlsx::Filters)
21
+ assert_equal 1, @filter_column.filter.filter_items.size
22
+ end
23
+
24
+ def test_initialize_filter_type_filters_with_options
25
+ assert_equal 200, @filter_column.filter.filter_items.first.val
26
+ end
27
+
28
+ def test_initialize_with_block
29
+ filter_column = Axlsx::FilterColumn.new(0, :filters) do |filters|
30
+ filters.filter_items = [700, 100, 5]
31
+ end
32
+ assert_equal 3, filter_column.filter.filter_items.size
33
+ assert_equal 700, filter_column.filter.filter_items.first.val
34
+ assert_equal 5, filter_column.filter.filter_items.last.val
35
+ end
36
+
37
+ def test_default_show_button
38
+ assert_equal true, @filter_column.show_button
39
+ end
40
+
41
+ def test_default_hidden_button
42
+ assert_equal false, @filter_column.hidden_button
43
+ end
44
+
45
+ def test_show_button
46
+ assert_raise ArgumentError do
47
+ @filter_column.show_button = :foo
48
+ end
49
+ assert_nothing_raised { @filter_column.show_button = false }
50
+ end
51
+
52
+ def test_hidden_button
53
+ assert_raise ArgumentError do
54
+ @filter_column.hidden_button = :hoge
55
+ end
56
+ assert_nothing_raised { @filter_column.hidden_button = true }
57
+ end
58
+
59
+ def test_col_id=
60
+ assert_raise ArgumentError do
61
+ @filter_column.col_id = :bar
62
+ end
63
+ assert_nothing_raised { @filter_column.col_id = 7 }
64
+ end
65
+
66
+ def test_to_xml_string
67
+ doc = Nokogiri::XML(@filter_column.to_xml_string)
68
+ assert doc.xpath("//filterColumn[@colId=#{@filter_column.col_id}]")
69
+ assert doc.xpath("//filterColumn[@hiddenButton=#{@filter_column.hidden_button}]")
70
+ assert doc.xpath("//filterColumn[@showButton=#{@filter_column.show_button}]")
71
+
72
+
73
+
74
+ assert doc.xpath("//filterColumn/filters")
75
+ end
76
+ end
@@ -0,0 +1,50 @@
1
+ require 'tc_helper.rb'
2
+
3
+ class TestFilters < Test::Unit::TestCase
4
+ def setup
5
+ @filters = Axlsx::Filters.new(:filter_items => [1, 'a'],
6
+ :date_group_items =>[ { :date_time_grouping => :year, :year => 2011, :month => 11, :day => 11, :hour => 0, :minute => 0, :second => 0 } ] ,
7
+ :blank => true)
8
+ end
9
+
10
+ def test_blank
11
+ assert_equal true, @filters.blank
12
+ assert_raise(ArgumentError) { @filters.blank = :only_if_you_want_it }
13
+ @filters.blank = true
14
+ assert_equal true, @filters.blank
15
+ end
16
+
17
+ def test_calendar_type
18
+ assert_raise(ArgumentError) { @filters.calendar_type = 'monkey calendar' }
19
+ @filters.calendar_type = 'japan'
20
+ assert_equal('japan', @filters.calendar_type)
21
+ end
22
+
23
+ def test_filters_items
24
+ assert @filters.filter_items.is_a?(Array)
25
+ assert_equal 2, @filters.filter_items.size
26
+ end
27
+
28
+ def test_date_group_items
29
+ assert @filters.date_group_items.is_a?(Array)
30
+ assert_equal 1, @filters.date_group_items.size
31
+ end
32
+
33
+ def test_apply_is_false_for_matching_values
34
+ keeper = Object.new
35
+ def keeper.value; 'a'; end
36
+ assert_equal false, @filters.apply(keeper)
37
+ end
38
+
39
+ def test_apply_is_true_for_non_matching_values
40
+ hidden = Object.new
41
+ def hidden.value; 'b'; end
42
+ assert_equal true, @filters.apply(hidden)
43
+ end
44
+
45
+ def test_to_xml_string
46
+ doc = Nokogiri::XML(@filters.to_xml_string)
47
+ assert_equal(1, doc.xpath('//filters[@blank="true"]').size)
48
+ end
49
+ end
50
+
@@ -60,7 +60,7 @@ class TestCell < Test::Unit::TestCase
60
60
  assert_raise(ArgumentError, "type must be :string, :integer, :float, :date, :time, :boolean") { @c.type = :array }
61
61
  assert_nothing_raised("type can be changed") { @c.type = :string }
62
62
  assert_equal(@c.value, "1.0", "changing type casts the value")
63
-
63
+ assert_equal(:float, @row.add_cell(1.0/10**7).type, 'properly identify exponential floats as float type')
64
64
  assert_equal(@row.add_cell(Time.now).type, :time, 'time should be time')
65
65
  assert_equal(@row.add_cell(Date.today).type, :date, 'date should be date')
66
66
  assert_equal(@row.add_cell(true).type, :boolean, 'boolean should be boolean')
@@ -88,6 +88,7 @@ class TestCell < Test::Unit::TestCase
88
88
  assert_equal(@c.send(:cell_type_from_value, -1), :integer)
89
89
  assert_equal(@c.send(:cell_type_from_value, true), :boolean)
90
90
  assert_equal(@c.send(:cell_type_from_value, false), :boolean)
91
+ assert_equal(@c.send(:cell_type_from_value, 1.0/10**6), :float)
91
92
  end
92
93
 
93
94
  def test_cast_value
@@ -161,9 +162,12 @@ class TestCell < Test::Unit::TestCase
161
162
  end
162
163
 
163
164
  def test_u
165
+ @c.type = :string
164
166
  assert_raise(ArgumentError) { @c.u = -1.1 }
165
- assert_nothing_raised { @c.u = false }
166
- assert_equal(@c.u, false)
167
+ assert_nothing_raised { @c.u = :single }
168
+ assert_equal(@c.u, :single)
169
+ doc = Nokogiri::XML(@c.to_xml_string(1,1))
170
+ assert(doc.xpath('//u[@val="single"]'))
167
171
  end
168
172
 
169
173
  def test_i
@@ -186,8 +190,8 @@ class TestCell < Test::Unit::TestCase
186
190
 
187
191
  def test_family
188
192
  assert_raise(ArgumentError) { @c.family = -1.1 }
189
- assert_nothing_raised { @c.family = "Who knows!" }
190
- assert_equal(@c.family, "Who knows!")
193
+ assert_nothing_raised { @c.family = 5 }
194
+ assert_equal(@c.family, 5)
191
195
  end
192
196
 
193
197
  def test_b
@@ -250,6 +254,8 @@ class TestCell < Test::Unit::TestCase
250
254
  end
251
255
 
252
256
  def test_to_xml_string_with_run
257
+ # Actually quite a number of similar run styles
258
+ # but the processing should be the same
253
259
  @c.b = true
254
260
  @c.type = :string
255
261
  @c.value = "a"
@@ -258,6 +264,7 @@ class TestCell < Test::Unit::TestCase
258
264
  c_xml = Nokogiri::XML(@c.to_xml_string(1,1))
259
265
  assert(c_xml.xpath("//b"))
260
266
  end
267
+
261
268
  def test_to_xml_string_formula
262
269
  p = Axlsx::Package.new
263
270
  ws = p.workbook.add_worksheet do |sheet|
@@ -268,9 +275,32 @@ class TestCell < Test::Unit::TestCase
268
275
 
269
276
  end
270
277
 
278
+ def test_font_size_with_custom_style_and_no_sz
279
+ @c.style = @c.row.worksheet.workbook.styles.add_style :bg_color => 'FF00FF'
280
+ sz = @c.send(:font_size)
281
+ assert_equal(sz, @c.row.worksheet.workbook.styles.fonts.first.sz)
282
+ end
283
+
284
+ def test_font_size_with_bolding
285
+ @c.style = @c.row.worksheet.workbook.styles.add_style :b => true
286
+ assert_equal(@c.row.worksheet.workbook.styles.fonts.first.sz * 1.5, @c.send(:font_size))
287
+ end
288
+
289
+ def test_font_size_with_custom_sz
290
+ @c.style = @c.row.worksheet.workbook.styles.add_style :sz => 52
291
+ sz = @c.send(:font_size)
292
+ assert_equal(sz, 52)
293
+ end
294
+
295
+
296
+ def test_cell_with_sz
297
+ @c.sz = 25
298
+ assert_equal(25, @c.send(:font_size))
299
+ end
271
300
  def test_to_xml
272
301
  # TODO This could use some much more stringent testing related to the xml content generated!
273
302
  @ws.add_row [Time.now, Date.today, true, 1, 1.0, "text", "=sum(A1:A2)"]
303
+ @ws.rows.last.cells[5].u = true
274
304
  schema = Nokogiri::XML::Schema(File.open(Axlsx::SML_XSD))
275
305
  doc = Nokogiri::XML(@ws.to_xml_string)
276
306
  errors = []