axlsx 1.0.17 → 1.1.0
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.
- data/CHANGELOG.md +11 -3
- data/README.md +159 -51
- data/examples/example.csv +1000 -0
- data/examples/example.rb +255 -150
- data/examples/example.xlsx +0 -0
- data/examples/example_streamed.xlsx +0 -0
- data/examples/no-use_autowidth.xlsx +0 -0
- data/examples/shared_strings_example.xlsx +0 -0
- data/lib/axlsx/content_type/content_type.rb +12 -12
- data/lib/axlsx/content_type/default.rb +9 -6
- data/lib/axlsx/content_type/override.rb +12 -8
- data/lib/axlsx/doc_props/app.rb +37 -40
- data/lib/axlsx/doc_props/core.rb +12 -17
- data/lib/axlsx/drawing/axis.rb +38 -19
- data/lib/axlsx/drawing/bar_3D_chart.rb +33 -32
- data/lib/axlsx/drawing/bar_series.rb +13 -14
- data/lib/axlsx/drawing/cat_axis.rb +15 -14
- data/lib/axlsx/drawing/cat_axis_data.rb +16 -18
- data/lib/axlsx/drawing/chart.rb +39 -40
- data/lib/axlsx/drawing/drawing.rb +15 -12
- data/lib/axlsx/drawing/graphic_frame.rb +21 -21
- data/lib/axlsx/drawing/hyperlink.rb +12 -11
- data/lib/axlsx/drawing/line_3D_chart.rb +30 -28
- data/lib/axlsx/drawing/line_series.rb +11 -11
- data/lib/axlsx/drawing/marker.rb +10 -8
- data/lib/axlsx/drawing/named_axis_data.rb +36 -0
- data/lib/axlsx/drawing/one_cell_anchor.rb +17 -16
- data/lib/axlsx/drawing/pic.rb +25 -37
- data/lib/axlsx/drawing/picture_locking.rb +21 -18
- data/lib/axlsx/drawing/pie_3D_chart.rb +10 -8
- data/lib/axlsx/drawing/pie_series.rb +15 -12
- data/lib/axlsx/drawing/scaling.rb +10 -10
- data/lib/axlsx/drawing/scatter_chart.rb +69 -0
- data/lib/axlsx/drawing/scatter_series.rb +39 -0
- data/lib/axlsx/drawing/ser_axis.rb +10 -10
- data/lib/axlsx/drawing/series.rb +15 -15
- data/lib/axlsx/drawing/series_title.rb +14 -14
- data/lib/axlsx/drawing/title.rb +26 -26
- data/lib/axlsx/drawing/two_cell_anchor.rb +18 -20
- data/lib/axlsx/drawing/val_axis.rb +8 -7
- data/lib/axlsx/drawing/val_axis_data.rb +17 -17
- data/lib/axlsx/drawing/view_3D.rb +22 -20
- data/lib/axlsx/package.rb +60 -43
- data/lib/axlsx/rels/relationship.rb +11 -8
- data/lib/axlsx/rels/relationships.rb +7 -1
- data/lib/axlsx/stylesheet/#num_fmt.rb# +69 -0
- data/lib/axlsx/stylesheet/border.rb +27 -23
- data/lib/axlsx/stylesheet/border_pr.rb +16 -15
- data/lib/axlsx/stylesheet/cell_alignment.rb +23 -21
- data/lib/axlsx/stylesheet/cell_protection.rb +10 -7
- data/lib/axlsx/stylesheet/cell_style.rb +8 -5
- data/lib/axlsx/stylesheet/color.rb +20 -14
- data/lib/axlsx/stylesheet/fill.rb +7 -5
- data/lib/axlsx/stylesheet/font.rb +21 -14
- data/lib/axlsx/stylesheet/gradient_fill.rb +19 -16
- data/lib/axlsx/stylesheet/gradient_stop.rb +9 -5
- data/lib/axlsx/stylesheet/num_fmt.rb +12 -6
- data/lib/axlsx/stylesheet/pattern_fill.rb +25 -10
- data/lib/axlsx/stylesheet/styles.rb +47 -35
- data/lib/axlsx/stylesheet/table_style.rb +9 -4
- data/lib/axlsx/stylesheet/table_style_element.rb +10 -7
- data/lib/axlsx/stylesheet/table_styles.rb +11 -8
- data/lib/axlsx/stylesheet/xf.rb +29 -25
- data/lib/axlsx/util/constants.rb +20 -14
- data/lib/axlsx/util/simple_typed_list.rb +18 -9
- data/lib/axlsx/util/validators.rb +13 -6
- data/lib/axlsx/version.rb +1 -1
- data/lib/axlsx/workbook/shared_strings_table.rb +19 -21
- data/lib/axlsx/workbook/workbook.rb +58 -34
- data/lib/axlsx/workbook/worksheet/cell.rb +149 -132
- data/lib/axlsx/workbook/worksheet/col.rb +114 -0
- data/lib/axlsx/workbook/worksheet/col.rb~ +0 -0
- data/lib/axlsx/workbook/worksheet/date_time_converter.rb +29 -0
- data/lib/axlsx/workbook/worksheet/page_margins.rb +97 -0
- data/lib/axlsx/workbook/worksheet/row.rb +40 -23
- data/lib/axlsx/workbook/worksheet/table.rb +96 -0
- data/lib/axlsx/workbook/worksheet/table.rb~ +97 -0
- data/lib/axlsx/workbook/worksheet/worksheet.rb +243 -127
- data/lib/axlsx.rb +30 -9
- data/lib/schema/dc.xsd +5 -5
- data/lib/schema/dcmitype.xsd +5 -3
- data/lib/schema/dcterms.xsd +15 -15
- data/lib/schema/opc-coreProperties.xsd +6 -2
- data/lib/schema/xml.xsd +7 -8
- data/test/#benchmark.txt# +7 -0
- data/test/#tc_helper.rb# +3 -0
- data/test/benchmark.rb +81 -0
- data/test/benchmark.rb~ +0 -0
- data/test/benchmark.txt +6 -0
- data/test/benchmark.txt~ +6 -0
- data/test/content_type/tc_content_type.rb +30 -32
- data/test/content_type/tc_default.rb +8 -23
- data/test/content_type/tc_override.rb +7 -21
- data/test/doc_props/tc_app.rb +2 -8
- data/test/doc_props/tc_core.rb +6 -7
- data/test/drawing/tc_axis.rb +7 -3
- data/test/drawing/tc_bar_3D_chart.rb +6 -7
- data/test/drawing/tc_bar_series.rb +4 -5
- data/test/drawing/tc_cat_axis.rb +2 -3
- data/test/drawing/tc_cat_axis_data.rb +2 -3
- data/test/drawing/tc_chart.rb +13 -14
- data/test/drawing/tc_drawing.rb +7 -8
- data/test/drawing/tc_graphic_frame.rb +3 -4
- data/test/drawing/tc_hyperlink.rb +2 -3
- data/test/drawing/tc_line_3d_chart.rb +5 -6
- data/test/drawing/tc_line_series.rb +3 -4
- data/test/drawing/tc_marker.rb +3 -4
- data/test/drawing/tc_one_cell_anchor.rb +6 -7
- data/test/drawing/tc_pic.rb +8 -9
- data/test/drawing/tc_picture_locking.rb +2 -3
- data/test/drawing/tc_pie_3D_chart.rb +5 -6
- data/test/drawing/tc_pie_series.rb +4 -5
- data/test/drawing/tc_scaling.rb +3 -4
- data/test/drawing/tc_scatter_chart.rb +43 -0
- data/test/drawing/tc_scatter_series.rb +20 -0
- data/test/drawing/tc_ser_axis.rb +2 -3
- data/test/drawing/tc_series.rb +4 -5
- data/test/drawing/tc_series_title.rb +4 -5
- data/test/drawing/tc_title.rb +4 -5
- data/test/drawing/tc_two_cell_anchor.rb +4 -5
- data/test/drawing/tc_val_axis.rb +2 -3
- data/test/drawing/tc_val_axis_data.rb +2 -3
- data/test/drawing/tc_view_3D.rb +6 -7
- data/test/example.csv +1000 -0
- data/test/example.xlsx +0 -0
- data/test/example_streamed.xlsx +0 -0
- data/test/profile.rb +33 -0
- data/test/rels/tc_relationship.rb +5 -6
- data/test/rels/tc_relationships.rb +4 -5
- data/test/stylesheet/tc_border.rb +3 -4
- data/test/stylesheet/tc_border_pr.rb +3 -4
- data/test/stylesheet/tc_cell_alignment.rb +10 -6
- data/test/stylesheet/tc_cell_protection.rb +2 -3
- data/test/stylesheet/tc_cell_style.rb +2 -3
- data/test/stylesheet/tc_color.rb +2 -3
- data/test/stylesheet/tc_fill.rb +1 -2
- data/test/stylesheet/tc_font.rb +12 -5
- data/test/stylesheet/tc_gradient_fill.rb +1 -2
- data/test/stylesheet/tc_gradient_stop.rb +1 -2
- data/test/stylesheet/tc_num_fmt.rb +1 -2
- data/test/stylesheet/tc_pattern_fill.rb +3 -4
- data/test/stylesheet/tc_styles.rb +16 -6
- data/test/stylesheet/tc_table_style.rb +2 -3
- data/test/stylesheet/tc_table_style_element.rb +2 -3
- data/test/stylesheet/tc_table_styles.rb +3 -4
- data/test/stylesheet/tc_xf.rb +16 -17
- data/test/tc_axlsx.rb +39 -0
- data/test/tc_axlsx.rb~ +0 -0
- data/test/tc_helper.rb +3 -0
- data/test/tc_helper.rb~ +3 -0
- data/test/tc_package.rb +13 -10
- data/test/util/tc_simple_typed_list.rb +8 -9
- data/test/util/tc_validators.rb +7 -8
- data/test/workbook/tc_shared_strings_table.rb +5 -6
- data/test/workbook/tc_workbook.rb +24 -6
- data/test/workbook/worksheet/table/tc_table.rb +71 -0
- data/test/workbook/worksheet/table/tc_table.rb~ +72 -0
- data/test/workbook/worksheet/tc_cell.rb +62 -18
- data/test/workbook/worksheet/tc_col.rb +59 -0
- data/test/workbook/worksheet/tc_col.rb~ +10 -0
- data/test/workbook/worksheet/tc_date_time_converter.rb +126 -0
- data/test/workbook/worksheet/tc_page_margins.rb +97 -0
- data/test/workbook/worksheet/tc_row.rb +54 -4
- data/test/workbook/worksheet/tc_worksheet.rb +177 -34
- metadata +69 -41
- data/test/drawing/tc_hyperlink.rb~ +0 -71
- data/test/workbook/tc_shared_strings_table.rb~ +0 -8
|
@@ -26,7 +26,7 @@ module Axlsx
|
|
|
26
26
|
attr_reader :drawing
|
|
27
27
|
|
|
28
28
|
|
|
29
|
-
# Creates a new TwoCellAnchor object and sets up a reference to the from and to markers in the
|
|
29
|
+
# Creates a new TwoCellAnchor object and sets up a reference to the from and to markers in the
|
|
30
30
|
# graphic_frame's chart. That means that you can do stuff like
|
|
31
31
|
# c = worksheet.add_chart Axlsx::Chart
|
|
32
32
|
# c.start_at 5, 9
|
|
@@ -38,13 +38,13 @@ module Axlsx
|
|
|
38
38
|
# @option options [Array] end_at the col, row to end at
|
|
39
39
|
def initialize(drawing, options={})
|
|
40
40
|
@drawing = drawing
|
|
41
|
-
drawing.anchors << self
|
|
41
|
+
drawing.anchors << self
|
|
42
42
|
@from, @to = Marker.new, Marker.new(:col => 5, :row=>10)
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
# Creates a graphic frame and chart object associated with this anchor
|
|
46
46
|
# @return [Chart]
|
|
47
|
-
def add_chart(chart_type, options)
|
|
47
|
+
def add_chart(chart_type, options)
|
|
48
48
|
@object = GraphicFrame.new(self, chart_type, options)
|
|
49
49
|
@object.chart
|
|
50
50
|
end
|
|
@@ -54,24 +54,22 @@ module Axlsx
|
|
|
54
54
|
def index
|
|
55
55
|
@drawing.anchors.index(self)
|
|
56
56
|
end
|
|
57
|
-
# Serializes the two cell anchor
|
|
58
|
-
# @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
|
|
59
|
-
# @return [String]
|
|
60
|
-
def to_xml(xml)
|
|
61
|
-
#build it for now, break it down later!
|
|
62
|
-
xml[:xdr].twoCellAnchor {
|
|
63
|
-
xml.from {
|
|
64
|
-
from.to_xml(xml)
|
|
65
|
-
}
|
|
66
|
-
xml.to {
|
|
67
|
-
to.to_xml(xml)
|
|
68
|
-
}
|
|
69
|
-
@object.to_xml(xml)
|
|
70
|
-
xml.clientData
|
|
71
|
-
}
|
|
72
|
-
end
|
|
73
57
|
|
|
74
|
-
|
|
58
|
+
# Serializes the object
|
|
59
|
+
# @param [String] str
|
|
60
|
+
# @return [String]
|
|
61
|
+
def to_xml_string(str = '')
|
|
62
|
+
str << '<xdr:twoCellAnchor>'
|
|
63
|
+
str << '<xdr:from>'
|
|
64
|
+
from.to_xml_string str
|
|
65
|
+
str << '</xdr:from>'
|
|
66
|
+
str << '<xdr:to>'
|
|
67
|
+
to.to_xml_string str
|
|
68
|
+
str << '</xdr:to>'
|
|
69
|
+
object.to_xml_string(str)
|
|
70
|
+
str << '<xdr:clientData/>'
|
|
71
|
+
str << '</xdr:twoCellAnchor>'
|
|
72
|
+
end
|
|
75
73
|
|
|
76
74
|
end
|
|
77
75
|
end
|
|
@@ -22,14 +22,15 @@ module Axlsx
|
|
|
22
22
|
# @see crossBetween
|
|
23
23
|
def crossBetween=(v) RestrictionValidator.validate "ValAxis.crossBetween", [:between, :midCat], v; @crossBetween = v; end
|
|
24
24
|
|
|
25
|
-
# Serializes the
|
|
26
|
-
# @param [
|
|
25
|
+
# Serializes the object
|
|
26
|
+
# @param [String] str
|
|
27
27
|
# @return [String]
|
|
28
|
-
def
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
def to_xml_string(str = '')
|
|
29
|
+
str << '<c:valAx>'
|
|
30
|
+
super(str)
|
|
31
|
+
str << '<c:crossBetween val="' << @crossBetween.to_s << '"/>'
|
|
32
|
+
str << '</c:valAx>'
|
|
33
33
|
end
|
|
34
|
+
|
|
34
35
|
end
|
|
35
36
|
end
|
|
@@ -3,25 +3,25 @@ module Axlsx
|
|
|
3
3
|
# The ValAxisData class manages the values for a chart value series.
|
|
4
4
|
class ValAxisData < CatAxisData
|
|
5
5
|
|
|
6
|
-
# Serializes the
|
|
7
|
-
# @param [
|
|
6
|
+
# Serializes the object
|
|
7
|
+
# @param [String] str
|
|
8
8
|
# @return [String]
|
|
9
|
-
def
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
9
|
+
def to_xml_string(str = '')
|
|
10
|
+
str << '<c:val>'
|
|
11
|
+
str << '<c:numRef>'
|
|
12
|
+
str << '<c:f>' << Axlsx::cell_range(@list) << '</c:f>'
|
|
13
|
+
str << '<c:numCache>'
|
|
14
|
+
str << '<c:formatCode>General</c:formatCode>'
|
|
15
|
+
str << '<c:ptCount val="' << size.to_s << '"/>'
|
|
16
|
+
each_with_index do |item, index|
|
|
17
|
+
v = item.is_a?(Cell) ? item.value.to_s : item
|
|
18
|
+
str << '<c:pt idx="' << index.to_s << '"><c:v>' << v << '</c:v></c:pt>'
|
|
19
|
+
end
|
|
20
|
+
str << '</c:numCache>'
|
|
21
|
+
str << '</c:numRef>'
|
|
22
|
+
str << '</c:val>'
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
end
|
|
26
|
-
|
|
26
|
+
|
|
27
27
|
end
|
|
@@ -5,34 +5,34 @@ module Axlsx
|
|
|
5
5
|
|
|
6
6
|
# Validation for hPercent
|
|
7
7
|
H_PERCENT_REGEX = /0*(([5-9])|([1-9][0-9])|([1-4][0-9][0-9])|500)%/
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
# validation for depthPercent
|
|
10
10
|
DEPTH_PERCENT_REGEX = /0*(([2-9][0-9])|([1-9][0-9][0-9])|(1[0-9][0-9][0-9])|2000)%/
|
|
11
11
|
|
|
12
|
-
# x rotation for the chart
|
|
12
|
+
# x rotation for the chart
|
|
13
13
|
# must be between -90 and 90
|
|
14
14
|
# @return [Integer]
|
|
15
15
|
attr_reader :rotX
|
|
16
|
-
|
|
16
|
+
|
|
17
17
|
# height of chart as % of chart
|
|
18
18
|
# must be between 5% and 500%
|
|
19
19
|
# @return [String]
|
|
20
20
|
attr_reader :hPercent
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
# y rotation for the chart
|
|
23
23
|
# must be between 0 and 360
|
|
24
24
|
# @return [Integer]
|
|
25
25
|
attr_reader :rotY
|
|
26
|
-
|
|
26
|
+
|
|
27
27
|
# depth or chart as % of chart width
|
|
28
28
|
# must be between 20% and 2000%
|
|
29
29
|
# @return [String]
|
|
30
30
|
attr_reader :depthPercent
|
|
31
|
-
|
|
31
|
+
|
|
32
32
|
# Chart axis are at right angles
|
|
33
33
|
# @return [Boolean]
|
|
34
34
|
attr_reader :rAngAx
|
|
35
|
-
|
|
35
|
+
|
|
36
36
|
# field of view angle
|
|
37
37
|
# @return [Integer]
|
|
38
38
|
attr_reader :perspective
|
|
@@ -45,10 +45,10 @@ module Axlsx
|
|
|
45
45
|
# @option options [Boolean] rAngAx
|
|
46
46
|
# @option options [Integer] perspective
|
|
47
47
|
def initialize(options={})
|
|
48
|
-
@rotX, @hPercent, @rotY, @depthPercent, @rAngAx, @perspective = nil, nil, nil, nil, nil, nil
|
|
48
|
+
@rotX, @hPercent, @rotY, @depthPercent, @rAngAx, @perspective = nil, nil, nil, nil, nil, nil
|
|
49
49
|
options.each do |o|
|
|
50
50
|
self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
|
|
51
|
-
end
|
|
51
|
+
end
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
# @see rotX
|
|
@@ -69,18 +69,20 @@ module Axlsx
|
|
|
69
69
|
# @see perspective
|
|
70
70
|
def perspective=(v) DataTypeValidator.validate "#{self.class}.perspective", [Integer, Fixnum], v, lambda {|arg| arg >= 0 && arg <= 240 }; @perspective = v; end
|
|
71
71
|
|
|
72
|
-
|
|
73
|
-
#
|
|
72
|
+
|
|
73
|
+
# Serializes the object
|
|
74
|
+
# @param [String] str
|
|
74
75
|
# @return [String]
|
|
75
|
-
def
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
76
|
+
def to_xml_string(str = '')
|
|
77
|
+
str << '<c:view3D>'
|
|
78
|
+
str << '<c:rotX val="' << @rotX.to_s << '"/>' unless @rotX.nil?
|
|
79
|
+
str << '<c:hPercent val="' << @hPercent.to_s << '"/>' unless @hPercent.nil?
|
|
80
|
+
str << '<c:rotY val="' << @rotY.to_s << '"/>' unless @rotY.nil?
|
|
81
|
+
str << '<c:depthPercent val="' << @depthPercent.to_s << '"/>' unless @depthPercent.nil?
|
|
82
|
+
str << '<c:rAngAx val="' << @rAngAx.to_s << '"/>' unless @rAngAx.nil?
|
|
83
|
+
str << '<c:perspective val="' << @perspective.to_s << '"/>' unless @perspective.nil?
|
|
84
|
+
str << '</c:view3D>'
|
|
84
85
|
end
|
|
86
|
+
|
|
85
87
|
end
|
|
86
88
|
end
|
data/lib/axlsx/package.rb
CHANGED
|
@@ -4,7 +4,7 @@ module Axlsx
|
|
|
4
4
|
# xlsx document including valdation and serialization.
|
|
5
5
|
class Package
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
|
|
8
8
|
# provides access to the app doc properties for this package
|
|
9
9
|
# see App
|
|
10
10
|
attr_reader :app
|
|
@@ -29,10 +29,18 @@ module Axlsx
|
|
|
29
29
|
yield self if block_given?
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
+
# Shortcut to specify that the workbook should use autowidth
|
|
33
|
+
# @see Workbook#use_autowidth
|
|
34
|
+
def use_autowidth=(v)
|
|
35
|
+
Axlsx::validate_boolean(v);
|
|
36
|
+
workbook.use_autowidth = v
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
|
|
32
40
|
# Shortcut to specify that the workbook should use shared strings
|
|
33
41
|
# @see Workbook#use_shared_strings
|
|
34
|
-
def use_shared_strings=(v)
|
|
35
|
-
Axlsx::validate_boolean(v);
|
|
42
|
+
def use_shared_strings=(v)
|
|
43
|
+
Axlsx::validate_boolean(v);
|
|
36
44
|
workbook.use_shared_strings = v
|
|
37
45
|
end
|
|
38
46
|
|
|
@@ -45,7 +53,7 @@ module Axlsx
|
|
|
45
53
|
# The workbook this package will serialize or validate.
|
|
46
54
|
# @return [Workbook] If no workbook instance has been assigned with this package a new Workbook instance is returned.
|
|
47
55
|
# @raise ArgumentError if workbook parameter is not a Workbook instance.
|
|
48
|
-
# @note As there are multiple ways to instantiate a workbook for the package,
|
|
56
|
+
# @note As there are multiple ways to instantiate a workbook for the package,
|
|
49
57
|
# here are a few examples:
|
|
50
58
|
# # assign directly during package instanciation
|
|
51
59
|
# wb = Package.new(:workbook => Workbook.new).workbook
|
|
@@ -59,13 +67,13 @@ module Axlsx
|
|
|
59
67
|
yield @workbook if block_given?
|
|
60
68
|
@workbook
|
|
61
69
|
end
|
|
62
|
-
|
|
70
|
+
|
|
63
71
|
#def self.parse(input, confirm_valid = false)
|
|
64
72
|
# p = Package.new
|
|
65
73
|
# z = Zip::ZipFile.open(input)
|
|
66
74
|
# p.workbook = Workbook.parse z.get_entry(WORKBOOK_PN)
|
|
67
75
|
# p
|
|
68
|
-
#end
|
|
76
|
+
#end
|
|
69
77
|
|
|
70
78
|
# @see workbook
|
|
71
79
|
def workbook=(workbook) DataTypeValidator.validate "Package.workbook", Workbook, workbook; @workbook = workbook; end
|
|
@@ -77,7 +85,7 @@ module Axlsx
|
|
|
77
85
|
# @option options stream indicates if we should be writing to a stream or a file. True for stream, nil for file
|
|
78
86
|
# @return [Boolean] False if confirm_valid and validation errors exist. True if the package was serialized
|
|
79
87
|
# @note A tremendous amount of effort has gone into ensuring that you cannot create invalid xlsx documents.
|
|
80
|
-
# confirm_valid should be used in the rare case that you cannot open the serialized file.
|
|
88
|
+
# confirm_valid should be used in the rare case that you cannot open the serialized file.
|
|
81
89
|
# @see Package#validate
|
|
82
90
|
# @example
|
|
83
91
|
# # This is how easy it is to create a valid xlsx file. Of course you might want to add a sheet or two, and maybe some data, styles and charts.
|
|
@@ -105,20 +113,20 @@ module Axlsx
|
|
|
105
113
|
stream.rewind
|
|
106
114
|
stream
|
|
107
115
|
end
|
|
108
|
-
|
|
116
|
+
|
|
109
117
|
# Encrypt the package into a CFB using the password provided
|
|
110
118
|
# This is not ready yet
|
|
111
|
-
def encrypt(file_name, password)
|
|
119
|
+
def encrypt(file_name, password)
|
|
112
120
|
return false
|
|
113
|
-
moc = MsOffCrypto.new(file_name, password)
|
|
114
|
-
moc.save
|
|
121
|
+
# moc = MsOffCrypto.new(file_name, password)
|
|
122
|
+
# moc.save
|
|
115
123
|
end
|
|
116
|
-
|
|
117
|
-
# Validate all parts of the package against xsd schema.
|
|
124
|
+
|
|
125
|
+
# Validate all parts of the package against xsd schema.
|
|
118
126
|
# @return [Array] An array of all validation errors found.
|
|
119
127
|
# @note This gem includes all schema from OfficeOpenXML-XMLSchema-Transitional.zip and OpenPackagingConventions-XMLSchema.zip
|
|
120
128
|
# as per ECMA-376, Third edition. opc schema require an internet connection to import remote schema from dublin core for dc,
|
|
121
|
-
# dcterms and xml namespaces. Those remote schema are included in this gem, and the original files have been altered to
|
|
129
|
+
# dcterms and xml namespaces. Those remote schema are included in this gem, and the original files have been altered to
|
|
122
130
|
# refer to the local versions.
|
|
123
131
|
#
|
|
124
132
|
# If by chance you are able to creat a package that does not validate it indicates that the internal
|
|
@@ -131,65 +139,71 @@ module Axlsx
|
|
|
131
139
|
# p.validate.each { |error| puts error.message }
|
|
132
140
|
def validate
|
|
133
141
|
errors = []
|
|
134
|
-
parts.each
|
|
142
|
+
parts.each do |part|
|
|
143
|
+
errors.concat validate_single_doc(part[:schema], part[:doc]) unless part[:schema].nil?
|
|
144
|
+
end
|
|
135
145
|
errors
|
|
136
146
|
end
|
|
137
147
|
|
|
138
|
-
private
|
|
148
|
+
private
|
|
139
149
|
|
|
140
150
|
# Writes the package parts to a zip archive.
|
|
141
151
|
# @param [Zip::ZipOutputStream] zip
|
|
142
152
|
# @return [Zip::ZipOutputStream]
|
|
143
153
|
def write_parts(zip)
|
|
144
154
|
p = parts
|
|
145
|
-
p.each do |part|
|
|
155
|
+
p.each do |part|
|
|
146
156
|
unless part[:doc].nil?
|
|
147
157
|
zip.put_next_entry(part[:entry]);
|
|
148
158
|
entry = ['1.9.2', '1.9.3'].include?(RUBY_VERSION) ? part[:doc].force_encoding('BINARY') : part[:doc]
|
|
149
159
|
zip.puts(entry)
|
|
150
160
|
end
|
|
151
161
|
unless part[:path].nil?
|
|
152
|
-
zip.put_next_entry(part[:entry]);
|
|
162
|
+
zip.put_next_entry(part[:entry]);
|
|
153
163
|
# binread for 1.9.3
|
|
154
164
|
zip.write IO.respond_to?(:binread) ? IO.binread(part[:path]) : IO.read(part[:path])
|
|
155
|
-
end
|
|
165
|
+
end
|
|
156
166
|
end
|
|
157
167
|
zip
|
|
158
168
|
end
|
|
159
169
|
|
|
160
170
|
# The parts of a package
|
|
161
|
-
# @return [Array] An array of hashes that define the entry, document and schema for each part of the package.
|
|
171
|
+
# @return [Array] An array of hashes that define the entry, document and schema for each part of the package.
|
|
162
172
|
# @private
|
|
163
173
|
def parts
|
|
164
174
|
@parts = [
|
|
165
|
-
{:entry => RELS_PN, :doc => relationships.
|
|
166
|
-
{:entry => "xl/#{STYLES_PN}", :doc => workbook.styles.
|
|
167
|
-
{:entry => CORE_PN, :doc => @core.
|
|
168
|
-
{:entry => APP_PN, :doc => @app.
|
|
169
|
-
{:entry => WORKBOOK_RELS_PN, :doc => workbook.relationships.
|
|
170
|
-
{:entry => CONTENT_TYPES_PN, :doc => content_types.
|
|
171
|
-
{:entry => WORKBOOK_PN, :doc => workbook.
|
|
175
|
+
{:entry => RELS_PN, :doc => relationships.to_xml_string, :schema => RELS_XSD},
|
|
176
|
+
{:entry => "xl/#{STYLES_PN}", :doc => workbook.styles.to_xml_string, :schema => SML_XSD},
|
|
177
|
+
{:entry => CORE_PN, :doc => @core.to_xml_string, :schema => CORE_XSD},
|
|
178
|
+
{:entry => APP_PN, :doc => @app.to_xml_string, :schema => APP_XSD},
|
|
179
|
+
{:entry => WORKBOOK_RELS_PN, :doc => workbook.relationships.to_xml_string, :schema => RELS_XSD},
|
|
180
|
+
{:entry => CONTENT_TYPES_PN, :doc => content_types.to_xml_string, :schema => CONTENT_TYPES_XSD},
|
|
181
|
+
{:entry => WORKBOOK_PN, :doc => workbook.to_xml_string, :schema => SML_XSD}
|
|
172
182
|
]
|
|
173
183
|
workbook.drawings.each do |drawing|
|
|
174
|
-
@parts << {:entry => "xl/#{drawing.rels_pn}", :doc => drawing.relationships.
|
|
175
|
-
@parts << {:entry => "xl/#{drawing.pn}", :doc => drawing.
|
|
184
|
+
@parts << {:entry => "xl/#{drawing.rels_pn}", :doc => drawing.relationships.to_xml_string, :schema => RELS_XSD}
|
|
185
|
+
@parts << {:entry => "xl/#{drawing.pn}", :doc => drawing.to_xml_string, :schema => DRAWING_XSD}
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
workbook.tables.each do |table|
|
|
189
|
+
@parts << {:entry => "xl/#{table.pn}", :doc => table.to_xml_string, :schema => SML_XSD}
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
workbook.charts.each do |chart|
|
|
193
|
+
@parts << {:entry => "xl/#{chart.pn}", :doc => chart.to_xml_string, :schema => DRAWING_XSD}
|
|
176
194
|
end
|
|
177
|
-
|
|
178
|
-
workbook.charts.each do |chart|
|
|
179
|
-
@parts << {:entry => "xl/#{chart.pn}", :doc => chart.to_xml, :schema => DRAWING_XSD}
|
|
180
|
-
end
|
|
181
195
|
|
|
182
196
|
workbook.images.each do |image|
|
|
183
197
|
@parts << {:entry => "xl/#{image.pn}", :path => image.image_src}
|
|
184
198
|
end
|
|
185
199
|
|
|
186
200
|
if use_shared_strings
|
|
187
|
-
@parts << {:entry => "xl/#{SHARED_STRINGS_PN}", :doc => workbook.shared_strings.
|
|
201
|
+
@parts << {:entry => "xl/#{SHARED_STRINGS_PN}", :doc => workbook.shared_strings.to_xml_string, :schema => SML_XSD}
|
|
188
202
|
end
|
|
189
203
|
|
|
190
|
-
workbook.worksheets.each do |sheet|
|
|
191
|
-
@parts << {:entry => "xl/#{sheet.rels_pn}", :doc => sheet.relationships.
|
|
192
|
-
@parts << {:entry => "xl/#{sheet.pn}", :doc => sheet.
|
|
204
|
+
workbook.worksheets.each do |sheet|
|
|
205
|
+
@parts << {:entry => "xl/#{sheet.rels_pn}", :doc => sheet.relationships.to_xml_string, :schema => RELS_XSD}
|
|
206
|
+
@parts << {:entry => "xl/#{sheet.pn}", :doc => sheet.to_xml_string, :schema => SML_XSD}
|
|
193
207
|
end
|
|
194
208
|
@parts
|
|
195
209
|
end
|
|
@@ -203,7 +217,6 @@ module Axlsx
|
|
|
203
217
|
def validate_single_doc(schema, doc)
|
|
204
218
|
schema = Nokogiri::XML::Schema(File.open(schema))
|
|
205
219
|
doc = Nokogiri::XML(doc)
|
|
206
|
-
|
|
207
220
|
errors = []
|
|
208
221
|
schema.validate(doc).each do |error|
|
|
209
222
|
errors << error
|
|
@@ -217,15 +230,19 @@ module Axlsx
|
|
|
217
230
|
def content_types
|
|
218
231
|
c_types = base_content_types
|
|
219
232
|
workbook.drawings.each do |drawing|
|
|
220
|
-
c_types << Axlsx::Override.new(:PartName => "/xl/#{drawing.pn}",
|
|
233
|
+
c_types << Axlsx::Override.new(:PartName => "/xl/#{drawing.pn}",
|
|
221
234
|
:ContentType => DRAWING_CT)
|
|
222
235
|
end
|
|
223
236
|
workbook.charts.each do |chart|
|
|
224
|
-
c_types << Axlsx::Override.new(:PartName => "/xl/#{chart.pn}",
|
|
225
|
-
:ContentType => CHART_CT)
|
|
237
|
+
c_types << Axlsx::Override.new(:PartName => "/xl/#{chart.pn}",
|
|
238
|
+
:ContentType => CHART_CT)
|
|
239
|
+
end
|
|
240
|
+
workbook.tables.each do |table|
|
|
241
|
+
c_types << Axlsx::Override.new(:PartName => "/xl/#{table.pn}",
|
|
242
|
+
:ContentType => TABLE_CT)
|
|
226
243
|
end
|
|
227
244
|
workbook.worksheets.each do |sheet|
|
|
228
|
-
c_types << Axlsx::Override.new(:PartName => "/xl/#{sheet.pn}",
|
|
245
|
+
c_types << Axlsx::Override.new(:PartName => "/xl/#{sheet.pn}",
|
|
229
246
|
:ContentType => WORKSHEET_CT)
|
|
230
247
|
end
|
|
231
248
|
exts = workbook.images.map { |image| image.extname }
|
|
@@ -256,7 +273,7 @@ module Axlsx
|
|
|
256
273
|
c_types << Override.new(:PartName => "/#{APP_PN}", :ContentType => APP_CT)
|
|
257
274
|
c_types << Override.new(:PartName => "/#{CORE_PN}", :ContentType => CORE_CT)
|
|
258
275
|
c_types << Override.new(:PartName => "/xl/#{STYLES_PN}", :ContentType => STYLES_CT)
|
|
259
|
-
c_types << Axlsx::Override.new(:PartName => "/#{WORKBOOK_PN}", :ContentType => WORKBOOK_CT)
|
|
276
|
+
c_types << Axlsx::Override.new(:PartName => "/#{WORKBOOK_PN}", :ContentType => WORKBOOK_CT)
|
|
260
277
|
c_types.lock
|
|
261
278
|
c_types
|
|
262
279
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# encoding: UTF-8
|
|
2
2
|
module Axlsx
|
|
3
3
|
# A relationship defines a reference between package parts.
|
|
4
|
-
# @note Packages
|
|
4
|
+
# @note Packages automatically manage relationships.
|
|
5
5
|
class Relationship
|
|
6
6
|
|
|
7
7
|
# The location of the relationship target
|
|
@@ -32,7 +32,7 @@ module Axlsx
|
|
|
32
32
|
# creates a new relationship
|
|
33
33
|
# @param [String] Type The type of the relationship
|
|
34
34
|
# @param [String] Target The target for the relationship
|
|
35
|
-
# @option [Symbol] target_mode only accepts :external.
|
|
35
|
+
# @option [Symbol] target_mode only accepts :external.
|
|
36
36
|
def initialize(type, target, options={})
|
|
37
37
|
self.Target=target
|
|
38
38
|
self.Type=type
|
|
@@ -47,14 +47,17 @@ module Axlsx
|
|
|
47
47
|
# @see TargetMode
|
|
48
48
|
def TargetMode=(v) RestrictionValidator.validate 'Relationship.TargetMode', [:External, :Internal], v; @TargetMode = v; end
|
|
49
49
|
|
|
50
|
-
#
|
|
51
|
-
# @param [
|
|
52
|
-
# @param [
|
|
50
|
+
# serialize relationship
|
|
51
|
+
# @param [String] str
|
|
52
|
+
# @param [Integer] rId the id for this relationship
|
|
53
53
|
# @return [String]
|
|
54
|
-
def
|
|
54
|
+
def to_xml_string(rId, str = '')
|
|
55
55
|
h = self.instance_values
|
|
56
|
-
h[:Id] = rId
|
|
57
|
-
|
|
56
|
+
h[:Id] = 'rId' << rId.to_s
|
|
57
|
+
str << '<Relationship '
|
|
58
|
+
str << h.map { |key, value| '' << key.to_s << '="' << value.to_s << '"'}.join(' ')
|
|
59
|
+
str << '/>'
|
|
58
60
|
end
|
|
61
|
+
|
|
59
62
|
end
|
|
60
63
|
end
|
|
@@ -11,6 +11,12 @@ require 'axlsx/rels/relationship.rb'
|
|
|
11
11
|
super Relationship
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
+
def to_xml_string(str = '')
|
|
15
|
+
str << '<?xml version="1.0" encoding="UTF-8"?>'
|
|
16
|
+
str << '<Relationships xmlns="' << RELS_R << '">'
|
|
17
|
+
each_with_index { |rel, index| rel.to_xml_string(index+1, str) }
|
|
18
|
+
str << '</Relationships>'
|
|
19
|
+
end
|
|
14
20
|
# Serializes the relationships document.
|
|
15
21
|
# @return [String]
|
|
16
22
|
def to_xml()
|
|
@@ -21,6 +27,6 @@ require 'axlsx/rels/relationship.rb'
|
|
|
21
27
|
end
|
|
22
28
|
builder.to_xml(:save_with => 0)
|
|
23
29
|
end
|
|
24
|
-
|
|
30
|
+
|
|
25
31
|
end
|
|
26
32
|
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
module Axlsx
|
|
3
|
+
# A NumFmt object defines an identifier and formatting code for data in cells.
|
|
4
|
+
# @note The recommended way to manage styles is Styles#add_style
|
|
5
|
+
class NumFmt
|
|
6
|
+
# @return [Integer] An unsinged integer referencing a standard or custom number format.
|
|
7
|
+
# @note
|
|
8
|
+
# These are the known formats I can dig up. The constant NUM_FMT_PERCENT is 9, and uses the default % formatting. Axlsx also defines a few formats for date and time that are commonly used in asia as NUM_FMT_YYYYMMDD and NUM_FRM_YYYYMMDDHHMMSS.
|
|
9
|
+
# 1 0
|
|
10
|
+
# 2 0.00
|
|
11
|
+
# 3 #,##0
|
|
12
|
+
# 4 #,##0.00
|
|
13
|
+
# 5 $#,##0_);($#,##0)
|
|
14
|
+
# 6 $#,##0_);[Red]($#,##0)
|
|
15
|
+
# 7 $#,##0.00_);($#,##0.00)
|
|
16
|
+
# 8 $#,##0.00_);[Red]($#,##0.00)
|
|
17
|
+
# 9 0%
|
|
18
|
+
# 10 0.00%
|
|
19
|
+
# 11 0.00E+00
|
|
20
|
+
# 12 # ?/?
|
|
21
|
+
# 13 # ??/??
|
|
22
|
+
# 14 m/d/yyyy
|
|
23
|
+
# 15 d-mmm-yy
|
|
24
|
+
# 16 d-mmm
|
|
25
|
+
# 17 mmm-yy
|
|
26
|
+
# 18 h:mm AM/PM
|
|
27
|
+
# 19 h:mm:ss AM/PM
|
|
28
|
+
# 20 h:mm
|
|
29
|
+
# 21 h:mm:ss
|
|
30
|
+
# 22 m/d/yyyy h:mm
|
|
31
|
+
# 37 #,##0_);(#,##0)
|
|
32
|
+
# 38 #,##0_);[Red](#,##0)
|
|
33
|
+
# 39 #,##0.00_);(#,##0.00)
|
|
34
|
+
# 40 #,##0.00_);[Red](#,##0.00)
|
|
35
|
+
# 45 mm:ss
|
|
36
|
+
# 46 [h]:mm:ss
|
|
37
|
+
# 47 mm:ss.0
|
|
38
|
+
# 48 ##0.0E+0
|
|
39
|
+
# 49 @
|
|
40
|
+
# @see Axlsx
|
|
41
|
+
attr_reader :numFmtId
|
|
42
|
+
|
|
43
|
+
# @return [String] The formatting to use for this number format.
|
|
44
|
+
# @see http://support.microsoft.com/kb/264372
|
|
45
|
+
attr_reader :formatCode
|
|
46
|
+
def initialize(options={})
|
|
47
|
+
@numFmtId = 0
|
|
48
|
+
@formatCode = ""
|
|
49
|
+
options.each do |o|
|
|
50
|
+
self.send("#{o[0]}=", o[1]) if self.respond_to? o[0]
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# @see numFmtId
|
|
55
|
+
def numFmtId=(v) Axlsx::validate_unsigned_int v; @numFmtId = v end
|
|
56
|
+
# @see formatCode
|
|
57
|
+
def formatCode=(v) Axlsx::validate_string v; @formatCode = v end
|
|
58
|
+
|
|
59
|
+
# Serializes the object
|
|
60
|
+
# @param [String] str
|
|
61
|
+
# @return [String]
|
|
62
|
+
def to_xml_string(str = '')
|
|
63
|
+
str << '<numFmt '
|
|
64
|
+
str << instance_values.map { |key, value| '' << key.to_s << '="' << value.to_s << '"' }.join(' ')
|
|
65
|
+
str << '/>'
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -3,38 +3,37 @@ module Axlsx
|
|
|
3
3
|
# This class details a border used in Office Open XML spreadsheet styles.
|
|
4
4
|
class Border
|
|
5
5
|
|
|
6
|
-
# @return [Boolean] The diagonal up property for the border that indicates if the border should include a diagonal line from the bottom left to the top right of the cell.
|
|
6
|
+
# @return [Boolean] The diagonal up property for the border that indicates if the border should include a diagonal line from the bottom left to the top right of the cell.
|
|
7
7
|
attr_reader :diagonalUp
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
# @return [Boolean] The diagonal down property for the border that indicates if the border should include a diagonal line from the top left to the top right of the cell.
|
|
10
10
|
attr_reader :diagonalDown
|
|
11
11
|
|
|
12
12
|
# @return [Boolean] The outline property for the border indicating that top, left, right and bottom borders should only be applied to the outside border of a range of cells.
|
|
13
13
|
attr_reader :outline
|
|
14
14
|
|
|
15
|
-
# @return [SimpleTypedList] A list of BorderPr objects for this border.
|
|
15
|
+
# @return [SimpleTypedList] A list of BorderPr objects for this border.
|
|
16
16
|
attr_reader :prs
|
|
17
17
|
|
|
18
18
|
# Creates a new Border object
|
|
19
19
|
# @option options [Boolean] diagonalUp
|
|
20
20
|
# @option options [Boolean] diagonalDown
|
|
21
21
|
# @option options [Boolean] outline
|
|
22
|
-
# @example Making a border
|
|
23
|
-
# p = Package.new
|
|
24
|
-
# red_border =
|
|
25
|
-
#
|
|
26
|
-
#
|
|
27
|
-
#
|
|
28
|
-
#
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
# p.workbook.add_worksheet.rows << :values=>[1,2,3] :style=>red_border
|
|
22
|
+
# @example - Making a border
|
|
23
|
+
# p = Axlsx::Package.new
|
|
24
|
+
# red_border = p.workbook.styles.add_style :border => { :style => :thin, :color => "FFFF0000" }
|
|
25
|
+
# ws = p.workbook.add_worksheet
|
|
26
|
+
# ws.add_row [1,2,3], :style => red_border
|
|
27
|
+
# p.serialize('red_border.xlsx')
|
|
28
|
+
#
|
|
29
|
+
# @note The recommended way to manage borders is with Style#add_style
|
|
30
|
+
# @see Style#add_style
|
|
32
31
|
def initialize(options={})
|
|
33
32
|
@prs = SimpleTypedList.new BorderPr
|
|
34
33
|
options.each do |o|
|
|
35
34
|
self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
|
|
36
35
|
end
|
|
37
|
-
end
|
|
36
|
+
end
|
|
38
37
|
|
|
39
38
|
# @see diagonalUp
|
|
40
39
|
def diagonalUp=(v) Axlsx::validate_boolean v; @diagonalUp = v end
|
|
@@ -43,16 +42,21 @@ module Axlsx
|
|
|
43
42
|
# @see outline
|
|
44
43
|
def outline=(v) Axlsx::validate_boolean v; @outline = v end
|
|
45
44
|
|
|
46
|
-
# Serializes the
|
|
47
|
-
# @param [
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
45
|
+
# Serializes the object
|
|
46
|
+
# @param [String] str
|
|
47
|
+
# @return [String]
|
|
48
|
+
def to_xml_string(str = '')
|
|
49
|
+
str << '<border '
|
|
50
|
+
h = self.instance_values.select{ |k,v| [:diagonalUp, :diagonalDown, :outline].include? k }
|
|
51
|
+
str << h.map { |key, value| '' << key.to_s << '="' << value.to_s << '"' }.join(' ')
|
|
52
|
+
str << '>'
|
|
53
|
+
[:start, :end, :left, :right, :top, :bottom, :diagonal, :vertical, :horizontal].each do |k|
|
|
54
|
+
@prs.select { |pr| pr.name == k }.each do |part|
|
|
55
|
+
part.to_xml_string(str)
|
|
54
56
|
end
|
|
55
|
-
|
|
57
|
+
end
|
|
58
|
+
str << '</border>'
|
|
56
59
|
end
|
|
60
|
+
|
|
57
61
|
end
|
|
58
62
|
end
|