axlsx 1.0.11 → 1.0.12
Sign up to get free protection for your applications and to get access to all the features.
- data/.yardopts +4 -0
- data/README.md +7 -4
- data/examples/example.rb +6 -4
- data/examples/example.rb~ +112 -0
- data/lib/schema/dc.xsd~ +118 -0
- data/lib/schema/dcterms.xsd~ +331 -0
- data/lib/schema/opc-coreProperties.xsd~ +50 -0
- metadata +43 -193
- data/Gemfile +0 -3
- data/Gemfile.lock +0 -29
- data/axlsx.gemspec +0 -42
- data/doc/Axlsx.html +0 -2718
- data/doc/Axlsx/App.html +0 -2640
- data/doc/Axlsx/Axis.html +0 -1075
- data/doc/Axlsx/Bar3DChart.html +0 -1182
- data/doc/Axlsx/BarSeries.html +0 -711
- data/doc/Axlsx/Border.html +0 -779
- data/doc/Axlsx/BorderPr.html +0 -709
- data/doc/Axlsx/CatAxis.html +0 -769
- data/doc/Axlsx/CatAxisData.html +0 -397
- data/doc/Axlsx/Cell.html +0 -3187
- data/doc/Axlsx/CellAlignment.html +0 -1247
- data/doc/Axlsx/CellProtection.html +0 -565
- data/doc/Axlsx/CellStyle.html +0 -949
- data/doc/Axlsx/Chart.html +0 -1692
- data/doc/Axlsx/Color.html +0 -670
- data/doc/Axlsx/ContentType.html +0 -335
- data/doc/Axlsx/Core.html +0 -465
- data/doc/Axlsx/DataTypeValidator.html +0 -324
- data/doc/Axlsx/Default.html +0 -565
- data/doc/Axlsx/Drawing.html +0 -1264
- data/doc/Axlsx/Fill.html +0 -460
- data/doc/Axlsx/Font.html +0 -1554
- data/doc/Axlsx/GradientFill.html +0 -1026
- data/doc/Axlsx/GradientStop.html +0 -526
- data/doc/Axlsx/GraphicFrame.html +0 -642
- data/doc/Axlsx/Line3DChart.html +0 -1004
- data/doc/Axlsx/LineSeries.html +0 -605
- data/doc/Axlsx/Marker.html +0 -857
- data/doc/Axlsx/NumFmt.html +0 -562
- data/doc/Axlsx/OneCellAnchor.html +0 -982
- data/doc/Axlsx/Override.html +0 -552
- data/doc/Axlsx/Package.html +0 -825
- data/doc/Axlsx/Parser.html +0 -549
- data/doc/Axlsx/PatternFill.html +0 -681
- data/doc/Axlsx/Pic.html +0 -1701
- data/doc/Axlsx/PictureLocking.html +0 -1159
- data/doc/Axlsx/Pie3DChart.html +0 -489
- data/doc/Axlsx/PieSeries.html +0 -710
- data/doc/Axlsx/RegexValidator.html +0 -268
- data/doc/Axlsx/Relationship.html +0 -554
- data/doc/Axlsx/Relationships.html +0 -338
- data/doc/Axlsx/RestrictionValidator.html +0 -300
- data/doc/Axlsx/Row.html +0 -916
- data/doc/Axlsx/Scaling.html +0 -742
- data/doc/Axlsx/SerAxis.html +0 -641
- data/doc/Axlsx/Series.html +0 -813
- data/doc/Axlsx/SeriesTitle.html +0 -290
- data/doc/Axlsx/Styles.html +0 -1754
- data/doc/Axlsx/TableStyle.html +0 -705
- data/doc/Axlsx/TableStyleElement.html +0 -677
- data/doc/Axlsx/TableStyles.html +0 -594
- data/doc/Axlsx/Title.html +0 -543
- data/doc/Axlsx/TwoCellAnchor.html +0 -973
- data/doc/Axlsx/ValAxis.html +0 -538
- data/doc/Axlsx/ValAxisData.html +0 -321
- data/doc/Axlsx/View3D.html +0 -973
- data/doc/Axlsx/Workbook.html +0 -1630
- data/doc/Axlsx/Worksheet.html +0 -2682
- data/doc/Axlsx/Xf.html +0 -1780
- data/doc/_index.html +0 -649
- data/doc/class_list.html +0 -47
- data/doc/css/common.css +0 -1
- data/doc/css/full_list.css +0 -55
- data/doc/css/style.css +0 -322
- data/doc/file.LICENSE.html +0 -91
- data/doc/file.README.html +0 -338
- data/doc/file_list.html +0 -52
- data/doc/frames.html +0 -13
- data/doc/index.html +0 -338
- data/doc/js/app.js +0 -205
- data/doc/js/full_list.js +0 -167
- data/doc/js/jquery.js +0 -16
- data/doc/method_list.html +0 -3502
- data/doc/top-level-namespace.html +0 -103
- data/lib/axlsx.rb +0 -54
- data/lib/axlsx/content_type/content_type.rb +0 -23
- data/lib/axlsx/content_type/default.rb +0 -37
- data/lib/axlsx/content_type/override.rb +0 -37
- data/lib/axlsx/doc_props/app.rb +0 -178
- data/lib/axlsx/doc_props/core.rb +0 -34
- data/lib/axlsx/drawing/axis.rb +0 -90
- data/lib/axlsx/drawing/bar_3D_chart.rb +0 -128
- data/lib/axlsx/drawing/bar_series.rb +0 -64
- data/lib/axlsx/drawing/cat_axis.rb +0 -63
- data/lib/axlsx/drawing/cat_axis_data.rb +0 -35
- data/lib/axlsx/drawing/chart.rb +0 -179
- data/lib/axlsx/drawing/drawing.rb +0 -137
- data/lib/axlsx/drawing/graphic_frame.rb +0 -52
- data/lib/axlsx/drawing/line_3D_chart.rb +0 -106
- data/lib/axlsx/drawing/line_series.rb +0 -46
- data/lib/axlsx/drawing/marker.rb +0 -61
- data/lib/axlsx/drawing/one_cell_anchor.rb +0 -89
- data/lib/axlsx/drawing/pic.rb +0 -153
- data/lib/axlsx/drawing/picture_locking.rb +0 -72
- data/lib/axlsx/drawing/pie_3D_chart.rb +0 -41
- data/lib/axlsx/drawing/pie_series.rb +0 -56
- data/lib/axlsx/drawing/scaling.rb +0 -59
- data/lib/axlsx/drawing/ser_axis.rb +0 -45
- data/lib/axlsx/drawing/series.rb +0 -71
- data/lib/axlsx/drawing/series_title.rb +0 -22
- data/lib/axlsx/drawing/title.rb +0 -61
- data/lib/axlsx/drawing/two_cell_anchor.rb +0 -76
- data/lib/axlsx/drawing/val_axis.rb +0 -34
- data/lib/axlsx/drawing/val_axis_data.rb +0 -28
- data/lib/axlsx/drawing/view_3D.rb +0 -85
- data/lib/axlsx/package.rb +0 -214
- data/lib/axlsx/rels/relationship.rb +0 -44
- data/lib/axlsx/rels/relationships.rb +0 -25
- data/lib/axlsx/stylesheet/border.rb +0 -57
- data/lib/axlsx/stylesheet/border_pr.rb +0 -68
- data/lib/axlsx/stylesheet/cell_alignment.rb +0 -105
- data/lib/axlsx/stylesheet/cell_protection.rb +0 -36
- data/lib/axlsx/stylesheet/cell_style.rb +0 -65
- data/lib/axlsx/stylesheet/color.rb +0 -69
- data/lib/axlsx/stylesheet/fill.rb +0 -32
- data/lib/axlsx/stylesheet/font.rb +0 -139
- data/lib/axlsx/stylesheet/gradient_fill.rb +0 -76
- data/lib/axlsx/stylesheet/gradient_stop.rb +0 -33
- data/lib/axlsx/stylesheet/num_fmt.rb +0 -63
- data/lib/axlsx/stylesheet/pattern_fill.rb +0 -66
- data/lib/axlsx/stylesheet/styles.rb +0 -298
- data/lib/axlsx/stylesheet/table_style.rb +0 -47
- data/lib/axlsx/stylesheet/table_style_element.rb +0 -71
- data/lib/axlsx/stylesheet/table_styles.rb +0 -39
- data/lib/axlsx/stylesheet/xf.rb +0 -138
- data/lib/axlsx/util/constants.rb +0 -216
- data/lib/axlsx/util/parser.rb +0 -43
- data/lib/axlsx/util/simple_typed_list.rb +0 -160
- data/lib/axlsx/util/validators.rb +0 -132
- data/lib/axlsx/version.rb +0 -4
- data/lib/axlsx/workbook/workbook.rb +0 -160
- data/lib/axlsx/workbook/worksheet/cell.rb +0 -340
- data/lib/axlsx/workbook/worksheet/row.rb +0 -107
- data/lib/axlsx/workbook/worksheet/worksheet.rb +0 -278
@@ -1,22 +0,0 @@
|
|
1
|
-
module Axlsx
|
2
|
-
# A series title is a Title with a slightly different serialization than chart titles.
|
3
|
-
class SeriesTitle < Title
|
4
|
-
|
5
|
-
# Serializes the series title
|
6
|
-
# @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
|
7
|
-
# @return [String]
|
8
|
-
def to_xml(xml)
|
9
|
-
xml.send('c:tx') {
|
10
|
-
xml.send('c:strRef') {
|
11
|
-
xml.send('c:f', Axlsx::cell_range([@cell]))
|
12
|
-
xml.send('c:strCache') {
|
13
|
-
xml.send('c:ptCount', :val=>1)
|
14
|
-
xml.send('c:pt', :idx=>0) {
|
15
|
-
xml.send('c:v', @text)
|
16
|
-
}
|
17
|
-
}
|
18
|
-
}
|
19
|
-
}
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
data/lib/axlsx/drawing/title.rb
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
module Axlsx
|
2
|
-
# A Title stores information about the title of a chart
|
3
|
-
class Title
|
4
|
-
|
5
|
-
# The text to be shown. Setting this property directly with a string will remove the cell reference.
|
6
|
-
# @return [String]
|
7
|
-
attr_reader :text
|
8
|
-
|
9
|
-
# The cell that holds the text for the title. Setting this property will automatically update the text attribute.
|
10
|
-
# @return [Cell]
|
11
|
-
attr_reader :cell
|
12
|
-
|
13
|
-
# Creates a new Title object
|
14
|
-
# @param [String, Cell] title The cell or string to be used for the chart's title
|
15
|
-
def initialize(title="")
|
16
|
-
self.cell = title if title.is_a?(Cell)
|
17
|
-
self.text = title.to_s unless title.is_a?(Cell)
|
18
|
-
end
|
19
|
-
|
20
|
-
# @see text
|
21
|
-
def text=(v)
|
22
|
-
DataTypeValidator.validate 'Title.text', String, v
|
23
|
-
@text = v
|
24
|
-
@cell = nil
|
25
|
-
v
|
26
|
-
end
|
27
|
-
|
28
|
-
# @see cell
|
29
|
-
def cell=(v)
|
30
|
-
DataTypeValidator.validate 'Title.text', Cell, v
|
31
|
-
@cell = v
|
32
|
-
@text = v.value.to_s
|
33
|
-
v
|
34
|
-
end
|
35
|
-
|
36
|
-
# Not implemented at this time.
|
37
|
-
#def layout=(v) DataTypeValidator.validate 'Title.layout', Layout, v; @layout = v; end
|
38
|
-
#def overlay=(v) Axlsx::validate_boolean v; @overlay=v; end
|
39
|
-
#def spPr=(v) DataTypeValidator.validate 'Title.spPr', SpPr, v; @spPr = v; end
|
40
|
-
|
41
|
-
# Serializes the chart title
|
42
|
-
# @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
|
43
|
-
# @return [String]
|
44
|
-
def to_xml(xml)
|
45
|
-
xml.send('c:title') {
|
46
|
-
xml.send('c:tx') {
|
47
|
-
xml.send('c:strRef') {
|
48
|
-
xml.send('c:f', Axlsx::cell_range([@cell]))
|
49
|
-
xml.send('c:strCache') {
|
50
|
-
xml.send('c:ptCount', :val=>1)
|
51
|
-
xml.send('c:pt', :idx=>0) {
|
52
|
-
xml.send('c:v', @text)
|
53
|
-
}
|
54
|
-
}
|
55
|
-
}
|
56
|
-
}
|
57
|
-
}
|
58
|
-
end
|
59
|
-
|
60
|
-
end
|
61
|
-
end
|
@@ -1,76 +0,0 @@
|
|
1
|
-
module Axlsx
|
2
|
-
# This class details the anchor points for drawings.
|
3
|
-
# @note The recommended way to manage drawings and charts is Worksheet#add_chart. Anchors are specified by the :start_at and :end_at options to that method.
|
4
|
-
# @see Worksheet#add_chart
|
5
|
-
class TwoCellAnchor
|
6
|
-
|
7
|
-
# A marker that defines the from cell anchor. The default from column and row are 0 and 0 respectively
|
8
|
-
# @return [Marker]
|
9
|
-
attr_reader :from
|
10
|
-
# A marker that returns the to cell anchor. The default to column and row are 5 and 10 respectively
|
11
|
-
# @return [Marker]
|
12
|
-
attr_reader :to
|
13
|
-
|
14
|
-
# The frame for your chart
|
15
|
-
# @note this will be discontinued in version 2.0 please use object
|
16
|
-
# @return [GraphicFrame]
|
17
|
-
# attr_reader :graphic_frame
|
18
|
-
|
19
|
-
# The object this anchor hosts
|
20
|
-
# @return [Pic, GraphicFrame]
|
21
|
-
attr_reader :object
|
22
|
-
|
23
|
-
# The drawing that holds this anchor
|
24
|
-
# @return [Drawing]
|
25
|
-
attr_reader :drawing
|
26
|
-
|
27
|
-
|
28
|
-
# Creates a new TwoCellAnchor object and sets up a reference to the from and to markers in the
|
29
|
-
# graphic_frame's chart. That means that you can do stuff like
|
30
|
-
# c = worksheet.add_chart Axlsx::Chart
|
31
|
-
# c.start_at 5, 9
|
32
|
-
# @note the chart_type parameter will be replaced with object in v. 2.0.0
|
33
|
-
# @param [Drawing] drawing
|
34
|
-
# @param [Class] chart_type This is passed to the graphic frame for instantiation. must be Chart or a subclass of Chart
|
35
|
-
# @param object The object this anchor holds.
|
36
|
-
# @option options [Array] start_at the col, row to start at
|
37
|
-
# @option options [Array] end_at the col, row to end at
|
38
|
-
def initialize(drawing, options={})
|
39
|
-
@drawing = drawing
|
40
|
-
drawing.anchors << self
|
41
|
-
@from, @to = Marker.new, Marker.new(:col => 5, :row=>10)
|
42
|
-
end
|
43
|
-
|
44
|
-
# Creates a graphic frame and chart object associated with this anchor
|
45
|
-
# @return [Chart]
|
46
|
-
def add_chart(chart_type, options)
|
47
|
-
@object = GraphicFrame.new(self, chart_type, options)
|
48
|
-
@object.chart
|
49
|
-
end
|
50
|
-
|
51
|
-
# The index of this anchor in the drawing
|
52
|
-
# @return [Integer]
|
53
|
-
def index
|
54
|
-
@drawing.anchors.index(self)
|
55
|
-
end
|
56
|
-
# Serializes the two cell anchor
|
57
|
-
# @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
|
58
|
-
# @return [String]
|
59
|
-
def to_xml(xml)
|
60
|
-
#build it for now, break it down later!
|
61
|
-
xml.send('xdr:twoCellAnchor') {
|
62
|
-
xml.send('xdr:from') {
|
63
|
-
from.to_xml(xml)
|
64
|
-
}
|
65
|
-
xml.send('xdr:to') {
|
66
|
-
to.to_xml(xml)
|
67
|
-
}
|
68
|
-
@object.to_xml(xml)
|
69
|
-
xml.send('xdr:clientData')
|
70
|
-
}
|
71
|
-
end
|
72
|
-
|
73
|
-
private
|
74
|
-
|
75
|
-
end
|
76
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
module Axlsx
|
2
|
-
# the ValAxis class defines a chart value axis.
|
3
|
-
class ValAxis < Axis
|
4
|
-
|
5
|
-
# This element specifies how the value axis crosses the category axis.
|
6
|
-
# must be one of [:between, :midCat]
|
7
|
-
# @return [Symbol]
|
8
|
-
attr_reader :crossBetween
|
9
|
-
|
10
|
-
# Creates a new ValAxis object
|
11
|
-
# @param [Integer] axId the id of this axis
|
12
|
-
# @param [Integer] crossAx the id of the perpendicular axis
|
13
|
-
# @option options [Symbol] axPos
|
14
|
-
# @option options [Symbol] tickLblPos
|
15
|
-
# @option options [Symbol] crosses
|
16
|
-
# @option options [Symbol] crossesBetween
|
17
|
-
def initialize(axId, crossAx, options={})
|
18
|
-
self.crossBetween = :between
|
19
|
-
super(axId, crossAx, options)
|
20
|
-
end
|
21
|
-
# @see crossBetween
|
22
|
-
def crossBetween=(v) RestrictionValidator.validate "ValAxis.crossBetween", [:between, :midCat], v; @crossBetween = v; end
|
23
|
-
|
24
|
-
# Serializes the value axis
|
25
|
-
# @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
|
26
|
-
# @return [String]
|
27
|
-
def to_xml(xml)
|
28
|
-
xml.send('c:valAx') {
|
29
|
-
super(xml)
|
30
|
-
xml.send('c:crossBetween', :val=>@crossBetween)
|
31
|
-
}
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
module Axlsx
|
2
|
-
# The ValAxisData class manages the values for a chart value series.
|
3
|
-
class ValAxisData < CatAxisData
|
4
|
-
|
5
|
-
# Serializes the value axis data
|
6
|
-
# @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
|
7
|
-
# @return [String]
|
8
|
-
def to_xml(xml)
|
9
|
-
xml.send('c:val') {
|
10
|
-
xml.send('c:numRef') {
|
11
|
-
xml.send('c:f', Axlsx::cell_range(@list))
|
12
|
-
xml.send('c:numCache') {
|
13
|
-
xml.send('c:formatCode', 'General')
|
14
|
-
xml.send('c:ptCount', :val=>size)
|
15
|
-
each_with_index do |item, index|
|
16
|
-
v = item.is_a?(Cell) ? item.value : item
|
17
|
-
xml.send('c:pt', :idx=>index) {
|
18
|
-
xml.send('c:v', v)
|
19
|
-
}
|
20
|
-
end
|
21
|
-
}
|
22
|
-
}
|
23
|
-
}
|
24
|
-
end
|
25
|
-
|
26
|
-
end
|
27
|
-
|
28
|
-
end
|
@@ -1,85 +0,0 @@
|
|
1
|
-
module Axlsx
|
2
|
-
# 3D attributes for a chart.
|
3
|
-
class View3D
|
4
|
-
|
5
|
-
# Validation for hPercent
|
6
|
-
H_PERCENT_REGEX = /0*(([5-9])|([1-9][0-9])|([1-4][0-9][0-9])|500)%/
|
7
|
-
|
8
|
-
# validation for depthPercent
|
9
|
-
DEPTH_PERCENT_REGEX = /0*(([2-9][0-9])|([1-9][0-9][0-9])|(1[0-9][0-9][0-9])|2000)%/
|
10
|
-
|
11
|
-
# x rotation for the chart
|
12
|
-
# must be between -90 and 90
|
13
|
-
# @return [Integer]
|
14
|
-
attr_reader :rotX
|
15
|
-
|
16
|
-
# height of chart as % of chart
|
17
|
-
# must be between 5% and 500%
|
18
|
-
# @return [String]
|
19
|
-
attr_reader :hPercent
|
20
|
-
|
21
|
-
# y rotation for the chart
|
22
|
-
# must be between 0 and 360
|
23
|
-
# @return [Integer]
|
24
|
-
attr_reader :rotY
|
25
|
-
|
26
|
-
# depth or chart as % of chart width
|
27
|
-
# must be between 20% and 2000%
|
28
|
-
# @return [String]
|
29
|
-
attr_reader :depthPercent
|
30
|
-
|
31
|
-
# Chart axis are at right angles
|
32
|
-
# @return [Boolean]
|
33
|
-
attr_reader :rAngAx
|
34
|
-
|
35
|
-
# field of view angle
|
36
|
-
# @return [Integer]
|
37
|
-
attr_reader :perspective
|
38
|
-
|
39
|
-
# Creates a new View3D for charts
|
40
|
-
# @option options [Integer] rotX
|
41
|
-
# @option options [String] hPercent
|
42
|
-
# @option options [Integer] rotY
|
43
|
-
# @option options [String] depthPercent
|
44
|
-
# @option options [Boolean] rAngAx
|
45
|
-
# @option options [Integer] perspective
|
46
|
-
def initialize(options={})
|
47
|
-
@rotX, @hPercent, @rotY, @depthPercent, @rAngAx, @perspective = nil, nil, nil, nil, nil, nil
|
48
|
-
options.each do |o|
|
49
|
-
self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
# @see rotX
|
54
|
-
def rotX=(v) DataTypeValidator.validate "#{self.class}.rotX", [Integer, Fixnum], v, lambda {|arg| arg >= -90 && arg <= 90 }; @rotX = v; end
|
55
|
-
|
56
|
-
# @see hPercent
|
57
|
-
def hPercent=(v) RegexValidator.validate "#{self.class}.rotX", H_PERCENT_REGEX, v; @hPercent = v; end
|
58
|
-
|
59
|
-
# @see rotY
|
60
|
-
def rotY=(v) DataTypeValidator.validate "#{self.class}.rotY", [Integer, Fixnum], v, lambda {|arg| arg >= 0 && arg <= 360 }; @rotY = v; end
|
61
|
-
|
62
|
-
# @see depthPercent
|
63
|
-
def depthPercent=(v) RegexValidator.validate "#{self.class}.depthPercent", DEPTH_PERCENT_REGEX, v; @depthPercent = v; end
|
64
|
-
|
65
|
-
# @see rAngAx
|
66
|
-
def rAngAx=(v) Axlsx::validate_boolean(v); @rAngAx = v; end
|
67
|
-
|
68
|
-
# @see perspective
|
69
|
-
def perspective=(v) DataTypeValidator.validate "#{self.class}.perspective", [Integer, Fixnum], v, lambda {|arg| arg >= 0 && arg <= 240 }; @perspective = v; end
|
70
|
-
|
71
|
-
# Serializes the view3D properties
|
72
|
-
# @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
|
73
|
-
# @return [String]
|
74
|
-
def to_xml(xml)
|
75
|
-
xml.send('c:view3D') {
|
76
|
-
xml.send('c:rotX', :val=>@rotX) unless @rotX.nil?
|
77
|
-
xml.send('c:hPercent', :val=>@hPercent) unless @hPercent.nil?
|
78
|
-
xml.send('c:rotY', :val=>@rotY) unless @rotY.nil?
|
79
|
-
xml.send('c:depthPercent', :val=>@depthPercent) unless @depthPercent.nil?
|
80
|
-
xml.send('c:rAngAx', :val=>@rAngAx) unless @rAngAx.nil?
|
81
|
-
xml.send('c:perspective', :val=>@perspective) unless @perspective.nil?
|
82
|
-
}
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
data/lib/axlsx/package.rb
DELETED
@@ -1,214 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
module Axlsx
|
3
|
-
# Package is responsible for managing all the bits and peices that Open Office XML requires to make a valid
|
4
|
-
# xlsx document including valdation and serialization.
|
5
|
-
class Package
|
6
|
-
|
7
|
-
# Initializes your package
|
8
|
-
#
|
9
|
-
# @param [Hash] options A hash that you can use to specify the author and workbook for this package.
|
10
|
-
# @option options [String] :author The author of the document
|
11
|
-
# @example Package.new :author => 'you!', :workbook => Workbook.new
|
12
|
-
def initialize(options={})
|
13
|
-
@workbook = nil
|
14
|
-
@core, @app = Core.new, App.new
|
15
|
-
@core.creator = options[:author] || @core.creator
|
16
|
-
yield self if block_given?
|
17
|
-
end
|
18
|
-
|
19
|
-
# The workbook this package will serialize or validate.
|
20
|
-
# @return [Workbook] If no workbook instance has been assigned with this package a new Workbook instance is returned.
|
21
|
-
# @raise ArgumentError if workbook parameter is not a Workbook instance.
|
22
|
-
# @note As there are multiple ways to instantiate a workbook for the package,
|
23
|
-
# here are a few examples:
|
24
|
-
# # assign directly during package instanciation
|
25
|
-
# wb = Package.new(:workbook => Workbook.new).workbook
|
26
|
-
#
|
27
|
-
# # get a fresh workbook automatically from the package
|
28
|
-
# wb = Pacakge.new().workbook
|
29
|
-
# # # set the workbook after creating the package
|
30
|
-
# wb = Package.new().workbook = Workbook.new
|
31
|
-
def workbook
|
32
|
-
@workbook || @workbook = Workbook.new
|
33
|
-
yield @workbook if block_given?
|
34
|
-
@workbook
|
35
|
-
end
|
36
|
-
|
37
|
-
#def self.parse(input, confirm_valid = false)
|
38
|
-
# p = Package.new
|
39
|
-
# z = Zip::ZipFile.open(input)
|
40
|
-
# p.workbook = Workbook.parse z.get_entry(WORKBOOK_PN)
|
41
|
-
# p
|
42
|
-
#end
|
43
|
-
|
44
|
-
# @see workbook
|
45
|
-
def workbook=(workbook) DataTypeValidator.validate "Package.workbook", Workbook, workbook; @workbook = workbook; end
|
46
|
-
|
47
|
-
# Serialize your workbook to disk as an xlsx document.
|
48
|
-
#
|
49
|
-
# @param [File] output The file you want to serialize your package to
|
50
|
-
# @param [Boolean] confirm_valid Validate the package prior to serialization.
|
51
|
-
# @return [Boolean] False if confirm_valid and validation errors exist. True if the package was serialized
|
52
|
-
# @note A tremendous amount of effort has gone into ensuring that you cannot create invalid xlsx documents.
|
53
|
-
# confirm_valid should be used in the rare case that you cannot open the serialized file.
|
54
|
-
# @see Package#validate
|
55
|
-
# @example
|
56
|
-
# # 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.
|
57
|
-
# # Take a look at the README for an example of how to do it!
|
58
|
-
# f = File.open('test.xlsx', 'w')
|
59
|
-
# Package.new.serialize(f)
|
60
|
-
#
|
61
|
-
# # You will find a file called test.xlsx
|
62
|
-
def serialize(output, confirm_valid=false)
|
63
|
-
return false unless !confirm_valid || self.validate.empty?
|
64
|
-
p = parts
|
65
|
-
Zip::ZipOutputStream.open(output) do |zip|
|
66
|
-
p.each do |part|
|
67
|
-
unless part[:doc].nil?
|
68
|
-
zip.put_next_entry(part[:entry]);
|
69
|
-
zip.puts(part[:doc])
|
70
|
-
end
|
71
|
-
unless part[:path].nil?
|
72
|
-
zip.put_next_entry(part[:entry]);
|
73
|
-
# binread for 1.9.3
|
74
|
-
zip.write IO.respond_to?(:binread) ? IO.binread(part[:path]) : IO.read(part[:path])
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
true
|
79
|
-
end
|
80
|
-
|
81
|
-
|
82
|
-
# Validate all parts of the package against xsd schema.
|
83
|
-
# @return [Array] An array of all validation errors found.
|
84
|
-
# @note This gem includes all schema from OfficeOpenXML-XMLSchema-Transitional.zip and OpenPackagingConventions-XMLSchema.zip
|
85
|
-
# as per ECMA-376, Third edition. opc schema require an internet connection to import remote schema from dublin core for dc,
|
86
|
-
# dcterms and xml namespaces. Those remote schema are included in this gem, and the original files have been altered to
|
87
|
-
# refer to the local versions.
|
88
|
-
#
|
89
|
-
# If by chance you are able to creat a package that does not validate it indicates that the internal
|
90
|
-
# validation is not robust enough and needs to be improved. Please report your errors to the gem author.
|
91
|
-
# @see http://www.ecma-international.org/publications/standards/Ecma-376.htm
|
92
|
-
# @example
|
93
|
-
# # The following will output any error messages found in serialization.
|
94
|
-
# p = Axlsx::Package.new
|
95
|
-
# # ... code to create sheets, charts, styles etc.
|
96
|
-
# p.validate.each { |error| puts error.message }
|
97
|
-
def validate
|
98
|
-
errors = []
|
99
|
-
parts.each { |part| errors.concat validate_single_doc(part[:schema], part[:doc]) unless part[:schema].nil? }
|
100
|
-
errors
|
101
|
-
end
|
102
|
-
|
103
|
-
private
|
104
|
-
|
105
|
-
# The parts of a package
|
106
|
-
# @return [Array] An array of hashes that define the entry, document and schema for each part of the package.
|
107
|
-
# @private
|
108
|
-
def parts
|
109
|
-
@parts = [
|
110
|
-
{:entry => RELS_PN, :doc => relationships.to_xml, :schema => RELS_XSD},
|
111
|
-
{:entry => CORE_PN, :doc => @core.to_xml, :schema => CORE_XSD},
|
112
|
-
{:entry => APP_PN, :doc => @app.to_xml, :schema => APP_XSD},
|
113
|
-
{:entry => WORKBOOK_RELS_PN, :doc => workbook.relationships.to_xml, :schema => RELS_XSD},
|
114
|
-
{:entry => WORKBOOK_PN, :doc => workbook.to_xml, :schema => SML_XSD},
|
115
|
-
{:entry => CONTENT_TYPES_PN, :doc => content_types.to_xml, :schema => CONTENT_TYPES_XSD},
|
116
|
-
{:entry => "xl/#{STYLES_PN}", :doc => workbook.styles.to_xml, :schema => SML_XSD}
|
117
|
-
]
|
118
|
-
workbook.drawings.each do |drawing|
|
119
|
-
@parts << {:entry => "xl/#{drawing.rels_pn}", :doc => drawing.relationships.to_xml, :schema => RELS_XSD}
|
120
|
-
@parts << {:entry => "xl/#{drawing.pn}", :doc => drawing.to_xml, :schema => DRAWING_XSD}
|
121
|
-
end
|
122
|
-
|
123
|
-
workbook.charts.each do |chart|
|
124
|
-
@parts << {:entry => "xl/#{chart.pn}", :doc => chart.to_xml, :schema => DRAWING_XSD}
|
125
|
-
end
|
126
|
-
|
127
|
-
workbook.images.each do |image|
|
128
|
-
@parts << {:entry => "xl/#{image.pn}", :path => image.image_src}
|
129
|
-
end
|
130
|
-
|
131
|
-
workbook.worksheets.each do |sheet|
|
132
|
-
@parts << {:entry => "xl/#{sheet.rels_pn}", :doc => sheet.relationships.to_xml, :schema => RELS_XSD}
|
133
|
-
@parts << {:entry => "xl/#{sheet.pn}", :doc => sheet.to_xml, :schema => SML_XSD}
|
134
|
-
end
|
135
|
-
@parts
|
136
|
-
end
|
137
|
-
|
138
|
-
# Performs xsd validation for a signle document
|
139
|
-
#
|
140
|
-
# @param [String] schema path to the xsd schema to be used in validation.
|
141
|
-
# @param [String] doc The xml text to be validated
|
142
|
-
# @return [Array] An array of all validation errors encountered.
|
143
|
-
# @private
|
144
|
-
def validate_single_doc(schema, doc)
|
145
|
-
schema = Nokogiri::XML::Schema(File.open(schema))
|
146
|
-
doc = Nokogiri::XML(doc)
|
147
|
-
|
148
|
-
errors = []
|
149
|
-
schema.validate(doc).each do |error|
|
150
|
-
errors << error
|
151
|
-
end
|
152
|
-
errors
|
153
|
-
end
|
154
|
-
|
155
|
-
# Appends override objects for drawings, charts, and sheets as they exist in your workbook to the default content types.
|
156
|
-
# @return [ContentType]
|
157
|
-
# @private
|
158
|
-
def content_types
|
159
|
-
c_types = base_content_types
|
160
|
-
workbook.drawings.each do |drawing|
|
161
|
-
c_types << Axlsx::Override.new(:PartName => "/xl/#{drawing.pn}",
|
162
|
-
:ContentType => DRAWING_CT)
|
163
|
-
end
|
164
|
-
workbook.charts.each do |chart|
|
165
|
-
c_types << Axlsx::Override.new(:PartName => "/xl/#{chart.pn}",
|
166
|
-
:ContentType => CHART_CT)
|
167
|
-
end
|
168
|
-
workbook.worksheets.each do |sheet|
|
169
|
-
c_types << Axlsx::Override.new(:PartName => "/xl/#{sheet.pn}",
|
170
|
-
:ContentType => WORKSHEET_CT)
|
171
|
-
end
|
172
|
-
exts = workbook.images.map { |image| image.extname }
|
173
|
-
exts.uniq.each do |ext|
|
174
|
-
ct = if ['jpeg', 'jpg'].include?(ext)
|
175
|
-
JPEG_CT
|
176
|
-
elsif ext == 'gif'
|
177
|
-
GIF_CT
|
178
|
-
elsif ext == 'png'
|
179
|
-
PNG_CT
|
180
|
-
end
|
181
|
-
c_types << Axlsx::Default.new(:ContentType => ct, :Extension => ext )
|
182
|
-
end
|
183
|
-
c_types
|
184
|
-
end
|
185
|
-
|
186
|
-
# Creates the minimum content types for generating a valid xlsx document.
|
187
|
-
# @return [ContentType]
|
188
|
-
# @private
|
189
|
-
def base_content_types
|
190
|
-
c_types = ContentType.new()
|
191
|
-
c_types << Default.new(:ContentType => RELS_CT, :Extension => RELS_EX)
|
192
|
-
c_types << Default.new(:Extension => XML_EX, :ContentType => XML_CT)
|
193
|
-
c_types << Override.new(:PartName => "/#{APP_PN}", :ContentType => APP_CT)
|
194
|
-
c_types << Override.new(:PartName => "/#{CORE_PN}", :ContentType => CORE_CT)
|
195
|
-
c_types << Override.new(:PartName => "/xl/#{STYLES_PN}", :ContentType => STYLES_CT)
|
196
|
-
c_types << Axlsx::Override.new(:PartName => "/#{WORKBOOK_PN}", :ContentType => WORKBOOK_CT)
|
197
|
-
c_types.lock
|
198
|
-
c_types
|
199
|
-
end
|
200
|
-
|
201
|
-
# Creates the relationships required for a valid xlsx document
|
202
|
-
# @return [Relationships]
|
203
|
-
# @private
|
204
|
-
def relationships
|
205
|
-
rels = Axlsx::Relationships.new
|
206
|
-
rels << Relationship.new(WORKBOOK_R, WORKBOOK_PN)
|
207
|
-
rels << Relationship.new(CORE_R, CORE_PN)
|
208
|
-
rels << Relationship.new(APP_R, APP_PN)
|
209
|
-
rels.lock
|
210
|
-
rels
|
211
|
-
end
|
212
|
-
end
|
213
|
-
end
|
214
|
-
|