roo 1.0.2 → 1.1.0
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/History.txt +7 -0
- data/Manifest.txt +3 -0
- data/Rakefile +15 -1
- data/lib/roo/excel.rb +113 -133
- data/lib/roo/excelx.rb +124 -53
- data/lib/roo/generic_spreadsheet.rb +266 -218
- data/lib/roo/google.rb +3 -2
- data/lib/roo/openoffice.rb +21 -57
- data/lib/roo/version.rb +2 -2
- data/test/Bibelbund.xlsx +0 -0
- data/test/emptysheets.ods +0 -0
- data/test/emptysheets.xls +0 -0
- data/test/test_helper.rb +11 -0
- data/test/test_roo.rb +741 -717
- data/website/index.html +87 -6
- data/website/index.txt +61 -3
- metadata +5 -2
@@ -9,17 +9,20 @@ class GenericSpreadsheet
|
|
9
9
|
# sets the line with attribute names (default: 1)
|
10
10
|
attr_accessor :header_line
|
11
11
|
|
12
|
+
def initialize
|
13
|
+
end
|
14
|
+
|
12
15
|
# set the working sheet in the document
|
13
16
|
def default_sheet=(sheet)
|
14
|
-
if sheet.kind_of? Fixnum
|
17
|
+
if sheet.kind_of? Fixnum
|
15
18
|
if sheet >= 0 and sheet <= sheets.length
|
16
|
-
sheet = self.sheets[sheet-1]
|
19
|
+
sheet = self.sheets[sheet-1]
|
17
20
|
else
|
18
21
|
raise RangeError
|
19
22
|
end
|
20
23
|
elsif sheet.kind_of?(String)
|
21
24
|
raise RangeError if ! self.sheets.include?(sheet)
|
22
|
-
else
|
25
|
+
else
|
23
26
|
raise TypeError, "what are you trying to set as default sheet?"
|
24
27
|
end
|
25
28
|
@default_sheet = sheet
|
@@ -27,121 +30,6 @@ class GenericSpreadsheet
|
|
27
30
|
@first_row[sheet] = @last_row[sheet] = @first_column[sheet] = @last_column[sheet] = nil
|
28
31
|
@cells_read[sheet] = false
|
29
32
|
end
|
30
|
-
|
31
|
-
# converts cell coordinate to numeric values of row,col
|
32
|
-
def normalize(row,col)
|
33
|
-
if row.class == String
|
34
|
-
if col.class == Fixnum
|
35
|
-
# ('A',1):
|
36
|
-
# ('B', 5) -> (5, 2)
|
37
|
-
row, col = col, row
|
38
|
-
else
|
39
|
-
raise ArgumentError
|
40
|
-
end
|
41
|
-
end
|
42
|
-
if col.class == String
|
43
|
-
col = GenericSpreadsheet.letter_to_number(col)
|
44
|
-
end
|
45
|
-
return row,col
|
46
|
-
end
|
47
|
-
|
48
|
-
# true if cell is empty
|
49
|
-
def empty?(row, col, sheet=nil)
|
50
|
-
#def excel_empty?(row, col, sheet=nil)
|
51
|
-
sheet = @default_sheet unless sheet
|
52
|
-
read_cells(sheet) unless @cells_read[sheet] or self.class == Excel
|
53
|
-
row,col = normalize(row,col)
|
54
|
-
return true unless cell(row, col, sheet)
|
55
|
-
return true if celltype(row, col, sheet) == :string && cell(row, col, sheet).empty?
|
56
|
-
#false
|
57
|
-
#end
|
58
|
-
|
59
|
-
# true if a cell is empty
|
60
|
-
#def oo_empty?(row, col, sheet=nil)
|
61
|
-
#sheet = @default_sheet unless sheet
|
62
|
-
#read_cells(sheet) unless @cells_read[sheet]
|
63
|
-
#row,col = normalize(row,col)
|
64
|
-
return true if row < first_row(sheet) || row > last_row(sheet) || col < first_column(sheet) || col > last_column(sheet)
|
65
|
-
#return true unless cell(row, col, sheet)
|
66
|
-
# return true if celltype(row, col, sheet) == "string" && cell(row, col, sheet) == ""
|
67
|
-
#return true if celltype(row, col, sheet) == :string && cell(row, col, sheet) == ""
|
68
|
-
false
|
69
|
-
end
|
70
|
-
|
71
|
-
|
72
|
-
# reopens and read a spreadsheet document
|
73
|
-
def reload
|
74
|
-
ds = @default_sheet
|
75
|
-
initialize(@filename) if self.class == Openoffice or
|
76
|
-
self.class == Excel
|
77
|
-
initialize(@spreadsheetkey,@user,@password) if self.class == Google
|
78
|
-
self.default_sheet = ds
|
79
|
-
#@first_row = @last_row = @first_column = @last_column = nil
|
80
|
-
end
|
81
|
-
|
82
|
-
# Returns information of the spreadsheet document and all sheets within
|
83
|
-
# this document.
|
84
|
-
def info
|
85
|
-
# $log.debug(self.class.to_s+"#info started")
|
86
|
-
result = "File: #{File.basename(@filename)}\n"+
|
87
|
-
"Number of sheets: #{sheets.size}\n"+
|
88
|
-
"Sheets: #{sheets.map{|sheet| sheet+", "}.to_s[0..-3]}\n"
|
89
|
-
n = 1
|
90
|
-
# $log.debug(sheets.inspect)
|
91
|
-
sheets.each {|sheet|
|
92
|
-
# $log.debug("Info fuer Sheet=#{sheet}")
|
93
|
-
self.default_sheet = sheet
|
94
|
-
# $log.debug("nach default_sheet=")
|
95
|
-
result << "Sheet " + n.to_s + ":\n"
|
96
|
-
unless first_row
|
97
|
-
result << " - empty -"
|
98
|
-
else
|
99
|
-
result << " First row: #{first_row}\n"
|
100
|
-
result << " Last row: #{last_row}\n"
|
101
|
-
result << " First column: #{GenericSpreadsheet.number_to_letter(first_column)}\n"
|
102
|
-
result << " Last column: #{GenericSpreadsheet.number_to_letter(last_column)}"
|
103
|
-
end
|
104
|
-
result << "\n" if sheet != sheets.last
|
105
|
-
n += 1
|
106
|
-
}
|
107
|
-
# $log.debug(self.class.to_s+"#info ended")
|
108
|
-
result
|
109
|
-
end
|
110
|
-
|
111
|
-
# returns a rectangular area (default: all cells) as yaml-output
|
112
|
-
# you can add additional attributes with the prefix parameter like:
|
113
|
-
# oo.to_yaml({"file"=>"flightdata_2007-06-26", "sheet" => "1"})
|
114
|
-
def to_yaml(prefix={}, from_row=nil, from_column=nil, to_row=nil, to_column=nil,sheet=nil)
|
115
|
-
sheet = @default_sheet unless sheet
|
116
|
-
result = "--- \n"
|
117
|
-
(from_row||first_row(sheet)).upto(to_row||last_row(sheet)) do |row|
|
118
|
-
(from_column||first_column(sheet)).upto(to_column||last_column(sheet)) do |col|
|
119
|
-
unless empty?(row,col,sheet)
|
120
|
-
result << "cell_#{row}_#{col}: \n"
|
121
|
-
prefix.each {|k,v|
|
122
|
-
result << " #{k}: #{v} \n"
|
123
|
-
}
|
124
|
-
result << " row: #{row} \n"
|
125
|
-
result << " col: #{col} \n"
|
126
|
-
result << " celltype: #{self.celltype(row,col,sheet)} \n"
|
127
|
-
if self.celltype(row,col,sheet) == :time
|
128
|
-
result << " value: #{GenericSpreadsheet.integer_to_timestring( self.cell(row,col,sheet))} \n"
|
129
|
-
else
|
130
|
-
result << " value: #{self.cell(row,col,sheet)} \n"
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
134
|
-
end
|
135
|
-
result
|
136
|
-
end
|
137
|
-
|
138
|
-
# recursively removes the current temporary directory
|
139
|
-
# this is only needed if you work with zipped files or files via the web
|
140
|
-
def remove_tmp
|
141
|
-
if File.exists?(@tmpdir)
|
142
|
-
FileUtils::rm_r(@tmpdir)
|
143
|
-
end
|
144
|
-
end
|
145
33
|
|
146
34
|
# first non-empty column as a letter
|
147
35
|
def first_column_as_letter(sheet=nil)
|
@@ -153,80 +41,43 @@ class GenericSpreadsheet
|
|
153
41
|
GenericSpreadsheet.number_to_letter(last_column(sheet))
|
154
42
|
end
|
155
43
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
begin
|
161
|
-
open(uri) do |net|
|
162
|
-
f.write(net.read)
|
163
|
-
end
|
164
|
-
rescue
|
165
|
-
raise "could not open #{uri}"
|
44
|
+
# returns the number of the first non-empty row
|
45
|
+
def first_row(sheet=nil)
|
46
|
+
if sheet == nil
|
47
|
+
sheet = @default_sheet
|
166
48
|
end
|
167
|
-
f.close
|
168
|
-
File.join(@tmpdir, File.basename(uri))
|
169
|
-
end
|
170
|
-
|
171
|
-
# returns the number of the last non-empty row
|
172
|
-
def last_row(sheet=nil)
|
173
|
-
sheet = @default_sheet unless sheet
|
174
49
|
read_cells(sheet) unless @cells_read[sheet]
|
175
|
-
if @
|
176
|
-
return @
|
50
|
+
if @first_row[sheet]
|
51
|
+
return @first_row[sheet]
|
177
52
|
end
|
178
|
-
impossible_value =
|
53
|
+
impossible_value = 999_999 # more than a spreadsheet can hold
|
179
54
|
result = impossible_value
|
180
55
|
@cell[sheet].each_pair {|key,value|
|
181
56
|
y,x = key.split(',')
|
182
57
|
y = y.to_i
|
183
|
-
result = [result, y].
|
58
|
+
result = [result, y].min if value
|
184
59
|
} if @cell[sheet]
|
185
60
|
result = nil if result == impossible_value
|
186
|
-
@
|
61
|
+
@first_row[sheet] = result
|
187
62
|
result
|
188
63
|
end
|
189
64
|
|
190
|
-
# returns the number of the last non-empty
|
191
|
-
def
|
192
|
-
# $log.debug("#{self.class.to_s}#last_column(#{sheet})")
|
65
|
+
# returns the number of the last non-empty row
|
66
|
+
def last_row(sheet=nil)
|
193
67
|
sheet = @default_sheet unless sheet
|
194
68
|
read_cells(sheet) unless @cells_read[sheet]
|
195
|
-
if @
|
196
|
-
|
197
|
-
return @last_column[sheet]
|
69
|
+
if @last_row[sheet]
|
70
|
+
return @last_row[sheet]
|
198
71
|
end
|
199
|
-
# $log.debug("last_column of sheet #{sheet} not yet set")
|
200
72
|
impossible_value = 0
|
201
73
|
result = impossible_value
|
202
74
|
@cell[sheet].each_pair {|key,value|
|
203
|
-
y,x = key.split(',')
|
204
|
-
x = x.to_i
|
205
|
-
result = [result, x].max if value
|
206
|
-
} if @cell[sheet]
|
207
|
-
result = nil if result == impossible_value
|
208
|
-
@last_column[sheet] = result
|
209
|
-
result
|
210
|
-
end
|
211
|
-
|
212
|
-
# returns the number of the first non-empty row
|
213
|
-
def first_row(sheet=nil)
|
214
|
-
if sheet == nil
|
215
|
-
sheet = @default_sheet
|
216
|
-
end
|
217
|
-
read_cells(sheet) unless @cells_read[sheet]
|
218
|
-
if @first_row[sheet]
|
219
|
-
return @first_row[sheet]
|
220
|
-
end
|
221
|
-
impossible_value = 999_999 # more than a spreadsheet can hold
|
222
|
-
result = impossible_value
|
223
|
-
@cell[sheet].each_pair {|key,value|
|
224
75
|
y,x = key.split(',')
|
225
76
|
y = y.to_i
|
226
|
-
result = [result, y].
|
77
|
+
result = [result, y].max if value
|
227
78
|
} if @cell[sheet]
|
228
79
|
result = nil if result == impossible_value
|
229
|
-
@
|
80
|
+
@last_row[sheet] = result
|
230
81
|
result
|
231
82
|
end
|
232
83
|
|
@@ -251,27 +102,51 @@ class GenericSpreadsheet
|
|
251
102
|
result
|
252
103
|
end
|
253
104
|
|
254
|
-
#
|
255
|
-
def
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
105
|
+
# returns the number of the last non-empty column
|
106
|
+
def last_column(sheet=nil)
|
107
|
+
# $log.debug("#{self.class.to_s}#last_column(#{sheet})")
|
108
|
+
sheet = @default_sheet unless sheet
|
109
|
+
read_cells(sheet) unless @cells_read[sheet]
|
110
|
+
if @last_column[sheet]
|
111
|
+
# $log.debug("last_column of sheet #{sheet} already set")
|
112
|
+
return @last_column[sheet]
|
261
113
|
end
|
262
|
-
|
114
|
+
# $log.debug("last_column of sheet #{sheet} not yet set")
|
115
|
+
impossible_value = 0
|
116
|
+
result = impossible_value
|
117
|
+
@cell[sheet].each_pair {|key,value|
|
118
|
+
y,x = key.split(',')
|
119
|
+
x = x.to_i
|
120
|
+
result = [result, x].max if value
|
121
|
+
} if @cell[sheet]
|
122
|
+
result = nil if result == impossible_value
|
123
|
+
@last_column[sheet] = result
|
124
|
+
result
|
263
125
|
end
|
264
126
|
|
265
|
-
#
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
127
|
+
# returns a rectangular area (default: all cells) as yaml-output
|
128
|
+
# you can add additional attributes with the prefix parameter like:
|
129
|
+
# oo.to_yaml({"file"=>"flightdata_2007-06-26", "sheet" => "1"})
|
130
|
+
def to_yaml(prefix={}, from_row=nil, from_column=nil, to_row=nil, to_column=nil,sheet=nil)
|
131
|
+
sheet = @default_sheet unless sheet
|
132
|
+
result = "--- \n"
|
133
|
+
(from_row||first_row(sheet)).upto(to_row||last_row(sheet)) do |row|
|
134
|
+
(from_column||first_column(sheet)).upto(to_column||last_column(sheet)) do |col|
|
135
|
+
unless empty?(row,col,sheet)
|
136
|
+
result << "cell_#{row}_#{col}: \n"
|
137
|
+
prefix.each {|k,v|
|
138
|
+
result << " #{k}: #{v} \n"
|
139
|
+
}
|
140
|
+
result << " row: #{row} \n"
|
141
|
+
result << " col: #{col} \n"
|
142
|
+
result << " celltype: #{self.celltype(row,col,sheet)} \n"
|
143
|
+
if self.celltype(row,col,sheet) == :time
|
144
|
+
result << " value: #{GenericSpreadsheet.integer_to_timestring( self.cell(row,col,sheet))} \n"
|
145
|
+
else
|
146
|
+
result << " value: #{self.cell(row,col,sheet)} \n"
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
275
150
|
end
|
276
151
|
result
|
277
152
|
end
|
@@ -333,7 +208,7 @@ class GenericSpreadsheet
|
|
333
208
|
if @header_line
|
334
209
|
result = [ tmp ]
|
335
210
|
else
|
336
|
-
result = tmp
|
211
|
+
result = tmp
|
337
212
|
end
|
338
213
|
#-- :all
|
339
214
|
elsif args[0] == :all
|
@@ -381,46 +256,224 @@ class GenericSpreadsheet
|
|
381
256
|
result
|
382
257
|
end
|
383
258
|
|
259
|
+
# returns all values in this row as an array
|
260
|
+
# row numbers are 1,2,3,... like in the spreadsheet
|
261
|
+
def row(rownumber,sheet=nil)
|
262
|
+
sheet = @default_sheet unless sheet
|
263
|
+
read_cells(sheet) unless @cells_read[sheet]
|
264
|
+
result = []
|
265
|
+
tmp_arr = []
|
266
|
+
@cell[sheet].each_pair {|key,value|
|
267
|
+
y,x = key.split(',')
|
268
|
+
x = x.to_i
|
269
|
+
y = y.to_i
|
270
|
+
if y == rownumber
|
271
|
+
tmp_arr[x] = value
|
272
|
+
end
|
273
|
+
}
|
274
|
+
result = tmp_arr[1..-1]
|
275
|
+
while result && result[-1] == nil
|
276
|
+
result = result[0..-2]
|
277
|
+
end
|
278
|
+
result
|
279
|
+
end
|
280
|
+
|
281
|
+
# returns all values in this column as an array
|
282
|
+
# column numbers are 1,2,3,... like in the spreadsheet
|
283
|
+
def column(columnnumber,sheet=nil)
|
284
|
+
if columnnumber.class == String
|
285
|
+
columnnumber = Excel.letter_to_number(columnnumber)
|
286
|
+
end
|
287
|
+
sheet = @default_sheet unless sheet
|
288
|
+
read_cells(sheet) unless @cells_read[sheet]
|
289
|
+
result = []
|
290
|
+
first_row(sheet).upto(last_row(sheet)) do |row|
|
291
|
+
result << cell(row,columnnumber,sheet)
|
292
|
+
end
|
293
|
+
result
|
294
|
+
end
|
295
|
+
|
296
|
+
# reopens and read a spreadsheet document
|
297
|
+
def reload
|
298
|
+
ds = @default_sheet
|
299
|
+
initialize(@filename) if self.class == Openoffice or
|
300
|
+
self.class == Excel
|
301
|
+
initialize(@spreadsheetkey,@user,@password) if self.class == Google
|
302
|
+
self.default_sheet = ds
|
303
|
+
#@first_row = @last_row = @first_column = @last_column = nil
|
304
|
+
end
|
305
|
+
|
306
|
+
# true if cell is empty
|
307
|
+
def empty?(row, col, sheet=nil)
|
308
|
+
sheet = @default_sheet unless sheet
|
309
|
+
read_cells(sheet) unless @cells_read[sheet] or self.class == Excel
|
310
|
+
row,col = normalize(row,col)
|
311
|
+
return true unless cell(row, col, sheet)
|
312
|
+
return true if celltype(row, col, sheet) == :string && cell(row, col, sheet).empty?
|
313
|
+
return true if row < first_row(sheet) || row > last_row(sheet) || col < first_column(sheet) || col > last_column(sheet)
|
314
|
+
false
|
315
|
+
end
|
316
|
+
|
317
|
+
# recursively removes the current temporary directory
|
318
|
+
# this is only needed if you work with zipped files or files via the web
|
319
|
+
def remove_tmp
|
320
|
+
if File.exists?(@tmpdir)
|
321
|
+
FileUtils::rm_r(@tmpdir)
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
# Returns information of the spreadsheet document and all sheets within
|
326
|
+
# this document.
|
327
|
+
def info
|
328
|
+
# $log.debug(self.class.to_s+"#info started")
|
329
|
+
result = "File: #{File.basename(@filename)}\n"+
|
330
|
+
"Number of sheets: #{sheets.size}\n"+
|
331
|
+
"Sheets: #{sheets.map{|sheet| sheet+", "}.to_s[0..-3]}\n"
|
332
|
+
n = 1
|
333
|
+
# $log.debug(sheets.inspect)
|
334
|
+
sheets.each {|sheet|
|
335
|
+
# $log.debug("Info fuer Sheet=#{sheet}")
|
336
|
+
self.default_sheet = sheet
|
337
|
+
# $log.debug("nach default_sheet=")
|
338
|
+
result << "Sheet " + n.to_s + ":\n"
|
339
|
+
unless first_row
|
340
|
+
result << " - empty -"
|
341
|
+
else
|
342
|
+
result << " First row: #{first_row}\n"
|
343
|
+
result << " Last row: #{last_row}\n"
|
344
|
+
result << " First column: #{GenericSpreadsheet.number_to_letter(first_column)}\n"
|
345
|
+
result << " Last column: #{GenericSpreadsheet.number_to_letter(last_column)}"
|
346
|
+
end
|
347
|
+
result << "\n" if sheet != sheets.last
|
348
|
+
n += 1
|
349
|
+
}
|
350
|
+
# $log.debug(self.class.to_s+"#info ended")
|
351
|
+
result
|
352
|
+
end
|
353
|
+
|
384
354
|
def to_xml
|
385
355
|
xml_document = ''
|
386
356
|
xml = Builder::XmlMarkup.new(:target => xml_document, :indent => 2)
|
387
357
|
xml.instruct! :xml, :version =>"1.0", :encoding => "utf-8"
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
358
|
+
xml.spreadsheet {
|
359
|
+
self.sheets.each do |sheet|
|
360
|
+
self.default_sheet = sheet
|
361
|
+
xml.sheet(:name => sheet) { |x|
|
362
|
+
if first_row and last_row and first_column and last_column
|
363
|
+
# sonst gibt es Fehler bei leeren Blaettern
|
364
|
+
first_row.upto(last_row) do |row|
|
365
|
+
first_column.upto(last_column) do |col|
|
366
|
+
unless empty?(row,col)
|
367
|
+
x.cell(cell(row,col),
|
368
|
+
:row =>row,
|
369
|
+
:column => col,
|
370
|
+
:type => celltype(row,col))
|
371
|
+
end
|
372
|
+
end
|
400
373
|
end
|
401
374
|
end
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
}
|
406
|
-
|
375
|
+
}
|
376
|
+
end
|
377
|
+
}
|
407
378
|
xml_document
|
408
379
|
end
|
409
|
-
|
380
|
+
|
410
381
|
protected
|
411
382
|
|
412
|
-
def
|
413
|
-
|
414
|
-
|
415
|
-
|
383
|
+
def file_type_check(filename, ext, name)
|
384
|
+
new_expression = {
|
385
|
+
'.ods' => 'Openoffice.new',
|
386
|
+
'.xls' => 'Excel.new',
|
387
|
+
'.xlsx' => 'Excelx.new',
|
388
|
+
}
|
389
|
+
case ext
|
390
|
+
when '.ods', '.xls', '.xlsx'
|
391
|
+
correct_class = "use #{new_expression[ext]} to handle #{ext} spreadsheet files"
|
392
|
+
else
|
393
|
+
raise "unknown file type: #{ext}"
|
394
|
+
end
|
395
|
+
if File.extname(filename).downcase != ext
|
396
|
+
case @file_warning
|
397
|
+
when :error
|
398
|
+
warn correct_class
|
399
|
+
raise TypeError, "#{filename} is not #{name} file"
|
400
|
+
when :warning
|
401
|
+
warn "are you sure, this is #{name} spreadsheet file?"
|
402
|
+
warn correct_class
|
403
|
+
when :ignore
|
404
|
+
# ignore
|
405
|
+
else
|
406
|
+
raise "#{@file_warning} illegal state of file_warning"
|
407
|
+
end
|
416
408
|
end
|
417
|
-
ret
|
418
409
|
end
|
419
410
|
|
411
|
+
|
420
412
|
private
|
421
413
|
|
422
|
-
|
414
|
+
# converts cell coordinate to numeric values of row,col
|
415
|
+
def normalize(row,col)
|
416
|
+
if row.class == String
|
417
|
+
if col.class == Fixnum
|
418
|
+
# ('A',1):
|
419
|
+
# ('B', 5) -> (5, 2)
|
420
|
+
row, col = col, row
|
421
|
+
else
|
422
|
+
raise ArgumentError
|
423
|
+
end
|
424
|
+
end
|
425
|
+
if col.class == String
|
426
|
+
col = GenericSpreadsheet.letter_to_number(col)
|
427
|
+
end
|
428
|
+
return row,col
|
429
|
+
end
|
423
430
|
|
431
|
+
def open_from_uri(uri)
|
432
|
+
require 'open-uri' ;
|
433
|
+
tempfilename = File.join(@tmpdir, File.basename(uri))
|
434
|
+
f = File.open(tempfilename,"wb")
|
435
|
+
begin
|
436
|
+
open(uri) do |net|
|
437
|
+
f.write(net.read)
|
438
|
+
end
|
439
|
+
rescue
|
440
|
+
raise "could not open #{uri}"
|
441
|
+
end
|
442
|
+
f.close
|
443
|
+
File.join(@tmpdir, File.basename(uri))
|
444
|
+
end
|
445
|
+
|
446
|
+
# convert a number to something like this: 'AB'
|
447
|
+
def GenericSpreadsheet.number_to_letter(n)
|
448
|
+
letters=""
|
449
|
+
while n > 0
|
450
|
+
num = n%26
|
451
|
+
letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[num-1,1] + letters
|
452
|
+
n = n.div(26)
|
453
|
+
end
|
454
|
+
letters
|
455
|
+
end
|
456
|
+
|
457
|
+
# convert letters like 'AB' to a number
|
458
|
+
def self.letter_to_number(letters)
|
459
|
+
result = 0
|
460
|
+
while letters && letters.length > 0
|
461
|
+
character = letters[0,1].upcase
|
462
|
+
num = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".index(character)
|
463
|
+
raise ArgumentError, "invalid column character '#{letters[0,1]}'" if num == nil
|
464
|
+
num += 1
|
465
|
+
result = result * 26 + num
|
466
|
+
letters = letters[1..-1]
|
467
|
+
end
|
468
|
+
result
|
469
|
+
end
|
470
|
+
|
471
|
+
def unzip(filename)
|
472
|
+
ret = nil
|
473
|
+
Zip::ZipFile.open(filename) do |zip|
|
474
|
+
ret = process_zipfile_packed zip
|
475
|
+
end
|
476
|
+
ret
|
424
477
|
end
|
425
478
|
|
426
479
|
# check if default_sheet was set and exists in sheets-array
|
@@ -460,7 +513,6 @@ class GenericSpreadsheet
|
|
460
513
|
end
|
461
514
|
|
462
515
|
def write_csv_content(file=nil,sheet=nil)
|
463
|
-
# sheet = @default_sheet unless sheet
|
464
516
|
file = STDOUT unless file
|
465
517
|
if first_row(sheet) # sheet is not empty
|
466
518
|
first_row(sheet).upto(last_row(sheet)) do |row|
|
@@ -512,20 +564,16 @@ class GenericSpreadsheet
|
|
512
564
|
raise "unhandled onecell-class "+onecell.class.to_s
|
513
565
|
end
|
514
566
|
when :date
|
515
|
-
# str << '"'+onecell.to_s+'"'
|
516
567
|
str << onecell.to_s
|
517
|
-
# str << onecell.strftime("%d.%m.%y")
|
518
568
|
when :time
|
519
569
|
str << GenericSpreadsheet.integer_to_timestring(onecell)
|
520
570
|
else
|
521
571
|
raise "unhandled celltype "+onecelltype.to_s
|
522
572
|
end
|
523
573
|
end
|
524
|
-
#cells << onecell
|
525
574
|
str
|
526
575
|
end
|
527
576
|
|
528
|
-
private
|
529
577
|
def GenericSpreadsheet.integer_to_timestring(content)
|
530
578
|
h = (content/3600.0).floor
|
531
579
|
content = content - h*3600
|