axlsx 1.3.6 → 2.0.1
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.
- checksums.yaml +4 -4
- data/.yardopts_guide +19 -0
- data/CHANGELOG.md +8 -0
- data/README.md +54 -79
- data/Rakefile +0 -5
- data/examples/2010_comments.rb +17 -0
- data/examples/anchor_swapping.rb +28 -0
- data/examples/example.rb +16 -1
- data/examples/pivot_table.rb +2 -0
- data/examples/underline.rb +13 -0
- data/lib/axlsx/doc_props/core.rb +6 -1
- data/lib/axlsx/drawing/axes.rb +7 -3
- data/lib/axlsx/drawing/bar_3D_chart.rb +2 -2
- data/lib/axlsx/drawing/chart.rb +20 -4
- data/lib/axlsx/drawing/drawing.rb +2 -17
- data/lib/axlsx/drawing/graphic_frame.rb +3 -8
- data/lib/axlsx/drawing/hyperlink.rb +5 -12
- data/lib/axlsx/drawing/marker.rb +25 -5
- data/lib/axlsx/drawing/one_cell_anchor.rb +9 -0
- data/lib/axlsx/drawing/pic.rb +17 -23
- data/lib/axlsx/drawing/two_cell_anchor.rb +7 -27
- data/lib/axlsx/package.rb +36 -16
- data/lib/axlsx/rels/relationship.rb +73 -8
- data/lib/axlsx/rels/relationships.rb +8 -1
- data/lib/axlsx/stylesheet/color.rb +1 -1
- data/lib/axlsx/stylesheet/num_fmt.rb +2 -2
- data/lib/axlsx/stylesheet/styles.rb +5 -3
- data/lib/axlsx/util/serialized_attributes.rb +11 -8
- data/lib/axlsx/util/simple_typed_list.rb +34 -13
- data/lib/axlsx/util/validators.rb +7 -0
- data/lib/axlsx/version.rb +1 -1
- data/lib/axlsx/workbook/defined_name.rb +1 -1
- data/lib/axlsx/workbook/shared_strings_table.rb +12 -3
- data/lib/axlsx/workbook/workbook.rb +31 -8
- data/lib/axlsx/workbook/worksheet/break.rb +37 -0
- data/lib/axlsx/workbook/worksheet/cell.rb +5 -5
- data/lib/axlsx/workbook/worksheet/cell_serializer.rb +1 -1
- data/lib/axlsx/workbook/worksheet/col_breaks.rb +35 -0
- data/lib/axlsx/workbook/worksheet/comment.rb +6 -5
- data/lib/axlsx/workbook/worksheet/comments.rb +3 -3
- data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +1 -1
- data/lib/axlsx/workbook/worksheet/date_time_converter.rb +6 -5
- data/lib/axlsx/workbook/worksheet/pivot_table.rb +32 -18
- data/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +4 -3
- data/lib/axlsx/workbook/worksheet/pivot_tables.rb +1 -1
- data/lib/axlsx/workbook/worksheet/row.rb +1 -1
- data/lib/axlsx/workbook/worksheet/row_breaks.rb +33 -0
- data/lib/axlsx/workbook/worksheet/table.rb +3 -2
- data/lib/axlsx/workbook/worksheet/tables.rb +1 -1
- data/lib/axlsx/workbook/worksheet/worksheet.rb +61 -26
- data/lib/axlsx/workbook/worksheet/worksheet_comments.rb +6 -5
- data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +3 -9
- data/lib/axlsx/workbook/worksheet/worksheet_hyperlink.rb +5 -10
- data/lib/axlsx.rb +10 -2
- data/lib/schema/sml.xsd +4 -0
- data/test/axlsx.qcachegrind +2226 -0
- data/test/doc_props/tc_core.rb +7 -0
- data/test/drawing/tc_axes.rb +8 -0
- data/test/drawing/tc_bar_3D_chart.rb +6 -0
- data/test/drawing/tc_chart.rb +13 -0
- data/test/drawing/tc_drawing.rb +0 -5
- data/test/drawing/tc_graphic_frame.rb +4 -7
- data/test/drawing/tc_hyperlink.rb +0 -4
- data/test/drawing/tc_pic.rb +14 -3
- data/test/drawing/tc_two_cell_anchor.rb +3 -3
- data/test/profile.rb +7 -3
- data/test/rels/tc_relationship.rb +29 -11
- data/test/rels/tc_relationships.rb +12 -1
- data/test/stylesheet/tc_color.rb +6 -0
- data/test/stylesheet/tc_styles.rb +2 -2
- data/test/tc_helper.rb +1 -0
- data/test/tc_package.rb +31 -1
- data/test/util/tc_serialized_attributes.rb +19 -0
- data/test/workbook/tc_shared_strings_table.rb +6 -0
- data/test/workbook/tc_workbook.rb +23 -1
- data/test/workbook/worksheet/tc_break.rb +49 -0
- data/test/workbook/worksheet/tc_comment.rb +17 -6
- data/test/workbook/worksheet/tc_conditional_formatting.rb +2 -2
- data/test/workbook/worksheet/tc_date_time_converter.rb +3 -11
- data/test/workbook/worksheet/tc_pivot_table.rb +40 -22
- data/test/workbook/worksheet/tc_pivot_table_cache_definition.rb +9 -1
- data/test/workbook/worksheet/tc_sheet_view.rb +39 -39
- data/test/workbook/worksheet/tc_table.rb +2 -2
- data/test/workbook/worksheet/tc_worksheet.rb +39 -7
- data/test/workbook/worksheet/tc_worksheet_hyperlink.rb +2 -11
- metadata +39 -11
- data/test/example.xlsx +0 -0
|
@@ -26,10 +26,16 @@ module Axlsx
|
|
|
26
26
|
# @see Cell#sharable
|
|
27
27
|
attr_reader :unique_cells
|
|
28
28
|
|
|
29
|
+
# The xml:space attribute
|
|
30
|
+
# @see Workbook#xml_space
|
|
31
|
+
attr_reader :xml_space
|
|
32
|
+
|
|
29
33
|
# Creates a new Shared Strings Table agains an array of cells
|
|
30
34
|
# @param [Array] cells This is an array of all of the cells in the workbook
|
|
31
|
-
|
|
35
|
+
# @param [Symbol] xml_space The xml:space behavior for the shared string table.
|
|
36
|
+
def initialize(cells, xml_space=:preserve)
|
|
32
37
|
@index = 0
|
|
38
|
+
@xml_space = xml_space
|
|
33
39
|
@unique_cells = {}
|
|
34
40
|
@shared_xml_string = ""
|
|
35
41
|
shareable_cells = cells.flatten.select{ |cell| cell.plain_string? }
|
|
@@ -40,8 +46,11 @@ module Axlsx
|
|
|
40
46
|
# Serializes the object
|
|
41
47
|
# @param [String] str
|
|
42
48
|
# @return [String]
|
|
43
|
-
def to_xml_string
|
|
44
|
-
'<?xml version="1.0" encoding="UTF-8"?><sst xmlns="' << XML_NS << '"
|
|
49
|
+
def to_xml_string(str='')
|
|
50
|
+
str << '<?xml version="1.0" encoding="UTF-8"?><sst xmlns="' << XML_NS << '"'
|
|
51
|
+
str << ' count="' << @count.to_s << '" uniqueCount="' << unique_count.to_s << '"'
|
|
52
|
+
str << ' xml:space="' << xml_space.to_s << '">' << @shared_xml_string << '</sst>'
|
|
53
|
+
str = Axlsx::sanitize(str)
|
|
45
54
|
end
|
|
46
55
|
|
|
47
56
|
private
|
|
@@ -34,6 +34,12 @@ require 'axlsx/workbook/worksheet/worksheet_drawing.rb'
|
|
|
34
34
|
require 'axlsx/workbook/worksheet/worksheet_comments.rb'
|
|
35
35
|
require 'axlsx/workbook/worksheet/worksheet_hyperlink'
|
|
36
36
|
require 'axlsx/workbook/worksheet/worksheet_hyperlinks'
|
|
37
|
+
require 'axlsx/workbook/worksheet/break'
|
|
38
|
+
require 'axlsx/workbook/worksheet/row_breaks'
|
|
39
|
+
require 'axlsx/workbook/worksheet/col_breaks'
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
37
43
|
require 'axlsx/workbook/worksheet/worksheet.rb'
|
|
38
44
|
require 'axlsx/workbook/shared_strings_table.rb'
|
|
39
45
|
require 'axlsx/workbook/defined_name.rb'
|
|
@@ -270,14 +276,14 @@ require 'axlsx/workbook/worksheet/selection.rb'
|
|
|
270
276
|
def relationships
|
|
271
277
|
r = Relationships.new
|
|
272
278
|
@worksheets.each do |sheet|
|
|
273
|
-
r << Relationship.new(WORKSHEET_R, WORKSHEET_PN % (r.size+1))
|
|
279
|
+
r << Relationship.new(sheet, WORKSHEET_R, WORKSHEET_PN % (r.size+1))
|
|
274
280
|
end
|
|
275
281
|
pivot_tables.each_with_index do |pivot_table, index|
|
|
276
|
-
r << Relationship.new(PIVOT_TABLE_CACHE_DEFINITION_R, PIVOT_TABLE_CACHE_DEFINITION_PN % (index+1))
|
|
282
|
+
r << Relationship.new(pivot_table.cache_definition, PIVOT_TABLE_CACHE_DEFINITION_R, PIVOT_TABLE_CACHE_DEFINITION_PN % (index+1))
|
|
277
283
|
end
|
|
278
|
-
r << Relationship.new(STYLES_R, STYLES_PN)
|
|
284
|
+
r << Relationship.new(self, STYLES_R, STYLES_PN)
|
|
279
285
|
if use_shared_strings
|
|
280
|
-
r << Relationship.new(SHARED_STRINGS_R, SHARED_STRINGS_PN)
|
|
286
|
+
r << Relationship.new(self, SHARED_STRINGS_R, SHARED_STRINGS_PN)
|
|
281
287
|
end
|
|
282
288
|
r
|
|
283
289
|
end
|
|
@@ -285,7 +291,25 @@ require 'axlsx/workbook/worksheet/selection.rb'
|
|
|
285
291
|
# generates a shared string object against all cells in all worksheets.
|
|
286
292
|
# @return [SharedStringTable]
|
|
287
293
|
def shared_strings
|
|
288
|
-
SharedStringsTable.new(worksheets.collect { |ws| ws.cells })
|
|
294
|
+
SharedStringsTable.new(worksheets.collect { |ws| ws.cells }, xml_space)
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
# The xml:space attribute for the worksheet.
|
|
298
|
+
# This determines how whitespace is handled withing the document.
|
|
299
|
+
# The most relevant part being whitespace in the cell text.
|
|
300
|
+
# allowed values are :preserve and :default. Axlsx uses :preserve unless
|
|
301
|
+
# you explicily set this to :default.
|
|
302
|
+
# @return Symbol
|
|
303
|
+
def xml_space
|
|
304
|
+
@xml_space ||= :preserve
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
# Sets the xml:space attribute for the worksheet
|
|
308
|
+
# @see Worksheet#xml_space
|
|
309
|
+
# @param [Symbol] space must be one of :preserve or :default
|
|
310
|
+
def xml_space=(space)
|
|
311
|
+
Axlsx::RestrictionValidator.validate(:xml_space, [:preserve, :default], space)
|
|
312
|
+
@xml_space = space;
|
|
289
313
|
end
|
|
290
314
|
|
|
291
315
|
# returns a range of cells in a worksheet
|
|
@@ -318,9 +342,8 @@ require 'axlsx/workbook/worksheet/selection.rb'
|
|
|
318
342
|
defined_names.to_xml_string(str)
|
|
319
343
|
unless pivot_tables.empty?
|
|
320
344
|
str << '<pivotCaches>'
|
|
321
|
-
pivot_tables.
|
|
322
|
-
|
|
323
|
-
str << '<pivotCache cacheId="' << pivot_table.cache_definition.cache_id.to_s << '" r:id="' << rId << '"/>'
|
|
345
|
+
pivot_tables.each do |pivot_table|
|
|
346
|
+
str << '<pivotCache cacheId="' << pivot_table.cache_definition.cache_id.to_s << '" r:id="' << pivot_table.cache_definition.rId << '"/>'
|
|
324
347
|
end
|
|
325
348
|
str << '</pivotCaches>'
|
|
326
349
|
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module Axlsx
|
|
2
|
+
|
|
3
|
+
# The Break class stores the details for row and column page breaks.
|
|
4
|
+
# @see RowBreaks, ColBreaks
|
|
5
|
+
class Break
|
|
6
|
+
|
|
7
|
+
include Axlsx::OptionsParser
|
|
8
|
+
include Axlsx::Accessors
|
|
9
|
+
include Axlsx::SerializedAttributes
|
|
10
|
+
|
|
11
|
+
# Creates a new Break object
|
|
12
|
+
# @param options A hash of attribute options for this break.
|
|
13
|
+
# @option options [Integer] id Zero-based row or column Id of the page break. Breaks occur above the specified row and left of the specified column.
|
|
14
|
+
# @option options [Integer] min Zero-based index of start row or column of the break. For row breaks, specifies column index; for column breaks, specifies row index.
|
|
15
|
+
# @option options [Integer] max Zero-based index of end row or column of the break. For row breaks, specifies column index; for column breaks, specifies row index.
|
|
16
|
+
# @option options [Boolean] man Manual Break flag. 1 means the break is a manually inserted break.
|
|
17
|
+
# @option option [Boolean] pt Flag indicating that a PivotTable created this break.
|
|
18
|
+
def initialize(options={})
|
|
19
|
+
parse_options options
|
|
20
|
+
yield self if block_given?
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
unsigned_int_attr_accessor :id, :min, :max
|
|
24
|
+
|
|
25
|
+
boolean_attr_accessor :man, :pt
|
|
26
|
+
|
|
27
|
+
serializable_attributes :id, :min, :max, :man, :pt
|
|
28
|
+
|
|
29
|
+
# serializes the break to xml
|
|
30
|
+
def to_xml_string(str='')
|
|
31
|
+
str << '<brk '
|
|
32
|
+
serialized_attributes str
|
|
33
|
+
str << '></brk>'
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
@@ -302,7 +302,7 @@ module Axlsx
|
|
|
302
302
|
def to_xml_string(r_index, c_index, str = '')
|
|
303
303
|
CellSerializer.to_xml_string r_index, c_index, self, str
|
|
304
304
|
end
|
|
305
|
-
|
|
305
|
+
|
|
306
306
|
def is_formula?
|
|
307
307
|
@type == :string && @value.to_s.start_with?('=')
|
|
308
308
|
end
|
|
@@ -318,9 +318,9 @@ module Axlsx
|
|
|
318
318
|
end
|
|
319
319
|
|
|
320
320
|
# returns the absolute or relative string style reference for
|
|
321
|
-
# this cell.
|
|
321
|
+
# this cell.
|
|
322
322
|
# @param [Boolean] absolute -when false a relative reference will be
|
|
323
|
-
# returned.
|
|
323
|
+
# returned.
|
|
324
324
|
# @return [String]
|
|
325
325
|
def reference(absolute=true)
|
|
326
326
|
absolute ? r_abs : r
|
|
@@ -353,7 +353,7 @@ module Axlsx
|
|
|
353
353
|
|
|
354
354
|
# assigns the owning row for this cell.
|
|
355
355
|
def row=(v) @row=v end
|
|
356
|
-
|
|
356
|
+
|
|
357
357
|
# Determines the cell type based on the cell value.
|
|
358
358
|
# @note This is only used when a cell is created but no :type option is specified, the following rules apply:
|
|
359
359
|
# 1. If the value is an instance of Date, the type is set to :date
|
|
@@ -375,7 +375,7 @@ module Axlsx
|
|
|
375
375
|
:float
|
|
376
376
|
# \A(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[0-1]|0[1-9]|[1-2][0-9])
|
|
377
377
|
# T(2[0-3]|[0-1][0-9]):([0-5][0-9]):([0-5][0-9])(\.[0-9]+)?
|
|
378
|
-
# (Z|[+-](?:2[0-3]|[0-1][0-9]):[0-5][0-9])?\Z
|
|
378
|
+
# (Z|[+-](?:2[0-3]|[0-1][0-9]):[0-5][0-9])?\Z
|
|
379
379
|
elsif v.to_s =~/\A(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[0-1]|0[1-9]|[1-2][0-9])T(2[0-3]|[0-1][0-9]):([0-5][0-9]):([0-5][0-9])(\.[0-9]+)?(Z|[+-](?:2[0-3]|[0-1][0-9]):[0-5][0-9])?\Z/
|
|
380
380
|
:iso_8601
|
|
381
381
|
else
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Axlsx
|
|
2
|
+
|
|
3
|
+
# A collection of Brake objects.
|
|
4
|
+
# Please do not use this class directly. Instead use
|
|
5
|
+
# Worksheet#add_break
|
|
6
|
+
class ColBreaks < SimpleTypedList
|
|
7
|
+
|
|
8
|
+
# Instantiates a new list restricted to Break types
|
|
9
|
+
def initialize
|
|
10
|
+
super Break
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# A column break specific helper for adding a break.
|
|
14
|
+
# @param [Hash] options A list of options to pass into the Break object
|
|
15
|
+
# The max and man options are fixed, however any other valid option for
|
|
16
|
+
# Break will be passed to the created break object.
|
|
17
|
+
# @see Break
|
|
18
|
+
def add_break(options)
|
|
19
|
+
@list << Break.new(options.merge(:max => 1048575, :man => true))
|
|
20
|
+
last
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Serialize the collection to xml
|
|
24
|
+
# @param [String] str The string to append this lists xml to.
|
|
25
|
+
# <colBreaks count="1" manualBreakCount="1">
|
|
26
|
+
# <brk id="3" max="1048575" man="1"/>
|
|
27
|
+
# </colBreaks>
|
|
28
|
+
def to_xml_string(str='')
|
|
29
|
+
return if empty?
|
|
30
|
+
str << '<colBreaks count="' << @list.size.to_s << '" manualBreakCount="' << @list.size.to_s << '">'
|
|
31
|
+
each { |brk| brk.to_xml_string(str) }
|
|
32
|
+
str << '</colBreaks>'
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -64,13 +64,14 @@ module Axlsx
|
|
|
64
64
|
def to_xml_string(str = "")
|
|
65
65
|
author = @comments.authors[author_index]
|
|
66
66
|
str << '<comment ref="' << ref << '" authorId="' << author_index.to_s << '">'
|
|
67
|
-
str << '<text
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
</t></r>
|
|
67
|
+
str << '<text>'
|
|
68
|
+
unless author.to_s == ""
|
|
69
|
+
str << '<r><rPr><b/><color indexed="81"/></rPr>'
|
|
70
|
+
str << "<t>" << ::CGI.escapeHTML(author.to_s) << ":\n</t></r>"
|
|
71
|
+
end
|
|
71
72
|
str << '<r>'
|
|
72
73
|
str << '<rPr><color indexed="81"/></rPr>'
|
|
73
|
-
str << '<t>' << text << '</t></r></text>'
|
|
74
|
+
str << '<t>' << ::CGI.escapeHTML(text) << '</t></r></text>'
|
|
74
75
|
str << '</comment>'
|
|
75
76
|
end
|
|
76
77
|
|
|
@@ -56,9 +56,9 @@ module Axlsx
|
|
|
56
56
|
# The relationships required by this object
|
|
57
57
|
# @return [Array]
|
|
58
58
|
def relationships
|
|
59
|
-
[Relationship.new(VML_DRAWING_R, "../#{vml_drawing.pn}"),
|
|
60
|
-
Relationship.new(COMMENT_R, "../#{pn}"),
|
|
61
|
-
Relationship.new(COMMENT_R_NULL, "NULL")]
|
|
59
|
+
[Relationship.new(self, VML_DRAWING_R, "../#{vml_drawing.pn}"),
|
|
60
|
+
Relationship.new(self, COMMENT_R, "../#{pn}"),
|
|
61
|
+
Relationship.new(self, COMMENT_R_NULL, "NULL")]
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
# serialize the object
|
|
@@ -182,7 +182,7 @@ module Axlsx
|
|
|
182
182
|
# @see timePeriod
|
|
183
183
|
def timePeriod=(v); Axlsx::validate_time_period_type(v); @timePeriod = v end
|
|
184
184
|
# @see formula
|
|
185
|
-
def formula=(v); [*v].each {|x| Axlsx::validate_string(x) }; @formula = v end
|
|
185
|
+
def formula=(v); [*v].each {|x| Axlsx::validate_string(x) }; @formula = [*v].map { |form| ::CGI.escapeHTML(form) } end
|
|
186
186
|
|
|
187
187
|
# @see color_scale
|
|
188
188
|
def color_scale=(v)
|
|
@@ -10,7 +10,8 @@ module Axlsx
|
|
|
10
10
|
# @return [Numeric]
|
|
11
11
|
def self.date_to_serial(date)
|
|
12
12
|
epoch = Axlsx::Workbook::date1904 ? Date.new(1904) : Date.new(1899, 12, 30)
|
|
13
|
-
(date
|
|
13
|
+
offset_date = date.respond_to?(:utc_offset) ? date + date.utc_offset.seconds : date
|
|
14
|
+
(offset_date - epoch).to_f
|
|
14
15
|
end
|
|
15
16
|
|
|
16
17
|
# The time_to_serial methond converts a Time object its excel serialized form.
|
|
@@ -19,11 +20,11 @@ module Axlsx
|
|
|
19
20
|
def self.time_to_serial(time)
|
|
20
21
|
# Using hardcoded offsets here as some operating systems will not except
|
|
21
22
|
# a 'negative' offset from the ruby epoch.
|
|
22
|
-
epoch1900 = -2209161600 # Time.utc(1899, 12, 30).to_i
|
|
23
|
-
epoch1904 = -2082844800 # Time.utc(1904, 1, 1).to_i
|
|
24
|
-
seconds_per_day = 86400 # 60*60*24
|
|
23
|
+
epoch1900 = -2209161600.0 # Time.utc(1899, 12, 30).to_i
|
|
24
|
+
epoch1904 = -2082844800.0 # Time.utc(1904, 1, 1).to_i
|
|
25
|
+
seconds_per_day = 86400.0 # 60*60*24
|
|
25
26
|
epoch = Axlsx::Workbook::date1904 ? epoch1904 : epoch1900
|
|
26
|
-
(time.to_f - epoch)/seconds_per_day
|
|
27
|
+
(time.utc_offset + time.to_f - epoch)/seconds_per_day
|
|
27
28
|
end
|
|
28
29
|
end
|
|
29
30
|
end
|
|
@@ -19,10 +19,12 @@ module Axlsx
|
|
|
19
19
|
@sheet = sheet
|
|
20
20
|
@sheet.workbook.pivot_tables << self
|
|
21
21
|
@name = "PivotTable#{index+1}"
|
|
22
|
+
@data_sheet = nil
|
|
22
23
|
@rows = []
|
|
23
24
|
@columns = []
|
|
24
25
|
@data = []
|
|
25
26
|
@pages = []
|
|
27
|
+
@subtotal = nil
|
|
26
28
|
parse_options options
|
|
27
29
|
yield self if block_given?
|
|
28
30
|
end
|
|
@@ -39,6 +41,15 @@ module Axlsx
|
|
|
39
41
|
# @return [String]
|
|
40
42
|
attr_reader :sheet
|
|
41
43
|
|
|
44
|
+
# The sheet used as data source for the pivot table
|
|
45
|
+
# @return [Worksheet]
|
|
46
|
+
attr_writer :data_sheet
|
|
47
|
+
|
|
48
|
+
# @see #data_sheet
|
|
49
|
+
def data_sheet
|
|
50
|
+
@data_sheet || @sheet
|
|
51
|
+
end
|
|
52
|
+
|
|
42
53
|
# The range where the data for this pivot table lives.
|
|
43
54
|
# @return [String]
|
|
44
55
|
attr_reader :range
|
|
@@ -85,10 +96,17 @@ module Axlsx
|
|
|
85
96
|
# (see #data)
|
|
86
97
|
def data=(v)
|
|
87
98
|
DataTypeValidator.validate "#{self.class}.data", [Array], v
|
|
88
|
-
|
|
89
|
-
|
|
99
|
+
@data = []
|
|
100
|
+
v.each do |data_field|
|
|
101
|
+
if data_field.is_a? String
|
|
102
|
+
data_field = {:ref => data_field}
|
|
103
|
+
end
|
|
104
|
+
data_field.values.each do |value|
|
|
105
|
+
DataTypeValidator.validate "#{self.class}.data[]", [String], value
|
|
106
|
+
end
|
|
107
|
+
@data << data_field
|
|
90
108
|
end
|
|
91
|
-
@data
|
|
109
|
+
@data
|
|
92
110
|
end
|
|
93
111
|
|
|
94
112
|
# The pages
|
|
@@ -128,20 +146,14 @@ module Axlsx
|
|
|
128
146
|
@cache_definition ||= PivotTableCacheDefinition.new(self)
|
|
129
147
|
end
|
|
130
148
|
|
|
131
|
-
# The
|
|
149
|
+
# The relationships for this pivot table.
|
|
132
150
|
# @return [Relationships]
|
|
133
151
|
def relationships
|
|
134
152
|
r = Relationships.new
|
|
135
|
-
r << Relationship.new(PIVOT_TABLE_CACHE_DEFINITION_R, "../#{cache_definition.pn}")
|
|
153
|
+
r << Relationship.new(cache_definition, PIVOT_TABLE_CACHE_DEFINITION_R, "../#{cache_definition.pn}")
|
|
136
154
|
r
|
|
137
155
|
end
|
|
138
156
|
|
|
139
|
-
# The relation reference id for this table
|
|
140
|
-
# @return [String]
|
|
141
|
-
def rId
|
|
142
|
-
"rId#{index+1}"
|
|
143
|
-
end
|
|
144
|
-
|
|
145
157
|
# Serializes the object
|
|
146
158
|
# @param [String] str
|
|
147
159
|
# @return [String]
|
|
@@ -186,11 +198,11 @@ module Axlsx
|
|
|
186
198
|
str << '</pageFields>'
|
|
187
199
|
end
|
|
188
200
|
unless data.empty?
|
|
189
|
-
str <<
|
|
201
|
+
str << "<dataFields count=\"#{data.size}\">"
|
|
190
202
|
data.each do |datum_value|
|
|
191
|
-
str <<
|
|
192
|
-
|
|
193
|
-
|
|
203
|
+
str << "<dataField name='#{@subtotal} of #{datum_value[:ref]}' fld='#{header_index_of(datum_value[:ref])}' baseField='0' baseItem='0'"
|
|
204
|
+
str << " subtotal='#{datum_value[:subtotal]}' " if datum_value[:subtotal]
|
|
205
|
+
str << "/>"
|
|
194
206
|
end
|
|
195
207
|
str << '</dataFields>'
|
|
196
208
|
end
|
|
@@ -206,7 +218,7 @@ module Axlsx
|
|
|
206
218
|
# The header cells for the pivot table
|
|
207
219
|
# @return [Array]
|
|
208
220
|
def header_cells
|
|
209
|
-
|
|
221
|
+
data_sheet[header_range]
|
|
210
222
|
end
|
|
211
223
|
|
|
212
224
|
# The values in the header cells collection
|
|
@@ -242,7 +254,7 @@ module Axlsx
|
|
|
242
254
|
'<pivotField axis="axisCol" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1">' <<
|
|
243
255
|
'<items count="1"><item t="default"/></items>' <<
|
|
244
256
|
'</pivotField>'
|
|
245
|
-
elsif
|
|
257
|
+
elsif data_refs.include? cell_ref
|
|
246
258
|
'<pivotField dataField="1" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1">' <<
|
|
247
259
|
'</pivotField>'
|
|
248
260
|
else
|
|
@@ -250,7 +262,9 @@ module Axlsx
|
|
|
250
262
|
'</pivotField>'
|
|
251
263
|
end
|
|
252
264
|
end
|
|
253
|
-
|
|
265
|
+
def data_refs
|
|
266
|
+
data.map { |hash| hash[:ref] }
|
|
267
|
+
end
|
|
254
268
|
def header_range
|
|
255
269
|
range.gsub(/^(\w+?)(\d+)\:(\w+?)\d+$/, '\1\2:\3\2')
|
|
256
270
|
end
|
|
@@ -35,10 +35,11 @@ module Axlsx
|
|
|
35
35
|
index + 1
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
-
# The
|
|
38
|
+
# The relationship id for this pivot table cache definition.
|
|
39
|
+
# @see Relationship#Id
|
|
39
40
|
# @return [String]
|
|
40
41
|
def rId
|
|
41
|
-
|
|
42
|
+
pivot_table.relationships.for(self).Id
|
|
42
43
|
end
|
|
43
44
|
|
|
44
45
|
# Serializes the object
|
|
@@ -48,7 +49,7 @@ module Axlsx
|
|
|
48
49
|
str << '<?xml version="1.0" encoding="UTF-8"?>'
|
|
49
50
|
str << '<pivotCacheDefinition xmlns="' << XML_NS << '" xmlns:r="' << XML_NS_R << '" invalid="1" refreshOnLoad="1" recordCount="0">'
|
|
50
51
|
str << '<cacheSource type="worksheet">'
|
|
51
|
-
str << '<worksheetSource ref="' << pivot_table.range << '" sheet="
|
|
52
|
+
str << '<worksheetSource ref="' << pivot_table.range << '" sheet="' << pivot_table.data_sheet.name << '"/>'
|
|
52
53
|
str << '</cacheSource>'
|
|
53
54
|
str << '<cacheFields count="' << pivot_table.header_cells_count.to_s << '">'
|
|
54
55
|
pivot_table.header_cells.each do |cell|
|
|
@@ -17,7 +17,7 @@ module Axlsx
|
|
|
17
17
|
# returns the relationships required by this collection
|
|
18
18
|
def relationships
|
|
19
19
|
return [] if empty?
|
|
20
|
-
map{ |pivot_table| Relationship.new(PIVOT_TABLE_R, "../#{pivot_table.pn}") }
|
|
20
|
+
map{ |pivot_table| Relationship.new(pivot_table, PIVOT_TABLE_R, "../#{pivot_table.pn}") }
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
23
|
|
|
@@ -97,7 +97,7 @@ module Axlsx
|
|
|
97
97
|
str << '</row>'
|
|
98
98
|
end
|
|
99
99
|
|
|
100
|
-
# Adds a
|
|
100
|
+
# Adds a single sell to the row based on the data provided and updates the worksheet's autofit data.
|
|
101
101
|
# @return [Cell]
|
|
102
102
|
def add_cell(value="", options={})
|
|
103
103
|
c = Cell.new(self, value, options)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Axlsx
|
|
2
|
+
|
|
3
|
+
# A collection of break objects that define row breaks (page breaks) for printing and preview
|
|
4
|
+
|
|
5
|
+
class RowBreaks < SimpleTypedList
|
|
6
|
+
|
|
7
|
+
def initialize
|
|
8
|
+
super Break
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Adds a row break
|
|
12
|
+
# @param [Hash] options The options for the break to be created.
|
|
13
|
+
# max and man values are fixed.
|
|
14
|
+
# @see Break
|
|
15
|
+
def add_break(options)
|
|
16
|
+
# force feed the excel default
|
|
17
|
+
@list << Break.new(options.merge(:max => 16383, :man => true))
|
|
18
|
+
last
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# <rowBreaks count="3" manualBreakCount="3">
|
|
22
|
+
# <brk id="1" max="16383" man="1"/>
|
|
23
|
+
# <brk id="7" max="16383" man="1"/>
|
|
24
|
+
# <brk id="13" max="16383" man="1"/>
|
|
25
|
+
# </rowBreaks>
|
|
26
|
+
def to_xml_string(str='')
|
|
27
|
+
return if empty?
|
|
28
|
+
str << '<rowBreaks count="' << @list.size.to_s << '" manualBreakCount="' << @list.size.to_s << '">'
|
|
29
|
+
each { |brk| brk.to_xml_string(str) }
|
|
30
|
+
str << '</rowBreaks>'
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -47,10 +47,11 @@ module Axlsx
|
|
|
47
47
|
"#{TABLE_PN % (index+1)}"
|
|
48
48
|
end
|
|
49
49
|
|
|
50
|
-
# The
|
|
50
|
+
# The relationship id for this table.
|
|
51
|
+
# @see Relationship#Id
|
|
51
52
|
# @return [String]
|
|
52
53
|
def rId
|
|
53
|
-
|
|
54
|
+
@sheet.relationships.for(self).Id
|
|
54
55
|
end
|
|
55
56
|
|
|
56
57
|
# The name of the Table.
|
|
@@ -17,7 +17,7 @@ module Axlsx
|
|
|
17
17
|
# returns the relationships required by this collection
|
|
18
18
|
def relationships
|
|
19
19
|
return [] if empty?
|
|
20
|
-
map{ |table| Relationship.new(TABLE_R, "../#{table.pn}") }
|
|
20
|
+
map{ |table| Relationship.new(table, TABLE_R, "../#{table.pn}") }
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def to_xml_string(str = "")
|