lib/rspreadsheet/workbook.rb in rspreadsheet-0.4.9 vs lib/rspreadsheet/workbook.rb in rspreadsheet-0.5.0
- old
+ new
@@ -1,15 +1,16 @@
require 'zip'
require 'libxml'
module Rspreadsheet
+
class Workbook
attr_reader :filename
attr_reader :xmlnode # debug
def xmldoc; @xmlnode.doc end
- #@!group Worskheets methods
+ #@!group Worksheet methods
def create_worksheet_from_node(source_node)
sheet = Worksheet.new(source_node,self)
register_worksheet(sheet)
return sheet
end
@@ -19,14 +20,15 @@
return sheet
end
alias :add_worksheet :create_worksheet
# @return [Integer] number of sheets in the workbook
def worksheets_count; @worksheets.length end
+ alias :worksheet_count :worksheets_count
# @return [String] names of sheets in the workbook
def worksheet_names; @worksheets.collect{ |ws| ws.name } end
# @param [Integer,String]
- # @return [Worskheet] worksheet with given index or name
+ # @return [Worksheet] worksheet with given index or name
def worksheets(index_or_name)
case index_or_name
when Integer then begin
case index_or_name
when 0 then nil
@@ -59,60 +61,65 @@
end
@xmlnode = @content_xml.find_first('//office:spreadsheet')
@xmlnode.find('./table:table').each do |node|
create_worksheet_from_node(node)
end
- end
-
+ end
# @param [String] Optional new filename
# Saves the worksheet. Optionally you can provide new filename or IO stream to which the file should be saved.
def save(io=nil)
case
when @filename.nil? && io.nil?
raise 'New file should be named on first save.'
- when @filename.nil? && (io.kind_of?(String) || io.kind_of?(File) || io.kind_of?(IO) || io.kind_of?(StringIO))
- Zip::File.open(TEMPLATE_FILE_NAME) do |empty_template_zip| # open empty_template file
- write_zip_to(io) do |output_zip| # open output stream of file
- copy_internally_without_content(empty_template_zip,output_zip) # copy empty_template internals
- update_manifest_and_content_xml(empty_template_zip,output_zip) # update xmls + pictures
- end
- end
when @filename.kind_of?(String) && io.nil?
- write_zip_to(@filename) do |input_and_output_zip| # open old file
- update_manifest_and_content_xml(input_and_output_zip,input_and_output_zip) # input and output are identical
+ Tools.output_to_zip_stream(@filename) do |input_and_output_zip| # open old file
+ update_zip_manifest_and_content_xml(input_and_output_zip,input_and_output_zip) # input and output are identical
end
-
- when @filename.kind_of?(String) && (io.kind_of?(String) || io.kind_of?(File))
- io = io.path if io.kind_of?(File) # convert file to its filename
- FileUtils.cp(@filename , io) # copy file externally
- @filename = io # remember new name
- save_to_io(nil) # continue modyfying file on spot
-
- when @filename.kind_of?(String) && (io.kind_of?(IO) || io.kind_of?(StringIO))
- Zip::File.open(@filename) do | old_zip | # open old file
- write_zip_to(io) do |output_zip_stream| # open output stream
- copy_internally_without_content(old_zip,output_zip_stream) # copy the old internals
- update_manifest_and_content_xml(old_zip,output_zip_stream) # update xmls + pictures
- end
+ when (@filename.kind_of?(String) && (io.kind_of?(String) || io.kind_of?(File)))
+ io = io.path if io.kind_of?(File) # convert file to its filename
+ FileUtils.cp(@filename , io) # copy file externally
+ @filename = io # remember new name
+ save_to_io(nil) # continue modyfying file on spot
+ when io.kind_of?(IO) || io.kind_of?(String) || io.kind_of?(StringIO)
+ Tools.output_to_zip_stream(io) do |output_io| # open output stream of file
+ write_ods_to_io(output_io)
end
- # rewind result
- io.rewind
- else
+ io.rewind if io.kind_of?(StringIO)
+ else raise 'Ivalid combinations of parameter types in save'
end
end
- alias :to_io :save
alias :save_to_io :save
+ alias :save_as :save
+ def to_io
+ WorkbookIO.new(self)
+ end
+ def write_ods_to_io(io)
+ if @filename.nil?
+ Zip::File.open(TEMPLATE_FILE_NAME) do |empty_template_zip| # open empty_template file
+ copy_internally_without_content(empty_template_zip,io) # copy empty_template internals
+ update_zip_manifest_and_content_xml(empty_template_zip,io) # update xmls + pictures
+ end
+ else
+ Zip::File.open(@filename) do | old_zip | # open old file
+ copy_internally_without_content(old_zip,io) # copy the old internals
+ update_zip_manifest_and_content_xml(old_zip,io) # update xmls + pictures
+ end
+ end
+ end
+
+ def flat_format?; false end
+ def normal_format?; true end
+
private
- def update_manifest_and_content_xml(input_zip,output_zip)
+ def update_zip_manifest_and_content_xml(input_zip,output_zip)
update_manifest_xml(input_zip,output_zip)
update_content_xml(output_zip)
end
-
def update_content_xml(zip)
save_entry_to_zip(zip,CONTENT_FILE_NAME,@content_xml.to_s(indent: false))
end
def update_manifest_xml(input_zip,output_zip)
@@ -160,37 +167,78 @@
end
end
def save_entry_to_zip(zip,internal_filename,contents)
if zip.kind_of? Zip::File
-# raise [internal_filename,contents].inspect unless File.exists?(internal_filename)
zip.get_output_stream(internal_filename) do |f|
f.write contents
end
else
zip.put_next_entry(internal_filename)
zip.write(contents)
end
end
-
- def write_zip_to(io,&block)
- if io.kind_of? File or io.kind_of? String
- Zip::File.open(io, 'br+') do |zip|
- yield zip
- end
- elsif io.kind_of? StringIO # or io.kind_of? IO
- Zip::OutputStream.write_buffer(io) do |zip|
- yield zip
- end
- end
- end
-
+
CONTENT_FILE_NAME = 'content.xml'
MANIFEST_FILE_NAME = 'META-INF/manifest.xml'
TEMPLATE_FILE_NAME = (File.dirname(__FILE__)+'/empty_file_template.ods').freeze
def register_worksheet(worksheet)
index = worksheets_count+1
@worksheets[index-1]=worksheet
@xmlnode << worksheet.xmlnode if worksheet.xmlnode.doc != @xmlnode.doc
end
+
end
+
+class WorkbookFlat < Workbook
+ def initialize(afilename=nil)
+ @worksheets=[]
+ @filename = afilename
+ @xml_doc = LibXML::XML::Document.file(@filename || FLAT_TEMPLATE_FILE_NAME)
+ @xmlnode = @xml_doc.find_first('//office:spreadsheet')
+ @xmlnode.find('./table:table').each do |node|
+ create_worksheet_from_node(node)
+ end
+ end
+
+ def save(io=nil)
+ case
+ when @filename.nil? && io.nil?
+ raise 'New file should be named on first save, please provide filename (or IO).'
+ when @filename.kind_of?(String) && io.nil?
+ @xml_doc.save(@filename)
+ when (@filename.kind_of?(String) && (io.kind_of?(String) || io.kind_of?(File)))
+ @filename = (io.kind_of?(File)) ? io.path : io
+ @xml_doc.save(@filename)
+ when io.kind_of?(IO) || io.kind_of?(String) || io.kind_of?(StringIO)
+ IO.write(io,@xml_doc.to_s)
+ io.rewind if io.kind_of?(StringIO)
+ else raise 'Invalid combinations of parameter types in save'
+ end
+ end
+ alias :save_to_io :save
+ alias :save_as :save
+
+ def flat_format?; true end
+ def normal_format?; false end
+
+ private
+ FLAT_TEMPLATE_FILE_NAME = (File.dirname(__FILE__)+'/empty_file_template.fods').freeze
+
+end
+
+class WorkbookIO
+ def initialize(workbook)
+ @workbook = workbook
+ end
+ def read
+ buffer.string
+ end
+ private
+ def buffer
+ Zip::OutputStream.write_buffer do |io|
+ @workbook.write_ods_to_io(io)
+ end
+ end
+end
+
end