axlsx 1.3.4 → 1.3.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +27 -5
- data/examples/example.rb +31 -9
- data/examples/ios_preview.rb +14 -0
- data/examples/pivot_table.rb +39 -0
- data/examples/styles.rb +4 -0
- data/lib/axlsx.rb +28 -0
- data/lib/axlsx/drawing/bar_3D_chart.rb +15 -10
- data/lib/axlsx/drawing/chart.rb +13 -1
- data/lib/axlsx/drawing/drawing.rb +12 -11
- data/lib/axlsx/drawing/graphic_frame.rb +6 -1
- data/lib/axlsx/drawing/hyperlink.rb +5 -0
- data/lib/axlsx/drawing/line_3D_chart.rb +3 -2
- data/lib/axlsx/drawing/pic.rb +6 -0
- data/lib/axlsx/drawing/pie_3D_chart.rb +2 -1
- data/lib/axlsx/drawing/scatter_chart.rb +2 -1
- data/lib/axlsx/package.rb +13 -0
- data/lib/axlsx/rels/relationship.rb +1 -0
- data/lib/axlsx/stylesheet/styles.rb +22 -18
- data/lib/axlsx/util/accessors.rb +15 -0
- data/lib/axlsx/util/constants.rb +25 -5
- data/lib/axlsx/util/validators.rb +10 -8
- data/lib/axlsx/version.rb +1 -1
- data/lib/axlsx/workbook/shared_strings_table.rb +1 -1
- data/lib/axlsx/workbook/workbook.rb +27 -3
- data/lib/axlsx/workbook/worksheet/cell.rb +26 -64
- data/lib/axlsx/workbook/worksheet/cell_serializer.rb +144 -0
- data/lib/axlsx/workbook/worksheet/col.rb +9 -2
- data/lib/axlsx/workbook/worksheet/pivot_table.rb +259 -0
- data/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +65 -0
- data/lib/axlsx/workbook/worksheet/pivot_tables.rb +24 -0
- data/lib/axlsx/workbook/worksheet/row.rb +10 -1
- data/lib/axlsx/workbook/worksheet/sheet_format_pr.rb +60 -0
- data/lib/axlsx/workbook/worksheet/worksheet.rb +55 -6
- data/test/benchmark.rb +1 -0
- data/test/drawing/tc_chart.rb +7 -0
- data/test/drawing/tc_graphic_frame.rb +5 -0
- data/test/example.xlsx +0 -0
- data/test/profile.rb +1 -0
- data/test/tc_axlsx.rb +15 -0
- data/test/tc_package.rb +13 -5
- data/test/workbook/worksheet/tc_cell.rb +5 -1
- data/test/workbook/worksheet/tc_pivot_table.rb +102 -0
- data/test/workbook/worksheet/tc_pivot_table_cache_definition.rb +46 -0
- data/test/workbook/worksheet/tc_sheet_format_pr.rb +88 -0
- data/test/workbook/worksheet/tc_worksheet.rb +45 -1
- 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
|
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, (
|
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,
|
data/test/benchmark.rb
CHANGED
data/test/drawing/tc_chart.rb
CHANGED
@@ -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
|
data/test/example.xlsx
CHANGED
Binary file
|
data/test/profile.rb
CHANGED
data/test/tc_axlsx.rb
CHANGED
@@ -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
|
data/test/tc_package.rb
CHANGED
@@ -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
|
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
|