hmcgowan-roo 1.3.5 → 1.3.6

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -1,6 +1,6 @@
1
1
  # README for Roo
2
2
 
3
- This is now the official roo repository and I'll be making a release on RubyForge in the next few weeks.
3
+ 1.3.5 is now available on Rubyforge. You can install the official release with 'gem install roo' or refer to the installation instructions below for the latest development gem.
4
4
 
5
5
 
6
6
  ## Installation
@@ -35,7 +35,7 @@ This is now the official roo repository and I'll be making a release on RubyForg
35
35
  s.cell(1,'A',s.sheets[0]) # same cell
36
36
 
37
37
  # almost all methods have an optional argument 'sheet'.
38
- # If this parameter is ommitted, the default_sheet will be used.
38
+ # If this parameter is omitted, the default_sheet will be used.
39
39
 
40
40
  s.info # prints infos about the spreadsheet file
41
41
 
@@ -44,6 +44,12 @@ This is now the official roo repository and I'll be making a release on RubyForg
44
44
  s.first_column # the number of the first column
45
45
  s.last_column # the number of the last column
46
46
 
47
+ # limited font information is available
48
+
49
+ s.font(1,1).bold?
50
+ s.font(1,1).italic?
51
+ s.font(1,1).underline?
52
+
47
53
 
48
54
  see http://roo.rubyforge.org for a more complete tutorial
49
55
 
data/lib/roo/excel.rb CHANGED
@@ -6,6 +6,26 @@ rescue LoadError => e
6
6
  false
7
7
  end
8
8
 
9
+ # The Spreadsheet library has a bug in handling Excel
10
+ # base dates so if the file is a 1904 base date then
11
+ # dates are off by a day. 1900 base dates work fine
12
+ module Spreadsheet
13
+ module Excel
14
+ class Row < Spreadsheet::Row
15
+ def _date data # :nodoc:
16
+ return data if data.is_a?(Date)
17
+ date = @worksheet.date_base + data.to_i
18
+ if LEAP_ERROR > @worksheet.date_base
19
+ date -= 1
20
+ end
21
+ date
22
+ end
23
+ public :_datetime
24
+ end
25
+ end
26
+ end
27
+
28
+
9
29
  # ruby-spreadsheet has a font object so we're extending it
10
30
  # with our own functionality but still providing full access
11
31
  # to the user for other font information
@@ -55,11 +75,7 @@ class Excel < GenericSpreadsheet
55
75
  raise IOError, "file #{@filename} does not exist"
56
76
  end
57
77
  @workbook = Spreadsheet.open(filename)
58
- @default_sheet = nil
59
- # no need to set default_sheet if there is only one sheet in the document
60
- if self.sheets.size == 1
61
- @default_sheet = self.sheets.first
62
- end
78
+ @default_sheet = self.sheets.first
63
79
  ensure
64
80
  #if ENV["roo_local"] != "thomas-p"
65
81
  FileUtils::rm_r(@tmpdir)
@@ -128,38 +144,6 @@ class Excel < GenericSpreadsheet
128
144
  end
129
145
  end
130
146
 
131
- # returns the first non empty column
132
- def first_column(sheet=nil)
133
- sheet = @default_sheet unless sheet
134
- return @first_column[sheet] if @first_column[sheet]
135
- fr, lr, fc, lc = get_firsts_lasts(sheet)
136
- fc
137
- end
138
-
139
- # returns the last non empty column
140
- def last_column(sheet=nil)
141
- sheet = @default_sheet unless sheet
142
- return @last_column[sheet] if @last_column[sheet]
143
- fr, lr, fc, lc = get_firsts_lasts(sheet)
144
- lc
145
- end
146
-
147
- # returns the first non empty row
148
- def first_row(sheet=nil)
149
- sheet = @default_sheet unless sheet
150
- return @first_row[sheet] if @first_row[sheet]
151
- fr, lr, fc, lc = get_firsts_lasts(sheet)
152
- fr
153
- end
154
-
155
- # returns the last non empty row
156
- def last_row(sheet=nil)
157
- sheet = @default_sheet unless sheet
158
- return @last_row[sheet] if @last_row[sheet]
159
- fr, lr, fc, lc = get_firsts_lasts(sheet)
160
- lr
161
- end
162
-
163
147
  # returns NO formula in excel spreadsheets
164
148
  def formula(row,col,sheet=nil)
165
149
  raise EXCEL_NO_FORMULAS
@@ -192,42 +176,6 @@ class Excel < GenericSpreadsheet
192
176
  end
193
177
 
194
178
  private
195
- # determine the first and last boundaries
196
- def get_firsts_lasts(sheet=nil)
197
-
198
- # 2008-09-14 BEGINf
199
- fr=lr=fc=lc=nil
200
- sheet = @default_sheet unless sheet
201
- if ! @cells_read[sheet]
202
- read_cells(sheet)
203
- end
204
- if @cell[sheet] # nur wenn ueberhaupt Zellen belegt sind
205
- @cell[sheet].each {|cellitem|
206
- key = cellitem.first
207
- y,x = key
208
-
209
- if cellitem[1].class != String or
210
- (cellitem[1].class == String and cellitem[1] != "")
211
- fr = y unless fr
212
- fr = y if y < fr
213
-
214
- lr = y unless lr
215
- lr = y if y > lr
216
-
217
- fc = x unless fc
218
- fc = x if x < fc
219
-
220
- lc = x unless lc
221
- lc = x if x > lc
222
- end
223
- }
224
- end
225
- @first_row[sheet] = fr
226
- @last_row[sheet] = lr
227
- @first_column[sheet] = fc
228
- @last_column[sheet] = lc
229
- return fr, lr, fc, lc
230
- end
231
179
 
232
180
  # converts name of a sheet to index (0,1,2,..)
233
181
  def sheet_no(name)
@@ -355,7 +303,7 @@ class Excel < GenericSpreadsheet
355
303
  (0..row.size).each do |cell_index|
356
304
  cell = row.at(cell_index)
357
305
  next if cell.nil? #skip empty cells
358
- next if cell.class == Spreadsheet::Formula
306
+ next if cell.class == Spreadsheet::Formula && cell.value.nil? # skip empty formla cells
359
307
  if date_or_time?(row, cell_index)
360
308
  vt, v = read_cell_date_or_time(row, cell_index)
361
309
  else
@@ -371,12 +319,20 @@ class Excel < GenericSpreadsheet
371
319
  end # worksheet
372
320
  @cells_read[sheet] = true
373
321
  end
374
-
322
+
323
+ # Get the contents of a cell, accounting for the
324
+ # way formula stores the value
325
+ def read_cell_content(row, idx)
326
+ cell = row.at(idx)
327
+ cell = cell.value if cell.class == Spreadsheet::Formula
328
+ cell
329
+ end
330
+
375
331
  # Test the cell to see if it's a valid date/time.
376
332
  def date_or_time?(row, idx)
377
333
  format = row.format(idx)
378
334
  if format.date_or_time?
379
- cell = row.at(idx)
335
+ cell = read_cell_content(row, idx)
380
336
  true if Float(cell) > 0 rescue false
381
337
  else
382
338
  false
@@ -387,7 +343,8 @@ class Excel < GenericSpreadsheet
387
343
  # Read the date-time cell and convert to,
388
344
  # the date-time values for Roo
389
345
  def read_cell_date_or_time(row, idx)
390
- cell = row.at(idx).to_s.to_f
346
+ cell = read_cell_content(row, idx)
347
+ cell = cell.to_s.to_f
391
348
  if cell < 1.0
392
349
  value_type = :time
393
350
  f = cell*24.0*60.0*60.0
@@ -399,7 +356,11 @@ class Excel < GenericSpreadsheet
399
356
  s = secs
400
357
  value = h*3600+m*60+s
401
358
  else
402
- datetime = row.datetime(idx)
359
+ if row.at(idx).class == Spreadsheet::Formula
360
+ datetime = row._datetime(cell)
361
+ else
362
+ datetime = row.datetime(idx)
363
+ end
403
364
  if datetime.hour != 0 or
404
365
  datetime.min != 0 or
405
366
  datetime.sec != 0
@@ -407,7 +368,11 @@ class Excel < GenericSpreadsheet
407
368
  value = datetime
408
369
  else
409
370
  value_type = :date
410
- value = row.date(idx)
371
+ if row.at(idx).class == Spreadsheet::Formula
372
+ value = row._date(cell)
373
+ else
374
+ value = row.date(idx)
375
+ end
411
376
  value = sprintf("%04d-%02d-%02d",value.year,value.month,value.day)
412
377
  end
413
378
  end
@@ -418,7 +383,7 @@ class Excel < GenericSpreadsheet
418
383
  # Read the cell and based on the class,
419
384
  # return the values for Roo
420
385
  def read_cell(row, idx)
421
- cell = row.at(idx)
386
+ cell = read_cell_content(row, idx)
422
387
  case cell
423
388
  when Float, Integer, Fixnum, Bignum
424
389
  value_type = :float
data/lib/roo/excelx.rb CHANGED
@@ -128,11 +128,7 @@ class Excelx < GenericSpreadsheet
128
128
  FileUtils::rm_r(@tmpdir)
129
129
  #end
130
130
  end
131
- @default_sheet = nil
132
- # no need to set default_sheet if there is only one sheet in the document
133
- if self.sheets.size == 1
134
- @default_sheet = self.sheets.first
135
- end
131
+ @default_sheet = self.sheets.first
136
132
  @cell = Hash.new
137
133
  @cell_type = Hash.new
138
134
  @formula = Hash.new
@@ -258,18 +258,8 @@ class GenericSpreadsheet
258
258
  sheet = @default_sheet unless sheet
259
259
  read_cells(sheet) unless @cells_read[sheet]
260
260
  result = []
261
- tmp_arr = []
262
- @cell[sheet].each_pair {|key,value|
263
- y,x = key # _to_string(key).split(',')
264
- x = x.to_i
265
- y = y.to_i
266
- if y == rownumber
267
- tmp_arr[x] = value
268
- end
269
- }
270
- result = tmp_arr[1..-1]
271
- while result && result[-1] == nil
272
- result = result[0..-2]
261
+ first_column(sheet).upto(last_column(sheet)) do |col|
262
+ result << cell(rownumber,col,sheet)
273
263
  end
274
264
  result
275
265
  end
data/lib/roo/google.rb CHANGED
@@ -109,10 +109,7 @@ class Google < GenericSpreadsheet
109
109
  #-- ----------------------------------------------------------------------
110
110
  #-- TODO: Behandlung von Berechtigungen hier noch einbauen ???
111
111
  #-- ----------------------------------------------------------------------
112
-
113
- if self.sheets.size == 1
114
- @default_sheet = self.sheets.first
115
- end
112
+ @default_sheet = self.sheets.first
116
113
  end
117
114
 
118
115
  # returns an array of sheet names in the spreadsheet
@@ -241,28 +238,6 @@ class Google < GenericSpreadsheet
241
238
  theformulas
242
239
  end
243
240
 
244
- # returns all values in this row as an array
245
- # row numbers are 1,2,3,... like in the spreadsheet
246
- def row(rownumber,sheet=nil)
247
- sheet = @default_sheet unless sheet
248
- read_cells(sheet) unless @cells_read[sheet]
249
- result = []
250
- tmp_arr = []
251
- @cell[sheet].each_pair {|key,value|
252
- y,x = key.split(',')
253
- x = x.to_i
254
- y = y.to_i
255
- if y == rownumber
256
- tmp_arr[x] = value
257
- end
258
- }
259
- result = tmp_arr[1..-1]
260
- while result[-1] == nil
261
- result = result[0..-2]
262
- end
263
- result
264
- end
265
-
266
241
  # true, if the cell is empty
267
242
  def empty?(row, col, sheet=nil)
268
243
  value = cell(row, col, sheet)
@@ -273,23 +248,6 @@ class Google < GenericSpreadsheet
273
248
  value.empty?
274
249
  end
275
250
 
276
- # returns all values in this column as an array
277
- # column numbers are 1,2,3,... like in the spreadsheet
278
- #--
279
- #TODO: refactoring nach GenericSpreadsheet?
280
- def column(columnnumber, sheet=nil)
281
- if columnnumber.class == String
282
- columnnumber = GenericSpreadsheet.letter_to_number(columnnumber)
283
- end
284
- sheet = @default_sheet unless sheet
285
- read_cells(sheet) unless @cells_read[sheet]
286
- result = []
287
- first_row(sheet).upto(last_row(sheet)) do |row|
288
- result << cell(row,columnnumber,sheet)
289
- end
290
- result
291
- end
292
-
293
251
  # sets the cell to the content of 'value'
294
252
  # a formula can be set in the form of '=SUM(...)'
295
253
  def set_value(row,col,value,sheet=nil)
@@ -43,11 +43,7 @@ class Openoffice < GenericSpreadsheet
43
43
  FileUtils::rm_r(@tmpdir)
44
44
  #end
45
45
  end
46
- @default_sheet = nil
47
- # no need to set default_sheet if there is only one sheet in the document
48
- if self.sheets.size == 1
49
- @default_sheet = self.sheets.first
50
- end
46
+ @default_sheet = self.sheets.first
51
47
  @cell = Hash.new
52
48
  @cell_type = Hash.new
53
49
  @formula = Hash.new
data/lib/roo/version.rb CHANGED
@@ -2,7 +2,7 @@ module Roo #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 1
4
4
  MINOR = 3
5
- TINY = 5
5
+ TINY = 6
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
data/lib/roo.rb CHANGED
@@ -1,4 +1,22 @@
1
1
  module Roo
2
+ class Spreadsheet
3
+ class << self
4
+ def open(file)
5
+ case File.extname(file)
6
+ when '.xls'
7
+ Excel.new(file)
8
+ when '.xlsx'
9
+ Excelx.new(file)
10
+ when '.ods'
11
+ Openoffice.new(file)
12
+ when ''
13
+ Google.new(file)
14
+ else
15
+ raise ArgumentError, "Don't know how to open file #{filename}"
16
+ end
17
+ end
18
+ end
19
+ end
2
20
  end
3
21
 
4
22
  require 'roo/version'
Binary file
Binary file