2
2
require 'libxml'
3
3
4
4
module Rspreadsheet
5
+
5
6
class Workbook
6
7
attr_reader :filename
7
8
attr_reader :xmlnode # debug
8
9
def xmldoc ; @xmlnode . doc end
9
10
10
- #@!group Worskheets methods
11
+ #@!group Worksheet methods
11
12
def create_worksheet_from_node ( source_node )
12
13
sheet = Worksheet . new ( source_node , self )
13
14
register_worksheet ( sheet )
@@ -21,10 +22,11 @@ def create_worksheet(name = "Sheet#{worksheets_count+1}")
21
22
alias :add_worksheet :create_worksheet
22
23
# @return [Integer] number of sheets in the workbook
23
24
def worksheets_count ; @worksheets . length end
25
+ alias :worksheet_count :worksheets_count
24
26
# @return [String] names of sheets in the workbook
25
27
def worksheet_names ; @worksheets . collect { |ws | ws . name } end
26
28
# @param [Integer,String]
27
- # @return [Worskheet ] worksheet with given index or name
29
+ # @return [Worksheet ] worksheet with given index or name
28
30
def worksheets ( index_or_name )
29
31
case index_or_name
30
32
when Integer then begin
@@ -61,8 +63,7 @@ def initialize(afilename=nil)
61
63
@xmlnode . find ( './table:table' ) . each do |node |
62
64
create_worksheet_from_node ( node )
63
65
end
64
- end
65
-
66
+ end
66
67
67
68
# @param [String] Optional new filename
68
69
# Saves the worksheet. Optionally you can provide new filename or IO stream to which the file should be saved.
@@ -71,16 +72,16 @@ def save(io=nil)
71
72
when @filename . nil? && io . nil?
72
73
raise 'New file should be named on first save.'
73
74
when @filename . kind_of? ( String ) && io . nil?
74
- Tools . output_to_stream ( @filename ) do |input_and_output_zip | # open old file
75
- update_manifest_and_content_xml ( input_and_output_zip , input_and_output_zip ) # input and output are identical
75
+ Tools . output_to_zip_stream ( @filename ) do |input_and_output_zip | # open old file
76
+ update_zip_manifest_and_content_xml ( input_and_output_zip , input_and_output_zip ) # input and output are identical
76
77
end
77
- when @filename . kind_of? ( String ) && ( io . kind_of? ( String ) || io . kind_of? ( File ) )
78
+ when ( @filename . kind_of? ( String ) && ( io . kind_of? ( String ) || io . kind_of? ( File ) ) )
78
79
io = io . path if io . kind_of? ( File ) # convert file to its filename
79
80
FileUtils . cp ( @filename , io ) # copy file externally
80
81
@filename = io # remember new name
81
82
save_to_io ( nil ) # continue modyfying file on spot
82
83
when io . kind_of? ( IO ) || io . kind_of? ( String ) || io . kind_of? ( StringIO )
83
- Tools . output_to_stream ( io ) do |output_io | # open output stream of file
84
+ Tools . output_to_zip_stream ( io ) do |output_io | # open output stream of file
84
85
write_ods_to_io ( output_io )
85
86
end
86
87
io . rewind if io . kind_of? ( StringIO )
@@ -97,19 +98,22 @@ def write_ods_to_io(io)
97
98
if @filename . nil?
98
99
Zip ::File . open ( TEMPLATE_FILE_NAME ) do |empty_template_zip | # open empty_template file
99
100
copy_internally_without_content ( empty_template_zip , io ) # copy empty_template internals
100
- update_manifest_and_content_xml ( empty_template_zip , io ) # update xmls + pictures
101
+ update_zip_manifest_and_content_xml ( empty_template_zip , io ) # update xmls + pictures
101
102
end
102
103
else
103
104
Zip ::File . open ( @filename ) do | old_zip | # open old file
104
105
copy_internally_without_content ( old_zip , io ) # copy the old internals
105
- update_manifest_and_content_xml ( old_zip , io ) # update xmls + pictures
106
+ update_zip_manifest_and_content_xml ( old_zip , io ) # update xmls + pictures
106
107
end
107
108
end
108
109
end
109
110
111
+ def flat_format? ; false end
112
+ def normal_format? ; true end
113
+
110
114
private
111
115
112
- def update_manifest_and_content_xml ( input_zip , output_zip )
116
+ def update_zip_manifest_and_content_xml ( input_zip , output_zip )
113
117
update_manifest_xml ( input_zip , output_zip )
114
118
update_content_xml ( output_zip )
115
119
end
@@ -182,6 +186,44 @@ def register_worksheet(worksheet)
182
186
@worksheets [ index -1 ] = worksheet
183
187
@xmlnode << worksheet . xmlnode if worksheet . xmlnode . doc != @xmlnode . doc
184
188
end
189
+
190
+ end
191
+
192
+ class WorkbookFlat < Workbook
193
+ def initialize ( afilename = nil )
194
+ @worksheets = [ ]
195
+ @filename = afilename
196
+ @xml_doc = LibXML ::XML ::Document . file ( @filename || FLAT_TEMPLATE_FILE_NAME )
197
+ @xmlnode = @xml_doc . find_first ( '//office:spreadsheet' )
198
+ @xmlnode . find ( './table:table' ) . each do |node |
199
+ create_worksheet_from_node ( node )
200
+ end
201
+ end
202
+
203
+ def save ( io = nil )
204
+ case
205
+ when @filename . nil? && io . nil?
206
+ raise 'New file should be named on first save, please provide filename (or IO).'
207
+ when @filename . kind_of? ( String ) && io . nil?
208
+ @xml_doc . save ( @filename )
209
+ when ( @filename . kind_of? ( String ) && ( io . kind_of? ( String ) || io . kind_of? ( File ) ) )
210
+ @filename = ( io . kind_of? ( File ) ) ? io . path : io
211
+ @xml_doc . save ( @filename )
212
+ when io . kind_of? ( IO ) || io . kind_of? ( String ) || io . kind_of? ( StringIO )
213
+ IO . write ( io , @xml_doc . to_s )
214
+ io . rewind if io . kind_of? ( StringIO )
215
+ else raise 'Invalid combinations of parameter types in save'
216
+ end
217
+ end
218
+ alias :save_to_io :save
219
+ alias :save_as :save
220
+
221
+ def flat_format? ; true end
222
+ def normal_format? ; false end
223
+
224
+ private
225
+ FLAT_TEMPLATE_FILE_NAME = ( File . dirname ( __FILE__ ) +'/empty_file_template.fods' ) . freeze
226
+
185
227
end
186
228
187
229
class WorkbookIO
0 commit comments