axlsx 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +13 -0
- data/lib/axlsx.rb +38 -0
- data/lib/axlsx/content_type/content_type.rb +23 -0
- data/lib/axlsx/content_type/default.rb +32 -0
- data/lib/axlsx/content_type/override.rb +30 -0
- data/lib/axlsx/doc_props/app.rb +148 -0
- data/lib/axlsx/doc_props/core.rb +34 -0
- data/lib/axlsx/drawing/axis.rb +78 -0
- data/lib/axlsx/drawing/bar_3D_chart.rb +138 -0
- data/lib/axlsx/drawing/bar_series.rb +91 -0
- data/lib/axlsx/drawing/cat_axis.rb +58 -0
- data/lib/axlsx/drawing/chart.rb +120 -0
- data/lib/axlsx/drawing/drawing.rb +121 -0
- data/lib/axlsx/drawing/graphic_frame.rb +55 -0
- data/lib/axlsx/drawing/marker.rb +57 -0
- data/lib/axlsx/drawing/pie_3D_chart.rb +59 -0
- data/lib/axlsx/drawing/pie_series.rb +88 -0
- data/lib/axlsx/drawing/scaling.rb +53 -0
- data/lib/axlsx/drawing/series.rb +70 -0
- data/lib/axlsx/drawing/title.rb +69 -0
- data/lib/axlsx/drawing/two_cell_anchor.rb +88 -0
- data/lib/axlsx/drawing/val_axis.rb +34 -0
- data/lib/axlsx/drawing/view_3D.rb +72 -0
- data/lib/axlsx/package.rb +181 -0
- data/lib/axlsx/rels/relationship.rb +43 -0
- data/lib/axlsx/rels/relationships.rb +25 -0
- data/lib/axlsx/stylesheet/border.rb +52 -0
- data/lib/axlsx/stylesheet/border_pr.rb +65 -0
- data/lib/axlsx/stylesheet/cell_alignment.rb +96 -0
- data/lib/axlsx/stylesheet/cell_protection.rb +33 -0
- data/lib/axlsx/stylesheet/cell_style.rb +60 -0
- data/lib/axlsx/stylesheet/color.rb +57 -0
- data/lib/axlsx/stylesheet/fill.rb +31 -0
- data/lib/axlsx/stylesheet/font.rb +128 -0
- data/lib/axlsx/stylesheet/gradient_fill.rb +70 -0
- data/lib/axlsx/stylesheet/gradient_stop.rb +31 -0
- data/lib/axlsx/stylesheet/num_fmt.rb +61 -0
- data/lib/axlsx/stylesheet/pattern_fill.rb +64 -0
- data/lib/axlsx/stylesheet/styles.rb +296 -0
- data/lib/axlsx/stylesheet/table_style.rb +44 -0
- data/lib/axlsx/stylesheet/table_style_element.rb +66 -0
- data/lib/axlsx/stylesheet/table_styles.rb +39 -0
- data/lib/axlsx/stylesheet/xf.rb +117 -0
- data/lib/axlsx/util/constants.rb +189 -0
- data/lib/axlsx/util/simple_typed_list.rb +150 -0
- data/lib/axlsx/util/validators.rb +132 -0
- data/lib/axlsx/workbook/workbook.rb +130 -0
- data/lib/axlsx/workbook/worksheet/cell.rb +184 -0
- data/lib/axlsx/workbook/worksheet/row.rb +92 -0
- data/lib/axlsx/workbook/worksheet/worksheet.rb +194 -0
- data/lib/schema/dc.xsd +118 -0
- data/lib/schema/dcmitype.xsd +50 -0
- data/lib/schema/dcterms.xsd +331 -0
- data/lib/schema/dml-chart.xsd +1499 -0
- data/lib/schema/dml-chartDrawing.xsd +146 -0
- data/lib/schema/dml-compatibility.xsd +14 -0
- data/lib/schema/dml-diagram.xsd +1091 -0
- data/lib/schema/dml-lockedCanvas.xsd +11 -0
- data/lib/schema/dml-main.xsd +3048 -0
- data/lib/schema/dml-picture.xsd +23 -0
- data/lib/schema/dml-spreadsheetDrawing.xsd +185 -0
- data/lib/schema/dml-wordprocessingDrawing.xsd +185 -0
- data/lib/schema/opc-contentTypes.xsd +42 -0
- data/lib/schema/opc-coreProperties.xsd +50 -0
- data/lib/schema/opc-digSig.xsd +49 -0
- data/lib/schema/opc-relationships.xsd +33 -0
- data/lib/schema/pml.xsd +1676 -0
- data/lib/schema/shared-additionalCharacteristics.xsd +28 -0
- data/lib/schema/shared-bibliography.xsd +144 -0
- data/lib/schema/shared-commonSimpleTypes.xsd +166 -0
- data/lib/schema/shared-customXmlDataProperties.xsd +25 -0
- data/lib/schema/shared-customXmlSchemaProperties.xsd +18 -0
- data/lib/schema/shared-documentPropertiesCustom.xsd +59 -0
- data/lib/schema/shared-documentPropertiesExtended.xsd +56 -0
- data/lib/schema/shared-documentPropertiesVariantTypes.xsd +195 -0
- data/lib/schema/shared-math.xsd +582 -0
- data/lib/schema/shared-relationshipReference.xsd +25 -0
- data/lib/schema/sml.xsd +4430 -0
- data/lib/schema/vml-main.xsd +569 -0
- data/lib/schema/vml-officeDrawing.xsd +509 -0
- data/lib/schema/vml-presentationDrawing.xsd +12 -0
- data/lib/schema/vml-spreadsheetDrawing.xsd +108 -0
- data/lib/schema/vml-wordprocessingDrawing.xsd +96 -0
- data/lib/schema/wml.xsd +3644 -0
- data/lib/schema/xml.xsd +117 -0
- data/test/content_type/tc_content_type.rb +81 -0
- data/test/content_type/tc_content_type.rb~ +81 -0
- data/test/content_type/tc_default.rb +40 -0
- data/test/content_type/tc_default.rb~ +40 -0
- data/test/content_type/tc_override.rb +40 -0
- data/test/content_type/tc_override.rb~ +40 -0
- data/test/doc_props/tc_app.rb +19 -0
- data/test/doc_props/tc_app.rb~ +19 -0
- data/test/doc_props/tc_core.rb +34 -0
- data/test/drawing/tc_axis.rb +39 -0
- data/test/drawing/tc_axis.rb~ +0 -0
- data/test/drawing/tc_bar_3D_chart.rb +66 -0
- data/test/drawing/tc_bar_3D_chart.rb~ +4 -0
- data/test/drawing/tc_bar_series.rb +34 -0
- data/test/drawing/tc_bar_series.rb~ +31 -0
- data/test/drawing/tc_cat_axis.rb +32 -0
- data/test/drawing/tc_cat_axis.rb~ +39 -0
- data/test/drawing/tc_chart.rb +59 -0
- data/test/drawing/tc_chart.rb~ +58 -0
- data/test/drawing/tc_drawing.rb +71 -0
- data/test/drawing/tc_graphic_frame.rb +26 -0
- data/test/drawing/tc_graphic_frame.rb~ +21 -0
- data/test/drawing/tc_marker.rb +45 -0
- data/test/drawing/tc_marker.rb~ +26 -0
- data/test/drawing/tc_pie_3D_chart.rb +33 -0
- data/test/drawing/tc_pie_3D_chart.rb~ +58 -0
- data/test/drawing/tc_pie_series.rb +35 -0
- data/test/drawing/tc_pie_series.rb~ +26 -0
- data/test/drawing/tc_scaling.rb +37 -0
- data/test/drawing/tc_scaling.rb~ +45 -0
- data/test/drawing/tc_series.rb +24 -0
- data/test/drawing/tc_series.rb~ +31 -0
- data/test/drawing/tc_title.rb +34 -0
- data/test/drawing/tc_title.rb~ +37 -0
- data/test/drawing/tc_two_cell_anchor.rb +37 -0
- data/test/drawing/tc_two_cell_anchor.rb~ +35 -0
- data/test/drawing/tc_val_axis.rb +20 -0
- data/test/drawing/tc_val_axis.rb~ +32 -0
- data/test/drawing/tc_view_3D.rb +46 -0
- data/test/drawing/tc_view_3D.rb~ +37 -0
- data/test/rels/tc_relationship.rb +16 -0
- data/test/rels/tc_relationship.rb~ +39 -0
- data/test/rels/tc_relationships.rb +32 -0
- data/test/rels/tc_relationships.rb~ +37 -0
- data/test/stylesheet/tc_border.rb +38 -0
- data/test/stylesheet/tc_border.rb~ +31 -0
- data/test/stylesheet/tc_border_pr.rb +33 -0
- data/test/stylesheet/tc_border_pr.rb~ +31 -0
- data/test/stylesheet/tc_cell_alignment.rb +77 -0
- data/test/stylesheet/tc_cell_alignment.rb~ +38 -0
- data/test/stylesheet/tc_cell_protection.rb +30 -0
- data/test/stylesheet/tc_cell_protection.rb~ +77 -0
- data/test/stylesheet/tc_cell_style.rb +58 -0
- data/test/stylesheet/tc_cell_style.rb~ +30 -0
- data/test/stylesheet/tc_color.rb +38 -0
- data/test/stylesheet/tc_color.rb~ +38 -0
- data/test/stylesheet/tc_fill.rb +19 -0
- data/test/stylesheet/tc_fill.rb~ +19 -0
- data/test/stylesheet/tc_font.rb +114 -0
- data/test/stylesheet/tc_font.rb~ +19 -0
- data/test/stylesheet/tc_gradient_fill.rb +65 -0
- data/test/stylesheet/tc_gradient_fill.rb~ +114 -0
- data/test/stylesheet/tc_gradient_stop.rb +32 -0
- data/test/stylesheet/tc_gradient_stop.rb~ +65 -0
- data/test/stylesheet/tc_num_fmt.rb +31 -0
- data/test/stylesheet/tc_num_fmt.rb~ +32 -0
- data/test/stylesheet/tc_pattern_fill.rb +38 -0
- data/test/stylesheet/tc_pattern_fill.rb~ +31 -0
- data/test/stylesheet/tc_styles.rb +64 -0
- data/test/stylesheet/tc_table_style.rb +37 -0
- data/test/stylesheet/tc_table_style.rb~ +38 -0
- data/test/stylesheet/tc_table_style_element.rb +37 -0
- data/test/stylesheet/tc_table_style_element.rb~ +37 -0
- data/test/stylesheet/tc_table_styles.rb +30 -0
- data/test/stylesheet/tc_table_styles.rb~ +37 -0
- data/test/stylesheet/tc_xf.rb +121 -0
- data/test/stylesheet/tc_xf.rb~ +30 -0
- data/test/tc_app.rb~ +19 -0
- data/test/tc_border_pr.rb~ +21 -0
- data/test/tc_package.rb +70 -0
- data/test/tc_package.rb~ +64 -0
- data/test/tc_pie_3D_chart.rb~ +66 -0
- data/test/tc_relationships.rb~ +37 -0
- data/test/tc_series.rb~ +31 -0
- data/test/tc_styles.rb~ +64 -0
- data/test/tc_validators.rb~ +77 -0
- data/test/tc_worksheet.rb~ +85 -0
- data/test/util/tc_simple_typed_list.rb +66 -0
- data/test/util/tc_validators.rb +76 -0
- data/test/workbook/tc_workbook.rb +53 -0
- data/test/workbook/worksheet/tc_cell.rb +78 -0
- data/test/workbook/worksheet/tc_row.rb +30 -0
- data/test/workbook/worksheet/tc_worksheet.rb +85 -0
- metadata +378 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
module Axlsx
|
2
|
+
# the ValAxis class defines a chart value axis.
|
3
|
+
class ValAxis < Axis
|
4
|
+
|
5
|
+
# This element specifies whether the value axis crosses the category axis between categories.
|
6
|
+
# must be one of [:between, :midCat]
|
7
|
+
# @return [Symbol]
|
8
|
+
attr_accessor :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] crosses
|
15
|
+
# @option options [Symbol] tickLblPos
|
16
|
+
# @option options [Symbol] crossesBetween
|
17
|
+
def initialize(axId, crossAx, options={})
|
18
|
+
@crossBetween = :between
|
19
|
+
super(axId, crossAx, options)
|
20
|
+
end
|
21
|
+
|
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
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Axlsx
|
2
|
+
# 3D attributes for a chart.
|
3
|
+
class View3D
|
4
|
+
# x rotation for the chart
|
5
|
+
# must be between -90 and 90
|
6
|
+
# @return [Integer]
|
7
|
+
attr_accessor :rotX
|
8
|
+
|
9
|
+
# height of chart as % of chart
|
10
|
+
# must be between 5% and 500%
|
11
|
+
# @return [String]
|
12
|
+
attr_accessor :hPercent
|
13
|
+
|
14
|
+
# y rotation for the chart
|
15
|
+
# must be between 0 and 360
|
16
|
+
# @return [Integer]
|
17
|
+
attr_accessor :rotY
|
18
|
+
|
19
|
+
# depth or chart as % of chart width
|
20
|
+
# must be between 20% and 2000%
|
21
|
+
# @return [String]
|
22
|
+
attr_accessor :depthPercent
|
23
|
+
|
24
|
+
# Chart axis are at right angles
|
25
|
+
# @return [Boolean]
|
26
|
+
attr_accessor :rAngAx
|
27
|
+
|
28
|
+
# field of view angle
|
29
|
+
# @return [Integer]
|
30
|
+
attr_accessor :perspective
|
31
|
+
|
32
|
+
# Creates a new View3D for charts
|
33
|
+
# @option options [Integer] rotX
|
34
|
+
# @option options [String] hPercent
|
35
|
+
# @option options [Integer] rotY
|
36
|
+
# @option options [String] depthPercent
|
37
|
+
# @option options [Boolean] rAngAx
|
38
|
+
# @option options [Integer] perspective
|
39
|
+
def initialize(options={})
|
40
|
+
options.each do |o|
|
41
|
+
self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Validation for hPercent
|
46
|
+
H_PERCENT_REGEX = /0*(([5-9])|([1-9][0-9])|([1-4][0-9][0-9])|500)%/
|
47
|
+
|
48
|
+
# validation for depthPercent
|
49
|
+
DEPTH_PERCENT_REGEX = /0*(([2-9][0-9])|([1-9][0-9][0-9])|(1[0-9][0-9][0-9])|2000)%/
|
50
|
+
|
51
|
+
def rotX=(v) DataTypeValidator.validate "#{self.class}.rotX", [Integer, Fixnum], v, lambda {|v| v >= -90 && v <= 90 }; @rotX = v; end
|
52
|
+
def hPercent=(v) RegexValidator.validate "#{self.class}.rotX", H_PERCENT_REGEX, v; @hPercent = v; end
|
53
|
+
def rotY=(v) DataTypeValidator.validate "#{self.class}.rotY", [Integer, Fixnum], v, lambda {|v| v >= 0 && v <= 360 }; @rotY = v; end
|
54
|
+
def depthPercent=(v) RegexValidator.validate "#{self.class}.depthPercent", DEPTH_PERCENT_REGEX, v; @depthPercent = v; end
|
55
|
+
def rAngAx=(v) Axlsx::validate_boolean(v); @rAngAx = v; end
|
56
|
+
def perspective=(v) DataTypeValidator.validate "#{self.class}.perspective", [Integer, Fixnum], v, lambda {|v| v >= 0 && v <= 240 }; @perspective = v; end
|
57
|
+
|
58
|
+
# Serializes the view3D properties
|
59
|
+
# @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
|
60
|
+
# @return [String]
|
61
|
+
def to_xml(xml)
|
62
|
+
xml.send('c:view3D') {
|
63
|
+
xml.send('c:rotX', :val=>@rotX) unless @rotX.nil?
|
64
|
+
xml.send('c:hPercent', :val=>@hPercent) unless @hPercent.nil?
|
65
|
+
xml.send('c:rotY', :val=>@rotY) unless @rotY.nil?
|
66
|
+
xml.send('c:depthPercent', :val=>@depthPercent) unless @depthPercent.nil?
|
67
|
+
xml.send('c:rAngAx', :val=>@rAngAx) unless @rAngAx.nil?
|
68
|
+
xml.send('c:perspective', :val=>@perspective) unless @perspective.nil?
|
69
|
+
}
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,181 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# Create Office Open XML Spreadsheets (xlsx) with safe and full control over cell styles, automatically resized column widths and 3D pie charts.
|
3
|
+
module Axlsx
|
4
|
+
# Package is responsible for managing all the bits and peices that Open Office XML requires to make a valid
|
5
|
+
# xlsx document including valdation and serialization.
|
6
|
+
class Package
|
7
|
+
|
8
|
+
# The workbook this package will serialize or validate.
|
9
|
+
# @attribute
|
10
|
+
# @return [Workbook] If no workbook instance has been assigned with this package a new Workbook instance is returned.
|
11
|
+
# @raise ArgumentError if workbook parameter is not a Workbook instance.
|
12
|
+
# @note As there are multiple ways to instantiate a workbook for the package,
|
13
|
+
# here are a few examples:
|
14
|
+
# # assign directly during package instanciation
|
15
|
+
# wb = Package.new(:workbook => Workbook.new).workbook
|
16
|
+
#
|
17
|
+
# # get a fresh workbook automatically from the package
|
18
|
+
# wb = Pacakge.new().workbook
|
19
|
+
# # # set the workbook after creating the package
|
20
|
+
# wb = Package.new().workbook = Workbook.new
|
21
|
+
attr_accessor :workbook
|
22
|
+
|
23
|
+
# Initializes your package
|
24
|
+
#
|
25
|
+
# @param [Hash] options A hash that you can use to specify the author and workbook for this package.
|
26
|
+
# @option options [String] :author The author of the document
|
27
|
+
# @option options [Workbook] :workbook The workbook associated with this package.
|
28
|
+
# @example Package.new :author => 'you!', :workbook => Workbook.new
|
29
|
+
def initialize(options={})
|
30
|
+
@core, @app = Core.new, App.new
|
31
|
+
@core.creator = options[:author] || @core.creator
|
32
|
+
self.workbook= options[:workbook] if options[:workbook]
|
33
|
+
end
|
34
|
+
|
35
|
+
def workbook=(workbook) DataTypeValidator.validate "Package.workbook", Workbook, workbook; @workbook = workbook; end
|
36
|
+
|
37
|
+
def workbook
|
38
|
+
@workbook || @workbook = Workbook.new
|
39
|
+
end
|
40
|
+
|
41
|
+
# Serialize your workbook to disk as an xlsx document.
|
42
|
+
#
|
43
|
+
# @param [File] output The file you want to serialize your package to
|
44
|
+
# @param [Boolean] confirm_valid Validate the package prior to serialization.
|
45
|
+
# @return [Boolean] False if confirm_valid and validation errors exist. True if the package was serialized
|
46
|
+
# @note A tremendous amount of effort has gone into ensuring that you cannot create invalid xlsx documents.
|
47
|
+
# confirm_valid should be used in the rare case that you cannot open the serialized file.
|
48
|
+
# @see Package#validate
|
49
|
+
# @example
|
50
|
+
# # 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.
|
51
|
+
# # Take a look at the README for an example of how to do it!
|
52
|
+
# f = File.open('test.xlsx', 'w')
|
53
|
+
# Package.new.serialize(f)
|
54
|
+
#
|
55
|
+
# # You will find a file called test.xlsx
|
56
|
+
def serialize(output, confirm_valid=false)
|
57
|
+
return false unless !confirm_valid || self.validate.empty?
|
58
|
+
Zip::ZipOutputStream.open(output.path) do |zip|
|
59
|
+
parts.each{ |part| zip.put_next_entry(part[:entry]); zip.puts(part[:doc]) }
|
60
|
+
end
|
61
|
+
true
|
62
|
+
end
|
63
|
+
|
64
|
+
# Validate all parts of the package against xsd schema.
|
65
|
+
# @return [Array] An array of all validation errors found.
|
66
|
+
# @note This gem includes all schema from OfficeOpenXML-XMLSchema-Transitional.zip and OpenPackagingConventions-XMLSchema.zip
|
67
|
+
# as per ECMA-376, Third edition. opc schema require an internet connection to import remote schema from dublin core for dc,
|
68
|
+
# dcterms and xml namespaces. Those remote schema are included in this gem, and the original files have been altered to
|
69
|
+
# refer to the local versions.
|
70
|
+
#
|
71
|
+
# If by chance you are able to creat a package that does not validate it indicates that the internal
|
72
|
+
# validation is not robust enough and needs to be improved. Please report your errors to the gem author.
|
73
|
+
# @see http://www.ecma-international.org/publications/standards/Ecma-376.htm
|
74
|
+
# @example
|
75
|
+
# # The following will output any error messages found in serialization.
|
76
|
+
# p = Axlsx::Package.new
|
77
|
+
# # ... code to create sheets, charts, styles etc.
|
78
|
+
# p.validate.each { |error| puts error.message }
|
79
|
+
def validate
|
80
|
+
errors = []
|
81
|
+
parts.each { |part| errors.concat validate_single_doc(part[:schema], part[:doc]) }
|
82
|
+
errors
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
# The parts of a package
|
88
|
+
# @return [Array] An array of hashes that define the entry, document and schema for each part of the package.
|
89
|
+
# @private
|
90
|
+
def parts
|
91
|
+
@parts = [
|
92
|
+
{:entry => RELS_PN, :doc => relationships.to_xml, :schema => RELS_XSD},
|
93
|
+
{:entry => CORE_PN, :doc => @core.to_xml, :schema => CORE_XSD},
|
94
|
+
{:entry => APP_PN, :doc => @app.to_xml, :schema => APP_XSD},
|
95
|
+
{:entry => WORKBOOK_RELS_PN, :doc => workbook.relationships.to_xml, :schema => RELS_XSD},
|
96
|
+
{:entry => WORKBOOK_PN, :doc => workbook.to_xml, :schema => SML_XSD},
|
97
|
+
{:entry => CONTENT_TYPES_PN, :doc => content_types.to_xml, :schema => CONTENT_TYPES_XSD},
|
98
|
+
{:entry => "xl/#{STYLES_PN}", :doc => workbook.styles.to_xml, :schema => SML_XSD}
|
99
|
+
]
|
100
|
+
workbook.drawings.each do |drawing|
|
101
|
+
@parts << {:entry => "xl/#{drawing.rels_pn}", :doc => drawing.relationships.to_xml, :schema => RELS_XSD}
|
102
|
+
@parts << {:entry => "xl/#{drawing.pn}", :doc => drawing.to_xml, :schema => DRAWING_XSD}
|
103
|
+
end
|
104
|
+
|
105
|
+
workbook.charts.each do |chart|
|
106
|
+
@parts << {:entry => "xl/#{chart.pn}", :doc => chart.to_xml, :schema => DRAWING_XSD}
|
107
|
+
end
|
108
|
+
|
109
|
+
workbook.worksheets.each do |sheet|
|
110
|
+
@parts << {:entry => "xl/#{sheet.rels_pn}", :doc => sheet.relationships.to_xml, :schema => RELS_XSD}
|
111
|
+
@parts << {:entry => "xl/#{sheet.pn}", :doc => sheet.to_xml, :schema => SML_XSD}
|
112
|
+
end
|
113
|
+
@parts
|
114
|
+
end
|
115
|
+
|
116
|
+
# Performs xsd validation for a signle document
|
117
|
+
#
|
118
|
+
# @param [String] schema path to the xsd schema to be used in validation.
|
119
|
+
# @param [String] doc The xml text to be validated
|
120
|
+
# @return [Array] An array of all validation errors encountered.
|
121
|
+
# @private
|
122
|
+
def validate_single_doc(schema, doc)
|
123
|
+
schema = Nokogiri::XML::Schema(File.open(schema))
|
124
|
+
doc = Nokogiri::XML(doc)
|
125
|
+
|
126
|
+
errors = []
|
127
|
+
schema.validate(doc).each do |error|
|
128
|
+
errors << error
|
129
|
+
end
|
130
|
+
errors
|
131
|
+
end
|
132
|
+
|
133
|
+
# Appends override objects for drawings, charts, and sheets as they exist in your workbook to the default content types.
|
134
|
+
# @return [ContentType]
|
135
|
+
# @private
|
136
|
+
def content_types
|
137
|
+
c_types = base_content_types
|
138
|
+
workbook.drawings.each do |drawing|
|
139
|
+
c_types << Axlsx::Override.new(:PartName => "/xl/#{drawing.pn}",
|
140
|
+
:ContentType => DRAWING_CT)
|
141
|
+
end
|
142
|
+
workbook.charts.each do |chart|
|
143
|
+
c_types << Axlsx::Override.new(:PartName => "/xl/#{chart.pn}",
|
144
|
+
:ContentType => CHART_CT)
|
145
|
+
end
|
146
|
+
workbook.worksheets.each do |sheet|
|
147
|
+
c_types << Axlsx::Override.new(:PartName => "/xl/#{sheet.pn}",
|
148
|
+
:ContentType => WORKSHEET_CT)
|
149
|
+
end
|
150
|
+
c_types
|
151
|
+
end
|
152
|
+
|
153
|
+
# Creates the minimum content types for generating a valid xlsx document.
|
154
|
+
# @return [ContentType]
|
155
|
+
# @private
|
156
|
+
def base_content_types
|
157
|
+
c_types = ContentType.new()
|
158
|
+
c_types << Default.new(:ContentType => RELS_CT, :Extension => RELS_EX)
|
159
|
+
c_types << Default.new(:Extension => XML_EX, :ContentType => XML_CT)
|
160
|
+
c_types << Override.new(:PartName => "/#{APP_PN}", :ContentType => APP_CT)
|
161
|
+
c_types << Override.new(:PartName => "/#{CORE_PN}", :ContentType => CORE_CT)
|
162
|
+
c_types << Override.new(:PartName => "/xl/#{STYLES_PN}", :ContentType => STYLES_CT)
|
163
|
+
c_types << Axlsx::Override.new(:PartName => "/#{WORKBOOK_PN}", :ContentType => WORKBOOK_CT)
|
164
|
+
c_types.lock
|
165
|
+
c_types
|
166
|
+
end
|
167
|
+
|
168
|
+
# Creates the relationships required for a valid xlsx document
|
169
|
+
# @return [Relationships]
|
170
|
+
# @private
|
171
|
+
def relationships
|
172
|
+
rels = Axlsx::Relationships.new
|
173
|
+
rels << Relationship.new(WORKBOOK_R, WORKBOOK_PN)
|
174
|
+
rels << Relationship.new(CORE_R, CORE_PN)
|
175
|
+
rels << Relationship.new(APP_R, APP_PN)
|
176
|
+
rels.lock
|
177
|
+
rels
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Axlsx
|
2
|
+
# A relationship defines a reference between package parts.
|
3
|
+
# @note Packages automatcially manage relationships.
|
4
|
+
class Relationship
|
5
|
+
|
6
|
+
# The location of the relationship target
|
7
|
+
# @return [String]
|
8
|
+
attr_accessor :Target
|
9
|
+
|
10
|
+
# The type of relationship
|
11
|
+
# @note Supported types are defined as constants in Axlsx:
|
12
|
+
# @see XML_NS_R
|
13
|
+
# @see TABLE_R
|
14
|
+
# @see WORKBOOK_R
|
15
|
+
# @see WORKSHEET_R
|
16
|
+
# @see APP_R
|
17
|
+
# @see RELS_R
|
18
|
+
# @see CORE_R
|
19
|
+
# @see STYLES_R
|
20
|
+
# @see CHART_R
|
21
|
+
# @see DRAWING_R
|
22
|
+
# @return [String]
|
23
|
+
attr_accessor :Type
|
24
|
+
def initialize(type, target)
|
25
|
+
self.Target=target
|
26
|
+
self.Type=type
|
27
|
+
end
|
28
|
+
|
29
|
+
def Target=(v) Axlsx::validate_string v; @Target = v end
|
30
|
+
def Type=(v) Axlsx::validate_relationship_type v; @Type = v end
|
31
|
+
|
32
|
+
# Serializes the relationship
|
33
|
+
# TODO: use object.rId to get this infomation
|
34
|
+
# @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
|
35
|
+
# @param [String] rId the reference id of the object.
|
36
|
+
# @return [String]
|
37
|
+
def to_xml(xml, rId)
|
38
|
+
h = self.instance_values
|
39
|
+
h[:Id] = rId
|
40
|
+
xml.Relationship(h)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Axlsx
|
2
|
+
require 'axlsx/rels/relationship.rb'
|
3
|
+
|
4
|
+
# Relationships are a collection of Relations that define how package parts are related.
|
5
|
+
# @note The package automatically manages releationships.
|
6
|
+
class Relationships < SimpleTypedList
|
7
|
+
|
8
|
+
# Creates a new Relationships collection based on SimpleTypedList
|
9
|
+
def initialize
|
10
|
+
super Relationship
|
11
|
+
end
|
12
|
+
|
13
|
+
# Serializes the relationships document.
|
14
|
+
# @return [String]
|
15
|
+
def to_xml()
|
16
|
+
builder = Nokogiri::XML::Builder.new(:encoding => ENCODING) do |xml|
|
17
|
+
xml.Relationships(:xmlns => Axlsx::RELS_R) {
|
18
|
+
each_with_index { |rel, index| rel.to_xml(xml, "rId#{index+1}") }
|
19
|
+
}
|
20
|
+
end
|
21
|
+
builder.to_xml
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Axlsx
|
2
|
+
# This class details a border used in Office Open XML spreadsheet styles.
|
3
|
+
class Border
|
4
|
+
|
5
|
+
# @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
|
+
attr_accessor :diagonalUp
|
7
|
+
|
8
|
+
# @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.
|
9
|
+
attr_accessor :diagonalDown
|
10
|
+
|
11
|
+
# @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.
|
12
|
+
attr_accessor :outline
|
13
|
+
|
14
|
+
# @return [SimpleTypedList] A list of BorderPr objects for this border.
|
15
|
+
attr_reader :prs
|
16
|
+
|
17
|
+
# Creates a new Border object
|
18
|
+
# @option options [Boolean] diagonalUp
|
19
|
+
# @option options [Boolean] diagonalDown
|
20
|
+
# @option options [Boolean] outline
|
21
|
+
# @example Making a border
|
22
|
+
# p = Package.new
|
23
|
+
# red_border = Border.new
|
24
|
+
# [:left, :right, :top, :bottom].each do |item|
|
25
|
+
# red_border.prs << BorderPr.new(:name=>item, :style=>:thin, :color=>Color.new(:rgb=>"FFFF0000")) #
|
26
|
+
# end
|
27
|
+
# # this sets red_border to be the index for the created border.
|
28
|
+
# red_border = p.workbook.styles.@borders << red_border
|
29
|
+
# #used in row creation as follows. This will add a red border to each of the cells in the row.
|
30
|
+
# p.workbook.add_worksheet.rows << :values=>[1,2,3] :style=>red_border
|
31
|
+
def initialize(options={})
|
32
|
+
@prs = SimpleTypedList.new BorderPr
|
33
|
+
options.each do |o|
|
34
|
+
self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def diagonalUp=(v) Axlsx::validate_boolean v; @diagonalUp = v end
|
39
|
+
def diagonalDown=(v) Axlsx::validate_boolean v; @diagonalDown = v end
|
40
|
+
def outline=(v) Axlsx::validate_boolean v; @outline = v end
|
41
|
+
|
42
|
+
# Serializes the border element
|
43
|
+
# @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
|
44
|
+
def to_xml(xml)
|
45
|
+
xml.border(self.instance_values.select{ |k,v| [:diagonalUp, :diagonalDown, :outline].include? k }) {
|
46
|
+
[:start, :end, :left, :right, :top, :bottom, :diagonal, :vertical, :horizontal].each do |k|
|
47
|
+
@prs.select { |pr| pr.name == k }.each { |pr| pr.to_xml(xml) }
|
48
|
+
end
|
49
|
+
}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Axlsx
|
2
|
+
# A border part.
|
3
|
+
class BorderPr
|
4
|
+
|
5
|
+
# @return [Color] The color of this border part.
|
6
|
+
attr_accessor :color
|
7
|
+
|
8
|
+
# @return [Symbol] The syle of this border part.
|
9
|
+
# @note
|
10
|
+
# The following are allowed
|
11
|
+
# :none
|
12
|
+
# :thin
|
13
|
+
# :medium
|
14
|
+
# :dashed
|
15
|
+
# :dotted
|
16
|
+
# :thick
|
17
|
+
# :double
|
18
|
+
# :hair
|
19
|
+
# :mediumDashed
|
20
|
+
# :dashDot
|
21
|
+
# :mediumDashDot
|
22
|
+
# :dashDotDot
|
23
|
+
# :mediumDashDotDot
|
24
|
+
# :slantDashDot
|
25
|
+
attr_accessor :style
|
26
|
+
|
27
|
+
# @return [Symbol] The name of this border part
|
28
|
+
# @note
|
29
|
+
# The following are allowed
|
30
|
+
# :start
|
31
|
+
# :end
|
32
|
+
# :left
|
33
|
+
# :right
|
34
|
+
# :top
|
35
|
+
# :bottom
|
36
|
+
# :diagonal
|
37
|
+
# :vertical
|
38
|
+
# :horizontal
|
39
|
+
attr_accessor :name
|
40
|
+
|
41
|
+
# Creates a new Border Part Object
|
42
|
+
# @option options [Color] color
|
43
|
+
# @option options [Symbol] name
|
44
|
+
# @option options [Symbol] style
|
45
|
+
# @see Axlsx::Border
|
46
|
+
def initialize(options={})
|
47
|
+
options.each do |o|
|
48
|
+
self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def name=(v) RestrictionValidator.validate "BorderPr.name", [:start, :end, :left, :right, :top, :bottom, :diagonal, :vertical, :horizontal], v; @name = v end
|
53
|
+
def color=(v) DataTypeValidator.validate(:color, Color, v); @color = v end
|
54
|
+
def style=(v) RestrictionValidator.validate "BorderPr.style", [:none, :thin, :medium, :dashed, :dotted, :thick, :double, :hair, :mediumDashed, :dashDot, :mediumDashDot, :dashDotDot, :mediumDashDotDot, :slantDashDot], v; @style = v end
|
55
|
+
|
56
|
+
# Serializes the border part
|
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
|
+
xml.send(@name, :style=>@style) {
|
61
|
+
@color.to_xml(xml) if @color.is_a? Color
|
62
|
+
}
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|