axlsx 2.0.1 → 3.0.0.pre
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/CHANGELOG.md +5 -0
- data/README.md +23 -23
- data/Rakefile +9 -11
- data/examples/auto_filter.rb +10 -1
- data/examples/conditional_formatting/example_conditional_formatting.rb +18 -3
- data/examples/example.rb +102 -4
- data/examples/merge_cells.rb +17 -0
- data/examples/no_grid_with_borders.rb +18 -0
- data/examples/pivot_test.rb +63 -0
- data/examples/split.rb +16 -0
- data/lib/axlsx/content_type/abstract_content_type.rb +1 -1
- data/lib/axlsx/content_type/content_type.rb +1 -1
- data/lib/axlsx/doc_props/app.rb +1 -1
- data/lib/axlsx/doc_props/core.rb +5 -5
- data/lib/axlsx/drawing/area_chart.rb +99 -0
- data/lib/axlsx/drawing/area_series.rb +110 -0
- data/lib/axlsx/drawing/axes.rb +1 -1
- data/lib/axlsx/drawing/axis.rb +12 -9
- data/lib/axlsx/drawing/bar_3D_chart.rb +13 -13
- data/lib/axlsx/drawing/bar_chart.rb +143 -0
- data/lib/axlsx/drawing/bar_series.rb +9 -9
- data/lib/axlsx/drawing/bubble_chart.rb +59 -0
- data/lib/axlsx/drawing/bubble_series.rb +63 -0
- data/lib/axlsx/drawing/cat_axis.rb +5 -5
- data/lib/axlsx/drawing/chart.rb +52 -8
- data/lib/axlsx/drawing/d_lbls.rb +3 -3
- data/lib/axlsx/drawing/drawing.rb +6 -1
- data/lib/axlsx/drawing/graphic_frame.rb +3 -3
- data/lib/axlsx/drawing/hyperlink.rb +1 -3
- data/lib/axlsx/drawing/line_3D_chart.rb +2 -2
- data/lib/axlsx/drawing/line_chart.rb +10 -10
- data/lib/axlsx/drawing/line_series.rb +32 -3
- data/lib/axlsx/drawing/marker.rb +1 -1
- data/lib/axlsx/drawing/num_data.rb +4 -4
- data/lib/axlsx/drawing/num_data_source.rb +6 -6
- data/lib/axlsx/drawing/num_val.rb +3 -1
- data/lib/axlsx/drawing/one_cell_anchor.rb +3 -2
- data/lib/axlsx/drawing/pic.rb +25 -19
- data/lib/axlsx/drawing/picture_locking.rb +1 -3
- data/lib/axlsx/drawing/pie_3D_chart.rb +5 -6
- data/lib/axlsx/drawing/pie_series.rb +6 -6
- data/lib/axlsx/drawing/scaling.rb +6 -6
- data/lib/axlsx/drawing/scatter_chart.rb +10 -10
- data/lib/axlsx/drawing/scatter_series.rb +40 -7
- data/lib/axlsx/drawing/ser_axis.rb +2 -2
- data/lib/axlsx/drawing/series.rb +3 -3
- data/lib/axlsx/drawing/series_title.rb +2 -2
- data/lib/axlsx/drawing/str_data.rb +3 -3
- data/lib/axlsx/drawing/str_val.rb +3 -1
- data/lib/axlsx/drawing/title.rb +22 -4
- data/lib/axlsx/drawing/two_cell_anchor.rb +6 -1
- data/lib/axlsx/drawing/val_axis.rb +1 -1
- data/lib/axlsx/drawing/view_3D.rb +2 -2
- data/lib/axlsx/drawing/vml_drawing.rb +1 -1
- data/lib/axlsx/package.rb +34 -32
- data/lib/axlsx/rels/relationship.rb +1 -1
- data/lib/axlsx/rels/relationships.rb +7 -4
- data/lib/axlsx/stylesheet/border_pr.rb +2 -2
- data/lib/axlsx/stylesheet/cell_alignment.rb +1 -3
- data/lib/axlsx/stylesheet/cell_protection.rb +1 -3
- data/lib/axlsx/stylesheet/cell_style.rb +1 -3
- data/lib/axlsx/stylesheet/color.rb +1 -3
- data/lib/axlsx/stylesheet/font.rb +1 -1
- data/lib/axlsx/stylesheet/gradient_stop.rb +1 -1
- data/lib/axlsx/stylesheet/num_fmt.rb +10 -3
- data/lib/axlsx/stylesheet/pattern_fill.rb +1 -1
- data/lib/axlsx/stylesheet/styles.rb +7 -7
- data/lib/axlsx/stylesheet/table_style_element.rb +1 -3
- data/lib/axlsx/util/accessors.rb +6 -6
- data/lib/axlsx/util/constants.rb +107 -99
- data/lib/axlsx/util/mime_type_utils.rb +11 -0
- data/lib/axlsx/util/options_parser.rb +2 -1
- data/lib/axlsx/util/parser.rb +4 -4
- data/lib/axlsx/util/serialized_attributes.rb +16 -6
- data/lib/axlsx/util/simple_typed_list.rb +28 -52
- data/lib/axlsx/util/storage.rb +4 -4
- data/lib/axlsx/util/validators.rb +29 -17
- data/lib/axlsx/version.rb +1 -1
- data/lib/axlsx/workbook/defined_name.rb +11 -12
- data/lib/axlsx/workbook/defined_names.rb +2 -2
- data/lib/axlsx/workbook/shared_strings_table.rb +5 -5
- data/lib/axlsx/workbook/workbook.rb +36 -11
- data/lib/axlsx/workbook/workbook_view.rb +80 -0
- data/lib/axlsx/workbook/workbook_views.rb +22 -0
- data/lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb +2 -2
- data/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +1 -3
- data/lib/axlsx/workbook/worksheet/break.rb +1 -3
- data/lib/axlsx/workbook/worksheet/cell.rb +136 -74
- data/lib/axlsx/workbook/worksheet/cell_serializer.rb +63 -43
- data/lib/axlsx/workbook/worksheet/cfvo.rb +1 -3
- data/lib/axlsx/workbook/worksheet/cfvos.rb +4 -1
- data/lib/axlsx/workbook/worksheet/col.rb +7 -10
- data/lib/axlsx/workbook/worksheet/col_breaks.rb +2 -2
- data/lib/axlsx/workbook/worksheet/cols.rb +5 -2
- data/lib/axlsx/workbook/worksheet/comment.rb +5 -6
- data/lib/axlsx/workbook/worksheet/comments.rb +9 -12
- data/lib/axlsx/workbook/worksheet/conditional_formatting.rb +1 -1
- data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +1 -1
- data/lib/axlsx/workbook/worksheet/data_bar.rb +4 -6
- data/lib/axlsx/workbook/worksheet/data_validation.rb +6 -4
- data/lib/axlsx/workbook/worksheet/dimension.rb +2 -2
- data/lib/axlsx/workbook/worksheet/header_footer.rb +6 -8
- data/lib/axlsx/workbook/worksheet/icon_set.rb +3 -5
- data/lib/axlsx/workbook/worksheet/merged_cells.rb +4 -2
- data/lib/axlsx/workbook/worksheet/outline_pr.rb +33 -0
- data/lib/axlsx/workbook/worksheet/page_margins.rb +1 -3
- data/lib/axlsx/workbook/worksheet/page_set_up_pr.rb +1 -1
- data/lib/axlsx/workbook/worksheet/page_setup.rb +21 -23
- data/lib/axlsx/workbook/worksheet/pane.rb +1 -3
- data/lib/axlsx/workbook/worksheet/pivot_table.rb +44 -28
- data/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +4 -4
- data/lib/axlsx/workbook/worksheet/print_options.rb +1 -3
- data/lib/axlsx/workbook/worksheet/protected_range.rb +1 -3
- data/lib/axlsx/workbook/worksheet/protected_ranges.rb +5 -2
- data/lib/axlsx/workbook/worksheet/rich_text.rb +55 -0
- data/lib/axlsx/workbook/worksheet/rich_text_run.rb +250 -0
- data/lib/axlsx/workbook/worksheet/row.rb +40 -51
- data/lib/axlsx/workbook/worksheet/row_breaks.rb +2 -2
- data/lib/axlsx/workbook/worksheet/selection.rb +1 -3
- data/lib/axlsx/workbook/worksheet/sheet_data.rb +3 -1
- data/lib/axlsx/workbook/worksheet/sheet_pr.rb +21 -3
- data/lib/axlsx/workbook/worksheet/sheet_protection.rb +1 -3
- data/lib/axlsx/workbook/worksheet/table.rb +6 -6
- data/lib/axlsx/workbook/worksheet/table_style_info.rb +1 -3
- data/lib/axlsx/workbook/worksheet/tables.rb +4 -1
- data/lib/axlsx/workbook/worksheet/worksheet.rb +64 -78
- data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +10 -10
- data/lib/axlsx/workbook/worksheet/worksheet_hyperlinks.rb +3 -3
- data/lib/axlsx.rb +34 -15
- data/test/drawing/tc_area_chart.rb +39 -0
- data/test/drawing/tc_area_series.rb +71 -0
- data/test/drawing/tc_axis.rb +27 -0
- data/test/drawing/tc_bar_chart.rb +71 -0
- data/test/drawing/tc_bubble_chart.rb +44 -0
- data/test/drawing/tc_bubble_series.rb +21 -0
- data/test/drawing/tc_chart.rb +23 -10
- data/test/drawing/tc_data_source.rb +6 -0
- data/test/drawing/tc_drawing.rb +2 -2
- data/test/drawing/tc_line_chart.rb +5 -5
- data/test/drawing/tc_line_series.rb +47 -6
- data/test/drawing/tc_pic.rb +11 -15
- data/test/drawing/tc_scatter_series.rb +36 -1
- data/test/drawing/tc_str_val.rb +9 -0
- data/test/drawing/tc_title.rb +5 -0
- data/test/stylesheet/tc_styles.rb +2 -2
- data/test/tc_axlsx.rb +31 -0
- data/test/tc_helper.rb +2 -0
- data/test/tc_package.rb +19 -1
- data/test/util/tc_mime_type_utils.rb +13 -0
- data/test/util/tc_simple_typed_list.rb +2 -3
- data/test/util/tc_validators.rb +34 -10
- data/test/workbook/tc_defined_name.rb +12 -4
- data/test/workbook/tc_shared_strings_table.rb +16 -1
- data/test/workbook/tc_workbook.rb +38 -3
- data/test/workbook/tc_workbook_view.rb +50 -0
- data/test/workbook/worksheet/auto_filter/tc_filters.rb +1 -1
- data/test/workbook/worksheet/tc_break.rb +1 -1
- data/test/workbook/worksheet/tc_cell.rb +76 -8
- data/test/workbook/worksheet/tc_col.rb +2 -2
- data/test/workbook/worksheet/tc_conditional_formatting.rb +2 -2
- data/test/workbook/worksheet/tc_data_bar.rb +1 -1
- data/test/workbook/worksheet/tc_data_validation.rb +11 -11
- data/test/workbook/worksheet/tc_header_footer.rb +2 -2
- data/test/workbook/worksheet/tc_icon_set.rb +1 -1
- data/test/workbook/worksheet/tc_outline_pr.rb +19 -0
- data/test/workbook/worksheet/tc_page_setup.rb +3 -3
- data/test/workbook/worksheet/tc_pivot_table.rb +21 -6
- data/test/workbook/worksheet/tc_print_options.rb +1 -1
- data/test/workbook/worksheet/tc_rich_text.rb +44 -0
- data/test/workbook/worksheet/tc_rich_text_run.rb +172 -0
- data/test/workbook/worksheet/tc_row.rb +7 -2
- data/test/workbook/worksheet/tc_sheet_calc_pr.rb +1 -1
- data/test/workbook/worksheet/tc_sheet_format_pr.rb +4 -4
- data/test/workbook/worksheet/tc_sheet_pr.rb +26 -4
- data/test/workbook/worksheet/tc_sheet_protection.rb +5 -5
- data/test/workbook/worksheet/tc_sheet_view.rb +4 -4
- data/test/workbook/worksheet/tc_table.rb +2 -3
- data/test/workbook/worksheet/tc_worksheet.rb +99 -45
- metadata +142 -64
@@ -1,6 +1,6 @@
|
|
1
1
|
module Axlsx
|
2
2
|
|
3
|
-
# The cols class manages the col object used to manage column widths.
|
3
|
+
# The cols class manages the col object used to manage column widths.
|
4
4
|
# This is where the magic happens with autowidth
|
5
5
|
class Cols < SimpleTypedList
|
6
6
|
|
@@ -10,11 +10,14 @@ module Axlsx
|
|
10
10
|
@worksheet = worksheet
|
11
11
|
end
|
12
12
|
|
13
|
+
# Serialize the Cols object
|
14
|
+
# @param [String] str
|
15
|
+
# @return [String]
|
13
16
|
def to_xml_string(str = '')
|
14
17
|
return if empty?
|
15
18
|
str << '<cols>'
|
16
19
|
each { |item| item.to_xml_string(str) }
|
17
|
-
str << '</cols>'
|
20
|
+
str << '</cols>'
|
18
21
|
end
|
19
22
|
end
|
20
23
|
end
|
@@ -24,11 +24,10 @@ module Axlsx
|
|
24
24
|
string_attr_accessor :text, :author
|
25
25
|
boolean_attr_accessor :visible
|
26
26
|
|
27
|
-
|
27
|
+
# The owning Comments object
|
28
28
|
# @return [Comments]
|
29
29
|
attr_reader :comments
|
30
30
|
|
31
|
-
|
32
31
|
# The string based cell position reference (e.g. 'A1') that determines the positioning of this comment
|
33
32
|
# @return [String|Cell]
|
34
33
|
attr_reader :ref
|
@@ -53,7 +52,7 @@ module Axlsx
|
|
53
52
|
|
54
53
|
# @see ref
|
55
54
|
def ref=(v)
|
56
|
-
Axlsx::DataTypeValidator.validate
|
55
|
+
Axlsx::DataTypeValidator.validate :comment_ref, [String, Cell], v
|
57
56
|
@ref = v if v.is_a?(String)
|
58
57
|
@ref = v.r if v.is_a?(Cell)
|
59
58
|
end
|
@@ -63,15 +62,15 @@ module Axlsx
|
|
63
62
|
# @return [String]
|
64
63
|
def to_xml_string(str = "")
|
65
64
|
author = @comments.authors[author_index]
|
66
|
-
str << '<comment ref="' << ref << '" authorId="' << author_index.to_s << '">'
|
65
|
+
str << ('<comment ref="' << ref << '" authorId="' << author_index.to_s << '">')
|
67
66
|
str << '<text>'
|
68
67
|
unless author.to_s == ""
|
69
68
|
str << '<r><rPr><b/><color indexed="81"/></rPr>'
|
70
|
-
str << "<t>" << ::CGI.escapeHTML(author.to_s) << ":\n</t></r>"
|
69
|
+
str << ("<t>" << ::CGI.escapeHTML(author.to_s) << ":\n</t></r>")
|
71
70
|
end
|
72
71
|
str << '<r>'
|
73
72
|
str << '<rPr><color indexed="81"/></rPr>'
|
74
|
-
str << '<t>' << ::CGI.escapeHTML(text) << '</t></r></text>'
|
73
|
+
str << ('<t>' << ::CGI.escapeHTML(text) << '</t></r></text>')
|
75
74
|
str << '</comment>'
|
76
75
|
end
|
77
76
|
|
@@ -42,23 +42,22 @@ module Axlsx
|
|
42
42
|
raise ArgumentError, "Comment require an author" unless options[:author]
|
43
43
|
raise ArgumentError, "Comment requires text" unless options[:text]
|
44
44
|
raise ArgumentError, "Comment requires ref" unless options[:ref]
|
45
|
-
|
46
|
-
yield
|
47
|
-
|
45
|
+
self << Comment.new(self, options)
|
46
|
+
yield last if block_given?
|
47
|
+
last
|
48
48
|
end
|
49
49
|
|
50
50
|
# A sorted list of the unique authors in the contained comments
|
51
51
|
# @return [Array]
|
52
52
|
def authors
|
53
|
-
|
53
|
+
map { |comment| comment.author.to_s }.uniq.sort
|
54
54
|
end
|
55
55
|
|
56
56
|
# The relationships required by this object
|
57
57
|
# @return [Array]
|
58
58
|
def relationships
|
59
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")]
|
60
|
+
Relationship.new(self, COMMENT_R, "../#{pn}")]
|
62
61
|
end
|
63
62
|
|
64
63
|
# serialize the object
|
@@ -66,14 +65,12 @@ module Axlsx
|
|
66
65
|
# @return [String]
|
67
66
|
def to_xml_string(str="")
|
68
67
|
str << '<?xml version="1.0" encoding="UTF-8"?>'
|
69
|
-
str << '<comments xmlns="' << XML_NS << '">'
|
70
|
-
str << '<authors>'
|
68
|
+
str << ('<comments xmlns="' << XML_NS << '"><authors>')
|
71
69
|
authors.each do |author|
|
72
|
-
str << '<author>' << author.to_s << '</author>'
|
70
|
+
str << ('<author>' << author.to_s << '</author>')
|
73
71
|
end
|
74
|
-
str << '</authors>'
|
75
|
-
|
76
|
-
@list.each do |comment|
|
72
|
+
str << '</authors><commentList>'
|
73
|
+
each do |comment|
|
77
74
|
comment.to_xml_string str
|
78
75
|
end
|
79
76
|
str << '</commentList></comments>'
|
@@ -74,7 +74,7 @@ module Axlsx
|
|
74
74
|
# @param [String] str
|
75
75
|
# @return [String]
|
76
76
|
def to_xml_string(str = '')
|
77
|
-
str << '<conditionalFormatting sqref="' << sqref << '">'
|
77
|
+
str << ('<conditionalFormatting sqref="' << sqref << '">')
|
78
78
|
str << rules.collect{ |rule| rule.to_xml_string }.join(' ')
|
79
79
|
str << '</conditionalFormatting>'
|
80
80
|
end
|
@@ -210,7 +210,7 @@ module Axlsx
|
|
210
210
|
str << '<cfRule '
|
211
211
|
serialized_attributes str
|
212
212
|
str << '>'
|
213
|
-
str << '<formula>' << [*self.formula].join('</formula><formula>') << '</formula>' if @formula
|
213
|
+
str << ('<formula>' << [*self.formula].join('</formula><formula>') << '</formula>') if @formula
|
214
214
|
@color_scale.to_xml_string(str) if @color_scale && @type == :colorScale
|
215
215
|
@data_bar.to_xml_string(str) if @data_bar && @type == :dataBar
|
216
216
|
@icon_set.to_xml_string(str) if @icon_set && @type == :iconSet
|
@@ -107,12 +107,10 @@ module Axlsx
|
|
107
107
|
# @param [String] str
|
108
108
|
# @return [String]
|
109
109
|
def to_xml_string(str="")
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
self.color.to_xml_string(str)
|
115
|
-
str << '</dataBar>'
|
110
|
+
serialized_tag('dataBar', str) do
|
111
|
+
value_objects.to_xml_string(str)
|
112
|
+
self.color.to_xml_string(str)
|
113
|
+
end
|
116
114
|
end
|
117
115
|
|
118
116
|
private
|
@@ -33,7 +33,7 @@ module Axlsx
|
|
33
33
|
end
|
34
34
|
|
35
35
|
# instance values that must be serialized as their own elements - e.g. not attributes.
|
36
|
-
CHILD_ELEMENTS = [:formula1, :formula2]
|
36
|
+
CHILD_ELEMENTS = [:formula1, :formula2].freeze
|
37
37
|
|
38
38
|
# Formula1
|
39
39
|
# Available for type whole, decimal, date, time, textLength, list, custom
|
@@ -216,10 +216,12 @@ module Axlsx
|
|
216
216
|
valid_attributes = get_valid_attributes
|
217
217
|
|
218
218
|
str << '<dataValidation '
|
219
|
-
str << instance_values.map
|
219
|
+
str << instance_values.map do |key, value|
|
220
|
+
'' << key << '="' << Axlsx.booleanize(value).to_s << '"' if (valid_attributes.include?(key.to_sym) && !CHILD_ELEMENTS.include?(key.to_sym))
|
221
|
+
end.join(' ')
|
220
222
|
str << '>'
|
221
|
-
str << '<formula1>' << self.formula1 << '</formula1>' if @formula1 and valid_attributes.include?(:formula1)
|
222
|
-
str << '<formula2>' << self.formula2 << '</formula2>' if @formula2 and valid_attributes.include?(:formula2)
|
223
|
+
str << ('<formula1>' << self.formula1 << '</formula1>') if @formula1 and valid_attributes.include?(:formula1)
|
224
|
+
str << ('<formula2>' << self.formula2 << '</formula2>') if @formula2 and valid_attributes.include?(:formula2)
|
223
225
|
str << '</dataValidation>'
|
224
226
|
end
|
225
227
|
|
@@ -43,13 +43,13 @@ module Axlsx
|
|
43
43
|
# The first cell in the dimension
|
44
44
|
# @return [String]
|
45
45
|
def first_cell_reference
|
46
|
-
dimension_reference(worksheet.rows.first.
|
46
|
+
dimension_reference(worksheet.rows.first.first, Dimension.default_first)
|
47
47
|
end
|
48
48
|
|
49
49
|
# the last cell in the dimension
|
50
50
|
# @return [String]
|
51
51
|
def last_cell_reference
|
52
|
-
dimension_reference(worksheet.rows.last.
|
52
|
+
dimension_reference(worksheet.rows.last.last, Dimension.default_last)
|
53
53
|
end
|
54
54
|
|
55
55
|
private
|
@@ -19,8 +19,8 @@ module Axlsx
|
|
19
19
|
# @option options [String] odd_footer The content for footers on odd numbered pages.
|
20
20
|
# @option options [String] even_header The content for headers on even numbered pages.
|
21
21
|
# @option options [String] even_footer The content for footers on even numbered pages.
|
22
|
-
# @option options [String] first_header The content for headers on
|
23
|
-
# @option options [String] first_footer The content for footers on
|
22
|
+
# @option options [String] first_header The content for headers on the first page.
|
23
|
+
# @option options [String] first_footer The content for footers on the first page.
|
24
24
|
# @option options [Boolean] different_odd_even Setting this to true will show different headers/footers on odd and even pages. When false, the odd headers/footers are used on each page. (Default: false)
|
25
25
|
# @option options [Boolean] different_first If true, will use the first header/footer on page 1. Otherwise, the odd header/footer is used.
|
26
26
|
def initialize(options = {})
|
@@ -42,13 +42,11 @@ module Axlsx
|
|
42
42
|
# @param [String] str
|
43
43
|
# @return [String]
|
44
44
|
def to_xml_string(str = '')
|
45
|
-
str
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
value = ::CGI.escapeHTML(value)
|
45
|
+
serialized_tag('headerFooter', str) do
|
46
|
+
serialized_element_attributes(str) do |value|
|
47
|
+
value = ::CGI.escapeHTML(value)
|
48
|
+
end
|
50
49
|
end
|
51
|
-
str << "</headerFooter>"
|
52
50
|
end
|
53
51
|
end
|
54
52
|
end
|
@@ -63,11 +63,9 @@ module Axlsx
|
|
63
63
|
# @param [String] str
|
64
64
|
# @return [String]
|
65
65
|
def to_xml_string(str="")
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
@value_objects.each { |cfvo| cfvo.to_xml_string(str) }
|
70
|
-
str << '</iconSet>'
|
66
|
+
serialized_tag('iconSet', str) do
|
67
|
+
@value_objects.each { |cfvo| cfvo.to_xml_string(str) }
|
68
|
+
end
|
71
69
|
end
|
72
70
|
|
73
71
|
private
|
@@ -15,10 +15,12 @@ module Axlsx
|
|
15
15
|
# collection. This can be an array of actual cells or a string style
|
16
16
|
# range like 'A1:C1'
|
17
17
|
def add(cells)
|
18
|
-
|
18
|
+
self << if cells.is_a?(String)
|
19
19
|
cells
|
20
20
|
elsif cells.is_a?(Array)
|
21
21
|
Axlsx::cell_range(cells, false)
|
22
|
+
elsif cells.is_a?(Row)
|
23
|
+
Axlsx::cell_range(cells, false)
|
22
24
|
end
|
23
25
|
end
|
24
26
|
|
@@ -26,7 +28,7 @@ module Axlsx
|
|
26
28
|
# @param [String] str
|
27
29
|
# @return [String]
|
28
30
|
def to_xml_string(str = '')
|
29
|
-
return if
|
31
|
+
return if empty?
|
30
32
|
str << "<mergeCells count='#{size}'>"
|
31
33
|
each { |merged_cell| str << "<mergeCell ref='#{merged_cell}'></mergeCell>" }
|
32
34
|
str << '</mergeCells>'
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Axlsx
|
2
|
+
|
3
|
+
# The OutlinePr class manages serialization of a worksheet's outlinePr element, which provides various
|
4
|
+
# options to control outlining.
|
5
|
+
class OutlinePr
|
6
|
+
include Axlsx::OptionsParser
|
7
|
+
include Axlsx::Accessors
|
8
|
+
include Axlsx::SerializedAttributes
|
9
|
+
|
10
|
+
serializable_attributes :summary_below,
|
11
|
+
:summary_right,
|
12
|
+
:apply_styles
|
13
|
+
|
14
|
+
# These attributes are all boolean so I'm doing a bit of a hand
|
15
|
+
# waving magic show to set up the attriubte accessors
|
16
|
+
boolean_attr_accessor :summary_below,
|
17
|
+
:summary_right,
|
18
|
+
:apply_styles
|
19
|
+
|
20
|
+
# Creates a new OutlinePr object
|
21
|
+
# @param [Hash] options used to create the outline_pr
|
22
|
+
def initialize(options = {})
|
23
|
+
parse_options options
|
24
|
+
end
|
25
|
+
|
26
|
+
# Serialize the object
|
27
|
+
# @param [String] str serialized output will be appended to this object if provided.
|
28
|
+
# @return [String]
|
29
|
+
def to_xml_string(str = '')
|
30
|
+
str << "<outlinePr #{serialized_attributes} />"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -91,9 +91,7 @@ module Axlsx
|
|
91
91
|
# @note For compatibility, this is a noop unless custom margins have been specified.
|
92
92
|
# @see #custom_margins_specified?
|
93
93
|
def to_xml_string(str = '')
|
94
|
-
|
95
|
-
serialized_attributes str
|
96
|
-
str << '/>'
|
94
|
+
serialized_tag('pageMargins', str)
|
97
95
|
end
|
98
96
|
end
|
99
97
|
end
|
@@ -44,13 +44,13 @@ module Axlsx
|
|
44
44
|
|
45
45
|
# Number of horizontal pages to fit on.
|
46
46
|
# @note PageSetup#fit_to is the recomended way to manage page fitting as only specifying one of width/height will result in the counterpart
|
47
|
-
# being set to 1.
|
47
|
+
# being set to 1.
|
48
48
|
# @return [Integer]
|
49
49
|
attr_reader :fit_to_width
|
50
50
|
|
51
51
|
# Orientation of the page (:default, :landscape, :portrait)
|
52
52
|
# @return [Symbol]
|
53
|
-
attr_reader :orientation
|
53
|
+
attr_reader :orientation
|
54
54
|
|
55
55
|
# Height of paper (string containing a number followed by a unit identifier: "297mm", "11in")
|
56
56
|
# @return [String]
|
@@ -74,18 +74,18 @@ module Axlsx
|
|
74
74
|
#7 = Executive paper (7.25 in. by 10.5 in.)
|
75
75
|
#8 = A3 paper (297 mm by 420 mm)
|
76
76
|
#9 = A4 paper (210 mm by 297 mm)
|
77
|
-
#10 = A4 small paper (210 mm by 297 mm)
|
77
|
+
#10 = A4 small paper (210 mm by 297 mm)
|
78
78
|
#11 = A5 paper (148 mm by 210 mm)
|
79
79
|
#12 = B4 paper (250 mm by 353 mm)
|
80
80
|
#13 = B5 paper (176 mm by 250 mm)
|
81
81
|
#14 = Folio paper (8.5 in. by 13 in.)
|
82
|
-
#15 = Quarto paper (215 mm by 275 mm)
|
82
|
+
#15 = Quarto paper (215 mm by 275 mm)
|
83
83
|
#16 = Standard paper (10 in. by 14 in.)
|
84
84
|
#17 = Standard paper (11 in. by 17 in.)
|
85
85
|
#18 = Note paper (8.5 in. by 11 in.)
|
86
|
-
#19 = #9 envelope (3.875 in. by 8.875 in.)
|
87
|
-
#20 = #10 envelope (4.125 in. by 9.5 in.)
|
88
|
-
#21 = #11 envelope (4.5 in. by 10.375 in.)
|
86
|
+
#19 = #9 envelope (3.875 in. by 8.875 in.)
|
87
|
+
#20 = #10 envelope (4.125 in. by 9.5 in.)
|
88
|
+
#21 = #11 envelope (4.5 in. by 10.375 in.)
|
89
89
|
#22 = #12 envelope (4.75 in. by 11 in.)
|
90
90
|
#23 = #14 envelope (5 in. by 11.5 in.) 24 = C paper (17 in. by 22 in.)
|
91
91
|
#25 = D paper (22 in. by 34 in.)
|
@@ -105,7 +105,7 @@ module Axlsx
|
|
105
105
|
#40 = German standard fanfold (8.5 in. by 12 in.)
|
106
106
|
#41 = German legal fanfold (8.5 in. by 13 in.)
|
107
107
|
#42 = ISO B4 (250 mm by 353 mm)
|
108
|
-
#43 = Japanese double postcard (200 mm by 148 mm)
|
108
|
+
#43 = Japanese double postcard (200 mm by 148 mm)
|
109
109
|
#44 = Standard paper (9 in. by 11 in.)
|
110
110
|
#45 = Standard paper (10 in. by 11 in.)
|
111
111
|
#46 = Standard paper (15 in. by 11 in.)
|
@@ -116,9 +116,9 @@ module Axlsx
|
|
116
116
|
#53 = A4 extra paper (236 mm by 322 mm)
|
117
117
|
#54 = Letter transverse paper (8.275 in. by 11 in.)
|
118
118
|
#55 = A4 transverse paper (210 mm by 297 mm)
|
119
|
-
#56 = Letter extra transverse paper (9.275 in. by 12 in.)
|
120
|
-
#57 = SuperA/SuperA/A4 paper (227 mm by 356 mm)
|
121
|
-
#58 = SuperB/SuperB/A3 paper (305 mm by 487 mm)
|
119
|
+
#56 = Letter extra transverse paper (9.275 in. by 12 in.)
|
120
|
+
#57 = SuperA/SuperA/A4 paper (227 mm by 356 mm)
|
121
|
+
#58 = SuperB/SuperB/A3 paper (305 mm by 487 mm)
|
122
122
|
#59 = Letter plus paper (8.5 in. by 12.69 in.)
|
123
123
|
#60 = A4 plus paper (210 mm by 330 mm)
|
124
124
|
#61 = A5 transverse paper (148 mm by 210 mm)
|
@@ -128,8 +128,8 @@ module Axlsx
|
|
128
128
|
#65 = ISO B5 extra paper (201 mm by 276 mm)
|
129
129
|
#66 = A2 paper (420 mm by 594 mm)
|
130
130
|
#67 = A3 transverse paper (297 mm by 420 mm)
|
131
|
-
#68 = A3 extra transverse paper (322 mm by 445 mm)
|
132
|
-
#69 = Japanese Double Postcard (200 mm x 148 mm)
|
131
|
+
#68 = A3 extra transverse paper (322 mm by 445 mm)
|
132
|
+
#69 = Japanese Double Postcard (200 mm x 148 mm)
|
133
133
|
#70 = A6 (105 mm x 148 mm
|
134
134
|
#71 = Japanese Envelope Kaku #2
|
135
135
|
#72 = Japanese Envelope Kaku #3
|
@@ -142,7 +142,7 @@ module Axlsx
|
|
142
142
|
#79 = B4 (JIS) Rotated (364 mm x 257 mm)
|
143
143
|
#80 = B5 (JIS) Rotated (257 mm x 182 mm)
|
144
144
|
#81 = Japanese Postcard Rotated (148 mm x 100 mm)
|
145
|
-
#82 = Double Japanese Postcard Rotated (148 mm x 200 mm)
|
145
|
+
#82 = Double Japanese Postcard Rotated (148 mm x 200 mm)
|
146
146
|
#83 = A6 Rotated (148 mm x 105 mm)
|
147
147
|
#84 = Japanese Envelope Kaku #2 Rotated
|
148
148
|
#85 = Japanese Envelope Kaku #3 Rotated
|
@@ -210,20 +210,20 @@ module Axlsx
|
|
210
210
|
# @see scale
|
211
211
|
def scale=(v); Axlsx::validate_scale_10_400(v); @scale = v; end
|
212
212
|
|
213
|
-
# convenience method to achieve sanity when setting fit_to_width and fit_to_height
|
213
|
+
# convenience method to achieve sanity when setting fit_to_width and fit_to_height
|
214
214
|
# as they both default to 1 if only their counterpart is specified.
|
215
215
|
# @note This method will overwrite any value you explicitly set via the fit_to_height or fit_to_width methods.
|
216
|
-
# @option options [Integer] width The number of pages to fit this worksheet on horizontally. Default
|
217
|
-
# @option options [Integer] height The number of pages to fit this worksheet on vertically. Default
|
216
|
+
# @option options [Integer] width The number of pages to fit this worksheet on horizontally. Default 999
|
217
|
+
# @option options [Integer] height The number of pages to fit this worksheet on vertically. Default 999
|
218
218
|
def fit_to(options={})
|
219
|
-
self.fit_to_width = options[:width] ||
|
220
|
-
self.fit_to_height = options[:height] ||
|
219
|
+
self.fit_to_width = options[:width] || 999
|
220
|
+
self.fit_to_height = options[:height] || 999
|
221
221
|
[@fit_to_width, @fit_to_height]
|
222
222
|
end
|
223
223
|
|
224
224
|
|
225
225
|
# helper method for worksheet to determine if the page setup is configured for fit to page printing
|
226
|
-
# We treat any page set up that has a value set for fit_to_width or fit_to_height value as fit_to_page.
|
226
|
+
# We treat any page set up that has a value set for fit_to_width or fit_to_height value as fit_to_page.
|
227
227
|
# @return [Boolean]
|
228
228
|
def fit_to_page?
|
229
229
|
# is there some better what to express this?
|
@@ -234,9 +234,7 @@ module Axlsx
|
|
234
234
|
# @param [String] str
|
235
235
|
# @return [String]
|
236
236
|
def to_xml_string(str = '')
|
237
|
-
|
238
|
-
serialized_attributes str
|
239
|
-
str << '/>'
|
237
|
+
serialized_tag('pageSetup', str)
|
240
238
|
end
|
241
239
|
end
|
242
240
|
end
|
@@ -25,10 +25,20 @@ module Axlsx
|
|
25
25
|
@data = []
|
26
26
|
@pages = []
|
27
27
|
@subtotal = nil
|
28
|
+
@no_subtotals_on_headers = []
|
29
|
+
@style_info = {}
|
28
30
|
parse_options options
|
29
31
|
yield self if block_given?
|
30
32
|
end
|
31
33
|
|
34
|
+
# Defines the headers in which subtotals are not to be included
|
35
|
+
# @return[Array]
|
36
|
+
attr_accessor :no_subtotals_on_headers
|
37
|
+
|
38
|
+
# Style info for the pivot table
|
39
|
+
# @return[Hash]
|
40
|
+
attr_accessor :style_info
|
41
|
+
|
32
42
|
# The reference to the table data
|
33
43
|
# @return [String]
|
34
44
|
attr_reader :ref
|
@@ -159,23 +169,23 @@ module Axlsx
|
|
159
169
|
# @return [String]
|
160
170
|
def to_xml_string(str = '')
|
161
171
|
str << '<?xml version="1.0" encoding="UTF-8"?>'
|
162
|
-
str << '<pivotTableDefinition xmlns="' << XML_NS << '" name="' << name << '" cacheId="' << cache_definition.cache_id.to_s << '" dataOnRows="1" applyNumberFormats="0" applyBorderFormats="0" applyFontFormats="0" applyPatternFormats="0" applyAlignmentFormats="0" applyWidthHeightFormats="1" dataCaption="Data" showMultipleLabel="0" showMemberPropertyTips="0" useAutoFormatting="1" indent="0" compact="0" compactData="0" gridDropZones="1" multipleFieldFilters="0">'
|
163
|
-
str <<
|
164
|
-
str <<
|
172
|
+
str << ('<pivotTableDefinition xmlns="' << XML_NS << '" name="' << name << '" cacheId="' << cache_definition.cache_id.to_s << '" dataOnRows="1" applyNumberFormats="0" applyBorderFormats="0" applyFontFormats="0" applyPatternFormats="0" applyAlignmentFormats="0" applyWidthHeightFormats="1" dataCaption="Data" showMultipleLabel="0" showMemberPropertyTips="0" useAutoFormatting="1" indent="0" compact="0" compactData="0" gridDropZones="1" multipleFieldFilters="0">')
|
173
|
+
str << ('<location firstDataCol="1" firstDataRow="1" firstHeaderRow="1" ref="' << ref << '"/>')
|
174
|
+
str << ('<pivotFields count="' << header_cells_count.to_s << '">')
|
165
175
|
header_cell_values.each do |cell_value|
|
166
|
-
str <<
|
176
|
+
str << pivot_field_for(cell_value, !no_subtotals_on_headers.include?(cell_value))
|
167
177
|
end
|
168
|
-
str <<
|
178
|
+
str << '</pivotFields>'
|
169
179
|
if rows.empty?
|
170
180
|
str << '<rowFields count="1"><field x="-2"/></rowFields>'
|
171
181
|
str << '<rowItems count="2"><i><x/></i> <i i="1"><x v="1"/></i></rowItems>'
|
172
182
|
else
|
173
|
-
str << '<rowFields count="' << rows.size.to_s << '">'
|
183
|
+
str << ('<rowFields count="' << rows.size.to_s << '">')
|
174
184
|
rows.each do |row_value|
|
175
|
-
str << '<field x="' << header_index_of(row_value).to_s << '"/>'
|
185
|
+
str << ('<field x="' << header_index_of(row_value).to_s << '"/>')
|
176
186
|
end
|
177
187
|
str << '</rowFields>'
|
178
|
-
str << '<rowItems count="' << rows.size.to_s << '">'
|
188
|
+
str << ('<rowItems count="' << rows.size.to_s << '">')
|
179
189
|
rows.size.times do |i|
|
180
190
|
str << '<i/>'
|
181
191
|
end
|
@@ -184,28 +194,37 @@ module Axlsx
|
|
184
194
|
if columns.empty?
|
185
195
|
str << '<colItems count="1"><i/></colItems>'
|
186
196
|
else
|
187
|
-
str << '<colFields count="' << columns.size.to_s << '">'
|
197
|
+
str << ('<colFields count="' << columns.size.to_s << '">')
|
188
198
|
columns.each do |column_value|
|
189
|
-
str << '<field x="' << header_index_of(column_value).to_s << '"/>'
|
199
|
+
str << ('<field x="' << header_index_of(column_value).to_s << '"/>')
|
190
200
|
end
|
191
201
|
str << '</colFields>'
|
192
202
|
end
|
193
203
|
unless pages.empty?
|
194
|
-
str << '<pageFields count="' << pages.size.to_s << '">'
|
204
|
+
str << ('<pageFields count="' << pages.size.to_s << '">')
|
195
205
|
pages.each do |page_value|
|
196
|
-
str << '<pageField fld="' << header_index_of(page_value).to_s << '"/>'
|
206
|
+
str << ('<pageField fld="' << header_index_of(page_value).to_s << '"/>')
|
197
207
|
end
|
198
208
|
str << '</pageFields>'
|
199
209
|
end
|
200
210
|
unless data.empty?
|
201
211
|
str << "<dataFields count=\"#{data.size}\">"
|
202
212
|
data.each do |datum_value|
|
203
|
-
|
213
|
+
# The correct name prefix in ["Sum","Average", etc...]
|
214
|
+
str << "<dataField name='#{(datum_value[:subtotal]||'')} of #{datum_value[:ref]}' fld='#{header_index_of(datum_value[:ref])}' baseField='0' baseItem='0'"
|
204
215
|
str << " subtotal='#{datum_value[:subtotal]}' " if datum_value[:subtotal]
|
205
216
|
str << "/>"
|
206
217
|
end
|
207
218
|
str << '</dataFields>'
|
208
219
|
end
|
220
|
+
# custom pivot table style
|
221
|
+
unless style_info.empty?
|
222
|
+
str << '<pivotTableStyleInfo'
|
223
|
+
style_info.each do |k,v|
|
224
|
+
str << ' ' << k.to_s << '="' << v.to_s << '"'
|
225
|
+
end
|
226
|
+
str << ' />'
|
227
|
+
end
|
209
228
|
str << '</pivotTableDefinition>'
|
210
229
|
end
|
211
230
|
|
@@ -241,33 +260,30 @@ module Axlsx
|
|
241
260
|
|
242
261
|
private
|
243
262
|
|
244
|
-
def pivot_field_for(cell_ref)
|
263
|
+
def pivot_field_for(cell_ref, subtotal=true)
|
245
264
|
if rows.include? cell_ref
|
246
|
-
|
247
|
-
'<items count="1"><item t="default"/></items>'
|
248
|
-
|
265
|
+
if subtotal
|
266
|
+
'<pivotField axis="axisRow" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1"><items count="1"><item t="default"/></items></pivotField>'
|
267
|
+
else
|
268
|
+
'<pivotField axis="axisRow" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1" defaultSubtotal="0"></pivotField>'
|
269
|
+
end
|
249
270
|
elsif columns.include? cell_ref
|
250
|
-
'<pivotField axis="axisCol" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1">'
|
251
|
-
'<items count="1"><item t="default"/></items>' <<
|
252
|
-
'</pivotField>'
|
271
|
+
'<pivotField axis="axisCol" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1"><items count="1"><item t="default"/></items></pivotField>'
|
253
272
|
elsif pages.include? cell_ref
|
254
|
-
'<pivotField axis="
|
255
|
-
'<items count="1"><item t="default"/></items>' <<
|
256
|
-
'</pivotField>'
|
273
|
+
'<pivotField axis="axisPage" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1"><items count="1"><item t="default"/></items></pivotField>'
|
257
274
|
elsif data_refs.include? cell_ref
|
258
|
-
'<pivotField dataField="1" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1">'
|
259
|
-
'</pivotField>'
|
275
|
+
'<pivotField dataField="1" compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1"></pivotField>'
|
260
276
|
else
|
261
|
-
'<pivotField compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1">'
|
262
|
-
'</pivotField>'
|
277
|
+
'<pivotField compact="0" outline="0" subtotalTop="0" showAll="0" includeNewItemsInFilter="1"></pivotField>'
|
263
278
|
end
|
264
279
|
end
|
280
|
+
|
265
281
|
def data_refs
|
266
282
|
data.map { |hash| hash[:ref] }
|
267
283
|
end
|
284
|
+
|
268
285
|
def header_range
|
269
286
|
range.gsub(/^(\w+?)(\d+)\:(\w+?)\d+$/, '\1\2:\3\2')
|
270
287
|
end
|
271
|
-
|
272
288
|
end
|
273
289
|
end
|
@@ -47,13 +47,13 @@ module Axlsx
|
|
47
47
|
# @return [String]
|
48
48
|
def to_xml_string(str = '')
|
49
49
|
str << '<?xml version="1.0" encoding="UTF-8"?>'
|
50
|
-
str << '<pivotCacheDefinition xmlns="' << XML_NS << '" xmlns:r="' << XML_NS_R << '" invalid="1" refreshOnLoad="1" recordCount="0">'
|
50
|
+
str << ('<pivotCacheDefinition xmlns="' << XML_NS << '" xmlns:r="' << XML_NS_R << '" invalid="1" refreshOnLoad="1" recordCount="0">')
|
51
51
|
str << '<cacheSource type="worksheet">'
|
52
|
-
str <<
|
52
|
+
str << ( '<worksheetSource ref="' << pivot_table.range << '" sheet="' << pivot_table.data_sheet.name << '"/>')
|
53
53
|
str << '</cacheSource>'
|
54
|
-
str <<
|
54
|
+
str << ( '<cacheFields count="' << pivot_table.header_cells_count.to_s << '">')
|
55
55
|
pivot_table.header_cells.each do |cell|
|
56
|
-
str <<
|
56
|
+
str << ( '<cacheField name="' << cell.value << '" numFmtId="0">')
|
57
57
|
str << '<sharedItems count="0">'
|
58
58
|
str << '</sharedItems>'
|
59
59
|
str << '</cacheField>'
|
@@ -41,9 +41,7 @@ module Axlsx
|
|
41
41
|
# our output to that object. Use this - it helps limit the number of
|
42
42
|
# objects created during serialization
|
43
43
|
def to_xml_string(str="")
|
44
|
-
|
45
|
-
serialized_attributes str
|
46
|
-
str << '/>'
|
44
|
+
serialized_tag 'protectedRange', str
|
47
45
|
end
|
48
46
|
end
|
49
47
|
end
|