axlsx 1.0.15 → 1.0.16
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +23 -0
- data/README.md +50 -53
- data/examples/example.rb +14 -2
- data/lib/axlsx/content_type/content_type.rb +1 -1
- data/lib/axlsx/doc_props/app.rb +1 -1
- data/lib/axlsx/doc_props/core.rb +1 -1
- data/lib/axlsx/drawing/chart.rb +1 -1
- data/lib/axlsx/drawing/drawing.rb +12 -1
- data/lib/axlsx/drawing/hlink_click.rb~ +0 -0
- data/lib/axlsx/drawing/hyperlink.rb +95 -0
- data/lib/axlsx/drawing/hyperlink.rb~ +64 -0
- data/lib/axlsx/drawing/pic.rb +29 -3
- data/lib/axlsx/package.rb +4 -4
- data/lib/axlsx/rels/relationship.rb +16 -1
- data/lib/axlsx/rels/relationships.rb +1 -1
- data/lib/axlsx/stylesheet/styles.rb +1 -1
- data/lib/axlsx/util/cbf.rb +68 -33
- data/lib/axlsx/util/constants.rb +12 -6
- data/lib/axlsx/util/ms_off_crypto.rb +9 -9
- data/lib/axlsx/util/storage.rb +0 -1
- data/lib/axlsx/util/validators.rb +1 -1
- data/lib/axlsx/version.rb +4 -2
- data/lib/axlsx/workbook/workbook.rb +14 -4
- data/lib/axlsx/workbook/worksheet/worksheet.rb +2 -1
- data/test/drawing/tc_hyperlink.rb +70 -0
- data/test/drawing/tc_hyperlink.rb~ +71 -0
- data/test/drawing/tc_pic.rb +6 -0
- data/test/rels/tc_relationship.rb +5 -0
- data/test/workbook/worksheet/tc_worksheet.rb +7 -0
- metadata +27 -24
- data/test/drawing/tc_line_series.tc~ +0 -34
- data/test/drawing/tc_picture_locking.rb~ +0 -77
data/lib/axlsx/drawing/pic.rb
CHANGED
@@ -47,7 +47,24 @@ module Axlsx
|
|
47
47
|
yield self if block_given?
|
48
48
|
@picture_locking = PictureLocking.new(options)
|
49
49
|
end
|
50
|
+
|
51
|
+
attr_reader :hyperlink
|
50
52
|
|
53
|
+
# sets or updates a hyperlink for this image.
|
54
|
+
# @param [String] v The href value for the hyper link
|
55
|
+
# @option options @see Hyperlink#initialize All options available to the Hyperlink class apply - however href will be overridden with the v parameter value.
|
56
|
+
def hyperlink=(v, options={})
|
57
|
+
options[:href] = v
|
58
|
+
if @hyperlink.is_a?(Hyperlink)
|
59
|
+
options.each do |o|
|
60
|
+
@hyperlink.send("#{o[0]}=", o[1]) if @hyperlink.respond_to? "#{o[0]}="
|
61
|
+
end
|
62
|
+
else
|
63
|
+
@hyperlink = Hyperlink.new(self, options)
|
64
|
+
end
|
65
|
+
@hyperlink
|
66
|
+
end
|
67
|
+
|
51
68
|
def image_src=(v)
|
52
69
|
Axlsx::validate_string(v)
|
53
70
|
RestrictionValidator.validate 'Pic.image_src', ALLOWED_EXTENSIONS, File.extname(v).delete('.')
|
@@ -75,7 +92,7 @@ module Axlsx
|
|
75
92
|
end
|
76
93
|
|
77
94
|
# The index of this image in the workbooks images collections
|
78
|
-
# @return [Index]
|
95
|
+
# @return [Index]
|
79
96
|
def index
|
80
97
|
@anchor.drawing.worksheet.workbook.images.index(self)
|
81
98
|
end
|
@@ -86,6 +103,11 @@ module Axlsx
|
|
86
103
|
"#{IMAGE_PN % [(index+1), extname]}"
|
87
104
|
end
|
88
105
|
|
106
|
+
# The relational id withing the drawing's relationships
|
107
|
+
def id
|
108
|
+
@anchor.drawing.charts.size + @anchor.drawing.images.index(self) + 1
|
109
|
+
end
|
110
|
+
|
89
111
|
# providing access to the anchor's width attribute
|
90
112
|
# @param [Integer] v
|
91
113
|
# @see OneCellAnchor.width
|
@@ -127,13 +149,17 @@ module Axlsx
|
|
127
149
|
def to_xml(xml)
|
128
150
|
xml.pic {
|
129
151
|
xml.nvPicPr {
|
130
|
-
xml.cNvPr
|
152
|
+
xml.cNvPr(:id=>"2", :name=>name, :descr=>descr) {
|
153
|
+
if @hyperlink.is_a?(Hyperlink)
|
154
|
+
@hyperlink.to_xml(xml)
|
155
|
+
end
|
156
|
+
}
|
131
157
|
xml.cNvPicPr {
|
132
158
|
picture_locking.to_xml(xml)
|
133
159
|
}
|
134
160
|
}
|
135
161
|
xml.blipFill {
|
136
|
-
xml[:a].blip :'xmlns:r' => XML_NS_R, :'r:embed'=>"
|
162
|
+
xml[:a].blip :'xmlns:r' => XML_NS_R, :'r:embed'=>"rId#{id}"
|
137
163
|
xml[:a].stretch {
|
138
164
|
xml.fillRect
|
139
165
|
}
|
data/lib/axlsx/package.rb
CHANGED
@@ -89,10 +89,10 @@ module Axlsx
|
|
89
89
|
end
|
90
90
|
|
91
91
|
# Encrypt the package into a CFB using the password provided
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
92
|
+
def encrypt(file_name, password)
|
93
|
+
moc = MsOffCrypto.new(file_name, password)
|
94
|
+
moc.save
|
95
|
+
end
|
96
96
|
|
97
97
|
# Validate all parts of the package against xsd schema.
|
98
98
|
# @return [Array] An array of all validation errors found.
|
@@ -21,9 +21,21 @@ module Axlsx
|
|
21
21
|
# @see DRAWING_R
|
22
22
|
# @return [String]
|
23
23
|
attr_reader :Type
|
24
|
-
|
24
|
+
|
25
|
+
# The target mode of the relationship
|
26
|
+
# used for hyperlink type relationships to mark the relationship to an external resource
|
27
|
+
# TargetMode can be specified during initialization by passing in a :target_mode option
|
28
|
+
# Target mode must be :external for now.
|
29
|
+
attr_reader :TargetMode
|
30
|
+
|
31
|
+
# creates a new relationship
|
32
|
+
# @param [String] Type The type of the relationship
|
33
|
+
# @param [String] Target The target for the relationship
|
34
|
+
# @option [Symbol] target_mode only accepts :external.
|
35
|
+
def initialize(type, target, options={})
|
25
36
|
self.Target=target
|
26
37
|
self.Type=type
|
38
|
+
self.TargetMode = options.delete(:target_mode) if options[:target_mode]
|
27
39
|
end
|
28
40
|
|
29
41
|
# @see Target
|
@@ -31,6 +43,9 @@ module Axlsx
|
|
31
43
|
# @see Type
|
32
44
|
def Type=(v) Axlsx::validate_relationship_type v; @Type = v end
|
33
45
|
|
46
|
+
# @see TargetMode
|
47
|
+
def TargetMode=(v) RestrictionValidator.validate 'Relationship.TargetMode', [:External, :Internal], v; @TargetMode = v; end
|
48
|
+
|
34
49
|
# Serializes the relationship
|
35
50
|
# @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
|
36
51
|
# @param [String] rId the reference id of the object.
|
data/lib/axlsx/util/cbf.rb
CHANGED
@@ -10,13 +10,13 @@ module Axlsx
|
|
10
10
|
VERSION_PACKING = 'l s30 l3'
|
11
11
|
|
12
12
|
# The serialization for the MS-OFF-CRYPTO dataspace map stream
|
13
|
-
DATA_SPACE_MAP_PACKING = 'l6 s16 l s25'
|
13
|
+
DATA_SPACE_MAP_PACKING = 'l6 s16 l s25 x2'
|
14
14
|
|
15
15
|
# The serialization for the MS-OFF-CRYPTO strong encrytion data space stream
|
16
|
-
STRONG_ENCRYPTION_DATA_SPACE_PACKING = 'l3
|
16
|
+
STRONG_ENCRYPTION_DATA_SPACE_PACKING = 'l3 s26'
|
17
17
|
|
18
18
|
# The serialization for the MS-OFF-CRYPTO primary stream
|
19
|
-
PRIMARY_PACKING = 'l3 s38 l
|
19
|
+
PRIMARY_PACKING = 'l3 s38 l s40 l3 x12 l'
|
20
20
|
|
21
21
|
# The cutoff size that determines if a stream should be in the mini-fat or the fat
|
22
22
|
MINI_CUTOFF = 4096
|
@@ -28,6 +28,7 @@ module Axlsx
|
|
28
28
|
# @param [MsOffCrypto] ms_off_crypto
|
29
29
|
def initialize(ms_off_crypto)
|
30
30
|
@file_name = ms_off_crypto.file_name
|
31
|
+
@ms_off_crypto = ms_off_crypto
|
31
32
|
create_storages
|
32
33
|
mini_fat_stream
|
33
34
|
mini_fat
|
@@ -95,6 +96,17 @@ module Axlsx
|
|
95
96
|
@header ||= create_header
|
96
97
|
end
|
97
98
|
|
99
|
+
# returns the encryption info from the ms_off_crypt object provided during intialization
|
100
|
+
# @return [String] encryption info
|
101
|
+
def encryption_info
|
102
|
+
@ms_off_crypto.encryption_info
|
103
|
+
end
|
104
|
+
|
105
|
+
# returns the encrypted package from the ms_off_crypt object provided during initalization
|
106
|
+
# @return [String] encrypted package
|
107
|
+
def encrypted_package
|
108
|
+
@ms_off_crypto.encrypted_package
|
109
|
+
end
|
98
110
|
|
99
111
|
# writes the compound binary file to disk
|
100
112
|
def save
|
@@ -114,12 +126,11 @@ module Axlsx
|
|
114
126
|
# Generates the storages required for ms-office-cryptography cfb
|
115
127
|
def create_storages
|
116
128
|
@storages = []
|
117
|
-
@encryption_info = ms_off_crypto.encryption_info
|
118
|
-
@encrypted_package = ms_off_crypto.encrypted_package
|
119
|
-
|
120
|
-
@storages.
|
121
|
-
@storages << Storage.new('
|
122
|
-
@storages << Storage.new('EncryptedPackage', :data=>@encrypted_package, :color=>Storage::COLORS[:red], :size=>@encrypted_package.size)
|
129
|
+
@encryption_info = @ms_off_crypto.encryption_info
|
130
|
+
@encrypted_package = @ms_off_crypto.encrypted_package
|
131
|
+
|
132
|
+
@storages << Storage.new('EncryptionInfo', :data=>encryption_info, :left=>3, :right=>11) # example shows right child. do we need the summary info????
|
133
|
+
@storages << Storage.new('EncryptedPackage', :data=>encrypted_package, :color=>Storage::COLORS[:red])
|
123
134
|
@storages << Storage.new([6].pack("c")+"DataSpaces", :child=>5, :modified =>129685612740945580, :created=>129685612740819979)
|
124
135
|
@storages << version
|
125
136
|
@storages << data_space_map
|
@@ -128,6 +139,12 @@ module Axlsx
|
|
128
139
|
@storages << Storage.new('TransformInfo', :color => Storage::COLORS[:red], :child=>9, :created=>129685612740834130, :modified=>129685612740943959)
|
129
140
|
@storages << Storage.new('StrongEncryptionTransform', :child=>10, :created=>129685612740834169, :modified=>129685612740942280)
|
130
141
|
@storages << primary
|
142
|
+
# @storages << summary_information
|
143
|
+
# @storages << document_summary_information
|
144
|
+
|
145
|
+
# we do this at the end as we need to build the minifat stream to determine the size. #HOWEVER - it looks like the size should not include the padding?
|
146
|
+
@storages.unshift Storage.new('Root Entry', :type=>Storage::TYPES[:root], :color=>Storage::COLORS[:red], :child=>1, :data => mini_fat_stream)
|
147
|
+
|
131
148
|
end
|
132
149
|
|
133
150
|
# generates the mini fat stream
|
@@ -135,10 +152,11 @@ module Axlsx
|
|
135
152
|
def create_mini_fat_stream
|
136
153
|
mfs = []
|
137
154
|
@storages.select{ |s| s.type == Storage::TYPES[:stream] && s.size < MINI_CUTOFF}.each_with_index do |stream, index|
|
155
|
+
puts "#{stream.name.pack('c*')}: #{stream.data.size}"
|
138
156
|
mfs.concat stream.data
|
139
|
-
mfs.concat Array.new(64 - (mfs.size % 64), 0) if mfs.size % 64
|
157
|
+
mfs.concat Array.new(64 - (mfs.size % 64), 0) if mfs.size % 64 > 0
|
158
|
+
puts "mini fat stream size: #{mfs.size}"
|
140
159
|
end
|
141
|
-
@storages[0].size = mfs.size
|
142
160
|
mfs.concat(Array.new(512 - (mfs.size % 512), 0))
|
143
161
|
mfs.pack 'c*'
|
144
162
|
end
|
@@ -149,7 +167,7 @@ module Axlsx
|
|
149
167
|
mfs = []
|
150
168
|
@storages.select{ |s| s.type == Storage::TYPES[:stream] && s.size >= MINI_CUTOFF}.each_with_index do |stream, index|
|
151
169
|
mfs.concat stream.data
|
152
|
-
mfs.concat Array.new(512 - (mfs.size % 512), 0) if mfs.size % 512
|
170
|
+
mfs.concat Array.new(512 - (mfs.size % 512), 0) if mfs.size % 512 > 0
|
153
171
|
end
|
154
172
|
mfs.pack 'c*'
|
155
173
|
end
|
@@ -214,7 +232,7 @@ module Axlsx
|
|
214
232
|
# creates the stron encryption data space storage
|
215
233
|
# @return [Storgae]
|
216
234
|
def create_strong_encryption_data_space
|
217
|
-
v_stream = [8,1,50,"StrongEncryptionTransform".bytes.to_a].flatten.pack STRONG_ENCRYPTION_DATA_SPACE_PACKING
|
235
|
+
v_stream = [8,1,50,"StrongEncryptionTransform".bytes.to_a,0].flatten.pack STRONG_ENCRYPTION_DATA_SPACE_PACKING
|
218
236
|
Storage.new("StrongEncryptionDataSpace", :data=>v_stream, :size => v_stream.size)
|
219
237
|
end
|
220
238
|
|
@@ -222,41 +240,58 @@ module Axlsx
|
|
222
240
|
# @return [Storgae]
|
223
241
|
def create_primary
|
224
242
|
v_stream = [88,1,76,"{FF9A3F03-56EF-4613-BDD5-5A41C1D07246}".bytes.to_a].flatten
|
225
|
-
v_stream.concat [78, "Microsoft.Container.EncryptionTransform".bytes.to_a,1,1,1,4].flatten
|
243
|
+
v_stream.concat [78, "Microsoft.Container.EncryptionTransform".bytes.to_a,0,1,1,1,4].flatten
|
226
244
|
v_stream = v_stream.pack PRIMARY_PACKING
|
227
245
|
Storage.new([6].pack("c")+"Primary", :data=>v_stream)
|
228
246
|
end
|
229
247
|
|
230
248
|
|
231
|
-
SUMMARY_INFORMATION_PACKING = ""
|
232
249
|
# creates the summary information storage
|
233
250
|
# @return [Storage]
|
234
251
|
def create_summary_information
|
235
|
-
# FEFF 0000 030A 0100 0000 0000 0000 0000
|
236
|
-
# 0000 0000 0000 0000 0100 0000 E085 9FF2
|
237
|
-
# F94F 6810 AB91 0800 2B27 B3D9 3000 0000
|
238
|
-
# AC00 0000 0700 0000 0100 0000 4000 0000
|
239
|
-
# 0400 0000 4800 0000 0800 0000 5800 0000
|
240
|
-
# 1200 0000 6800 0000 0C00 0000 8C00 0000
|
241
|
-
# 0D00 0000 9800 0000 1300 0000 A400 0000
|
242
|
-
# 0200 0000 E9FD 0000 1E00 0000 0800 0000
|
243
|
-
# 7261 6E64 796D 0000 1E00 0000 0800 0000
|
244
|
-
# 7261 6E64 796D 0000 1E00 0000 1C00 0000
|
245
|
-
# 4D69 6372 6F73 6F66 7420 4D61 6369 6E74
|
246
|
-
# 6F73 6820 4578 6365 6C00 0000 4000 0000
|
247
|
-
# 10AC 5396 60BC CC01 4000 0000 40F4 FDAF
|
248
|
-
# 60BC CC01 0300 0000 0100 0000
|
249
252
|
v_stream = []
|
250
|
-
v_stream
|
251
|
-
|
253
|
+
v_stream.concat [0xFEFF, 0x0000, 0x030A, 0x0100, 0x0000, 0x0000, 0x0000, 0x0000]
|
254
|
+
v_stream.concat [0x0000, 0x0000, 0x0000, 0x0000, 0x0100, 0x0000, 0xE085, 0x9FF2]
|
255
|
+
v_stream.concat [0xF94F, 0x6810, 0xAB91, 0x0800, 0x2B27, 0xB3D9, 0x3000, 0x0000]
|
256
|
+
v_stream.concat [0xAC00, 0x0000, 0x0700, 0x0000, 0x0100, 0x0000, 0x4000, 0x0000]
|
257
|
+
v_stream.concat [0x0400, 0x0000, 0x4800, 0x0000, 0x0800, 0x0000, 0x5800, 0x0000]
|
258
|
+
v_stream.concat [0x1200, 0x0000, 0x6800, 0x0000, 0x0C00, 0x0000, 0x8C00, 0x0000]
|
259
|
+
v_stream.concat [0x0D00, 0x0000, 0x9800, 0x0000, 0x1300, 0x0000, 0xA400, 0x0000]
|
260
|
+
v_stream.concat [0x0200, 0x0000, 0xE9FD, 0x0000, 0x1E00, 0x0000, 0x0800, 0x0000]
|
261
|
+
v_stream.concat [0x7261, 0x6E64, 0x796D, 0x0000, 0x1E00, 0x0000, 0x0800, 0x0000]
|
262
|
+
v_stream.concat [0x7261, 0x6E64, 0x796D, 0x0000, 0x1E00, 0x0000, 0x1C00, 0x0000]
|
263
|
+
v_stream.concat [0x4D69, 0x6372, 0x6F73, 0x6F66, 0x7420, 0x4D61, 0x6369, 0x6E74]
|
264
|
+
v_stream.concat [0x6F73, 0x6820, 0x4578, 0x6365, 0x6C00, 0x0000, 0x4000, 0x0000]
|
265
|
+
v_stream.concat [0x10AC, 0x5396, 0x60BC, 0xCC01, 0x4000, 0x0000, 0x40F4, 0xFDAF]
|
266
|
+
v_stream.concat [0x60BC, 0xCC01, 0x0300, 0x0000, 0x0100, 0x0000]
|
267
|
+
|
268
|
+
v_stream = v_stream.pack "s*"
|
269
|
+
|
270
|
+
Storage.new([5].pack('c')+"SummaryInformation", :data=>v_stream, :left => 2)
|
252
271
|
end
|
253
272
|
|
254
|
-
|
273
|
+
|
255
274
|
# creates the document summary information storage
|
256
275
|
# @return [Storage]
|
257
276
|
def create_document_summary_information
|
258
277
|
v_stream = []
|
259
|
-
v_stream
|
278
|
+
v_stream.concat [0xFEFF, 0x0000, 0x030A, 0x0100, 0x0000, 0x0000, 0x0000, 0x0000]
|
279
|
+
v_stream.concat [0x0000, 0x0000, 0x0000, 0x0000, 0x0100, 0x0000, 0x02D5, 0xCDD5]
|
280
|
+
v_stream.concat [0x9C2E, 0x1B10, 0x9397, 0x0800, 0x2B2C, 0xF9AE, 0x3000, 0x0000]
|
281
|
+
v_stream.concat [0xCC00, 0x0000, 0x0900, 0x0000, 0x0100, 0x0000, 0x5000, 0x0000]
|
282
|
+
v_stream.concat [0x0F00, 0x0000, 0x5800, 0x0000, 0x1700, 0x0000, 0x6400, 0x0000]
|
283
|
+
v_stream.concat [0x0B00, 0x0000, 0x6C00, 0x0000, 0x1000, 0x0000, 0x7400, 0x0000]
|
284
|
+
v_stream.concat [0x1300, 0x0000, 0x7C00, 0x0000, 0x1600, 0x0000, 0x8400, 0x0000]
|
285
|
+
v_stream.concat [0x0D00, 0x0000, 0x8C00, 0x0000, 0x0C00, 0x0000, 0x9F00, 0x0000]
|
286
|
+
v_stream.concat [0x0200, 0x0000, 0xE9FD, 0x0000, 0x1E00, 0x0000, 0x0400, 0x0000]
|
287
|
+
v_stream.concat [0x0000, 0x0000, 0x0300, 0x0000, 0x0000, 0x0C00, 0x0B00, 0x0000]
|
288
|
+
v_stream.concat [0x0000, 0x0000, 0x0B00, 0x0000, 0x0000, 0x0000, 0x0B00, 0x0000]
|
289
|
+
v_stream.concat [0x0000, 0x0000, 0x0B00, 0x0000, 0x0000, 0x0000, 0x1E10, 0x0000]
|
290
|
+
v_stream.concat [0x0100, 0x0000, 0x0700, 0x0000, 0x5368, 0x6565, 0x7431, 0x000C]
|
291
|
+
v_stream.concat [0x1000, 0x0002, 0x0000, 0x001E, 0x0000, 0x0013, 0x0000, 0x00E3]
|
292
|
+
v_stream.concat [0x83AF, 0xE383, 0xBCE3, 0x82AF, 0xE382, 0xB7E3, 0x83BC, 0xE383]
|
293
|
+
v_stream.concat [0x8800, 0x0300, 0x0000, 0x0100, 0x0000, 0x0000]
|
294
|
+
v_stream = v_stream.pack 'c*'
|
260
295
|
Storage.new([5].pack('c')+"DocumentSummaryInformation", :data=>v_stream)
|
261
296
|
end
|
262
297
|
|
data/lib/axlsx/util/constants.rb
CHANGED
@@ -73,6 +73,9 @@ module Axlsx
|
|
73
73
|
# image rels namespace
|
74
74
|
IMAGE_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"
|
75
75
|
|
76
|
+
# image rels namespace
|
77
|
+
HYPERLINK_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"
|
78
|
+
|
76
79
|
# table content type
|
77
80
|
TABLE_CT = "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml"
|
78
81
|
|
@@ -169,23 +172,26 @@ module Axlsx
|
|
169
172
|
# chart part
|
170
173
|
IMAGE_PN = "media/image%d.%s"
|
171
174
|
|
175
|
+
# location of schema files for validation
|
176
|
+
SCHEMA_BASE = File.dirname(__FILE__)+'/../../schema/'
|
177
|
+
|
172
178
|
# App validation schema
|
173
|
-
APP_XSD = "
|
179
|
+
APP_XSD = SCHEMA_BASE + "shared-documentPropertiesExtended.xsd"
|
174
180
|
|
175
181
|
# core validation schema
|
176
|
-
CORE_XSD = "
|
182
|
+
CORE_XSD = SCHEMA_BASE + "opc-coreProperties.xsd"
|
177
183
|
|
178
184
|
# content types validation schema
|
179
|
-
CONTENT_TYPES_XSD = "
|
185
|
+
CONTENT_TYPES_XSD = SCHEMA_BASE + "opc-contentTypes.xsd"
|
180
186
|
|
181
187
|
# rels validation schema
|
182
|
-
RELS_XSD = "
|
188
|
+
RELS_XSD = SCHEMA_BASE + "opc-relationships.xsd"
|
183
189
|
|
184
190
|
# spreadsheetML validation schema
|
185
|
-
SML_XSD = "
|
191
|
+
SML_XSD = SCHEMA_BASE + "sml.xsd"
|
186
192
|
|
187
193
|
# drawing validation schema
|
188
|
-
DRAWING_XSD = "
|
194
|
+
DRAWING_XSD = SCHEMA_BASE + "dml-spreadsheetDrawing.xsd"
|
189
195
|
|
190
196
|
# number format id for pecentage formatting using the default formatting id.
|
191
197
|
NUM_FMT_PERCENT = 9
|
@@ -48,7 +48,7 @@ module Axlsx
|
|
48
48
|
# encrypts and returns the package specified by the file name
|
49
49
|
# @return [String]
|
50
50
|
def encrypted_package
|
51
|
-
@encrypted_package ||= encrypt_package(file_name
|
51
|
+
@encrypted_package ||= encrypt_package(file_name)
|
52
52
|
end
|
53
53
|
|
54
54
|
# returns the encryption info for this instance of ms-off-crypto
|
@@ -94,10 +94,10 @@ module Axlsx
|
|
94
94
|
end
|
95
95
|
|
96
96
|
# size of unencrypted package? concated with encrypted package
|
97
|
-
def encrypt_package(file_name
|
97
|
+
def encrypt_package(file_name)
|
98
98
|
package = File.open(file_name, 'r')
|
99
|
-
|
100
|
-
[
|
99
|
+
crypt_pack = encrypt(package.read)
|
100
|
+
[crypt_pack.size].pack('q') + crypt_pack
|
101
101
|
end
|
102
102
|
|
103
103
|
# Generates an encryption info structure
|
@@ -106,18 +106,18 @@ module Axlsx
|
|
106
106
|
header = [3, 0, 2, 0] # version
|
107
107
|
# Header flags copy
|
108
108
|
header.concat [0x24, 0, 0, 0] #flags -- VERY UNSURE ABOUT THIS STILL
|
109
|
-
header.concat [0, 0, 0, 0] #unused
|
109
|
+
# header.concat [0, 0, 0, 0] #unused
|
110
110
|
header.concat [0xA4, 0, 0, 0] #length
|
111
111
|
# Header
|
112
112
|
header.concat [0x24, 0, 0, 0] #flags again
|
113
|
-
header.concat [0, 0, 0, 0] #unused again,
|
113
|
+
# header.concat [0, 0, 0, 0] #unused again,
|
114
114
|
header.concat [0x0E, 0x66, 0, 0] #alg id
|
115
115
|
header.concat [0x04, 0x80, 0, 0] #alg hash id
|
116
116
|
header.concat [key.size, 0, 0, 0] #key size
|
117
117
|
header.concat [0x18, 0, 0, 0] #provider type
|
118
|
-
header.concat [0, 0, 0, 0] #reserved 1
|
119
|
-
header.concat [0, 0, 0, 0] #reserved 2
|
120
|
-
|
118
|
+
# header.concat [0, 0, 0, 0] #reserved 1
|
119
|
+
# header.concat [0, 0, 0, 0] #reserved 2
|
120
|
+
header.concat [0xA0, 0xC7, 0xDC, 0x2, 0, 0, 0, 0]
|
121
121
|
header.concat "Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)".bytes.to_a.pack('s*').bytes.to_a
|
122
122
|
header.concat [0, 0] #null terminator
|
123
123
|
|
data/lib/axlsx/util/storage.rb
CHANGED
@@ -119,7 +119,7 @@ module Axlsx
|
|
119
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
120
|
# @param [Any] v The value validated
|
121
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
|
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, HYPERLINK_R], v
|
123
123
|
end
|
124
124
|
|
125
125
|
# Requires that the value is a valid table element type
|
data/lib/axlsx/version.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
module Axlsx
|
2
|
-
|
2
|
+
|
3
|
+
# The version of the gem
|
3
4
|
# When using bunle exec rake and referencing the gem on github or locally
|
4
5
|
# it will use the gemspec, which preloads this constant for the gem's version.
|
5
6
|
# We check to make sure that it has not already been loaded
|
6
|
-
VERSION="1.0.
|
7
|
+
VERSION="1.0.16" unless Axlsx.const_defined? :VERSION
|
8
|
+
|
7
9
|
end
|
@@ -82,17 +82,27 @@ require 'axlsx/workbook/worksheet/worksheet.rb'
|
|
82
82
|
#end
|
83
83
|
|
84
84
|
# Creates a new Workbook
|
85
|
-
#
|
85
|
+
#
|
86
|
+
# @option options [Boolean] date1904. If this is not specified, we try to determine if the platform is bsd/darwin and set date1904 to true automatically.
|
87
|
+
#
|
86
88
|
def initialize(options={})
|
87
89
|
@styles = Styles.new
|
88
90
|
@worksheets = SimpleTypedList.new Worksheet
|
89
91
|
@drawings = SimpleTypedList.new Drawing
|
90
92
|
@charts = SimpleTypedList.new Chart
|
91
93
|
@images = SimpleTypedList.new Pic
|
92
|
-
self.date1904= options[:date1904]
|
94
|
+
self.date1904= options[:date1904].nil? ? is_bsd? : options[:date1904]
|
93
95
|
yield self if block_given?
|
94
96
|
end
|
95
97
|
|
98
|
+
# Uses RUBY_PLATFORM constant to determine if the OS is freebsd or darwin
|
99
|
+
# based on this value we attempt to set date1904.
|
100
|
+
# @return [Boolean]
|
101
|
+
def is_bsd?
|
102
|
+
platform = RUBY_PLATFORM.downcase
|
103
|
+
platform.include?('freebsd') || platform.include?('darwin')
|
104
|
+
end
|
105
|
+
|
96
106
|
# Instance level access to the class variable 1904
|
97
107
|
# @return [Boolean]
|
98
108
|
def date1904() @@date1904; end
|
@@ -144,7 +154,7 @@ require 'axlsx/workbook/worksheet/worksheet.rb'
|
|
144
154
|
# @return [String]
|
145
155
|
def to_xml()
|
146
156
|
add_worksheet unless worksheets.size > 0
|
147
|
-
builder = Nokogiri::XML::Builder.new(:encoding => ENCODING) do |xml|
|
157
|
+
builder = Nokogiri::XML::Builder.new(:encoding => ENCODING) do |xml|
|
148
158
|
xml.workbook(:xmlns => XML_NS, :'xmlns:r' => XML_NS_R) {
|
149
159
|
xml.workbookPr(:date1904=>@@date1904)
|
150
160
|
#<x:workbookProtection workbookPassword="xsd:hexBinary data" lockStructure="1" lockWindows="1" />
|
@@ -155,7 +165,7 @@ require 'axlsx/workbook/worksheet/worksheet.rb'
|
|
155
165
|
}
|
156
166
|
}
|
157
167
|
end
|
158
|
-
builder.to_xml(:
|
168
|
+
builder.to_xml(:save_with => 0)
|
159
169
|
end
|
160
170
|
end
|
161
171
|
end
|