roo 1.3.5 → 1.3.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.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'
@@ -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
@@ -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
@@ -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
@@ -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
Binary file
Binary file
@@ -0,0 +1,789 @@
1
+ # These tests were all removed from test_roo.rb because they were
2
+ # from unimplemented functionality, or more commonly, missing
3
+ # the source test data to run against.
4
+
5
+ module SkippedTests
6
+ # don't have these test files so removing. We can easily add in
7
+ # by modifying with_each_spreadsheet
8
+ GNUMERIC_ODS = false # do gnumeric with ods files Tests?
9
+ OPENOFFICEWRITE = false # experimental: write access with OO-Documents
10
+
11
+ def SKIP_test_writeopenoffice
12
+ if OPENOFFICEWRITE
13
+ File.cp(File.join(TESTDIR,"numbers1.ods"),
14
+ File.join(TESTDIR,"numbers2.ods"))
15
+ File.cp(File.join(TESTDIR,"numbers2.ods"),
16
+ File.join(TESTDIR,"bak_numbers2.ods"))
17
+ oo = Openoffice.new(File.join(TESTDIR,"numbers2.ods"))
18
+ oo.default_sheet = oo.sheets.first
19
+ oo.first_row.upto(oo.last_row) {|y|
20
+ oo.first_column.upto(oo.last_column) {|x|
21
+ unless oo.empty?(y,x)
22
+ # oo.set(y, x, oo.cell(y,x) + 7) if oo.celltype(y,x) == "float"
23
+ oo.set(y, x, oo.cell(y,x) + 7) if oo.celltype(y,x) == :float
24
+ end
25
+ }
26
+ }
27
+ oo.save
28
+
29
+ oo1 = Openoffice.new(File.join(TESTDIR,"numbers2.ods"))
30
+ oo2 = Openoffice.new(File.join(TESTDIR,"bak_numbers2.ods"))
31
+ #p oo2.to_s
32
+ assert_equal 999, oo2.cell('a',1), oo2.cell('a',1)
33
+ assert_equal oo2.cell('a',1) + 7, oo1.cell('a',1)
34
+ assert_equal oo2.cell('b',1)+7, oo1.cell('b',1)
35
+ assert_equal oo2.cell('c',1)+7, oo1.cell('c',1)
36
+ assert_equal oo2.cell('d',1)+7, oo1.cell('d',1)
37
+ assert_equal oo2.cell('a',2)+7, oo1.cell('a',2)
38
+ assert_equal oo2.cell('b',2)+7, oo1.cell('b',2)
39
+ assert_equal oo2.cell('c',2)+7, oo1.cell('c',2)
40
+ assert_equal oo2.cell('d',2)+7, oo1.cell('d',2)
41
+ assert_equal oo2.cell('e',2)+7, oo1.cell('e',2)
42
+
43
+ File.cp(File.join(TESTDIR,"bak_numbers2.ods"),
44
+ File.join(TESTDIR,"numbers2.ods"))
45
+ end
46
+ end
47
+
48
+ def SKIP_test_possible_bug_snowboard_borders #no test file
49
+ after Date.new(2008,12,15) do
50
+ local_only do
51
+ if EXCEL
52
+ ex = Excel.new(File.join(TESTDIR,'problem.xls'))
53
+ ex.default_sheet = ex.sheets.first
54
+ assert_equal 2, ex.first_row
55
+ assert_equal 30, ex.last_row
56
+ assert_equal 'A', ex.first_column_as_letter
57
+ assert_equal 'J', ex.last_column_as_letter
58
+ end
59
+ if EXCELX
60
+ ex = Excelx.new(File.join(TESTDIR,'problem.xlsx'))
61
+ ex.default_sheet = ex.sheets.first
62
+ assert_equal 2, ex.first_row
63
+ assert_equal 30, ex.last_row
64
+ assert_equal 'A', ex.first_column_as_letter
65
+ assert_equal 'J', ex.last_column_as_letter
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ def common_possible_bug_snowboard_cells(ss)
72
+ assert_equal "A.", ss.cell(13,'A'), ss.class
73
+ assert_equal 147, ss.cell(13,'f'), ss.class
74
+ assert_equal 152, ss.cell(13,'g'), ss.class
75
+ assert_equal 156, ss.cell(13,'h'), ss.class
76
+ assert_equal 158, ss.cell(13,'i'), ss.class
77
+ assert_equal 160, ss.cell(13,'j'), ss.class
78
+ assert_equal 164, ss.cell(13,'k'), ss.class
79
+ assert_equal 168, ss.cell(13,'l'), ss.class
80
+ assert_equal :string, ss.celltype(13,'m'), ss.class
81
+ assert_equal "159W", ss.cell(13,'m'), ss.class
82
+ assert_equal "164W", ss.cell(13,'n'), ss.class
83
+ assert_equal "168W", ss.cell(13,'o'), ss.class
84
+ end
85
+
86
+ def SKIP_test_possible_bug_snowboard_cells # no test file
87
+ local_only do
88
+ after Date.new(2009,1,6) do
89
+ # warten auf Bugfix in parseexcel
90
+ if EXCEL
91
+ ex = Excel.new(File.join(TESTDIR,'problem.xls'))
92
+ ex.default_sheet = 'Custom X'
93
+ common_possible_bug_snowboard_cells(ex)
94
+ end
95
+ end
96
+ if EXCELX
97
+ ex = Excelx.new(File.join(TESTDIR,'problem.xlsx'))
98
+ ex.default_sheet = 'Custom X'
99
+ common_possible_bug_snowboard_cells(ex)
100
+ end
101
+ end
102
+ end
103
+
104
+ if EXCELX
105
+ def test_possible_bug_2008_09_13
106
+ local_only do
107
+ # war nur in der 1.0.0 Release ein Fehler und sollte mit aktueller
108
+ # Release nicht mehr auftreten.
109
+ =begin
110
+
111
+ <sst count="46" uniqueCount="39">
112
+
113
+ 0<si>
114
+ <t>Bond</t>
115
+ <phoneticPr fontId="1" type="noConversion"/>
116
+ </si>
117
+
118
+ 1<si>
119
+ <t>James</t>
120
+ <phoneticPr fontId="1" type="noConversion"/>
121
+ </si>
122
+
123
+ 2<si>
124
+ <t>8659</t>
125
+ <phoneticPr fontId="1" type="noConversion"/>
126
+ </si>
127
+
128
+ 3<si>
129
+ <t>12B</t>
130
+ <phoneticPr fontId="1" type="noConversion"/>
131
+ </si>
132
+
133
+ 4<si>
134
+ <t>087692</t>
135
+ <phoneticPr fontId="1" type="noConversion"/>
136
+ </si>
137
+
138
+ 5<si>
139
+ <t>Rowe</t>
140
+ <phoneticPr fontId="1" type="noConversion"/>
141
+ </si>
142
+
143
+ 6<si>
144
+ <t>Karl</t>
145
+ <phoneticPr fontId="1" type="noConversion"/>
146
+ </si>
147
+
148
+ 7<si>
149
+ <t>9128</t>
150
+ <phoneticPr fontId="1" type="noConversion"/>
151
+ </si>
152
+
153
+ 8<si>
154
+ <t>79A</t>
155
+ <phoneticPr fontId="1" type="noConversion"/>
156
+ </si>
157
+
158
+ 9<si>
159
+ <t>Benson</t>
160
+ <phoneticPr fontId="1" type="noConversion"/>
161
+ </si>
162
+
163
+ 10<si>
164
+ <t>Cedric</t>
165
+ <phoneticPr fontId="1" type="noConversion"/>
166
+ </si>
167
+
168
+ 11<si>
169
+ <t>Greenstreet</t>
170
+ <phoneticPr fontId="1" type="noConversion"/>
171
+ </si>
172
+
173
+ 12<si>
174
+ <t>Jenny</t>
175
+ <phoneticPr fontId="1" type="noConversion"/>
176
+ </si>
177
+
178
+ 13<si>
179
+ <t>Smith</t>
180
+ <phoneticPr fontId="1" type="noConversion"/>
181
+ </si>
182
+
183
+ 14<si>
184
+ <t>Greame</t>
185
+ <phoneticPr fontId="1" type="noConversion"/>
186
+ </si>
187
+
188
+ 15<si>
189
+ <t>Lucas</t>
190
+ <phoneticPr fontId="1" type="noConversion"/>
191
+ </si>
192
+
193
+ 16<si>
194
+ <t>Ward</t>
195
+ <phoneticPr fontId="1" type="noConversion"/>
196
+ </si>
197
+
198
+ 17<si>
199
+ <t>Lee</t>
200
+ <phoneticPr fontId="1" type="noConversion"/>
201
+ </si>
202
+
203
+ 18<si>
204
+ <t>Bret</t>
205
+ <phoneticPr fontId="1" type="noConversion"/>
206
+ </si>
207
+
208
+ 19<si>
209
+ <t>Warne</t>
210
+ <phoneticPr fontId="1" type="noConversion"/>
211
+ </si>
212
+
213
+ 20<si>
214
+ <t>Shane</t>
215
+ <phoneticPr fontId="1" type="noConversion"/>
216
+ </si>
217
+
218
+ 21<si>
219
+ <t>782</t>
220
+ <phoneticPr fontId="1" type="noConversion"/>
221
+ </si>
222
+
223
+ 22<si>
224
+ <t>876</t>
225
+ <phoneticPr fontId="1" type="noConversion"/>
226
+ </si>
227
+
228
+ 23<si>
229
+ <t>9901</t>
230
+ <phoneticPr fontId="1" type="noConversion"/>
231
+ </si>
232
+
233
+ 24<si>
234
+ <t>1235</t>
235
+ <phoneticPr fontId="1" type="noConversion"/>
236
+ </si>
237
+
238
+ 25<si>
239
+ <t>16547</t>
240
+ <phoneticPr fontId="1" type="noConversion"/>
241
+ </si>
242
+
243
+ 26<si>
244
+ <t>7789</t>
245
+ <phoneticPr fontId="1" type="noConversion"/>
246
+ </si>
247
+
248
+ 27<si>
249
+ <t>89</t>
250
+ <phoneticPr fontId="1" type="noConversion"/>
251
+ </si>
252
+
253
+ 28<si>
254
+ <t>12A</t>
255
+ <phoneticPr fontId="1" type="noConversion"/>
256
+ </si>
257
+
258
+ 29<si>
259
+ <t>19A</t>
260
+ <phoneticPr fontId="1" type="noConversion"/>
261
+ </si>
262
+
263
+ 30<si>
264
+ <t>256</t>
265
+ <phoneticPr fontId="1" type="noConversion"/>
266
+ </si>
267
+
268
+ 31<si>
269
+ <t>129B</t>
270
+ <phoneticPr fontId="1" type="noConversion"/>
271
+ </si>
272
+
273
+ 32<si>
274
+ <t>11</t>
275
+ <phoneticPr fontId="1" type="noConversion"/>
276
+ </si>
277
+
278
+ 33<si>
279
+ <t>Last Name</t>
280
+ </si>
281
+
282
+ 34<si>
283
+ <t>First Name</t>
284
+ </si>
285
+
286
+ 35 <si>
287
+ <t>Middle Name</t>
288
+ </si>
289
+
290
+ 36<si>
291
+ <t>Resident ID</t>
292
+ </si>
293
+
294
+ 37<si>
295
+ <t>Room Number</t>
296
+ </si>
297
+
298
+ 38<si>
299
+ <t>Provider ID #</t>
300
+ </si>
301
+ </sst>
302
+ Hello Thomas,
303
+ How are you doing ? I am running into this strange issue with roo plugin (1.0.0). The attached
304
+ spreadsheet has all the cells formatted as "text", when I view in the Excel spreadsheet. But when it
305
+ get's into roo plugin (set_cell_values method - line 299), the values for the cells 1,1, 1,2, 1,3...1,6
306
+ show as 'date' instead of 'string'.
307
+ Because of this my parser is failing to get the proper values from the spreadsheet. Any ideas why
308
+ the formatting is getting set to the wrong value ?
309
+ Even stranger is if I save this file as ".XLS" and parse it the cells parse out fine as they are treated as
310
+ 'string' instead of 'date'.
311
+ This attached file is the newer format of Microsoft Excel (.xlsx).
312
+
313
+ =end
314
+ xx = Excelx.new(File.join(TESTDIR,'sample_file_2008-09-13.xlsx'))
315
+ assert_equal 1, xx.sheets.size
316
+
317
+ assert_equal 1, xx.first_row
318
+ assert_equal 9, xx.last_row # 9 ist richtig. Es sind zwar 44 Zeilen definiert, aber der Rest hat keinen Inhalt
319
+ assert_equal 1, xx.first_column
320
+ assert_equal 6, xx.last_column
321
+ assert_equal 'A', xx.first_column_as_letter
322
+ assert_equal 'F', xx.last_column_as_letter
323
+
324
+ assert_nothing_raised() {
325
+ puts xx.info
326
+ }
327
+ p xx.cell(1,1)
328
+ p xx.cell(1,2)
329
+ p xx.cell(1,3)
330
+ p xx.cell(1,4)
331
+ p xx.cell(1,5)
332
+ p xx.cell(1,6)
333
+ xx.default_sheet = xx.sheets.first
334
+
335
+ assert_equal 'Last Name', xx.cell('A',1)
336
+
337
+ 1.upto(6) do |col|
338
+ assert_equal :string, xx.celltype(1,col)
339
+ end
340
+ #for col in (1..6)
341
+ # assert_equal "1234", xx.cell(1,col)
342
+ #end
343
+ end
344
+ end
345
+ end
346
+
347
+ #-- bei diesen Test bekomme ich seltsamerweise einen Fehler can't allocate
348
+ #-- memory innerhalb der zip-Routinen => erstmal deaktiviert
349
+ def SKIP_test_huge_table_timing_10_000_openoffice #no test file
350
+ with_each_spreadsheet(:name=>'/home/tp/ruby-test/too-testing/speedtest_10000') do |oo|
351
+ after Date.new(2009,1,1) do
352
+ if LONG_RUN
353
+ assert_nothing_raised(Timeout::Error) {
354
+ Timeout::timeout(3.minutes) do |timeout_length|
355
+ # process every cell
356
+ sum = 0
357
+ oo.sheets.each {|sheet|
358
+ oo.default_sheet = sheet
359
+ for row in oo.first_row..oo.last_row do
360
+ for col in oo.first_column..oo.last_column do
361
+ c = oo.cell(row,col)
362
+ sum += c.length if c
363
+ end
364
+ end
365
+ p sum
366
+ assert sum > 0
367
+ }
368
+ end
369
+ }
370
+ end
371
+ end
372
+ end
373
+ end
374
+
375
+ # Eine Spreadsheetdatei wird nicht als Dateiname sondern direkt als Dokument
376
+ # geoeffnettest_problemx_csv_imported
377
+ def SKIP_test_from_stream_openoffice
378
+ after Date.new(2009,1,6) do
379
+ if OPENOFFICE
380
+ filecontent = nil
381
+ File.open(File.join(TESTDIR,"numbers1.ods")) do |f|
382
+ filecontent = f.read
383
+ p filecontent.class
384
+ p filecontent.size
385
+ #p filecontent
386
+ assert filecontent.size > 0
387
+ # #stream macht das gleiche wie #new liest abe aus Stream anstatt Datei
388
+ oo = Openoffice.stream(filecontent)
389
+ end
390
+ #oo = Openoffice.open()
391
+ end
392
+ end
393
+ end
394
+
395
+
396
+ def SKIP_test_bug_encoding_exported_from_google
397
+ if EXCEL
398
+ xl = Excel.new(File.join(TESTDIR,"numbers1_from_google.xls"))
399
+ xl.default_sheet = xl.sheets.first
400
+ assert_equal 'test', xl.cell(2,'F')
401
+ end
402
+ end
403
+
404
+ def SKIP_test_invalid_iconv_from_ms
405
+ #TODO: does only run within a darwin-environment
406
+ if RUBY_PLATFORM.downcase =~ /darwin/
407
+ assert_nothing_raised() {
408
+ oo = Excel.new(File.join(TESTDIR,"ms.xls"))
409
+ }
410
+ end
411
+ end
412
+
413
+ def SKIP_test_false_encoding
414
+ ex = Excel.new(File.join(TESTDIR,'false_encoding.xls'))
415
+ ex.default_sheet = ex.sheets.first
416
+ assert_equal "Sheet1", ex.sheets.first
417
+ ex.first_row.upto(ex.last_row) do |row|
418
+ ex.first_column.upto(ex.last_column) do |col|
419
+ content = ex.cell(row,col)
420
+ puts "#{row}/#{col}"
421
+ #puts content if ! ex.empty?(row,col) or ex.formula?(row,col)
422
+ if ex.formula?(row,col)
423
+ #! ex.empty?(row,col)
424
+ puts content
425
+ end
426
+ end
427
+ end
428
+ end
429
+
430
+ def SKIP_test_simple_google
431
+ if GOOGLE
432
+ go = Google.new("egal")
433
+ assert_equal "42", go.cell(1,1)
434
+ end
435
+ end
436
+ def SKIP_test_bug_c2 # no test file
437
+ with_each_spreadsheet(:name=>'problem', :foramt=>:excel) do |oo|
438
+ after Date.new(2009,1,6) do
439
+ local_only do
440
+ expected = ['Supermodel X','T6','Shaun White','Jeremy','Custom',
441
+ 'Warhol','Twin','Malolo','Supermodel','Air','Elite',
442
+ 'King','Dominant','Dominant Slick','Blunt','Clash',
443
+ 'Bullet','Tadashi Fuse','Jussi','Royale','S-Series',
444
+ 'Fish','Love','Feelgood ES','Feelgood','GTwin','Troop',
445
+ 'Lux','Stigma','Feather','Stria','Alpha','Feelgood ICS']
446
+ result = []
447
+ oo.sheets[2..oo.sheets.length].each do |s|
448
+ #(13..13).each do |s|
449
+ oo.default_sheet = s
450
+ name = oo.cell(2,'C')
451
+ result << name
452
+ #puts "#{name} (sheet: #{s})"
453
+ #assert_equal "whatever (sheet: 13)", "#{name} (sheet: #{s})"
454
+ end
455
+ assert_equal expected, result
456
+ end
457
+ end
458
+ end
459
+ end
460
+
461
+ def SKIP_test_bug_c2_parseexcel #no test file
462
+ after Date.new(2009,1,10) do
463
+ local_only do
464
+ #-- this is OK
465
+ @workbook = Spreadsheet::ParseExcel.parse(File.join(TESTDIR,"problem.xls"))
466
+ worksheet = @workbook.worksheet(11)
467
+ skip = 0
468
+ line = 1
469
+ row = 2
470
+ col = 3
471
+ worksheet.each(skip) { |row_par|
472
+ if line == row
473
+ if row_par == nil
474
+ raise "nil"
475
+ end
476
+ cell = row_par.at(col-1)
477
+ assert cell, "cell should not be nil"
478
+ assert_equal "Air", cell.to_s('utf-8')
479
+ end
480
+ line += 1
481
+ }
482
+ #-- worksheet 12 does not work
483
+ @workbook = Spreadsheet::ParseExcel.parse(File.join(TESTDIR,"problem.xls"))
484
+ worksheet = @workbook.worksheet(12)
485
+ skip = 0
486
+ line = 1
487
+ row = 2
488
+ col = 3
489
+ worksheet.each(skip) { |row_par|
490
+ if line == row
491
+ if row_par == nil
492
+ raise "nil"
493
+ end
494
+ cell = row_par.at(col-1)
495
+ assert cell, "cell should not be nil"
496
+ assert_equal "Elite", cell.to_s('utf-8')
497
+ end
498
+ line += 1
499
+ }
500
+ end
501
+ end
502
+ end
503
+
504
+ def SKIP_test_bug_c2_excelx #no test file
505
+ after Date.new(2008,9,15) do
506
+ local_only do
507
+ expected = ['Supermodel X','T6','Shaun White','Jeremy','Custom',
508
+ 'Warhol','Twin','Malolo','Supermodel','Air','Elite',
509
+ 'King','Dominant','Dominant Slick','Blunt','Clash',
510
+ 'Bullet','Tadashi Fuse','Jussi','Royale','S-Series',
511
+ 'Fish','Love','Feelgood ES','Feelgood','GTwin','Troop',
512
+ 'Lux','Stigma','Feather','Stria','Alpha','Feelgood ICS']
513
+ result = []
514
+ @e = Excelx.new(File.join(TESTDIR,"problem.xlsx"))
515
+ @e.sheets[2..@e.sheets.length].each do |s|
516
+ @e.default_sheet = s
517
+ # assert_equal "A.",@e.cell('a',13)
518
+ name = @e.cell(2,'C')
519
+ result << name
520
+ #puts "#{name} (sheet: #{s})"
521
+ #assert_equal :string, @e.celltype('c',2)
522
+ #assert_equal "Vapor (sheet: Vapor)", "#{name} (sheet: #{@e.sheets.first})"
523
+ assert @e.cell(2,'c')
524
+ end
525
+ assert_equal expected, result
526
+
527
+ @e = Excelx.new(File.join(TESTDIR,"problem.xlsx"))
528
+ #@e.sheets[2..@e.sheets.length].each do |s|
529
+ (13..13).each do |s|
530
+ @e.default_sheet = s
531
+ name = @e.cell(2,'C')
532
+ #puts "#{name} (sheet: #{s})"
533
+ assert_equal "Elite (sheet: 13)", "#{name} (sheet: #{s})"
534
+ end
535
+ end
536
+ end
537
+ end
538
+
539
+ def SKIP_test_compare_csv_excelx_excel #no test file
540
+ if EXCELX
541
+ after Date.new(2008,12,30) do
542
+ # parseexcel bug
543
+ local_only do
544
+ s1 = Excel.new(File.join(TESTDIR,"problem.xls"))
545
+ s2 = Excelx.new(File.join(TESTDIR,"problem.xlsx"))
546
+ s1.sheets.each {|sh| #TODO:
547
+ s1.default_sheet = sh
548
+ s2.default_sheet = sh
549
+ File.delete_if_exist("/tmp/problem.csv")
550
+ File.delete_if_exist("/tmp/problemx.csv")
551
+ assert s1.to_csv("/tmp/problem.csv")
552
+ assert s2.to_csv("/tmp/problemx.csv")
553
+ assert File.exists?("/tmp/problem.csv")
554
+ assert File.exists?("/tmp/problemx.csv")
555
+ assert_equal "", `diff /tmp/problem.csv /tmp/problemx.csv`, "Unterschied in Sheet #{sh} #{s1.sheets.index(sh)}"
556
+ }
557
+ end
558
+ end
559
+ end
560
+ end
561
+
562
+ def SKIP_test_problemx_csv_imported #no test file
563
+ after Date.new(2009,1,6) do
564
+ if EXCEL
565
+ local_only do
566
+ # wieder eingelesene CSV-Datei aus obigem Test
567
+ # muss identisch mit problem.xls sein
568
+ # Importieren aus csv-Datei muss manuell gemacht werden
569
+ ex = Excel.new(File.join(TESTDIR,"problem.xls"))
570
+ cs = Excel.new(File.join(TESTDIR,"problemx_csv_imported.xls"))
571
+ # nur das erste sheet betrachten
572
+ ex.default_sheet = ex.sheets.first
573
+ cs.default_sheet = cs.sheets.first
574
+ ex.first_row.upto(ex.last_row) do |row|
575
+ ex.first_column.upto(ex.last_column) do |col|
576
+ assert_equal ex.cell(row,col), cs.cell(row,col), "cell #{row}/#{col} does not match '#{ex.cell(row,col)}' '#{cs.cell(row,col)}'"
577
+ assert_equal ex.celltype(row,col), cs.celltype(row,col), "celltype #{row}/#{col} does not match"
578
+ assert_equal ex.empty?(row,col), cs.empty?(row,col), "empty? #{row}/#{col} does not match"
579
+ if defined? excel_supports_formulas
580
+ assert_equal ex.formula?(row,col), cs.formula?(row,col), "formula? #{row}/#{col} does not match"
581
+ assert_equal ex.formula(row,col), cs.formula(row,col), "formula #{row}/#{col} does not match"
582
+ end
583
+ end
584
+ end
585
+ cs.first_row.upto(cs.last_row) do |row|
586
+ cs.first_column.upto(cs.last_column) do |col|
587
+ assert_equal ex.cell(row,col), cs.cell(row,col), "cell #{row}/#{col} does not match '#{ex.cell(row,col)}' '#{cs.cell(row,col)}'"
588
+ assert_equal ex.celltype(row,col), cs.celltype(row,col), "celltype #{row}/#{col} does not match"
589
+ assert_equal ex.empty?(row,col), cs.empty?(row,col), "empty? #{row}/#{col} does not match"
590
+ if defined? excel_supports_formulas
591
+ assert_equal ex.formula?(row,col), cs.formula?(row,col), "formula? #{row}/#{col} does not match"
592
+ assert_equal ex.formula(row,col), cs.formula(row,col), "formula #{row}/#{col} does not match"
593
+ end
594
+ end
595
+ end
596
+ end
597
+ end
598
+ end
599
+ end
600
+
601
+ def SKIP_test_open_from_uri
602
+ if ONLINE
603
+ if OPENOFFICE
604
+ assert_raises(RuntimeError) {
605
+ oo = Openoffice.new("http://gibbsnichtdomainxxxxx.com/file.ods")
606
+ }
607
+ end
608
+ if EXCEL
609
+ assert_raises(RuntimeError) {
610
+ oo = Excel.new("http://gibbsnichtdomainxxxxx.com/file.xls")
611
+ }
612
+ end
613
+ if EXCELX
614
+ assert_raises(RuntimeError) {
615
+ oo = Excelx.new("http://gibbsnichtdomainxxxxx.com/file.xlsx")
616
+ }
617
+ end
618
+ end
619
+ end
620
+
621
+ def SKIP_test_to_ascii_openoffice #file does not exist
622
+ after Date.new(9999,12,31) do
623
+ with_each_spreadsheet(:name=>'verysimple_spreadsheet', :format=>:openoffice) do |oo|
624
+ oo.default_sheet = oo.sheets.first
625
+ expected="
626
+ A | B | C |
627
+ -------+-------+------|
628
+ 7| 8| 9|
629
+ -------+-------+------|
630
+ 4| 5| 6|
631
+ -------+-------+------|
632
+ 1| 2| 3|
633
+ ----------------------/
634
+ "
635
+ assert_equal expected, oo.to_ascii
636
+ end
637
+ end
638
+ end
639
+ if false
640
+ def test_soap_server
641
+ #threads = []
642
+ #threads << Thread.new("serverthread") do
643
+ fork do
644
+ p "serverthread started"
645
+ puts "in child, pid = #$$"
646
+ puts `/usr/bin/ruby rooserver.rb`
647
+ p "serverthread finished"
648
+ end
649
+ #threads << Thread.new("clientthread") do
650
+ p "clientthread started"
651
+ sleep 10
652
+ proxy = SOAP::RPC::Driver.new("http://localhost:12321","spreadsheetserver")
653
+ proxy.add_method('cell','row','col')
654
+ proxy.add_method('officeversion')
655
+ proxy.add_method('last_row')
656
+ proxy.add_method('last_column')
657
+ proxy.add_method('first_row')
658
+ proxy.add_method('first_column')
659
+ proxy.add_method('sheets')
660
+ proxy.add_method('set_default_sheet','s')
661
+ proxy.add_method('ferien_fuer_region', 'region')
662
+
663
+ sheets = proxy.sheets
664
+ p sheets
665
+ proxy.set_default_sheet(sheets.first)
666
+
667
+ assert_equal 1, proxy.first_row
668
+ assert_equal 1, proxy.first_column
669
+ assert_equal 187, proxy.last_row
670
+ assert_equal 7, proxy.last_column
671
+ assert_equal 42, proxy.cell('C',8)
672
+ assert_equal 43, proxy.cell('F',12)
673
+ assert_equal "1.0", proxy.officeversion
674
+ p "clientthread finished"
675
+ #end
676
+ #threads.each {|t| t.join }
677
+ puts "fertig"
678
+ Process.kill("INT",pid)
679
+ pid = Process.wait
680
+ puts "child terminated, pid= #{pid}, status= #{$?.exitstatus}"
681
+ end
682
+ end # false
683
+
684
+ def split_coord(s)
685
+ letter = ""
686
+ number = 0
687
+ i = 0
688
+ while i<s.length and "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".include?(s[i,1])
689
+ letter += s[i,1]
690
+ i+=1
691
+ end
692
+ while i<s.length and "01234567890".include?(s[i,1])
693
+ number = number*10 + s[i,1].to_i
694
+ i+=1
695
+ end
696
+ if letter=="" or number==0
697
+ raise ArgumentError
698
+ end
699
+ return letter,number
700
+ end
701
+
702
+ #def sum(s,expression)
703
+ # arg = expression.split(':')
704
+ # b,z = split_coord(arg[0])
705
+ # first_row = z
706
+ # first_col = Openoffice.letter_to_number(b)
707
+ # b,z = split_coord(arg[1])
708
+ # last_row = z
709
+ # last_col = Openoffice.letter_to_number(b)
710
+ # result = 0
711
+ # first_row.upto(last_row) {|row|
712
+ # first_col.upto(last_col) {|col|
713
+ # result = result + s.cell(row,col)
714
+ # }
715
+ # }
716
+ # result
717
+ #end
718
+
719
+ #def test_dsl
720
+ # s = Openoffice.new(File.join(TESTDIR,"numbers1.ods"))
721
+ # s.default_sheet = s.sheets.first
722
+ #
723
+ # s.set 'a',1, 5
724
+ # s.set 'b',1, 3
725
+ # s.set 'c',1, 7
726
+ # s.set('a',2, s.cell('a',1)+s.cell('b',1))
727
+ # assert_equal 8, s.cell('a',2)
728
+ #
729
+ # assert_equal 15, sum(s,'A1:C1')
730
+ # end
731
+
732
+ #def test_create_spreadsheet1
733
+ # name = File.join(TESTDIR,'createdspreadsheet.ods')
734
+ # rm(name) if File.exists?(File.join(TESTDIR,'createdspreadsheet.ods'))
735
+ # # anlegen, falls noch nicht existierend
736
+ # s = Openoffice.new(name,true)
737
+ # assert File.exists?(name)
738
+ #end
739
+
740
+ #def test_create_spreadsheet2
741
+ # # anlegen, falls noch nicht existierend
742
+ # s = Openoffice.new(File.join(TESTDIR,"createdspreadsheet.ods"),true)
743
+ # s.set 'a',1,42
744
+ # s.set 'b',1,43
745
+ # s.set 'c',1,44
746
+ # s.save
747
+ #
748
+ # #after Date.new(2007,7,3) do
749
+ # # t = Openoffice.new(File.join(TESTDIR,"createdspreadsheet.ods"))
750
+ # # assert_equal 42, t.cell(1,'a')
751
+ # # assert_equal 43, t.cell('b',1)
752
+ # # assert_equal 44, t.cell('c',3)
753
+ # #end
754
+ #end
755
+
756
+ #TODO: xlsx-Datei anpassen!
757
+ def test_excelx_open_from_uri_and_zipped
758
+ #TODO: gezippte xlsx Datei online zum Testen suchen
759
+ after Date.new(2999,6,30) do
760
+ if EXCELX
761
+ if ONLINE
762
+ url = 'http://stiny-leonhard.de/bode-v1.xlsx.zip'
763
+ excel = Excelx.new(url, :zip)
764
+ assert_equal 'ist "e" im Nenner von H(s)', excel.cell('b', 5)
765
+ excel.remove_tmp # don't forget to remove the temporary files
766
+ end
767
+ end
768
+ end
769
+ end
770
+
771
+ def test_excelx_zipped
772
+ # TODO: bode...xls bei Gelegenheit nach .xlsx konverieren lassen und zippen!
773
+ if EXCELX
774
+ after Date.new(2999,7,30) do
775
+ # diese Datei gibt es noch nicht gezippt
776
+ excel = Excelx.new(File.join(TESTDIR,"bode-v1.xlsx.zip"), :zip)
777
+ assert excel
778
+ assert_raises (ArgumentError) {
779
+ assert_equal 'ist "e" im Nenner von H(s)', excel.cell('b', 5)
780
+ }
781
+ excel.default_sheet = excel.sheets.first
782
+ assert_equal 'ist "e" im Nenner von H(s)', excel.cell('b', 5)
783
+ excel.remove_tmp # don't forget to remove the temporary files
784
+ end
785
+ end
786
+ end
787
+
788
+
789
+ end