axlsx 1.0.15 → 1.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +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
|