axlsx 1.0.12 → 1.0.14

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.
Files changed (77) hide show
  1. data/README.md +165 -134
  2. data/examples/example.rb +133 -153
  3. data/lib/axlsx/#cfb.xlsx# +0 -0
  4. data/lib/axlsx/content_type/content_type.rb +23 -0
  5. data/lib/axlsx/content_type/default.rb +37 -0
  6. data/lib/axlsx/content_type/override.rb +37 -0
  7. data/lib/axlsx/doc_props/app.rb +178 -0
  8. data/lib/axlsx/doc_props/core.rb +34 -0
  9. data/lib/axlsx/drawing/axis.rb +93 -0
  10. data/lib/axlsx/drawing/bar_3D_chart.rb +136 -0
  11. data/lib/axlsx/drawing/bar_series.rb +64 -0
  12. data/lib/axlsx/drawing/cat_axis.rb +63 -0
  13. data/lib/axlsx/drawing/cat_axis_data.rb +35 -0
  14. data/lib/axlsx/drawing/chart.rb +193 -0
  15. data/lib/axlsx/drawing/drawing.rb +137 -0
  16. data/lib/axlsx/drawing/graphic_frame.rb +52 -0
  17. data/lib/axlsx/drawing/line_3D_chart.rb +114 -0
  18. data/lib/axlsx/drawing/line_series.rb +46 -0
  19. data/lib/axlsx/drawing/marker.rb +61 -0
  20. data/lib/axlsx/drawing/one_cell_anchor.rb +89 -0
  21. data/lib/axlsx/drawing/pic.rb +153 -0
  22. data/lib/axlsx/drawing/picture_locking.rb +72 -0
  23. data/lib/axlsx/drawing/picture_locking.rb~ +36 -0
  24. data/lib/axlsx/drawing/pie_3D_chart.rb +41 -0
  25. data/lib/axlsx/drawing/pie_series.rb +56 -0
  26. data/lib/axlsx/drawing/scaling.rb +59 -0
  27. data/lib/axlsx/drawing/ser_axis.rb +45 -0
  28. data/lib/axlsx/drawing/series.rb +71 -0
  29. data/lib/axlsx/drawing/series_title.rb +22 -0
  30. data/lib/axlsx/drawing/title.rb +65 -0
  31. data/lib/axlsx/drawing/two_cell_anchor.rb +76 -0
  32. data/lib/axlsx/drawing/val_axis.rb +34 -0
  33. data/lib/axlsx/drawing/val_axis_data.rb +26 -0
  34. data/lib/axlsx/drawing/view_3D.rb +85 -0
  35. data/lib/axlsx/package.rb +223 -0
  36. data/lib/axlsx/rels/relationship.rb +44 -0
  37. data/lib/axlsx/rels/relationships.rb +25 -0
  38. data/lib/axlsx/stylesheet/border.rb +57 -0
  39. data/lib/axlsx/stylesheet/border_pr.rb +68 -0
  40. data/lib/axlsx/stylesheet/cell_alignment.rb +105 -0
  41. data/lib/axlsx/stylesheet/cell_protection.rb +36 -0
  42. data/lib/axlsx/stylesheet/cell_style.rb +65 -0
  43. data/lib/axlsx/stylesheet/color.rb +69 -0
  44. data/lib/axlsx/stylesheet/fill.rb +32 -0
  45. data/lib/axlsx/stylesheet/font.rb +139 -0
  46. data/lib/axlsx/stylesheet/gradient_fill.rb +76 -0
  47. data/lib/axlsx/stylesheet/gradient_stop.rb +33 -0
  48. data/lib/axlsx/stylesheet/num_fmt.rb +63 -0
  49. data/lib/axlsx/stylesheet/pattern_fill.rb +66 -0
  50. data/lib/axlsx/stylesheet/styles.rb +298 -0
  51. data/lib/axlsx/stylesheet/table_style.rb +47 -0
  52. data/lib/axlsx/stylesheet/table_style_element.rb +71 -0
  53. data/lib/axlsx/stylesheet/table_styles.rb +39 -0
  54. data/lib/axlsx/stylesheet/xf.rb +138 -0
  55. data/lib/axlsx/util/constants.rb +216 -0
  56. data/lib/axlsx/util/ms_off_crypto.rb +88 -0
  57. data/lib/axlsx/util/ms_off_crypto.rb~ +3 -0
  58. data/lib/axlsx/util/ms_offcrypto.rb~ +0 -0
  59. data/lib/axlsx/util/parser.rb +43 -0
  60. data/lib/axlsx/util/parser.rb~ +6 -0
  61. data/lib/axlsx/util/simple_typed_list.rb +160 -0
  62. data/lib/axlsx/util/validators.rb +132 -0
  63. data/lib/axlsx/version.rb +4 -0
  64. data/lib/axlsx/workbook/workbook.rb +161 -0
  65. data/lib/axlsx/workbook/worksheet/cell.rb +350 -0
  66. data/lib/axlsx/workbook/worksheet/row.rb +107 -0
  67. data/lib/axlsx/workbook/worksheet/worksheet.rb +335 -0
  68. data/lib/axlsx.rb +59 -0
  69. data/test/drawing/tc_axis.rb +1 -1
  70. data/test/drawing/tc_cat_axis.rb +1 -1
  71. data/test/drawing/tc_line_series.tc~ +34 -0
  72. data/test/drawing/tc_picture_locking.rb~ +77 -0
  73. data/test/tc_package.rb +10 -0
  74. data/test/workbook/worksheet/tc_cell.rb +15 -0
  75. data/test/workbook/worksheet/tc_worksheet.rb +22 -1
  76. metadata +117 -5
  77. data/examples/follow_20111202.xlsx +0 -0
@@ -0,0 +1,216 @@
1
+ module Axlsx
2
+
3
+ # XML Encoding
4
+ ENCODING = "UTF-8"
5
+
6
+ # spreadsheetML namespace
7
+ XML_NS = "http://schemas.openxmlformats.org/spreadsheetml/2006/main"
8
+
9
+ # content-types namespace
10
+ XML_NS_T = "http://schemas.openxmlformats.org/package/2006/content-types"
11
+
12
+ # extended-properties namespace
13
+ APP_NS = "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"
14
+
15
+ # doc props namespace
16
+ APP_NS_VT = "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"
17
+
18
+ # core properties namespace
19
+ CORE_NS = "http://schemas.openxmlformats.org/package/2006/metadata/core-properties"
20
+
21
+ # dc elements (core) namespace
22
+ CORE_NS_DC = "http://purl.org/dc/elements/1.1/"
23
+
24
+ # dcmit (core) namespcace
25
+ CORE_NS_DCMIT = "http://purl.org/dc/dcmitype/"
26
+
27
+ # dc terms namespace
28
+ CORE_NS_DCT = "http://purl.org/dc/terms/"
29
+
30
+ # xml schema namespace
31
+ CORE_NS_XSI = "http://www.w3.org/2001/XMLSchema-instance"
32
+
33
+ # spreadsheet drawing namespace
34
+ XML_NS_XDR = "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"
35
+
36
+ # drawing namespace
37
+ XML_NS_A = "http://schemas.openxmlformats.org/drawingml/2006/main"
38
+
39
+ # chart namespace
40
+ XML_NS_C = "http://schemas.openxmlformats.org/drawingml/2006/chart"
41
+
42
+ # relationships namespace
43
+ XML_NS_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships"
44
+
45
+
46
+ # relationships name space
47
+ RELS_R = "http://schemas.openxmlformats.org/package/2006/relationships"
48
+
49
+ # table rels namespace
50
+ TABLE_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/table"
51
+
52
+ # workbook rels namespace
53
+ WORKBOOK_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"
54
+
55
+ # worksheet rels namespace
56
+ WORKSHEET_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet"
57
+
58
+ # app rels namespace
59
+ APP_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties"
60
+
61
+ # core rels namespace
62
+ CORE_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/metadata/core-properties"
63
+
64
+ # styles rels namespace
65
+ STYLES_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"
66
+
67
+ # drawing rels namespace
68
+ DRAWING_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing"
69
+
70
+ # chart rels namespace
71
+ CHART_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart"
72
+
73
+ # image rels namespace
74
+ IMAGE_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"
75
+
76
+ # table content type
77
+ TABLE_CT = "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml"
78
+
79
+ # workbook content type
80
+ WORKBOOK_CT = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"
81
+
82
+ # app content type
83
+ APP_CT = "application/vnd.openxmlformats-officedocument.extended-properties+xml"
84
+
85
+ # rels content type
86
+ RELS_CT = "application/vnd.openxmlformats-package.relationships+xml"
87
+
88
+ # styles content type
89
+ STYLES_CT = "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"
90
+
91
+ # xml content type
92
+ XML_CT = "application/xml"
93
+
94
+ # worksheet content type
95
+ WORKSHEET_CT = "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"
96
+
97
+ # shared strings content type
98
+ SHARED_STRINGS_CT = "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"
99
+
100
+ # core content type
101
+ CORE_CT = "application/vnd.openxmlformats-package.core-properties+xml"
102
+
103
+ # chart content type
104
+ CHART_CT = "application/vnd.openxmlformats-officedocument.drawingml.chart+xml"
105
+
106
+ # jpeg content type
107
+ JPEG_CT = "image/jpeg"
108
+
109
+ # gif content type
110
+ GIF_CT = "image/gif"
111
+
112
+ # png content type
113
+ PNG_CT = "image/png"
114
+
115
+ #drawing content type
116
+ DRAWING_CT = "application/vnd.openxmlformats-officedocument.drawing+xml"
117
+
118
+ # xml content type extensions
119
+ XML_EX = "xml"
120
+
121
+ # jpeg extension
122
+ JPEG_EX = "jpeg"
123
+
124
+ # gif extension
125
+ GIF_EX = "gif"
126
+
127
+ # png extension
128
+ PNG_EX = "png"
129
+
130
+ # rels content type extension
131
+ RELS_EX = "rels"
132
+
133
+ # workbook part
134
+ WORKBOOK_PN = "xl/workbook.xml"
135
+
136
+ # styles part
137
+ STYLES_PN = "styles.xml"
138
+
139
+ # app part
140
+ APP_PN = "docProps/app.xml"
141
+
142
+ # core part
143
+ CORE_PN = "docProps/core.xml"
144
+
145
+ # content types part
146
+ CONTENT_TYPES_PN = "[Content_Types].xml"
147
+
148
+ # rels part
149
+ RELS_PN = "_rels/.rels"
150
+
151
+ # workbook rels part
152
+ WORKBOOK_RELS_PN = "xl/_rels/workbook.xml.rels"
153
+
154
+ # worksheet part
155
+ WORKSHEET_PN = "worksheets/sheet%d.xml"
156
+
157
+ # worksheet rels part
158
+ WORKSHEET_RELS_PN = "worksheets/_rels/sheet%d.xml.rels"
159
+
160
+ # drawing part
161
+ DRAWING_PN = "drawings/drawing%d.xml"
162
+
163
+ # drawing rels part
164
+ DRAWING_RELS_PN = "drawings/_rels/drawing%d.xml.rels"
165
+
166
+ # chart part
167
+ CHART_PN = "charts/chart%d.xml"
168
+
169
+ # chart part
170
+ IMAGE_PN = "media/image%d.%s"
171
+
172
+ # App validation schema
173
+ APP_XSD = "lib/schema/shared-documentPropertiesExtended.xsd"
174
+
175
+ # core validation schema
176
+ CORE_XSD = "lib/schema/opc-coreProperties.xsd"
177
+
178
+ # content types validation schema
179
+ CONTENT_TYPES_XSD = "lib/schema/opc-contentTypes.xsd"
180
+
181
+ # rels validation schema
182
+ RELS_XSD = "lib/schema/opc-relationships.xsd"
183
+
184
+ # spreadsheetML validation schema
185
+ SML_XSD = "lib/schema/sml.xsd"
186
+
187
+ # drawing validation schema
188
+ DRAWING_XSD = "lib/schema/dml-spreadsheetDrawing.xsd"
189
+
190
+ # number format id for pecentage formatting using the default formatting id.
191
+ NUM_FMT_PERCENT = 9
192
+
193
+ # number format id for date format like 2011/11/13
194
+ NUM_FMT_YYYYMMDD = 100
195
+
196
+ # number format id for time format the creates 2011/11/13 12:23:10
197
+ NUM_FMT_YYYYMMDDHHMMSS = 101
198
+
199
+ # cellXfs id for thin borders around the cell
200
+ STYLE_THIN_BORDER = 1
201
+
202
+ # cellXfs id for default date styling
203
+ STYLE_DATE = 2
204
+
205
+ # error messages RestrictionValidor
206
+ ERR_RESTRICTION = "Invalid Data: %s. %s must be one of %s."
207
+
208
+ # error message DataTypeValidator
209
+ ERR_TYPE = "Invalid Data %s for %s. must be %s."
210
+
211
+ # error message for RegexValidator
212
+ ERR_REGEX = "Invalid Data. %s does not match %s."
213
+
214
+ # error message for duplicate sheet names
215
+ ERR_DUPLICATE_SHEET_NAME = "There is already a worksheet in this workbook named '%s'. Please use a unique name"
216
+ end
@@ -0,0 +1,88 @@
1
+ require 'digest'
2
+ require 'base64'
3
+ require 'openssl'
4
+ module Axlsx
5
+ class MsOffCrypto
6
+
7
+ attr_reader :verifier
8
+ attr_reader :key
9
+
10
+ def initialize(password = "passowrd")
11
+ @password = password
12
+ @salt_size = 0x10
13
+ @key_size = 0x100
14
+ @verifier = rand(16**16).to_s
15
+
16
+ #fixed salt for testing
17
+ @salt = [0x90,0xAC,0x68,0x0E,0x76,0xF9,0x43,0x2B,0x8D,0x13,0xB7,0x1D,0xB7,0xC0,0xFC,0x0D].join
18
+ # @salt =Digest::SHA1.digest(rand(16**16).to_s)
19
+ end
20
+
21
+ def encryption_info
22
+ # v.major v.minor flags header length flags size # AES 128 bit
23
+ header = [3, 0, 2, 0, 0x24, 0, 0, 0, 0xA4, 0, 0, 0, 0x24, 0, 0, 0, 0, 0, 0, 0, 0x0E, 0x66, 0, 0]
24
+ header.concat [0x04, 0x80, 0, 0, 0x80, 0, 0, 0, 0x18, 0, 0, 0, 0xA0, 0xC7, 0xDC, 0x2, 0, 0, 0, 0]
25
+ header.concat "Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)".bytes.to_a.pack('s*').bytes.to_a
26
+ header.concat [0, 0]
27
+ header.concat [0x10, 0, 0, 0]
28
+ header.concat [0x90,0xAC,0x68,0x0E,0x76,0xF9,0x43,0x2B,0x8D,0x13,0xB7,0x1D,0xB7,0xC0,0xFC,0x0D]
29
+ header.concat encrypted_verifier.bytes.to_a.pack('c*').bytes.to_a
30
+ header.concat [20, 0,0,0]
31
+ header.concat encrypted_verifier_hash.bytes.to_a.pack('c*').bytes.to_a
32
+ header.flatten!
33
+ header.pack('c*')
34
+ end
35
+
36
+ def encryption_verifier
37
+ {:salt_size => @salt_size,
38
+ :salt => @salt,
39
+ :encrypted_verifier => encrypted_verifier,
40
+ :varifier_hash_size => 0x14,
41
+ :encrypted_verifier_hash => encrypted_verifier_hash}
42
+ end
43
+
44
+ # 2.3.3
45
+ def encrypted_verifier
46
+ @encrypted_verifier ||= encrypt(@verifier)
47
+ end
48
+
49
+ # 2.3.3
50
+ def encrypted_verifier_hash
51
+ verifier_hash = Digest::SHA1.digest(@verifier)
52
+ verifier_hash << Array.new(32 - verifier_hash.size, 0).join('')
53
+ @encrypted_verifier_hash ||= encrypt(verifier_hash)
54
+ end
55
+
56
+ # 2.3.4.7 ECMA-376 Document Encryption Key Generation (Standard Encryption)
57
+ def key
58
+ sha = Digest::SHA1.new() << (@salt + @password)
59
+ (0..49999).each { |i| sha.update(i.to_s+sha.to_s) }
60
+ key = sha.update(sha.to_s+'0').digest
61
+ a = key.bytes.each_with_index.map { |item, i| 0x36 ^ item }
62
+ x1 = Digest::SHA1.digest((a.concat Array.new(64 - key.size, 0x36)).to_s)
63
+ a = key.bytes.each_with_index.map { |item, i| 0x5C ^ item }
64
+ x2 = Digest::SHA1.digest( (a.concat Array.new(64 - key.size, 0x5C) ).to_s)
65
+ x3 = x1 + x2
66
+ @key ||= x3.bytes.to_a[(0..31)].pack('c*')
67
+ end
68
+
69
+ def verify_password
70
+ puts decrypt(@encrypted_verifier)
71
+ end
72
+
73
+ def encrypt(data)
74
+ aes = OpenSSL::Cipher.new("AES-128-ECB")
75
+ aes.encrypt
76
+ aes.key = key
77
+ aes.update(data)
78
+ end
79
+
80
+ def decrypt(data)
81
+ aes = OpenSSL::Cipher.new("AES-128-ECB")
82
+ aes.decrypt
83
+ aes.key = key
84
+ aes.update(data)
85
+ end
86
+
87
+ end
88
+ end
@@ -0,0 +1,3 @@
1
+ module Axlsx
2
+ class MsOffcrypto
3
+ end
File without changes
@@ -0,0 +1,43 @@
1
+ module Axlsx
2
+ # The Parser module mixes in a number of methods to help in generating a model from xml
3
+ # This module is not included in the axlsx library at this time. It is for future development only,
4
+ module Parser
5
+
6
+ # The xml to be parsed
7
+ attr_accessor :parser_xml
8
+
9
+ # parse and assign string attribute
10
+ def parse_string attr_name, xpath
11
+ send("#{attr_name.to_s}=", parse_value(xpath))
12
+ end
13
+
14
+ # parse convert and assign node text to symbol
15
+ def parse_symbol attr_name, xpath
16
+ v = parse_value xpath
17
+ v = v.to_sym unless v.nil?
18
+ send("#{attr_name.to_s}=", v)
19
+ end
20
+
21
+ # parse, convert and assign note text to integer
22
+ def parse_integer attr_name, xpath
23
+ v = parse_value xpath
24
+ v = v.to_i if v.respond_to?(:to_i)
25
+ send("#{attr_name.to_s}=", v)
26
+ end
27
+
28
+ # parse, convert and assign node text to float
29
+ def parse_float attr_name, xpath
30
+ v = parse_value xpath
31
+ v = v.to_f if v.respond_to?(:to_f)
32
+ send("#{attr_name.to_s}=", v)
33
+ end
34
+
35
+ # return node text based on xpath
36
+ def parse_value xpath
37
+ node = parser_xml.xpath(xpath)
38
+ return nil if node.empty?
39
+ node.text.strip
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,6 @@
1
+ module Axlsx
2
+ # THe Parser class unzips an xlsx spread sheet and populates a new axlsx package from it.
3
+ class Parser
4
+
5
+ end
6
+ end
@@ -0,0 +1,160 @@
1
+ module Axlsx
2
+ # A SimpleTypedList is a type restrictive collection that allows some of the methods from Array and supports basic xml serialization.
3
+ # @private
4
+ class SimpleTypedList
5
+ # The class constants of allowed types
6
+ # @return [Array]
7
+ attr_reader :allowed_types
8
+
9
+ # The index below which items cannot be removed
10
+ # @return [Integer]
11
+ attr_reader :locked_at
12
+
13
+ # The tag name to use when serializing this object
14
+ # by default the parent node for all items in the list is the classname of the first allowed type with the first letter in lowercase.
15
+ # @return [String]
16
+ attr_reader :serialize_as
17
+
18
+ # Creats a new typed list
19
+ # @param [Array, Class] type An array of Class objects or a single Class object
20
+ # @param [String] serialize The tag name to use in serialization
21
+ # @raise [ArgumentError] if all members of type are not Class objects
22
+ def initialize type, serialize_as=nil
23
+ if type.is_a? Array
24
+ type.each { |item| raise ArgumentError, "All members of type must be Class objects" unless item.is_a? Class }
25
+ @allowed_types = type
26
+ else
27
+ raise ArgumentError, "Type must be a Class object or array of Class objects" unless type.is_a? Class
28
+ @allowed_types = [type]
29
+ end
30
+ @list = []
31
+ @locked_at = nil
32
+ @serialize_as = serialize_as
33
+ end
34
+
35
+ # Lock this list at the current size
36
+ # @return [self]
37
+ def lock
38
+ @locked_at = @list.size
39
+ self
40
+ end
41
+
42
+ def to_ary
43
+ @list
44
+ end
45
+
46
+ # Unlock the list
47
+ # @return [self]
48
+ def unlock
49
+ @locked_at = nil
50
+ self
51
+ end
52
+
53
+ # Concat operator
54
+ # @param [Any] v the data to be added
55
+ # @raise [ArgumentError] if the value being added is not one fo the allowed types
56
+ # @return [Integer] returns the index of the item added.
57
+ def <<(v)
58
+ DataTypeValidator.validate "SimpleTypedList.<<", @allowed_types, v
59
+ @list << v
60
+ @list.size - 1
61
+ end
62
+
63
+ # alternate of << method
64
+ # @see <<
65
+ def push(v)
66
+ self.<< v
67
+ end
68
+
69
+ # delete the item from the list
70
+ # @param [Any] v The item to be deleted.
71
+ # @raise [ArgumentError] if the item's index is protected by locking
72
+ # @return [Any] The item deleted
73
+ def delete(v)
74
+ return unless @list.include? v
75
+ raise ArgumentError, "Item is protected and cannot be deleted" if protected? @list.index(v)
76
+ @list.delete v
77
+ end
78
+
79
+ # delete the item from the list at the index position provided
80
+ # @raise [ArgumentError] if the index is protected by locking
81
+ # @return [Any] The item deleted
82
+ def delete_at(index)
83
+ @list[index]
84
+ raise ArgumentError, "Item is protected and cannot be deleted" if protected? index
85
+ @list.delete_at index
86
+ end
87
+
88
+ # positional assignment. Adds the item at the index specified
89
+ # @param [Integer] index
90
+ # @param [Any] v
91
+ # @raise [ArgumentError] if the index is protected by locking
92
+ # @raise [ArgumentError] if the item is not one of the allowed types
93
+ def []=(index, v)
94
+ DataTypeValidator.validate "SimpleTypedList.<<", @allowed_types, v
95
+ raise ArgumentError, "Item is protected and cannot be changed" if protected? index
96
+ @list[index] = v
97
+ v
98
+ end
99
+
100
+ # determines if the index is protected
101
+ # @param [Integer] index
102
+ def protected? index
103
+ return false unless @locked_at.is_a? Fixnum
104
+ index < @locked_at
105
+ end
106
+
107
+ # override the equality method so that this object can be compared to a simple array.
108
+ # if this object's list is equal to the specifiec array, we return true.
109
+ def ==(v)
110
+ v == @list
111
+ end
112
+ # method_mission override to pass allowed methods to the list.
113
+ # @note
114
+ # the following methods are not allowed
115
+ # :replace
116
+ # :insert
117
+ # :collect!
118
+ # :map!
119
+ # :pop
120
+ # :delete_if
121
+ # :reverse!
122
+ # :shift
123
+ # :shuffle!
124
+ # :slice!
125
+ # :sort!
126
+ # :uniq!
127
+ # :unshift
128
+ # :zip
129
+ # :flatten!
130
+ # :fill
131
+ # :drop
132
+ # :drop_while
133
+ # :delete_if
134
+ # :clear
135
+ def method_missing(meth, *args, &block)
136
+ raise ArgumentError, "#{meth} not supported" if [:replace, :insert, :collect!, :map!, :pop, :delete_if, :reverse!, :shift, :shuffle!, :slice!, :sort!, :uniq!, :unshift, :zip, :flatten!, :fill, :drop, :drop_while, :delete_if, :clear].include? meth.to_sym
137
+ if @list.respond_to? meth
138
+ @list.send(meth, *args, &block)
139
+ else
140
+ puts "method:#{meth.inspect}"
141
+ super
142
+ end
143
+ end
144
+
145
+ # Serializes the list
146
+ # If the serialize_as property is set, it is used as the parent node name.
147
+ # If the serialize_as property is nil, the first item in the list of allowed_types will be used, having the first letter of the class changed to lower case.
148
+ # @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
149
+ # @return [String]
150
+ def to_xml(xml)
151
+ classname = @allowed_types[0].name.split('::').last
152
+ el_name = serialize_as || (classname[0,1].downcase + classname[1..-1]).pluralize
153
+ xml.send(el_name, :count=>@list.size) {
154
+ @list.each { |item| item.to_xml(xml) }
155
+ }
156
+ end
157
+ end
158
+
159
+
160
+ end
@@ -0,0 +1,132 @@
1
+ module Axlsx
2
+ # Validate a value against a specific list of allowed values.
3
+ class RestrictionValidator
4
+ # Perform validation
5
+ # @param [String] name The name of what is being validatied. This is included in the error message
6
+ # @param [Array] choices The list of choices to validate against
7
+ # @param [Any] v The value to be validated
8
+ # @raise [ArgumentError] Raised if the value provided is not in the list of choices.
9
+ # @return [Boolean] true if validation succeeds.
10
+ def self.validate(name, choices, v)
11
+ raise ArgumentError, (ERR_RESTRICTION % [v.to_s, name, choices.inspect]) unless choices.include?(v)
12
+ true
13
+ end
14
+ end
15
+
16
+ # Validates the value against the regular expression provided.
17
+ class RegexValidator
18
+ # @param [String] name The name of what is being validated. This is included in the output when the value is invalid
19
+ # @param [Regexp] regex The regular expression to evaluate
20
+ # @param [Any] v The value to validate.
21
+ def self.validate(name, regex, v)
22
+ raise ArgumentError, (ERR_REGEX % [v.inspect, regex.to_s]) unless (v.respond_to?(:=~) && v =~ regex)
23
+ end
24
+ end
25
+ # Validate that the class of the value provided is either an instance or the class of the allowed types and that any specified additional validation returns true.
26
+ class DataTypeValidator
27
+ # Perform validation
28
+ # @param [String] name The name of what is being validated. This is included in the error message
29
+ # @param [Array, Class] types A single class or array of classes that the value is validated against.
30
+ # @param [Block] other Any block that must evaluate to true for the value to be valid
31
+ # @raise [ArugumentError] Raised if the class of the value provided is not in the specified array of types or the block passed returns false
32
+ # @return [Boolean] true if validation succeeds.
33
+ # @see validate_boolean
34
+ def self.validate(name, types, v, other= lambda{|arg| true })
35
+ types = [types] unless types.is_a? Array
36
+ valid_type = false
37
+ if v.class == Class
38
+ types.each { |t| valid_type = true if v.ancestors.include?(t) }
39
+ else
40
+ types.each { |t| valid_type = true if v.is_a?(t) }
41
+ end
42
+ raise ArgumentError, (ERR_TYPE % [v.inspect, name, types.inspect]) unless (other.call(v) && valid_type)
43
+ end
44
+ true
45
+ end
46
+
47
+ # Requires that the value is a Fixnum or Integer and is greater or equal to 0
48
+ # @param [Any] v The value validated
49
+ # @raise [ArgumentError] raised if the value is not a Fixnum or Integer value greater or equal to 0
50
+ # @return [Boolean] true if the data is valid
51
+ def self.validate_unsigned_int(v)
52
+ DataTypeValidator.validate(:unsigned_int, [Fixnum, Integer], v, lambda { |arg| arg.respond_to?(:>=) && arg >= 0 })
53
+ end
54
+
55
+ # Requires that the value is a Fixnum or Integer
56
+ # @param [Any] v The value validated
57
+ def self.validate_int(v)
58
+ DataTypeValidator.validate :unsigned_int, [Fixnum, Integer], v
59
+ end
60
+
61
+ # Requires that the value is a form that can be evaluated as a boolean in an xml document.
62
+ # The value must be an instance of Fixnum, String, Integer, Symbol, TrueClass or FalseClass and
63
+ # it must be one of 0, 1, "true", "false", :true, :false, true, false, "0", or "1"
64
+ # @param [Any] v The value validated
65
+ def self.validate_boolean(v)
66
+ DataTypeValidator.validate(:boolean, [Fixnum, String, Integer, Symbol, TrueClass, FalseClass], v, lambda { |arg| [0, 1, "true", "false", :true, :false, true, false, "0", "1"].include?(arg) })
67
+ end
68
+
69
+ # Requires that the value is a String
70
+ # @param [Any] v The value validated
71
+ def self.validate_string(v)
72
+ DataTypeValidator.validate :string, String, v
73
+ end
74
+
75
+ # Requires that the value is a Float
76
+ # @param [Any] v The value validated
77
+ def self.validate_float(v)
78
+ DataTypeValidator.validate :float, Float, v
79
+ end
80
+
81
+ # Requires that the value is valid pattern type.
82
+ # valid pattern types must be one of :none, :solid, :mediumGray, :darkGray, :lightGray, :darkHorizontal, :darkVertical, :darkDown,
83
+ # :darkUp, :darkGrid, :darkTrellis, :lightHorizontal, :lightVertical, :lightDown, :lightUp, :lightGrid, :lightTrellis, :gray125, or :gray0625.
84
+ # @param [Any] v The value validated
85
+ def self.validate_pattern_type(v)
86
+ RestrictionValidator.validate :pattern_type, [:none, :solid, :mediumGray, :darkGray, :lightGray, :darkHorizontal, :darkVertical, :darkDown, :darkUp, :darkGrid,
87
+ :darkTrellis, :lightHorizontal, :lightVertical, :lightDown, :lightUp, :lightGrid, :lightTrellis, :gray125, :gray0625], v
88
+ end
89
+
90
+ # Requires that the value is a gradient_type.
91
+ # valid types are :linear and :path
92
+ # @param [Any] v The value validated
93
+ def self.validate_gradient_type(v)
94
+ RestrictionValidator.validate :gradient_type, [:linear, :path], v
95
+ end
96
+
97
+ # Requires that the value is a valid horizontal_alignment
98
+ # :general, :left, :center, :right, :fill, :justify, :centerContinuous, :distributed are allowed
99
+ # @param [Any] v The value validated
100
+ def self.validate_horizontal_alignment(v)
101
+ RestrictionValidator.validate :horizontal_alignment, [:general, :left, :center, :right, :fill, :justify, :centerContinuous, :distributed], v
102
+ end
103
+
104
+ # Requires that the value is a valid vertical_alignment
105
+ # :top, :center, :bottom, :justify, :distributed are allowed
106
+ # @param [Any] v The value validated
107
+ def self.validate_vertical_alignment(v)
108
+ RestrictionValidator.validate :vertical_alignment, [:top, :center, :bottom, :justify, :distributed], v
109
+ end
110
+
111
+ # Requires that the value is a valid content_type
112
+ # TABLE_CT, WORKBOOK_CT, APP_CT, RELS_CT, STYLES_CT, XML_CT, WORKSHEET_CT, SHARED_STRINGS_CT, CORE_CT, CHART_CT, DRAWING_CT are allowed
113
+ # @param [Any] v The value validated
114
+ def self.validate_content_type(v)
115
+ RestrictionValidator.validate :content_type, [TABLE_CT, WORKBOOK_CT, APP_CT, RELS_CT, STYLES_CT, XML_CT, WORKSHEET_CT, SHARED_STRINGS_CT, CORE_CT, CHART_CT, JPEG_CT, GIF_CT, PNG_CT, DRAWING_CT], v
116
+ end
117
+
118
+ # Requires that the value is a valid relationship_type
119
+ # XML_NS_R, TABLE_R, WORKBOOK_R, WORKSHEET_R, APP_R, RELS_R, CORE_R, STYLES_R, CHART_R, DRAWING_R are allowed
120
+ # @param [Any] v The value validated
121
+ def self.validate_relationship_type(v)
122
+ RestrictionValidator.validate :relationship_type, [XML_NS_R, TABLE_R, WORKBOOK_R, WORKSHEET_R, APP_R, RELS_R, CORE_R, STYLES_R, CHART_R, DRAWING_R, IMAGE_R], v
123
+ end
124
+
125
+ # Requires that the value is a valid table element type
126
+ # :wholeTable, :headerRow, :totalRow, :firstColumn, :lastColumn, :firstRowStripe, :secondRowStripe, :firstColumnStripe, :secondColumnStripe, :firstHeaderCell, :lastHeaderCell, :firstTotalCell, :lastTotalCell, :firstSubtotalColumn, :secondSubtotalColumn, :thirdSubtotalColumn, :firstSubtotalRow, :secondSubtotalRow, :thirdSubtotalRow, :blankRow, :firstColumnSubheading, :secondColumnSubheading, :thirdColumnSubheading, :firstRowSubheading, :secondRowSubheading, :thirdRowSubheading, :pageFieldLabels, :pageFieldValues are allowed
127
+ # @param [Any] v The value validated
128
+ def self.validate_table_element_type(v)
129
+ RestrictionValidator.validate :table_element_type, [:wholeTable, :headerRow, :totalRow, :firstColumn, :lastColumn, :firstRowStripe, :secondRowStripe, :firstColumnStripe, :secondColumnStripe, :firstHeaderCell, :lastHeaderCell, :firstTotalCell, :lastTotalCell, :firstSubtotalColumn, :secondSubtotalColumn, :thirdSubtotalColumn, :firstSubtotalRow, :secondSubtotalRow, :thirdSubtotalRow, :blankRow, :firstColumnSubheading, :secondColumnSubheading, :thirdColumnSubheading, :firstRowSubheading, :secondRowSubheading, :thirdRowSubheading, :pageFieldLabels, :pageFieldValues], v
130
+ end
131
+
132
+ end
@@ -0,0 +1,4 @@
1
+ module Axlsx
2
+ # version
3
+ VERSION="1.0.14"
4
+ end