roo 1.2.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,6 @@
1
+ == 1.2.1 2008-11-13
2
+ * 1 enhancement
3
+ * added celltype :datetime in Openoffice and Excel
1
4
  == 1.2.0 2008-08-24
2
5
  * 3 major enhancements
3
6
  * Excelx: improved the detection of cell type and conversion into roo types
data/Manifest.txt CHANGED
@@ -58,6 +58,8 @@ test/ric.ods
58
58
  test/bug-row-column-fixnum-float.xls
59
59
  test/emptysheets.ods
60
60
  test/emptysheets.xls
61
+ test/datetime.ods
62
+ test/datetime.xls
61
63
  website/index.html
62
64
  website/index.txt
63
65
  website/javascripts/rounded_corners_lite.inc.js
data/lib/roo/excel.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'rubygems'
2
2
  gem 'parseexcel', '>= 0.5.2'
3
3
  require 'parseexcel'
4
- CHARGUESS=false
4
+ CHARGUESS = false
5
5
  require 'charguess' if CHARGUESS
6
6
 
7
7
  module Spreadsheet # :nodoc
@@ -29,6 +29,7 @@ class Excel < GenericSpreadsheet
29
29
  FileUtils::mkdir(@tmpdir)
30
30
  end
31
31
  filename = open_from_uri(filename) if filename[0,7] == "http://"
32
+ filename = open_from_stream(filename[7..-1]) if filename[0,7] == "stream:"
32
33
  filename = unzip(filename) if packed and packed == :zip
33
34
  begin
34
35
  file_type_check(filename,'.xls','an Excel')
@@ -61,7 +62,8 @@ class Excel < GenericSpreadsheet
61
62
  # returns an array of sheet names in the spreadsheet
62
63
  def sheets
63
64
  result = []
64
- 0.upto(@workbook.sheet_count - 1) do |i|
65
+ #0.upto(@workbook.worksheets.size - 1) do |i| # spreadsheet
66
+ 0.upto(@workbook.sheet_count - 1) do |i| # parseexcel
65
67
  # TODO: is there a better way to do conversion?
66
68
  if CHARGUESS
67
69
  encoding = CharGuess::guess(@workbook.worksheet(i).name)
@@ -81,13 +83,15 @@ class Excel < GenericSpreadsheet
81
83
  # returns the content of a cell. The upper left corner is (1,1) or ('A',1)
82
84
  def cell(row,col,sheet=nil)
83
85
  sheet = @default_sheet unless sheet
86
+ raise ArgumentError unless sheet
84
87
  read_cells(sheet) unless @cells_read[sheet]
88
+ raise "should be read" unless @cells_read[sheet]
85
89
  row,col = normalize(row,col)
86
90
  if celltype(row,col,sheet) == :date
87
- yyyy,mm,dd = @cell[sheet]["#{row},#{col}"].split('-')
91
+ yyyy,mm,dd = @cell[sheet][[row,col]].split('-')
88
92
  return Date.new(yyyy.to_i,mm.to_i,dd.to_i)
89
93
  end
90
- return @cell[sheet]["#{row},#{col}"]
94
+ return @cell[sheet][[row,col]]
91
95
  end
92
96
 
93
97
  # returns the type of a cell:
@@ -97,14 +101,20 @@ class Excel < GenericSpreadsheet
97
101
  # * :percentage
98
102
  # * :formula
99
103
  # * :time
104
+ # * :datetime
100
105
  def celltype(row,col,sheet=nil)
101
106
  sheet = @default_sheet unless sheet
102
107
  read_cells(sheet) unless @cells_read[sheet]
103
108
  row,col = normalize(row,col)
104
- if @formula[sheet]["#{row},#{col}"]
105
- return :formula
106
- else
107
- @cell_type[sheet]["#{row},#{col}"]
109
+ begin
110
+ if @formula[sheet][[row,col]]
111
+ return :formula
112
+ else
113
+ @cell_type[sheet][[row,col]]
114
+ end
115
+ rescue
116
+ puts "Error in sheet #{sheet}, row #{row}, col #{col}"
117
+ raise
108
118
  end
109
119
  end
110
120
 
@@ -155,86 +165,45 @@ class Excel < GenericSpreadsheet
155
165
  raise EXCEL_NO_FORMULAS
156
166
  end
157
167
 
158
- private
159
-
160
- # determine the first and last boundaries
161
- def get_firsts_lasts_parseexcel(sheet=nil)
168
+ # shows the internal representation of all cells
169
+ # mainly for debugging purposes
170
+ def to_s(sheet=nil)
162
171
  sheet = @default_sheet unless sheet
163
- fr = fc = 999_999
164
- lr = lc = -999_999
165
- worksheet = @workbook.worksheet(sheet_no(sheet))
166
- unless worksheet.min_row
167
- fr = nil
168
- else
169
- fr = worksheet.min_row + 1
170
- end
171
- unless worksheet.max_row
172
- lr = nil
173
- else
174
- lr = worksheet.max_row + 1
175
- end
176
- unless worksheet.min_col
177
- fc = nil
178
- else
179
- fc = worksheet.min_col + 1
180
- end
181
- unless worksheet.max_col
182
- lc = nil
183
- else
184
- lc = worksheet.max_col + 1
185
- end
186
- if lr
187
- # 2007-11-05 BEGIN
188
- # parsexcel liefert (mir unverstaendlich) eine Zeile als letzte Zeile
189
- # zurueck, die aber leer ist. Deshalb Korrekturfunktion, die wirklich
190
- # die letzte nicht leere Zeile liefert.
191
- # 2008-07-23 meine Loesung funtionierte auch noch nicht unter allen
192
- # Umstaenden row() == nil ergaenzt
193
- while row(lr,sheet) == nil || empty_row?(row(lr,sheet))
194
- lr -= 1
195
- end
196
- end
197
- # 2007-11-05 END
198
-
199
- if lc
200
- letzte_spalte_leer = true
201
- until ! letzte_spalte_leer
202
- worksheet.each(0) {|reihe|
203
- if reihe
204
- cell = reihe.at(lc-1)
205
- if cell
206
- case cell.type
207
- when :numeric, :date
208
- letzte_spalte_leer = false
209
- when :text
210
- letzte_spalte_leer = false if cell.to_s != ""
211
- end
212
- end
213
- end
214
- }
215
- lc -= 1 if letzte_spalte_leer
216
- #puts "letzte Spalte auf #{lc} verringert" if letzte_spalte_leer
217
- end
218
- end
219
-
220
- return fr, lr, fc, lc
172
+ read_cells(sheet) unless @cells_read[sheet]
173
+ @cell[sheet].inspect
221
174
  end
222
175
 
176
+ private
223
177
  # determine the first and last boundaries
224
178
  def get_firsts_lasts(sheet=nil)
225
- fr,lr,fc,lc = get_firsts_lasts_parseexcel(sheet)
226
- if lr
227
- # 2007-11-05 BEGIN
228
- # parsexcel liefert (mir unverstaendlich) eine Zeile als letzte Zeile
229
- # zurueck, die aber leer ist. Deshalb Korrekturfunktion, die wirklich
230
- # die letzte nicht leere Zeile liefert.
231
- # 2008-07-23 meine Loesung funtionierte auch noch nicht unter allen
232
- # Umstaenden row() == nil ergaenzt
233
- while row(lr,sheet) == nil || empty_row?(row(lr,sheet))
234
- lr -= 1
235
- end
179
+
180
+ # 2008-09-14 BEGINf
181
+ fr=lr=fc=lc=nil
182
+ sheet = @default_sheet unless sheet
183
+ if ! @cells_read[sheet]
184
+ read_cells(sheet)
185
+ end
186
+ if @cell[sheet] # nur wenn ueberhaupt Zellen belegt sind
187
+ @cell[sheet].each {|cellitem|
188
+ key = cellitem.first
189
+ y,x = key
190
+
191
+ if cellitem[1].class != String or
192
+ (cellitem[1].class == String and cellitem[1] != "")
193
+ fr = y unless fr
194
+ fr = y if y < fr
195
+
196
+ lr = y unless lr
197
+ lr = y if y > lr
198
+
199
+ fc = x unless fc
200
+ fc = x if x < fc
201
+
202
+ lc = x unless lc
203
+ lc = x if x > lc
204
+ end
205
+ }
236
206
  end
237
- # 2007-11-05 END
238
207
  @first_row[sheet] = fr
239
208
  @last_row[sheet] = lr
240
209
  @first_column[sheet] = fc
@@ -246,6 +215,7 @@ class Excel < GenericSpreadsheet
246
215
  def sheet_no(name)
247
216
  return name-1 if name.kind_of?(Fixnum)
248
217
  0.upto(@workbook.sheet_count - 1) do |i|
218
+ #0.upto(@workbook.worksheets.size - 1) do |i|
249
219
  # TODO: is there a better way to do conversion?
250
220
  return i if name == platform_specific_iconv(
251
221
  @workbook.worksheet(i).name)
@@ -317,19 +287,22 @@ class Excel < GenericSpreadsheet
317
287
 
318
288
  # helper function to set the internal representation of cells
319
289
  def set_cell_values(sheet,x,y,i,v,vt,formula,tr,str_v)
320
- key = "#{y},#{x+i}"
290
+ #key = "#{y},#{x+i}"
291
+ key = [y,x+i]
321
292
  @cell_type[sheet] = {} unless @cell_type[sheet]
322
293
  @cell_type[sheet][key] = vt
323
294
  @formula[sheet] = {} unless @formula[sheet]
324
295
  @formula[sheet][key] = formula if formula
325
296
  @cell[sheet] = {} unless @cell[sheet]
326
- case @cell_type[sheet][key]
297
+ case vt # @cell_type[sheet][key]
327
298
  when :float
328
299
  @cell[sheet][key] = v.to_f
329
300
  when :string
330
301
  @cell[sheet][key] = str_v
331
302
  when :date
332
303
  @cell[sheet][key] = v
304
+ when :datetime
305
+ @cell[sheet][key] = DateTime.new(v.year,v.month,v.day,v.hour,v.min,v.sec)
333
306
  when :percentage
334
307
  @cell[sheet][key] = v.to_f
335
308
  when :time
@@ -344,6 +317,11 @@ class Excel < GenericSpreadsheet
344
317
  sheet = @default_sheet unless sheet
345
318
  raise ArgumentError, "Error: sheet '#{sheet||'nil'}' not valid" if @default_sheet == nil and sheet==nil
346
319
  raise RangeError unless self.sheets.include? sheet
320
+
321
+ if @cells_read[sheet]
322
+ raise "sheet #{sheet} already read"
323
+ end
324
+
347
325
  worksheet = @workbook.worksheet(sheet_no(sheet))
348
326
  skip = 0
349
327
  x =1
@@ -352,7 +330,7 @@ class Excel < GenericSpreadsheet
352
330
  worksheet.each(skip) { |row_par|
353
331
  if row_par
354
332
  x =1
355
- row_par.each do # |void|
333
+ row_par.each do # |void|
356
334
  cell = row_par.at(x-1)
357
335
  if cell
358
336
  case cell.type
@@ -374,17 +352,26 @@ class Excel < GenericSpreadsheet
374
352
  s = secs
375
353
  v = h*3600+m*60+s
376
354
  else
377
- vt = :date
378
- v = cell.date
379
- v = sprintf("%04d-%02d-%02d",v.year,v.month,v.day)
355
+ if cell.datetime.hour != 0 or
356
+ cell.datetime.min != 0 or
357
+ cell.datetime.sec != 0 or
358
+ cell.datetime.msec != 0
359
+ vt = :datetime
360
+ v = cell.datetime
361
+ else
362
+ vt = :date
363
+ v = cell.date
364
+ v = sprintf("%04d-%02d-%02d",v.year,v.month,v.day)
365
+ end
380
366
  end
381
367
  else
382
- vt = cell.type.to_sym
368
+ vt = cell.type.to_s.downcase.to_sym
383
369
  v = nil
384
370
  end # case
385
371
  formula = tr = nil #TODO:???
386
372
  set_cell_values(sheet,x,y,i,v,vt,formula,tr,str_v)
387
373
  end # if cell
374
+
388
375
  x += 1
389
376
  end
390
377
  end
@@ -393,18 +380,18 @@ class Excel < GenericSpreadsheet
393
380
  @cells_read[sheet] = true
394
381
  end
395
382
 
396
- #TODO: testing only
397
- # def inject_null_characters(str)
398
- # if str.class != String
399
- # return str
400
- # end
401
- # new_str=''
402
- # 0.upto(str.size-1) do |i|
403
- # new_str += str[i,1]
404
- # new_str += "\000"
405
- # end
406
- # new_str
407
- # end
408
- #
383
+ #TODO: testing only
384
+ # def inject_null_characters(str)
385
+ # if str.class != String
386
+ # return str
387
+ # end
388
+ # new_str=''
389
+ # 0.upto(str.size-1) do |i|
390
+ # new_str += str[i,1]
391
+ # new_str += "\000"
392
+ # end
393
+ # new_str
394
+ # end
395
+ #
409
396
 
410
397
  end
data/lib/roo/excelx.rb CHANGED
@@ -4,7 +4,6 @@ require 'rexml/document'
4
4
  require 'fileutils'
5
5
  require 'zip/zipfilesystem'
6
6
  require 'date'
7
- #require 'base64'
8
7
 
9
8
  class String
10
9
  def end_with?(str)
@@ -156,10 +155,10 @@ class Excelx < GenericSpreadsheet
156
155
  read_cells(sheet) unless @cells_read[sheet]
157
156
  row,col = normalize(row,col)
158
157
  if celltype(row,col,sheet) == :date
159
- yyyy,mm,dd = @cell[sheet]["#{row},#{col}"].split('-')
158
+ yyyy,mm,dd = @cell[sheet][[row,col]].split('-')
160
159
  return Date.new(yyyy.to_i,mm.to_i,dd.to_i)
161
160
  end
162
- @cell[sheet]["#{row},#{col}"]
161
+ @cell[sheet][[row,col]]
163
162
  end
164
163
 
165
164
  # Returns the formula at (row,col).
@@ -169,10 +168,10 @@ class Excelx < GenericSpreadsheet
169
168
  sheet = @default_sheet unless sheet
170
169
  read_cells(sheet) unless @cells_read[sheet]
171
170
  row,col = normalize(row,col)
172
- if @formula[sheet]["#{row},#{col}"] == nil
171
+ if @formula[sheet][[row,col]] == nil
173
172
  return nil
174
173
  else
175
- return @formula[sheet]["#{row},#{col}"]
174
+ return @formula[sheet][[row,col]]
176
175
  end
177
176
  end
178
177
 
@@ -209,15 +208,15 @@ class Excelx < GenericSpreadsheet
209
208
  # * :percentage
210
209
  # * :formula
211
210
  # * :time
212
- def celltype(row,col,sheet=nil)
211
+ # * :datetime
212
+ def celltype(row,col,sheet=nil)
213
213
  sheet = @default_sheet unless sheet
214
214
  read_cells(sheet) unless @cells_read[sheet]
215
215
  row,col = normalize(row,col)
216
- # if @formula and @formula[sheet] and @formula[sheet]["#{row},#{col}"]
217
- if @formula[sheet]["#{row},#{col}"]
216
+ if @formula[sheet][[row,col]]
218
217
  return :formula
219
218
  else
220
- @cell_type[sheet]["#{row},#{col}"]
219
+ @cell_type[sheet][[row,col]]
221
220
  end
222
221
  end
223
222
 
@@ -229,7 +228,7 @@ class Excelx < GenericSpreadsheet
229
228
  sheet = @default_sheet unless sheet
230
229
  read_cells(sheet) unless @cells_read[sheet]
231
230
  row,col = normalize(row,col)
232
- return @excelx_type[sheet]["#{row},#{col}"]
231
+ return @excelx_type[sheet][[row,col]]
233
232
  end
234
233
 
235
234
  # returns the internal value of an excelx cell
@@ -238,7 +237,7 @@ class Excelx < GenericSpreadsheet
238
237
  sheet = @default_sheet unless sheet
239
238
  read_cells(sheet) unless @cells_read[sheet]
240
239
  row,col = normalize(row,col)
241
- return @excelx_value[sheet]["#{row},#{col}"]
240
+ return @excelx_value[sheet][[row,col]]
242
241
  end
243
242
 
244
243
  # returns the internal format of an excel cell
@@ -246,7 +245,7 @@ class Excelx < GenericSpreadsheet
246
245
  sheet = @default_sheet unless sheet
247
246
  read_cells(sheet) unless @cells_read[sheet]
248
247
  row,col = normalize(row,col)
249
- s = @s_attribute[sheet]["#{row},#{col}"]
248
+ s = @s_attribute[sheet][[row,col]]
250
249
  result = attribute2format(s)
251
250
  result
252
251
  end
@@ -298,7 +297,7 @@ class Excelx < GenericSpreadsheet
298
297
  excelx_type=nil,
299
298
  excelx_value=nil,
300
299
  s_attribute=nil)
301
- key = "#{y},#{x+i}"
300
+ key = [y,x+i]
302
301
  @cell_type[sheet] = {} unless @cell_type[sheet]
303
302
  @cell_type[sheet][key] = vt
304
303
  @formula[sheet] = {} unless @formula[sheet]
@@ -314,8 +313,6 @@ class Excelx < GenericSpreadsheet
314
313
  when :percentage
315
314
  @cell[sheet][key] = v.to_f
316
315
  when :time
317
- #hms = v.split(':')
318
- #@cell[sheet][key] = hms[0].to_i*3600 + hms[1].to_i*60 + hms[2].to_i
319
316
  @cell[sheet][key] = v.to_f*(24*60*60)
320
317
  else
321
318
  @cell[sheet][key] = v
@@ -497,13 +494,13 @@ class Excelx < GenericSpreadsheet
497
494
  # sets the value of a cell
498
495
  def set_value(row,col,value,sheet=nil)
499
496
  sheet = @default_value unless sheet
500
- @cell[sheet]["#{row},#{col}"] = value
497
+ @cell[sheet][[row,col]] = value
501
498
  end
502
499
 
503
500
  # sets the type of a cell
504
501
  def set_type(row,col,type,sheet=nil)
505
502
  sheet = @default_value unless sheet
506
- @cell_type[sheet]["#{row},#{col}"] = type
503
+ @cell_type[sheet][[row,col]] = type
507
504
  end
508
505
 
509
506
  # read the shared strings xml document
@@ -542,7 +539,6 @@ class Excelx < GenericSpreadsheet
542
539
  e2.each_element do |e3|
543
540
  if e3.name == 'xf'
544
541
  numFmtId = e3.attributes['numFmtId']
545
- # p numFmtId
546
542
  @cellXfs << [numFmtId]
547
543
  end
548
544
  end
@@ -53,7 +53,7 @@ class GenericSpreadsheet
53
53
  impossible_value = 999_999 # more than a spreadsheet can hold
54
54
  result = impossible_value
55
55
  @cell[sheet].each_pair {|key,value|
56
- y,x = key.split(',')
56
+ y,x = key # _to_string(key).split(',')
57
57
  y = y.to_i
58
58
  result = [result, y].min if value
59
59
  } if @cell[sheet]
@@ -72,7 +72,7 @@ class GenericSpreadsheet
72
72
  impossible_value = 0
73
73
  result = impossible_value
74
74
  @cell[sheet].each_pair {|key,value|
75
- y,x = key.split(',')
75
+ y,x = key # _to_string(key).split(',')
76
76
  y = y.to_i
77
77
  result = [result, y].max if value
78
78
  } if @cell[sheet]
@@ -93,8 +93,8 @@ class GenericSpreadsheet
93
93
  impossible_value = 999_999 # more than a spreadsheet can hold
94
94
  result = impossible_value
95
95
  @cell[sheet].each_pair {|key,value|
96
- y,x = key.split(',')
97
- x = x.to_i
96
+ y,x = key # _to_string(key).split(',')
97
+ x = x # .to_i
98
98
  result = [result, x].min if value
99
99
  } if @cell[sheet]
100
100
  result = nil if result == impossible_value
@@ -112,7 +112,7 @@ class GenericSpreadsheet
112
112
  impossible_value = 0
113
113
  result = impossible_value
114
114
  @cell[sheet].each_pair {|key,value|
115
- y,x = key.split(',')
115
+ y,x = key # _to_string(key).split(',')
116
116
  x = x.to_i
117
117
  result = [result, x].max if value
118
118
  } if @cell[sheet]
@@ -227,7 +227,6 @@ class GenericSpreadsheet
227
227
  found *= 0
228
228
  end
229
229
  }
230
- # p self.row(i) if found > 0
231
230
  if found > 0
232
231
  tmp = {}
233
232
  1.upto(self.row(i).size) {|j|
@@ -261,7 +260,7 @@ class GenericSpreadsheet
261
260
  result = []
262
261
  tmp_arr = []
263
262
  @cell[sheet].each_pair {|key,value|
264
- y,x = key.split(',')
263
+ y,x = key # _to_string(key).split(',')
265
264
  x = x.to_i
266
265
  y = y.to_i
267
266
  if y == rownumber
@@ -400,6 +399,21 @@ class GenericSpreadsheet
400
399
  end
401
400
  end
402
401
 
402
+ # konvertiert einen Key in der Form "12,45" (=row,column) in
403
+ # ein Array mit numerischen Werten ([12,45])
404
+ # Diese Methode ist eine temp. Loesung, um zu erforschen, ob der
405
+ # Zugriff mit numerischen Keys schneller ist.
406
+ def key_to_num(str)
407
+ r,c = str.split(',')
408
+ r = r.to_i
409
+ c = c.to_i
410
+ [r,c]
411
+ end
412
+
413
+ # siehe: key_to_num
414
+ def key_to_string(arr)
415
+ "#{arr[0]},#{arr[1]}"
416
+ end
403
417
 
404
418
  private
405
419
 
@@ -435,6 +449,14 @@ class GenericSpreadsheet
435
449
  File.join(@tmpdir, File.basename(uri))
436
450
  end
437
451
 
452
+ def open_from_stream(stream)
453
+ tempfilename = File.join(@tmpdir, "spreadsheet")
454
+ f = File.open(tempfilename,"wb")
455
+ f.write(stream[7..-1])
456
+ f.close
457
+ File.join(@tmpdir, "spreadsheet")
458
+ end
459
+
438
460
  # convert a number to something like 'AB' (1 => 'A', 2 => 'B', ...)
439
461
  def self.number_to_letter(n)
440
462
  letters=""
data/lib/roo/google.rb CHANGED
@@ -162,6 +162,7 @@ class Google < GenericSpreadsheet
162
162
  # * :percentage
163
163
  # * :formula
164
164
  # * :time
165
+ # * :datetime
165
166
  def celltype(row, col, sheet=nil)
166
167
  sheet = @default_sheet unless sheet
167
168
  read_cells(sheet) unless @cells_read[sheet]
@@ -321,6 +322,7 @@ class Google < GenericSpreadsheet
321
322
  # read all cells in a sheet
322
323
  def read_cells(sheet=nil)
323
324
  sheet = @default_sheet unless sheet
325
+ raise RangeError, "illegal sheet <#{sheet}>" unless sheets.index(sheet)
324
326
  sheet_no = sheets.index(sheet)+1
325
327
  doc = @gs.fulldoc(sheet_no)
326
328
  (doc/"gs:cell").each {|item|
@@ -80,10 +80,10 @@ class Openoffice < GenericSpreadsheet
80
80
  read_cells(sheet) unless @cells_read[sheet]
81
81
  row,col = normalize(row,col)
82
82
  if celltype(row,col,sheet) == :date
83
- yyyy,mm,dd = @cell[sheet]["#{row},#{col}"].split('-')
83
+ yyyy,mm,dd = @cell[sheet][[row,col]].split('-')
84
84
  return Date.new(yyyy.to_i,mm.to_i,dd.to_i)
85
85
  end
86
- @cell[sheet]["#{row},#{col}"]
86
+ @cell[sheet][[row,col]]
87
87
  end
88
88
 
89
89
  # Returns the formula at (row,col).
@@ -93,10 +93,10 @@ class Openoffice < GenericSpreadsheet
93
93
  sheet = @default_sheet unless sheet
94
94
  read_cells(sheet) unless @cells_read[sheet]
95
95
  row,col = normalize(row,col)
96
- if @formula[sheet]["#{row},#{col}"] == nil
96
+ if @formula[sheet][[row,col]] == nil
97
97
  return nil
98
98
  else
99
- return @formula[sheet]["#{row},#{col}"]["oooc:".length..-1]
99
+ return @formula[sheet][[row,col]]["oooc:".length..-1]
100
100
  end
101
101
  end
102
102
 
@@ -133,14 +133,15 @@ class Openoffice < GenericSpreadsheet
133
133
  # * :percentage
134
134
  # * :formula
135
135
  # * :time
136
+ # * :datetime
136
137
  def celltype(row,col,sheet=nil)
137
138
  sheet = @default_sheet unless sheet
138
139
  read_cells(sheet) unless @cells_read[sheet]
139
140
  row,col = normalize(row,col)
140
- if @formula[sheet]["#{row},#{col}"]
141
+ if @formula[sheet][[row,col]]
141
142
  return :formula
142
143
  else
143
- @cell_type[sheet]["#{row},#{col}"]
144
+ @cell_type[sheet][[row,col]]
144
145
  end
145
146
  end
146
147
 
@@ -172,7 +173,6 @@ class Openoffice < GenericSpreadsheet
172
173
  # version of the openoffice document
173
174
  # at 2007 this is always "1.0"
174
175
  def officeversion
175
- # read_cells(false) unless @cells_read
176
176
  oo_version
177
177
  @officeversion
178
178
  end
@@ -211,7 +211,6 @@ class Openoffice < GenericSpreadsheet
211
211
 
212
212
  # read the version of the OO-Version
213
213
  def oo_version
214
- #sheet_found = false
215
214
  @doc.each_element do |oo_document|
216
215
  @officeversion = oo_document.attributes['version']
217
216
  end
@@ -219,7 +218,7 @@ class Openoffice < GenericSpreadsheet
219
218
 
220
219
  # helper function to set the internal representation of cells
221
220
  def set_cell_values(sheet,x,y,i,v,vt,formula,tr,str_v)
222
- key = "#{y},#{x+i}"
221
+ key = [y,x+i]
223
222
  @cell_type[sheet] = {} unless @cell_type[sheet]
224
223
  @cell_type[sheet][key] = Openoffice.oo_type_2_roo_type(vt)
225
224
  @formula[sheet] = {} unless @formula[sheet]
@@ -231,7 +230,14 @@ class Openoffice < GenericSpreadsheet
231
230
  when :string
232
231
  @cell[sheet][key] = str_v
233
232
  when :date
234
- @cell[sheet][key] = tr.attributes['date-value']
233
+ if tr.attributes['date-value'].size != "XXXX-XX-XX".size
234
+ #-- dann ist noch eine Uhrzeit vorhanden
235
+ #-- "1961-11-21T12:17:18"
236
+ @cell[sheet][key] = DateTime.parse(tr.attributes['date-value'])
237
+ @cell_type[sheet][key] = :datetime
238
+ else
239
+ @cell[sheet][key] = tr.attributes['date-value']
240
+ end
235
241
  when :percentage
236
242
  @cell[sheet][key] = v.to_f
237
243
  when :time
@@ -264,7 +270,7 @@ class Openoffice < GenericSpreadsheet
264
270
  if be.name == "spreadsheet"
265
271
  be.each_element do |se|
266
272
  if se.name == "table"
267
- if se.attributes['name']==sheet #@default_sheet
273
+ if se.attributes['name']==sheet
268
274
  sheet_found = true
269
275
  x=1
270
276
  y=1
@@ -303,13 +309,24 @@ class Openoffice < GenericSpreadsheet
303
309
  str_v.gsub!(/&apos;/,"'")
304
310
  end # == 'p'
305
311
  end
306
- end
307
- if vt == 'time'
312
+ elsif vt == 'time'
308
313
  tr.each_element do |str|
309
314
  if str.name == 'p'
310
315
  v = str.text
311
316
  end
312
317
  end
318
+ elsif vt == '' or vt == nil
319
+ #
320
+ elsif vt == 'date'
321
+ #
322
+ elsif vt == 'percentage'
323
+ #
324
+ elsif vt == 'float'
325
+ #
326
+ elsif vt == 'boolean'
327
+ #
328
+ else
329
+ # raise "unknown type #{vt}"
313
330
  end
314
331
  if skip
315
332
  if v != nil or tr.attributes['date-value']
@@ -373,7 +390,7 @@ class Openoffice < GenericSpreadsheet
373
390
  def process_zipfile(zip, path='')
374
391
  if zip.file.file? path
375
392
  if path == "content.xml"
376
- open(@tmpdir+'/'+@file_nr.to_s+'_roo_content.xml','wb') {|f|
393
+ open(File.join(@tmpdir, @file_nr.to_s+'_roo_content.xml'),'wb') {|f|
377
394
  f << zip.read(path)
378
395
  }
379
396
  end
@@ -395,12 +412,12 @@ class Openoffice < GenericSpreadsheet
395
412
 
396
413
  def set_value(row,col,value,sheet=nil)
397
414
  sheet = @default_value unless sheet
398
- @cell[sheet]["#{row},#{col}"] = value
415
+ @cell[sheet][[row,col]] = value
399
416
  end
400
417
 
401
418
  def set_type(row,col,type,sheet=nil)
402
419
  sheet = @default_value unless sheet
403
- @cell_type[sheet]["#{row},#{col}"] = type
420
+ @cell_type[sheet][[row,col]] = type
404
421
  end
405
422
 
406
423
  A_ROO_TYPE = {