lib/axlsx/package.rb in axlsx-1.0.16 vs lib/axlsx/package.rb in axlsx-1.0.17
- old
+ new
@@ -1,12 +1,12 @@
-# -*- coding: utf-8 -*-
+# encoding: UTF-8
module Axlsx
# Package is responsible for managing all the bits and peices that Open Office XML requires to make a valid
# xlsx document including valdation and serialization.
class Package
- # plain text password
+
# provides access to the app doc properties for this package
# see App
attr_reader :app
# provides access to the core doc properties for the package
@@ -15,18 +15,35 @@
# Initializes your package
#
# @param [Hash] options A hash that you can use to specify the author and workbook for this package.
# @option options [String] :author The author of the document
+ # @option options [Boolean] :use_shared_strings This is passed to the workbook to specify that shared strings should be used when serializing the package.
# @example Package.new :author => 'you!', :workbook => Workbook.new
def initialize(options={})
@workbook = nil
@core, @app = Core.new, App.new
@core.creator = options[:author] || @core.creator
+ options.each do |o|
+ self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
+ end
yield self if block_given?
end
+ # Shortcut to specify that the workbook should use shared strings
+ # @see Workbook#use_shared_strings
+ def use_shared_strings=(v)
+ Axlsx::validate_boolean(v);
+ workbook.use_shared_strings = v
+ end
+
+ # Shortcut to determine if the workbook is configured to use shared strings
+ # @see Workbook#use_shared_strings
+ def use_shared_strings
+ workbook.use_shared_strings
+ end
+
# The workbook this package will serialize or validate.
# @return [Workbook] If no workbook instance has been assigned with this package a new Workbook instance is returned.
# @raise ArgumentError if workbook parameter is not a Workbook instance.
# @note As there are multiple ways to instantiate a workbook for the package,
# here are a few examples:
@@ -55,10 +72,11 @@
# Serialize your workbook to disk as an xlsx document.
#
# @param [File] output The file you want to serialize your package to
# @param [Boolean] confirm_valid Validate the package prior to serialization.
+ # @option options stream indicates if we should be writing to a stream or a file. True for stream, nil for file
# @return [Boolean] False if confirm_valid and validation errors exist. True if the package was serialized
# @note A tremendous amount of effort has gone into ensuring that you cannot create invalid xlsx documents.
# confirm_valid should be used in the rare case that you cannot open the serialized file.
# @see Package#validate
# @example
@@ -68,30 +86,32 @@
# Package.new.serialize(f)
#
# # You will find a file called test.xlsx
def serialize(output, confirm_valid=false)
return false unless !confirm_valid || self.validate.empty?
- p = parts
Zip::ZipOutputStream.open(output) do |zip|
- p.each do |part|
- unless part[:doc].nil?
- zip.put_next_entry(part[:entry]);
- 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]);
- # binread for 1.9.3
- zip.write IO.respond_to?(:binread) ? IO.binread(part[:path]) : IO.read(part[:path])
- end
- end
+ write_parts(zip)
end
true
end
+
+
+ # Serialize your workbook to a StringIO instance
+ # @param [Boolean] confirm_valid Validate the package prior to serialization.
+ # @return [StringIO|Boolean] False if confirm_valid and validation errors exist. rewound string IO if not.
+ def to_stream(confirm_valid=false)
+ return false unless !confirm_valid || self.validate.empty?
+ zip = write_parts(Zip::ZipOutputStream.new("streamed", true))
+ stream = zip.close_buffer
+ stream.rewind
+ stream
+ end
# Encrypt the package into a CFB using the password provided
+ # This is not ready yet
def encrypt(file_name, password)
+ return false
moc = MsOffCrypto.new(file_name, password)
moc.save
end
# Validate all parts of the package against xsd schema.
@@ -115,10 +135,30 @@
errors
end
private
+ # Writes the package parts to a zip archive.
+ # @param [Zip::ZipOutputStream] zip
+ # @return [Zip::ZipOutputStream]
+ def write_parts(zip)
+ p = parts
+ p.each do |part|
+ unless part[:doc].nil?
+ zip.put_next_entry(part[:entry]);
+ 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]);
+ # binread for 1.9.3
+ zip.write IO.respond_to?(:binread) ? IO.binread(part[:path]) : IO.read(part[:path])
+ end
+ end
+ zip
+ 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
def parts
@parts = [
@@ -141,10 +181,14 @@
workbook.images.each do |image|
@parts << {:entry => "xl/#{image.pn}", :path => image.image_src}
end
+ if use_shared_strings
+ @parts << {:entry => "xl/#{SHARED_STRINGS_PN}", :doc => workbook.shared_strings.to_xml, :schema => SML_XSD}
+ end
+
workbook.worksheets.each do |sheet|
@parts << {:entry => "xl/#{sheet.rels_pn}", :doc => sheet.relationships.to_xml, :schema => RELS_XSD}
@parts << {:entry => "xl/#{sheet.pn}", :doc => sheet.to_xml, :schema => SML_XSD}
end
@parts
@@ -192,9 +236,13 @@
GIF_CT
elsif ext == 'png'
PNG_CT
end
c_types << Axlsx::Default.new(:ContentType => ct, :Extension => ext )
+ end
+ if use_shared_strings
+ c_types << Axlsx::Override.new(:PartName => "/xl/#{SHARED_STRINGS_PN}",
+ :ContentType => SHARED_STRINGS_CT)
end
c_types
end
# Creates the minimum content types for generating a valid xlsx document.