axlsx 1.3.4 → 1.3.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/README.md +27 -5
  2. data/examples/example.rb +31 -9
  3. data/examples/ios_preview.rb +14 -0
  4. data/examples/pivot_table.rb +39 -0
  5. data/examples/styles.rb +4 -0
  6. data/lib/axlsx.rb +28 -0
  7. data/lib/axlsx/drawing/bar_3D_chart.rb +15 -10
  8. data/lib/axlsx/drawing/chart.rb +13 -1
  9. data/lib/axlsx/drawing/drawing.rb +12 -11
  10. data/lib/axlsx/drawing/graphic_frame.rb +6 -1
  11. data/lib/axlsx/drawing/hyperlink.rb +5 -0
  12. data/lib/axlsx/drawing/line_3D_chart.rb +3 -2
  13. data/lib/axlsx/drawing/pic.rb +6 -0
  14. data/lib/axlsx/drawing/pie_3D_chart.rb +2 -1
  15. data/lib/axlsx/drawing/scatter_chart.rb +2 -1
  16. data/lib/axlsx/package.rb +13 -0
  17. data/lib/axlsx/rels/relationship.rb +1 -0
  18. data/lib/axlsx/stylesheet/styles.rb +22 -18
  19. data/lib/axlsx/util/accessors.rb +15 -0
  20. data/lib/axlsx/util/constants.rb +25 -5
  21. data/lib/axlsx/util/validators.rb +10 -8
  22. data/lib/axlsx/version.rb +1 -1
  23. data/lib/axlsx/workbook/shared_strings_table.rb +1 -1
  24. data/lib/axlsx/workbook/workbook.rb +27 -3
  25. data/lib/axlsx/workbook/worksheet/cell.rb +26 -64
  26. data/lib/axlsx/workbook/worksheet/cell_serializer.rb +144 -0
  27. data/lib/axlsx/workbook/worksheet/col.rb +9 -2
  28. data/lib/axlsx/workbook/worksheet/pivot_table.rb +259 -0
  29. data/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +65 -0
  30. data/lib/axlsx/workbook/worksheet/pivot_tables.rb +24 -0
  31. data/lib/axlsx/workbook/worksheet/row.rb +10 -1
  32. data/lib/axlsx/workbook/worksheet/sheet_format_pr.rb +60 -0
  33. data/lib/axlsx/workbook/worksheet/worksheet.rb +55 -6
  34. data/test/benchmark.rb +1 -0
  35. data/test/drawing/tc_chart.rb +7 -0
  36. data/test/drawing/tc_graphic_frame.rb +5 -0
  37. data/test/example.xlsx +0 -0
  38. data/test/profile.rb +1 -0
  39. data/test/tc_axlsx.rb +15 -0
  40. data/test/tc_package.rb +13 -5
  41. data/test/workbook/worksheet/tc_cell.rb +5 -1
  42. data/test/workbook/worksheet/tc_pivot_table.rb +102 -0
  43. data/test/workbook/worksheet/tc_pivot_table_cache_definition.rb +46 -0
  44. data/test/workbook/worksheet/tc_sheet_format_pr.rb +88 -0
  45. data/test/workbook/worksheet/tc_worksheet.rb +45 -1
  46. metadata +23 -9
@@ -0,0 +1,24 @@
1
+ module Axlsx
2
+
3
+ # A simple, self serializing class for storing pivot tables
4
+ class PivotTables < SimpleTypedList
5
+
6
+ # creates a new Tables object
7
+ def initialize(worksheet)
8
+ raise ArgumentError, "you must provide a worksheet" unless worksheet.is_a?(Worksheet)
9
+ super PivotTable
10
+ @worksheet = worksheet
11
+ end
12
+
13
+ # The worksheet that owns this collection of pivot tables
14
+ # @return [Worksheet]
15
+ attr_reader :worksheet
16
+
17
+ # returns the relationships required by this collection
18
+ def relationships
19
+ return [] if empty?
20
+ map{ |pivot_table| Relationship.new(PIVOT_TABLE_R, "../#{pivot_table.pn}") }
21
+ end
22
+ end
23
+
24
+ end
@@ -147,15 +147,24 @@ module Axlsx
147
147
  def array_to_cells(values, options={})
148
148
  values = values
149
149
  DataTypeValidator.validate 'Row.array_to_cells', Array, values
150
- types, style = options.delete(:types), options.delete(:style)
150
+ types, style, formula_values = options.delete(:types), options.delete(:style), options.delete(:formula_values)
151
151
  values.each_with_index do |value, index|
152
+
153
+ #WTF IS THIS PAP?
152
154
  cell_style = style.is_a?(Array) ? style[index] : style
153
155
  options[:style] = cell_style if cell_style
156
+
154
157
  cell_type = types.is_a?(Array)? types[index] : types
155
158
  options[:type] = cell_type if cell_type
159
+
160
+ formula_value = formula_values[index] if formula_values.is_a?(Array)
161
+ options[:formula_value] = formula_value if formula_value
162
+
156
163
  Cell.new(self, value, options)
164
+
157
165
  options.delete(:style)
158
166
  options.delete(:type)
167
+ options.delete(:formula_value)
159
168
  end
160
169
  end
161
170
  end
@@ -0,0 +1,60 @@
1
+ module Axlsx
2
+
3
+ #Sheet formatting properties
4
+ # <xsd:complexType name="CT_SheetFormatPr">
5
+ # <xsd:attribute name="baseColWidth" type="xsd:unsignedInt" use="optional" default="8"/>
6
+ # <xsd:attribute name="defaultColWidth" type="xsd:double" use="optional"/>
7
+ # <xsd:attribute name="defaultRowHeight" type="xsd:double" use="required"/>
8
+ # <xsd:attribute name="customHeight" type="xsd:boolean" use="optional" default="false"/>
9
+ # <xsd:attribute name="zeroHeight" type="xsd:boolean" use="optional" default="false"/>
10
+ # <xsd:attribute name="thickTop" type="xsd:boolean" use="optional" default="false"/>
11
+ # <xsd:attribute name="thickBottom" type="xsd:boolean" use="optional" default="false"/>
12
+ # <xsd:attribute name="outlineLevelRow" type="xsd:unsignedByte" use="optional" default="0"/>
13
+ # <xsd:attribute name="outlineLevelCol" type="xsd:unsignedByte" use="optional" default="0"/>
14
+ #</xsd:complexType>
15
+
16
+ class SheetFormatPr
17
+ include Axlsx::SerializedAttributes
18
+ include Axlsx::OptionsParser
19
+ include Axlsx::Accessors
20
+
21
+ # creates a new sheet_format_pr object
22
+ # @param [Hash] options initialization options
23
+ # @option [Integer] base_col_width Specifies the number of characters of the maximum digit width of the normal style's font. This value does not include margin padding or extra padding for gridlines. It is only the number of characters.
24
+ # @option [Float] default_col_width Default column width measured as the number of characters of the maximum digit width of the normal style's font.
25
+ # @option [Float] default_row_height Default row height measured in point size. Optimization so we don't have to write the height on all rows. This can be written out if most rows have custom height, to achieve the optimization.
26
+ # @option [Boolean] custom_height 'True' if defaultRowHeight value has been manually set, or is different from the default value.
27
+ # @option [Boolean] zero_height 'True' if rows are hidden by default. This setting is an optimization used when most rows of the sheet are hidden.
28
+ # @option [Boolean] think_top 'True' if rows have a thick top border by default.
29
+ # @option [Boolean] thick_bottom 'True' if rows have a thick bottom border by default.
30
+ # @option [Integer] outline_level_row Highest number of outline level for rows in this sheet. These values shall be in synch with the actual sheet outline levels.
31
+ # @option [Integer] outline_level_col Highest number of outline levels for columns in this sheet. These values shall be in synch with the actual sheet outline levels.
32
+ def initialize(options={})
33
+ set_defaults
34
+ parse_options options
35
+ end
36
+
37
+ serializable_attributes :base_col_width, :default_col_width, :default_row_height,
38
+ :custom_height, :zero_height, :thick_top, :thick_bottom,
39
+ :outline_level_row, :outline_level_col
40
+
41
+ float_attr_accessor :default_col_width, :default_row_height
42
+
43
+ boolean_attr_accessor :custom_height, :zero_height, :thick_top, :thick_bottom
44
+
45
+ unsigned_int_attr_accessor :base_col_width, :outline_level_row, :outline_level_col
46
+
47
+ # serializes this object to an xml string
48
+ # @param [String] str The string this objects serialization will be appended to
49
+ # @return [String]
50
+ def to_xml_string(str='')
51
+ str << "<sheetFormatPr #{serialized_attributes}/>"
52
+ end
53
+
54
+ private
55
+ def set_defaults
56
+ @base_col_width = 8
57
+ @default_row_height = 18
58
+ end
59
+ end
60
+ end
@@ -23,11 +23,11 @@ module Axlsx
23
23
  # @option options [Boolean] show_gridlines indicates if gridlines should be shown for this sheet.
24
24
  def initialize(wb, options={})
25
25
  self.workbook = wb
26
- @workbook.worksheets << self
27
26
  @sheet_protection = nil
28
27
 
29
28
  initialize_page_options(options)
30
29
  parse_options options
30
+ @workbook.worksheets << self
31
31
  end
32
32
 
33
33
  # Initalizes page margin, setup and print options
@@ -69,6 +69,15 @@ module Axlsx
69
69
  @sheet_view
70
70
  end
71
71
 
72
+ # The sheet format pr for this worksheet
73
+ # @return [SheetFormatPr]
74
+ # @see [SheetFormatPr]
75
+ def sheet_format_pr
76
+ @sheet_format_pr ||= SheetFormatPr.new
77
+ yeild @sheet_format_pr if block_given?
78
+ @sheet_format_pr
79
+ end
80
+
72
81
  # The workbook that owns this worksheet
73
82
  # @return [Workbook]
74
83
  attr_reader :workbook
@@ -79,6 +88,12 @@ module Axlsx
79
88
  @tables ||= Tables.new self
80
89
  end
81
90
 
91
+ # The pivot tables in this worksheet
92
+ # @return [Array] of Table
93
+ def pivot_tables
94
+ @pivot_tables ||= PivotTables.new self
95
+ end
96
+
82
97
  # A typed collection of hyperlinks associated with this worksheet
83
98
  # @return [WorksheetHyperlinks]
84
99
  def hyperlinks
@@ -454,6 +469,12 @@ module Axlsx
454
469
  tables.last
455
470
  end
456
471
 
472
+ def add_pivot_table(ref, range, options={})
473
+ pivot_tables << PivotTable.new(ref, range, self, options)
474
+ yield pivot_tables.last if block_given?
475
+ pivot_tables.last
476
+ end
477
+
457
478
  # Shortcut to worsksheet_comments#add_comment
458
479
  def add_comment(options={})
459
480
  worksheet_comments.add_comment(options)
@@ -539,7 +560,8 @@ module Axlsx
539
560
  r + [tables.relationships,
540
561
  worksheet_comments.relationships,
541
562
  hyperlinks.relationships,
542
- worksheet_drawing.relationship].flatten.compact || []
563
+ worksheet_drawing.relationship,
564
+ pivot_tables.relationships].flatten.compact || []
543
565
  r
544
566
  end
545
567
 
@@ -586,21 +608,48 @@ module Axlsx
586
608
  @styles ||= self.workbook.styles
587
609
  end
588
610
 
611
+ # shortcut level to specify the outline level for a series of rows
612
+ # Oulining is what lets you add collapse and expand to a data set.
613
+ # @param [Integer] start_index The zero based index of the first row of outlining.
614
+ # @param [Integer] end_index The zero based index of the last row to be outlined
615
+ # @param [integer] level The level of outline to apply
616
+ # @param [Integer] collapsed The initial collapsed state of the outline group
617
+ def outline_level_rows(start_index, end_index, level = 1, collapsed = true)
618
+ outline rows, (start_index..end_index), level, collapsed
619
+ end
620
+
621
+ # shortcut level to specify the outline level for a series of columns
622
+ # Oulining is what lets you add collapse and expand to a data set.
623
+ # @param [Integer] start_index The zero based index of the first column of outlining.
624
+ # @param [Integer] end_index The zero based index of the last column to be outlined
625
+ # @param [integer] level The level of outline to apply
626
+ # @param [Integer] collapsed The initial collapsed state of the outline group
627
+ def outline_level_columns(start_index, end_index, level = 1, collapsed = true)
628
+ outline column_info, (start_index..end_index), level, collapsed
629
+ end
589
630
 
590
631
  private
632
+ def outline(collection, range, level = 1, collapsed = true)
633
+ range.each do |index|
634
+ unless (item = collection[index]).nil?
635
+ item.outline_level = level
636
+ item.hidden = collapsed
637
+ end
638
+ sheet_view.show_outline_symbols = true
639
+ end
640
+ end
591
641
 
592
642
  def validate_sheet_name(name)
593
643
  DataTypeValidator.validate "Worksheet.name", String, name
594
644
  raise ArgumentError, (ERR_SHEET_NAME_TOO_LONG % name) if name.size > 31
595
- raise ArgumentError, (ERR_SHEET_NAME_COLON_FORBIDDEN % name) if name.include? ':'
645
+ raise ArgumentError, (ERR_SHEET_NAME_CHARACTER_FORBIDDEN % name) if '[]*/\?:'.chars.any? { |char| name.include? char }
596
646
  name = Axlsx::coder.encode(name)
597
- sheet_names = @workbook.worksheets.map { |s| s.name }
647
+ sheet_names = @workbook.worksheets.reject { |s| s == self }.map { |s| s.name }
598
648
  raise ArgumentError, (ERR_DUPLICATE_SHEET_NAME % name) if sheet_names.include?(name)
599
649
  end
600
650
 
601
-
602
651
  def serializable_parts
603
- [sheet_pr, dimension, sheet_view, column_info,
652
+ [sheet_pr, dimension, sheet_view, sheet_format_pr, column_info,
604
653
  sheet_data, sheet_calc_pr, @sheet_protection, protected_ranges,
605
654
  auto_filter, merged_cells, conditional_formattings,
606
655
  data_validations, hyperlinks, print_options, page_margins,
@@ -4,6 +4,7 @@ $:.unshift "#{File.dirname(__FILE__)}/../lib"
4
4
  require 'axlsx'
5
5
  require 'csv'
6
6
  require 'benchmark'
7
+ Axlsx::trust_input = true
7
8
  row = []
8
9
  input = (32..126).to_a.pack('U*').chars.to_a
9
10
  20.times { row << input.shuffle.join}
@@ -37,6 +37,13 @@ class TestChart < Test::Unit::TestCase
37
37
  assert_nothing_raised { @chart.style = 2 }
38
38
  assert_equal(@chart.style, 2)
39
39
  end
40
+
41
+ def test_vary_colors
42
+ assert_equal(true, @chart.vary_colors)
43
+ assert_raise(ArgumentError) { @chart.vary_colors = 7 }
44
+ assert_nothing_raised { @chart.vary_colors = false }
45
+ assert_equal(false, @chart.vary_colors)
46
+ end
40
47
 
41
48
  def test_start_at
42
49
  @chart.start_at 15, 25
@@ -22,4 +22,9 @@ class TestGraphicFrame < Test::Unit::TestCase
22
22
  assert_equal(chart.graphic_frame.rId, "rId2")
23
23
  end
24
24
 
25
+ def test_rId_with_image_and_chart
26
+ image = @ws.add_image :image_src => (File.dirname(__FILE__) + "/../../examples/image1.jpeg"), :start_at => [0,25], :width => 200, :height => 200
27
+ assert_equal(2, image.id)
28
+ assert_equal(1, @chart.index+1)
29
+ end
25
30
  end
Binary file
@@ -8,6 +8,7 @@
8
8
  $:.unshift "#{File.dirname(__FILE__)}/../lib"
9
9
  require 'axlsx'
10
10
  require 'perftools'
11
+ Axlsx.trust_input = true
11
12
  row = []
12
13
  # Taking worst case scenario of all string data
13
14
  input = (32..126).to_a.pack('U*').chars.to_a
@@ -18,6 +18,15 @@ class TestAxlsx < Test::Unit::TestCase
18
18
  assert_equal(Axlsx.cell_range([]), "")
19
19
  end
20
20
 
21
+ def test_do_not_trust_input_by_default
22
+ assert_equal false, Axlsx.trust_input
23
+ end
24
+
25
+
26
+ def test_trust_input_can_be_set_to_true
27
+ Axlsx.trust_input = true
28
+ assert_equal true, Axlsx.trust_input
29
+ end
21
30
  def test_cell_range_relative
22
31
  p = Axlsx::Package.new
23
32
  ws = p.workbook.add_worksheet
@@ -54,4 +63,10 @@ class TestAxlsx < Test::Unit::TestCase
54
63
  # todo
55
64
  end
56
65
 
66
+ def test_range_to_a
67
+ assert_equal([['A1', 'B1', 'C1']], Axlsx::range_to_a('A1:C1'))
68
+ assert_equal([['A1', 'B1', 'C1'], ['A2', 'B2', 'C2']], Axlsx::range_to_a('A1:C2'))
69
+ assert_equal([['Z5', 'AA5', 'AB5'], ['Z6', 'AA6', 'AB6']], Axlsx::range_to_a('Z5:AB6'))
70
+ end
71
+
57
72
  end
@@ -7,6 +7,8 @@ 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.outline_level_rows 0, 1
11
+ ws.outline_level_columns 0, 1
10
12
  ws.add_hyperlink :ref => ws.rows.first.cells.last, :location => 'https://github.com/randym'
11
13
  ws.workbook.add_defined_name("#{ws.name}!A1:C2", :name => '_xlnm.Print_Titles', :hidden => true)
12
14
  ws.protect_range('A1:C1')
@@ -38,15 +40,15 @@ class TestPackage < Test::Unit::TestCase
38
40
  ws.add_chart(Axlsx::Line3DChart, :title => "axis labels") do |chart|
39
41
  chart.valAxis.title = 'bob'
40
42
  chart.d_lbls.show_val = true
41
- end
42
-
43
+ end
44
+
43
45
  ws.add_chart(Axlsx::Bar3DChart, :title => 'bar chart') do |chart|
44
46
  chart.add_series :data => [1,4,5], :labels => %w(A B C)
45
47
  chart.d_lbls.show_percent = true
46
48
  end
47
49
 
48
50
  ws.add_chart(Axlsx::ScatterChart, :title => 'scat man') do |chart|
49
- chart.add_series :xData => [1,2,3,4], :yData => [4,3,2,1]
51
+ chart.add_series :xData => [1,2,3,4], :yData => [4,3,2,1]
50
52
  chart.d_lbls.show_val = true
51
53
  end
52
54
 
@@ -61,7 +63,7 @@ class TestPackage < Test::Unit::TestCase
61
63
  ws.add_image :image_src => File.expand_path('../../examples/image1.gif', __FILE__) do |image|
62
64
  image.start_at 0, 20
63
65
  image.width=360
64
- image.height=333
66
+ image.height=333
65
67
  end
66
68
  ws.add_image :image_src => File.expand_path('../../examples/image1.png', __FILE__) do |image|
67
69
  image.start_at 9, 20
@@ -69,6 +71,9 @@ class TestPackage < Test::Unit::TestCase
69
71
  image.height = 167
70
72
  end
71
73
  ws.add_table 'A1:C1'
74
+
75
+ ws.add_pivot_table 'G5:G6', 'A1:B3'
76
+
72
77
  end
73
78
 
74
79
  def test_use_autowidth
@@ -135,10 +140,13 @@ class TestPackage < Test::Unit::TestCase
135
140
  assert_equal(p.select{ |part| part[:entry] =~ /xl\/worksheets\/sheet\d\.xml/ }.size, @package.workbook.worksheets.size, "one or more sheet missing")
136
141
  assert_equal(p.select{ |part| part[:entry] =~ /xl\/worksheets\/_rels\/sheet\d\.xml\.rels/ }.size, @package.workbook.worksheets.size, "one or more sheet rels missing")
137
142
  assert_equal(p.select{ |part| part[:entry] =~ /xl\/comments\d\.xml/ }.size, @package.workbook.worksheets.size, "one or more sheet rels missing")
143
+ assert_equal(p.select{ |part| part[:entry] =~ /xl\/pivotTables\/pivotTable\d\.xml/ }.size, @package.workbook.worksheets.first.pivot_tables.size, "one or more pivot tables missing")
144
+ assert_equal(p.select{ |part| part[:entry] =~ /xl\/pivotTables\/_rels\/pivotTable\d\.xml.rels/ }.size, @package.workbook.worksheets.first.pivot_tables.size, "one or more pivot tables rels missing")
145
+ assert_equal(p.select{ |part| part[:entry] =~ /xl\/pivotCache\/pivotCacheDefinition\d\.xml/ }.size, @package.workbook.worksheets.first.pivot_tables.size, "one or more pivot tables missing")
138
146
 
139
147
 
140
148
  #no mystery parts
141
- assert_equal(p.size, 21)
149
+ assert_equal(24, p.size)
142
150
 
143
151
  end
144
152
 
@@ -89,6 +89,7 @@ class TestCell < Test::Unit::TestCase
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
91
  assert_equal(@c.send(:cell_type_from_value, 1.0/10**6), :float)
92
+ assert_equal(:iso_8601, @c.send(:cell_type_from_value, '2008-08-30T01:45:36.123+09:00'))
92
93
  end
93
94
 
94
95
  def test_cast_value
@@ -105,6 +106,8 @@ class TestCell < Test::Unit::TestCase
105
106
  @c.type = :boolean
106
107
  assert_equal(@c.send(:cast_value, true), 1)
107
108
  assert_equal(@c.send(:cast_value, false), 0)
109
+ @c.type = :iso_8601
110
+ assert_equal("2012-10-10T12:24", @c.send(:cast_value, "2012-10-10T12:24"))
108
111
  end
109
112
 
110
113
  def test_color
@@ -299,8 +302,9 @@ class TestCell < Test::Unit::TestCase
299
302
  end
300
303
  def test_to_xml
301
304
  # TODO This could use some much more stringent testing related to the xml content generated!
302
- @ws.add_row [Time.now, Date.today, true, 1, 1.0, "text", "=sum(A1:A2)"]
305
+ @ws.add_row [Time.now, Date.today, true, 1, 1.0, "text", "=sum(A1:A2)", "2013-01-13T13:31:25.123"]
303
306
  @ws.rows.last.cells[5].u = true
307
+
304
308
  schema = Nokogiri::XML::Schema(File.open(Axlsx::SML_XSD))
305
309
  doc = Nokogiri::XML(@ws.to_xml_string)
306
310
  errors = []
@@ -0,0 +1,102 @@
1
+ require 'tc_helper.rb'
2
+
3
+ class TestPivotTable < Test::Unit::TestCase
4
+ def setup
5
+ p = Axlsx::Package.new
6
+ @ws = p.workbook.add_worksheet
7
+
8
+ @ws << ["Year","Month","Region", "Type", "Sales"]
9
+ @ws << [2012, "Nov", "East", "Soda", "12345"]
10
+ end
11
+
12
+ def test_initialization
13
+ assert(@ws.workbook.pivot_tables.empty?)
14
+ assert(@ws.pivot_tables.empty?)
15
+ end
16
+
17
+ def test_add_pivot_table
18
+ pivot_table = @ws.add_pivot_table('G5:G6', 'A1:D5')
19
+ assert_equal('G5:G6', pivot_table.ref, 'ref assigned from first parameter')
20
+ assert_equal('A1:D5', pivot_table.range, 'range assigned from second parameter')
21
+ assert_equal('PivotTable1', pivot_table.name, 'name automatically generated')
22
+ assert(pivot_table.is_a?(Axlsx::PivotTable), "must create a pivot table")
23
+ assert_equal(@ws.workbook.pivot_tables.last, pivot_table, "must be added to workbook pivot tables collection")
24
+ assert_equal(@ws.pivot_tables.last, pivot_table, "must be added to worksheet pivot tables collection")
25
+ end
26
+
27
+ def test_add_pivot_table_with_config
28
+ pivot_table = @ws.add_pivot_table('G5:G6', 'A1:D5') do |pt|
29
+ pt.rows = ['Year', 'Month']
30
+ pt.columns = ['Type']
31
+ pt.data = ['Sales']
32
+ pt.pages = ['Region']
33
+ end
34
+ assert_equal(['Year', 'Month'], pivot_table.rows)
35
+ assert_equal(['Type'], pivot_table.columns)
36
+ assert_equal(['Sales'], pivot_table.data)
37
+ assert_equal(['Region'], pivot_table.pages)
38
+ end
39
+
40
+ def test_header_indices
41
+ pivot_table = @ws.add_pivot_table('G5:G6', 'A1:E5')
42
+ assert_equal(0, pivot_table.header_index_of('Year' ))
43
+ assert_equal(1, pivot_table.header_index_of('Month' ))
44
+ assert_equal(2, pivot_table.header_index_of('Region' ))
45
+ assert_equal(3, pivot_table.header_index_of('Type' ))
46
+ assert_equal(4, pivot_table.header_index_of('Sales' ))
47
+ assert_equal(nil, pivot_table.header_index_of('Missing'))
48
+ assert_equal(%w(A1 B1 C1 D1 E1), pivot_table.header_cell_refs)
49
+ end
50
+
51
+ def test_pn
52
+ @ws.add_pivot_table('G5:G6', 'A1:D5')
53
+ assert_equal(@ws.pivot_tables.first.pn, "pivotTables/pivotTable1.xml")
54
+ end
55
+
56
+ def test_rId
57
+ @ws.add_pivot_table('G5:G6', 'A1:D5')
58
+ assert_equal(@ws.pivot_tables.first.rId, "rId1")
59
+ end
60
+
61
+ def test_index
62
+ @ws.add_pivot_table('G5:G6', 'A1:D5')
63
+ assert_equal(@ws.pivot_tables.first.index, @ws.workbook.pivot_tables.index(@ws.pivot_tables.first))
64
+ end
65
+
66
+ def test_relationships
67
+ assert(@ws.relationships.empty?)
68
+ @ws.add_pivot_table('G5:G6', 'A1:D5')
69
+ assert_equal(@ws.relationships.size, 1, "adding a pivot table adds a relationship")
70
+ @ws.add_pivot_table('G10:G11', 'A1:D5')
71
+ assert_equal(@ws.relationships.size, 2, "adding a pivot table adds a relationship")
72
+ end
73
+
74
+ def test_to_xml_string
75
+ pivot_table = @ws.add_pivot_table('G5:G6', 'A1:D5')
76
+ schema = Nokogiri::XML::Schema(File.open(Axlsx::SML_XSD))
77
+ doc = Nokogiri::XML(pivot_table.to_xml_string)
78
+ errors = []
79
+ schema.validate(doc).each do |error|
80
+ errors.push error
81
+ puts error.message
82
+ end
83
+ assert(errors.empty?, "error free validation")
84
+ end
85
+
86
+ def test_to_xml_string_with_configuration
87
+ pivot_table = @ws.add_pivot_table('G5:G6', 'A1:E5') do |pt|
88
+ pt.rows = ['Year', 'Month']
89
+ pt.columns = ['Type']
90
+ pt.data = ['Sales']
91
+ pt.pages = ['Region']
92
+ end
93
+ schema = Nokogiri::XML::Schema(File.open(Axlsx::SML_XSD))
94
+ doc = Nokogiri::XML(pivot_table.to_xml_string)
95
+ errors = []
96
+ schema.validate(doc).each do |error|
97
+ errors.push error
98
+ puts error.message
99
+ end
100
+ assert(errors.empty?, "error free validation")
101
+ end
102
+ end