axlsx 1.3.6 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts_guide +19 -0
- data/CHANGELOG.md +8 -0
- data/README.md +52 -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.rb +8 -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 +31 -11
- 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/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 +30 -0
- 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 +37 -10
- data/test/example.xlsx +0 -0
@@ -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 = "")
|
@@ -37,6 +37,8 @@ module Axlsx
|
|
37
37
|
@page_setup = PageSetup.new options[:page_setup] if options[:page_setup]
|
38
38
|
@print_options = PrintOptions.new options[:print_options] if options[:print_options]
|
39
39
|
@header_footer = HeaderFooter.new options[:header_footer] if options[:header_footer]
|
40
|
+
@row_breaks = RowBreaks.new
|
41
|
+
@col_breaks = ColBreaks.new
|
40
42
|
end
|
41
43
|
|
42
44
|
# The name of the worksheet
|
@@ -94,6 +96,22 @@ module Axlsx
|
|
94
96
|
@pivot_tables ||= PivotTables.new self
|
95
97
|
end
|
96
98
|
|
99
|
+
# A collection of column breaks added to this worksheet
|
100
|
+
# @note Please do not use this directly. Instead use
|
101
|
+
# add_page_break
|
102
|
+
# @see Worksheet#add_page_break
|
103
|
+
def col_breaks
|
104
|
+
@col_breaks ||= ColBreaks.new
|
105
|
+
end
|
106
|
+
|
107
|
+
# A collection of row breaks added to this worksheet
|
108
|
+
# @note Please do not use this directly. Instead use
|
109
|
+
# add_page_break
|
110
|
+
# @see Worksheet#add_page_break
|
111
|
+
def row_breaks
|
112
|
+
@row_breaks ||= RowBreaks.new
|
113
|
+
end
|
114
|
+
|
97
115
|
# A typed collection of hyperlinks associated with this worksheet
|
98
116
|
# @return [WorksheetHyperlinks]
|
99
117
|
def hyperlinks
|
@@ -114,14 +132,19 @@ module Axlsx
|
|
114
132
|
@rows ||= SimpleTypedList.new Row
|
115
133
|
end
|
116
134
|
|
117
|
-
# returns the sheet data as
|
118
|
-
|
119
|
-
|
135
|
+
# returns the sheet data as columns
|
136
|
+
# If you pass a block, it will be evaluated whenever a row does not have a
|
137
|
+
# cell at a specific index. The block will be called with the row and column
|
138
|
+
# index in the missing cell was found.
|
139
|
+
# @example
|
140
|
+
# cols { |row_index, column_index| p "warn - row #{row_index} is does not have a cell at #{column_index}
|
141
|
+
def cols(&block)
|
142
|
+
@rows.transpose(&block)
|
120
143
|
end
|
121
144
|
|
122
|
-
# An range that excel will apply an
|
145
|
+
# An range that excel will apply an auto-filter to "A1:B3"
|
123
146
|
# This will turn filtering on for the cells in the range.
|
124
|
-
# The first row is considered the header, while subsequent rows are
|
147
|
+
# The first row is considered the header, while subsequent rows are considered to be data.
|
125
148
|
# @return String
|
126
149
|
def auto_filter
|
127
150
|
@auto_filter ||= AutoFilter.new self
|
@@ -327,6 +350,10 @@ module Axlsx
|
|
327
350
|
auto_filter.range = v
|
328
351
|
end
|
329
352
|
|
353
|
+
# Accessor for controlling whether leading and trailing spaces in cells are
|
354
|
+
# preserved or ignored. The default is to preserve spaces.
|
355
|
+
attr_accessor :preserve_spaces
|
356
|
+
|
330
357
|
# The part name of this worksheet
|
331
358
|
# @return [String]
|
332
359
|
def pn
|
@@ -339,10 +366,11 @@ module Axlsx
|
|
339
366
|
"#{WORKSHEET_RELS_PN % (index+1)}"
|
340
367
|
end
|
341
368
|
|
342
|
-
# The relationship
|
369
|
+
# The relationship id of this worksheet.
|
343
370
|
# @return [String]
|
371
|
+
# @see Relationship#Id
|
344
372
|
def rId
|
345
|
-
|
373
|
+
@workbook.relationships.for(self).Id
|
346
374
|
end
|
347
375
|
|
348
376
|
# The index of this worksheet in the owning Workbook's worksheets list.
|
@@ -488,6 +516,24 @@ module Axlsx
|
|
488
516
|
image
|
489
517
|
end
|
490
518
|
|
519
|
+
# Adds a page break (row break) to the worksheet
|
520
|
+
# @param cell A Cell object or excel style string reference indicating where the break
|
521
|
+
# should be added to the sheet.
|
522
|
+
# @example
|
523
|
+
# ws.add_page_break("A4")
|
524
|
+
def add_page_break(cell)
|
525
|
+
DataTypeValidator.validate "Worksheet#add_page_break cell", [String, Cell], cell
|
526
|
+
column_index, row_index = if cell.is_a?(String)
|
527
|
+
Axlsx.name_to_indices(cell)
|
528
|
+
else
|
529
|
+
cell.pos
|
530
|
+
end
|
531
|
+
if column_index > 0
|
532
|
+
col_breaks.add_break(:id => column_index)
|
533
|
+
end
|
534
|
+
row_breaks.add_break(:id => row_index)
|
535
|
+
end
|
536
|
+
|
491
537
|
# This is a helper method that Lets you specify a fixed width for multiple columns in a worksheet in one go.
|
492
538
|
# Axlsx is sparse, so if you have not set data for a column, you cannot set the width.
|
493
539
|
# Setting a fixed column width to nil will revert the behaviour back to calculating the width for you on the next call to add_row.
|
@@ -542,15 +588,7 @@ module Axlsx
|
|
542
588
|
item.to_xml_string(str) if item
|
543
589
|
end
|
544
590
|
str << '</worksheet>'
|
545
|
-
sanitize(str)
|
546
|
-
end
|
547
|
-
|
548
|
-
# returns the provided string with all invalid control charaters
|
549
|
-
# removed.
|
550
|
-
# @param [String] str The sting to process
|
551
|
-
# @return [String]
|
552
|
-
def sanitize(str)
|
553
|
-
str.gsub(CONTROL_CHAR_REGEX, '')
|
591
|
+
Axlsx::sanitize(str)
|
554
592
|
end
|
555
593
|
|
556
594
|
# The worksheet relationships. This is managed automatically by the worksheet
|
@@ -565,14 +603,6 @@ module Axlsx
|
|
565
603
|
r
|
566
604
|
end
|
567
605
|
|
568
|
-
# identifies the index of an object withing the collections used in generating relationships for the worksheet
|
569
|
-
# @param [Any] object the object to search for
|
570
|
-
# @return [Integer] The index of the object
|
571
|
-
def relationships_index_of(object)
|
572
|
-
objects = [tables.to_a, worksheet_comments.comments.to_a, hyperlinks.to_a, worksheet_drawing.drawing].flatten.compact || []
|
573
|
-
objects.index(object)
|
574
|
-
end
|
575
|
-
|
576
606
|
# Returns the cell or cells defined using excel style A1:B3 references.
|
577
607
|
# @param [String|Integer] cell_def the string defining the cell or range of cells, or the rownumber
|
578
608
|
# @return [Cell, Array]
|
@@ -629,6 +659,11 @@ module Axlsx
|
|
629
659
|
end
|
630
660
|
|
631
661
|
private
|
662
|
+
|
663
|
+
def xml_space
|
664
|
+
workbook.xml_space
|
665
|
+
end
|
666
|
+
|
632
667
|
def outline(collection, range, level = 1, collapsed = true)
|
633
668
|
range.each do |index|
|
634
669
|
unless (item = collection[index]).nil?
|
@@ -653,7 +688,7 @@ module Axlsx
|
|
653
688
|
sheet_data, sheet_calc_pr, @sheet_protection, protected_ranges,
|
654
689
|
auto_filter, merged_cells, conditional_formattings,
|
655
690
|
data_validations, hyperlinks, print_options, page_margins,
|
656
|
-
page_setup, header_footer, worksheet_drawing, worksheet_comments,
|
691
|
+
page_setup, header_footer, row_breaks, col_breaks, worksheet_drawing, worksheet_comments,
|
657
692
|
tables]
|
658
693
|
end
|
659
694
|
|
@@ -699,7 +734,7 @@ module Axlsx
|
|
699
734
|
# Helper method for parsingout the root node for worksheet
|
700
735
|
# @return [String]
|
701
736
|
def worksheet_node
|
702
|
-
|
737
|
+
"<worksheet xmlns=\"%s\" xmlns:r=\"%s\" xml:space=\"#{xml_space}\">" % [XML_NS, XML_NS_R]
|
703
738
|
end
|
704
739
|
|
705
740
|
def sheet_data
|