roo 1.3.5 → 1.3.6

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.
@@ -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