diff options
| author | Stefan Daschek <[email protected]> | 2013-07-08 14:15:32 +0200 |
|---|---|---|
| committer | Stefan Daschek <[email protected]> | 2013-07-08 14:15:32 +0200 |
| commit | b7e14c242c0d9fc3af7b7ad969ec25df21475547 (patch) | |
| tree | 6e08e812a46ebd19463db88027c77f21760d2c87 /lib | |
| parent | a60d1889744205dbc86ce0e23f8ed04ba7093d23 (diff) | |
| download | caxlsx-b7e14c242c0d9fc3af7b7ad969ec25df21475547.tar.gz caxlsx-b7e14c242c0d9fc3af7b7ad969ec25df21475547.zip | |
Make sure serializing axlsx packages with identical contents always results in identical zip files.
This improves the possibilites for caching and/or consolidating the generated zip (xlsx) files.
Up to now, serializing the same package at different times resulted in different zip files because of the timestamp in the zip entry metadata.
Note: To generate identical packages (and thus identical zip files), you'll have set Core#created explicitly, eg. with `Package.new(created_at: Time.local(2013, 1, 1)`.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/axlsx/package.rb | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/lib/axlsx/package.rb b/lib/axlsx/package.rb index 37620b48..7e4bad60 100644 --- a/lib/axlsx/package.rb +++ b/lib/axlsx/package.rb @@ -158,12 +158,12 @@ module Axlsx p = parts p.each do |part| unless part[:doc].nil? - zip.put_next_entry(part[:entry]) + zip.put_next_entry(zip_entry_for_part(part)) entry = ['1.9.2', '1.9.3'].include?(RUBY_VERSION) ? part[:doc].force_encoding('BINARY') : part[:doc] zip.puts(entry) end unless part[:path].nil? - zip.put_next_entry(part[:entry]); + zip.put_next_entry(zip_entry_for_part(part)) # binread for 1.9.3 zip.write IO.respond_to?(:binread) ? IO.binread(part[:path]) : IO.read(part[:path]) end @@ -171,6 +171,22 @@ module Axlsx zip end + # Generate a ZipEntry for the given package part. + # The important part here is to explicitly set the timestamp for the zip entry: Serializing axlsx packages + # with identical contents should result in identical zip files – however, the timestamp of a zip entry + # defaults to the time of serialization and therefore the zip file contents would be different every time + # the package is serialized. + # + # Note: {Core#created} also defaults to the current time – so to generate identical axlsx packages you have + # to set this explicitly, too (eg. with `Package.new(created_at: Time.local(2013, 1, 1))`). + # + # @param part A hash describing a part of this pacakge (see {#parts}) + # @return [Zip::ZipEntry] + def zip_entry_for_part(part) + timestamp = Zip::DOSTime.at(@core.created.to_i) + Zip::ZipEntry.new("", part[:entry], "", "", 0, 0, Zip::ZipEntry::DEFLATED, 0, timestamp) + end + # The parts of a package # @return [Array] An array of hashes that define the entry, document and schema for each part of the package. # @private |
