roo 0.8.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/History.txt CHANGED
@@ -1,3 +1,8 @@
1
+ == 0.8.1 2007-12-22
2
+ * 3 bugfixes
3
+ * fixed a bug with first/last-row/column in empty sheet
4
+ * #info prints now '- empty -' if a sheet within a document is empty
5
+ * tried to fix the iconv conversion problem
1
6
  == 0.8.0 2007-12-15
2
7
  * 2 enhancements:
3
8
  * Google online spreadsheets were implemented
data/Manifest.txt CHANGED
@@ -15,6 +15,13 @@ lib/roo/excel.rb
15
15
  lib/roo/google.rb
16
16
  scripts/txt2html
17
17
  setup.rb
18
+ test/false_encoding.xls
19
+ test/Bibelbund1.ods
20
+ test/bbu.xls
21
+ test/bbu.ods
22
+ test/simple_spreadsheet.ods
23
+ test/simple_spreadsheet_from_italo.ods
24
+ test/simple_spreadsheet_from_italo.xls
18
25
  test/test_helper.rb
19
26
  test/test_roo.rb
20
27
  test/numbers1.ods
data/lib/roo/excel.rb CHANGED
@@ -4,7 +4,7 @@ require 'parseexcel'
4
4
  CHARGUESS=false
5
5
  require 'charguess' if CHARGUESS
6
6
 
7
- module Spreadsheet
7
+ module Spreadsheet # :nodoc
8
8
  module ParseExcel
9
9
  class Worksheet
10
10
  include Enumerable
@@ -13,8 +13,8 @@ module Spreadsheet
13
13
  end
14
14
  end
15
15
 
16
-
17
- class Excel < GenericSpreadsheet #Openoffice
16
+ # Class for handling Excel-Spreadsheets
17
+ class Excel < GenericSpreadsheet
18
18
 
19
19
  EXCEL_NO_FORMULAS = 'formulas are not supported for excel spreadsheets'
20
20
 
@@ -51,6 +51,7 @@ class Excel < GenericSpreadsheet #Openoffice
51
51
  @cells_read = Hash.new
52
52
  end
53
53
 
54
+ # returns an array of sheet names in the spreadsheet
54
55
  def sheets
55
56
  result = []
56
57
  0.upto(@workbook.sheet_count - 1) do |i|
@@ -64,9 +65,17 @@ class Excel < GenericSpreadsheet #Openoffice
64
65
  @workbook.worksheet(i).name
65
66
  )
66
67
  else
67
- result << Iconv.new('utf-8','unicode').iconv(
68
- @workbook.worksheet(i).name
69
- )
68
+ result << platform_specific_iconv(@workbook.worksheet(i).name)
69
+ #case RUBY_PLATFORM.downcase
70
+ #when /darwin/
71
+ # result << Iconv.new('utf-8','utf-8').iconv(
72
+ # @workbook.worksheet(i).name
73
+ # )
74
+ #else
75
+ # result << Iconv.new('utf-8','unicode').iconv(
76
+ # @workbook.worksheet(i).name
77
+ # )
78
+ #end # case
70
79
  end
71
80
  end
72
81
  return result
@@ -105,7 +114,7 @@ class Excel < GenericSpreadsheet #Openoffice
105
114
  when :numeric then return cell.to_f
106
115
  when :text then return cell.to_s('utf-8')
107
116
  when :date then return cell.date
108
- else
117
+ else
109
118
  return nil # cell.to_s('utf-8')
110
119
  end
111
120
  end
@@ -128,13 +137,13 @@ class Excel < GenericSpreadsheet #Openoffice
128
137
  cell = row_par.at(col-1)
129
138
  return nil unless cell
130
139
  case cell.type
131
- when :numeric
140
+ when :numeric
132
141
  return :float
133
- when :text
142
+ when :text
134
143
  return :string
135
- when :date
144
+ when :date
136
145
  return :date
137
- else
146
+ else
138
147
  return cell.type.to_sym
139
148
  end
140
149
  end
@@ -148,7 +157,7 @@ class Excel < GenericSpreadsheet #Openoffice
148
157
  sheet = @default_sheet unless sheet
149
158
  default_sheet_check
150
159
  worksheet = @workbook.worksheet(sheet_no(sheet))
151
- #therow = worksheet.row(rownumber-1)
160
+ #therow = worksheet.row(rownumber-1)
152
161
  result = []
153
162
  worksheet.row(rownumber-1).each {|cell|
154
163
  if cell
@@ -195,7 +204,7 @@ class Excel < GenericSpreadsheet #Openoffice
195
204
  else
196
205
  result << nil
197
206
  end
198
- }
207
+ }
199
208
  result
200
209
  end
201
210
 
@@ -230,7 +239,7 @@ class Excel < GenericSpreadsheet #Openoffice
230
239
  fr, lr, fc, lc = get_firsts_lasts(sheet)
231
240
  lr
232
241
  end
233
-
242
+
234
243
  # returns NO formula in excel spreadsheets
235
244
  def formula(row,col,sheet=nil)
236
245
  raise EXCEL_NO_FORMULAS
@@ -240,7 +249,7 @@ class Excel < GenericSpreadsheet #Openoffice
240
249
  def formula?(row,col,sheet=nil)
241
250
  raise EXCEL_NO_FORMULAS
242
251
  end
243
-
252
+
244
253
  # returns NO formulas in excel spreadsheets
245
254
  def formulas(sheet=nil)
246
255
  raise EXCEL_NO_FORMULAS
@@ -257,18 +266,36 @@ class Excel < GenericSpreadsheet #Openoffice
257
266
  def get_firsts_lasts(sheet=nil)
258
267
  sheet = @default_sheet unless sheet
259
268
  fr = fc = 999_999
260
- lr = lc = -999_999
269
+ lr = lc = -999_999
261
270
  worksheet = @workbook.worksheet(sheet_no(sheet))
262
- fr = worksheet.min_row + 1
263
- lr = worksheet.max_row + 1
264
- fc = worksheet.min_col + 1
265
- lc = worksheet.max_col + 1
266
- # 2007-11-05 BEGIN
267
- # parsexcel liefert (mir unverstaendlich) eine Zeile als letzte Zeile
268
- # zurueck, die aber leer ist. Deshalb Korrekturfunktion, die wirklich
269
- # die letzte nicht leere Zeile liefert.
270
- while empty_row? row(lr,sheet)
271
- lr -= 1
271
+ unless worksheet.min_row
272
+ fr = nil
273
+ else
274
+ fr = worksheet.min_row + 1
275
+ end
276
+ unless worksheet.max_row
277
+ lr = nil
278
+ else
279
+ lr = worksheet.max_row + 1
280
+ end
281
+ unless worksheet.min_col
282
+ fc = nil
283
+ else
284
+ fc = worksheet.min_col + 1
285
+ end
286
+ unless worksheet.max_col
287
+ lc = nil
288
+ else
289
+ lc = worksheet.max_col + 1
290
+ end
291
+ if lr
292
+ # 2007-11-05 BEGIN
293
+ # parsexcel liefert (mir unverstaendlich) eine Zeile als letzte Zeile
294
+ # zurueck, die aber leer ist. Deshalb Korrekturfunktion, die wirklich
295
+ # die letzte nicht leere Zeile liefert.
296
+ while empty_row? row(lr,sheet)
297
+ lr -= 1
298
+ end
272
299
  end
273
300
  # 2007-11-05 END
274
301
  @first_row[sheet] = fr
@@ -283,9 +310,11 @@ class Excel < GenericSpreadsheet #Openoffice
283
310
  return name-1 if name.kind_of?(Fixnum)
284
311
  0.upto(@workbook.sheet_count - 1) do |i|
285
312
  # TODO: is there a better way to do conversion?
286
- return i if name == Iconv.new('utf-8','unicode').iconv(
287
- @workbook.worksheet(i).name
288
- )
313
+ return i if name == platform_specific_iconv(
314
+ @workbook.worksheet(i).name)
315
+ #Iconv.new('utf-8','unicode').iconv(
316
+ # @workbook.worksheet(i).name
317
+ # )
289
318
  end
290
319
  raise StandardError, "sheet '#{name}' not found"
291
320
  end
@@ -304,21 +333,21 @@ class Excel < GenericSpreadsheet #Openoffice
304
333
  empty = true
305
334
  else
306
335
  case cell.type
307
- when :numeric
336
+ when :numeric
308
337
  onecelltype = :float
309
338
  onecell = cell.to_f
310
- when :text
339
+ when :text
311
340
  onecelltype = :string
312
341
  onecell = cell.to_s('utf-8')
313
- when :date
342
+ when :date
314
343
  onecelltype = :date
315
344
  onecell = cell.date
316
345
  else
317
346
  onecelltype = nil
318
- onecell = nil
347
+ onecell = nil
319
348
  end
320
- end
321
- file.print one_cell_output(onecelltype,onecell,empty)
349
+ end
350
+ file.print one_cell_output(onecelltype,onecell,empty)
322
351
  }
323
352
  file.print("\n")
324
353
  }
@@ -331,8 +360,20 @@ class Excel < GenericSpreadsheet #Openoffice
331
360
  #if elem.class == String and elem.size > 0
332
361
  content = true
333
362
  end
334
- }
363
+ }
335
364
  ! content
336
365
  end
337
366
 
367
+ def platform_specific_iconv(value)
368
+ case RUBY_PLATFORM.downcase
369
+ when /darwin/
370
+ result = Iconv.new('utf-8','utf-8').iconv(value)
371
+ when /mswin32/
372
+ result = Iconv.new('utf-8','iso-8859-1').iconv(value)
373
+ else
374
+ result = Iconv.new('utf-8','unicode').iconv(value)
375
+ end # case
376
+ result
377
+ end
378
+
338
379
  end
@@ -68,13 +68,24 @@ class GenericSpreadsheet
68
68
  self.default_sheet = sheet
69
69
  # $log.debug("nach default_sheet=")
70
70
  result << "Sheet " + n.to_s + ":\n"
71
- result << " First row: #{first_row}\n"
71
+ if !(first_row) # && last_row && first_column) # && last_column)
72
+ result << " - empty -"
73
+ end
74
+ if first_row
75
+ result << " First row: #{first_row}\n"
76
+ end
72
77
  # $log.debug("nach first_row")
73
- result << " Last row: #{last_row}\n"
78
+ if last_row
79
+ result << " Last row: #{last_row}\n"
80
+ end
74
81
  # $log.debug("nach last_row")
75
- result << " First column: #{GenericSpreadsheet.number_to_letter(first_column)}\n"
82
+ if first_column
83
+ result << " First column: #{GenericSpreadsheet.number_to_letter(first_column)}\n"
84
+ end
76
85
  # $log.debug("nach first_column")
77
- result << " Last column: #{GenericSpreadsheet.number_to_letter(last_column)}"
86
+ if last_column
87
+ result << " Last column: #{GenericSpreadsheet.number_to_letter(last_column)}"
88
+ end
78
89
  # $log.debug("nach last_column")
79
90
  result << "\n" if sheet != sheets.last
80
91
  n += 1
@@ -141,7 +152,7 @@ class GenericSpreadsheet
141
152
 
142
153
  # returns the number of the last non-empty row
143
154
  def last_row(sheet=nil)
144
- sheet = @default_sheet unless sheet
155
+ sheet = @default_sheet unless sheet
145
156
  read_cells(sheet) unless @cells_read[sheet]
146
157
  if @last_row[sheet]
147
158
  return @last_row[sheet]
@@ -153,7 +164,7 @@ class GenericSpreadsheet
153
164
  y = y.to_i
154
165
  result = [result, y].max if value
155
166
  }
156
- result = nil if result == impossible_value
167
+ result = nil if result == impossible_value
157
168
  @last_row[sheet] = result
158
169
  result
159
170
  end
@@ -190,7 +201,7 @@ class GenericSpreadsheet
190
201
  return @first_row[sheet]
191
202
  end
192
203
  impossible_value = 999_999 # more than a spreadsheet can hold
193
- result = impossible_value
204
+ result = impossible_value
194
205
  @cell[sheet].each_pair {|key,value|
195
206
  y,x = key.split(',')
196
207
  y = y.to_i
@@ -211,7 +222,7 @@ class GenericSpreadsheet
211
222
  return @first_column[sheet]
212
223
  end
213
224
  impossible_value = 999_999 # more than a spreadsheet can hold
214
- result = impossible_value
225
+ result = impossible_value
215
226
  @cell[sheet].each_pair {|key,value|
216
227
  y,x = key.split(',')
217
228
  x = x.to_i
@@ -221,7 +232,7 @@ class GenericSpreadsheet
221
232
  @first_column[sheet] = result
222
233
  result
223
234
  end
224
-
235
+
225
236
  # convert a number to something like this: 'AB'
226
237
  def GenericSpreadsheet.number_to_letter(n)
227
238
  letters=""
@@ -261,15 +272,15 @@ class GenericSpreadsheet
261
272
  def after(d)
262
273
  if DateTime.now > d
263
274
  yield
264
- end
265
- end
275
+ end
276
+ end
266
277
 
267
278
  # helper method
268
279
  def before(d)
269
- if DateTime.now <= d
280
+ if DateTime.now <= d
270
281
  yield
271
- end
272
- end
282
+ end
283
+ end
273
284
 
274
285
  private
275
286
 
data/lib/roo/google.rb CHANGED
@@ -8,9 +8,9 @@ module GData
8
8
  #-- modified
9
9
  def evaluate_cell(cell, sheet_no=1)
10
10
  raise ArgumentError, "invalid cell: #{cell}" unless cell
11
- raise ArgumentError, "invalid sheet_no: #{sheet_no}" unless sheet_no >0 and sheet_no.class == Fixnum
11
+ raise ArgumentError, "invalid sheet_no: #{sheet_no}" unless sheet_no >0 and sheet_no.class == Fixnum
12
12
  path = "/feeds/cells/#{@spreadsheet_id}/#{sheet_no}/#{@headers ? "private" : "public"}/basic/#{cell}"
13
-
13
+
14
14
  doc = Hpricot(request(path))
15
15
  result = (doc/"content").inner_html
16
16
  end
@@ -26,7 +26,7 @@ module GData
26
26
  result
27
27
  end
28
28
 
29
- # #-- new (testing only)
29
+ # #-- new (testing only)
30
30
  # def raw_url(url)
31
31
  # path = "/feeds/worksheets/#{@spreadsheet_id}/private/basic"
32
32
  # path = url
@@ -38,7 +38,7 @@ module GData
38
38
  path = "/feeds/cells/#{@spreadsheet_id}/1/#{@headers ? 'private' : 'public'}/full"
39
39
  post(path, entry)
40
40
  end
41
-
41
+
42
42
  #-- new
43
43
  def entry_roo(formula, row=1, col=1)
44
44
  <<XML
@@ -47,7 +47,7 @@ module GData
47
47
  </entry>
48
48
  XML
49
49
  end
50
-
50
+
51
51
  #-- new
52
52
  def add_to_cell_roo(row,col,value)
53
53
  save_entry_roo(entry_roo(value,row,col))
@@ -55,41 +55,20 @@ XML
55
55
 
56
56
  #-- new
57
57
  def get_one_sheet
58
- ath = "/feeds/worksheets/#{@spreadsheet_id}/private/basic"
59
58
  path = "/feeds/cells/#{@spreadsheet_id}/1/private/full"
60
59
  doc = Hpricot(request(path))
61
- #pp doc
62
- #p doc # TODO:prey:
63
- # result = (doc/"content[@type='text']").inner_html
64
- # p (doc/"content").inner_html
65
- #result = (doc/"content").inner_html.each { |item| item + '#'}
66
- #-- result = []
67
- #-- (doc/"content").each { |elem|
68
- #-- #p elem
69
- #-- result << elem.inner_html
70
- #-- }
71
- #-- result
72
60
  end
73
61
 
74
62
  #new
75
63
  def oben_unten_links_rechts(sheet_no)
76
- #sheet_no = sheets.index(sheet) + 1
77
64
  path = "/feeds/cells/#{@spreadsheet_id}/#{sheet_no}/private/full"
78
65
  doc = Hpricot(request(path))
79
- #(doc/"entry").each {|item|
80
66
  rows = []
81
67
  cols = []
82
68
  (doc/"gs:cell").each {|item|
83
- # p item
84
- #p item['row']
85
69
  rows.push item['row'].to_i
86
- #p item['col']
87
70
  cols.push item['col'].to_i
88
71
  }
89
- # $log.debug("row min: #{rows.min}")
90
- # $log.debug("row max: #{rows.max}")
91
- # $log.debug("col min: #{cols.min}")
92
- # $log.debug("col max: #{cols.max}")
93
72
  return rows.min, rows.max, cols.min, cols.max
94
73
  end
95
74
 
@@ -97,54 +76,31 @@ XML
97
76
  path = "/feeds/cells/#{@spreadsheet_id}/#{sheet_no}/private/full"
98
77
  doc = Hpricot(request(path))
99
78
  return doc
100
- #(doc/"entry").each {|item|
101
- rows = []
102
- cols = []
103
- (doc/"gs:cell").each {|item|
104
- # p item
105
- #p item['row']
106
- rows.push item['row'].to_i
107
- #p item['col']
108
- cols.push item['col'].to_i
109
- }
110
- # $log.debug("row min: #{rows.min}")
111
- # $log.debug("row max: #{rows.max}")
112
- # $log.debug("col min: #{cols.min}")
113
- # $log.debug("col max: #{cols.max}")
114
- return rows.min, rows.max, cols.min, cols.max
115
79
  end
116
80
  end # class
117
81
  end # module
118
82
 
119
83
  class Google < GenericSpreadsheet
120
84
  #include Log4r
121
-
122
- attr_accessor :header_line
123
85
 
124
- # TIMEOUT_IN_SECONDS = 42
125
- # GOOGLE_MAX_ROWS = 99
126
- # GOOGLE_MAX_COLS = 10 # TODO:
127
-
86
+ attr_accessor :header_line
87
+
128
88
  # Creates a new Google spreadsheet object.
129
89
  def initialize(spreadsheetkey,user=nil,password=nil)
130
90
  @filename = spreadsheetkey
131
91
  # $log = Logger.new("my_log")
132
92
  # $log.outputters = FileOutputter.new("f1", :filename => "roo.log")
133
-
134
- # $log.debug("created a new Google-object")
93
+
94
+ # $log.debug("created a new Google-object")
135
95
  @spreadsheetkey = spreadsheetkey
136
96
  @user = user
137
97
  @password = password
138
- unless user
98
+ unless user
139
99
  user = ENV['GOOGLE_MAIL']
140
100
  end
141
101
  unless password
142
102
  password = ENV['GOOGLE_PASSWORD']
143
103
  end
144
- #p spreadsheetkey
145
- #p user
146
- #p password
147
- #spreadsheetkey = ENV['GOOGLE_KEY']
148
104
  @default_sheet = nil
149
105
  @cell = Hash.new
150
106
  @cell_type = Hash.new
@@ -155,73 +111,28 @@ class Google < GenericSpreadsheet
155
111
  @last_column = Hash.new
156
112
  @cells_read = Hash.new
157
113
  @header_line = 1
158
- #??? @sheets = Array.new
159
-
114
+
160
115
  @gs = GData::Spreadsheet.new(spreadsheetkey)
161
- #@column = FromGData::Spreadsheet.new(spreadsheetkey)
162
116
  @gs.authenticate(user, password)
163
-
164
- #--Test only
165
- #@gs.get_one_sheet
166
- #@gs.oben_unten_links_rechts
167
- #--
117
+
168
118
  #-- ----------------------------------------------------------------------
169
- #-- Behandlung von Berechtigungen hier noch einbauen
119
+ #-- Behandlung von Berechtigungen hier noch einbauen ???
170
120
  #-- ----------------------------------------------------------------------
171
-
172
- #result = gs.add_to_cell formula
173
- #puts gs.evaluate_cell('A1')
174
- #p gs.evaluate_cell('A1')
175
- #puts gs.evaluate_cell('A2')
176
- #puts gs.evaluate_cell('A3')
177
-
178
- #Timeout.timeout(TIMEOUT_IN_SECONDS) {
179
- # @gs = GoogleSpreadSheet.new(spreadsheetkey)
180
- # @gs.authenticate(user, password)
181
- # @default_sheet = nil
182
- #}
183
- # alle eigenen Spreadsheets bei Google
184
- # @spreadsheets= GData::Spreadsheet.spreadsheets("emmanuel.pirsch@gmail.com", "secret") # funktioniert anscheinend noch nicht!!!!!!!!!
185
- # ein einzelnes Spreadsheet bei Google
186
- # @spreadsheet= spreadsheet[spreadsheetname]
187
-
188
- #gb = GData::Base.new
189
- #gb.authenticate("thopre@gmail.com","secret")
190
-
191
- #g = GData::Spreadsheet.new("ttt")
192
- #@default_sheet = nil
121
+
193
122
  if self.sheets.size == 1
194
123
  @default_sheet = self.sheets.first
195
- end
124
+ end
196
125
  end
197
126
 
198
- #def gssheetlist
199
- # @gs.sheetlist
200
- #end
201
-
202
127
  # returns an array of sheet names in the spreadsheet
203
128
  def sheets
204
- #if @sheets == []
205
- # @sheets = @gs.sheetlist
206
- #end
207
- #return @sheets
208
- #p gssheetlist
209
- return @gs.sheetlist
129
+ return @gs.sheetlist
210
130
  end
211
131
 
212
- #def reload
213
- # sav_default_sheet = default_sheet
214
- # super
215
- # @sheets = sheets #[]
216
- # puts "DEBUG: reload: erneutes Einlesen ergibt @sheets=#{@sheets.to_s}"
217
- # @default_sheet = sav_default_sheet
218
- #end
219
-
220
132
  # set the working sheet in the document
221
133
  #--
222
134
  # TODO: eigenlich identisch mit Openoffice => refactoring
223
135
  def default_sheet=(sheet)
224
- #puts "DEBUG: default_sheet=#{sheet}"
225
136
  if ! sheet.kind_of?(String)
226
137
  raise TypeError, "what are you trying to set as default sheet?"
227
138
  end
@@ -249,23 +160,23 @@ class Google < GenericSpreadsheet
249
160
  row,col = normalize(row,col)
250
161
 
251
162
  if celltype(row,col,sheet) == :date
252
- # $log.debug("splitte Datumsfeld auf (#{row},#{col}): #{ @cell[sheet]["#{row},#{col}"]}")
163
+ # $log.debug("splitte Datumsfeld auf (#{row},#{col}): #{ @cell[sheet]["#{row},#{col}"]}")
253
164
  yyyy,mm,dd = @cell[sheet]["#{row},#{col}"].split('-')
254
165
  # $log.debug(yyyy)
255
166
  # $log.debug(mm)
256
167
  # $log.debug(dd)
257
- #TODO:
258
- if dd.to_i < 1 or dd.to_i >31 or mm.to_i < 1 or mm.to_i > 12 or yyyy.to_i < 1900 or yyyy.to_i > 3000
259
- raise "Invalid date parameter: #{yyyy}, #{mm}, #{dd}"
260
- end
168
+ #TODO:
169
+ if dd.to_i < 1 or dd.to_i >31 or mm.to_i < 1 or mm.to_i > 12 or yyyy.to_i < 1900 or yyyy.to_i > 3000
170
+ raise "Invalid date parameter: #{yyyy}, #{mm}, #{dd}"
171
+ end
261
172
  return Date.new(yyyy.to_i,mm.to_i,dd.to_i)
262
173
  end
263
174
  return @cell[sheet]["#{row},#{col}"]
264
175
  end
265
176
 
266
177
  # returns the type of a cell:
267
- # * :float
268
- # * :string,
178
+ # * :float
179
+ # * :string,
269
180
  # * :date
270
181
  # * :percentage
271
182
  def celltype(row, col, sheet=nil)
@@ -278,7 +189,7 @@ end
278
189
  @cell_type[sheet]["#{row},#{col}"]
279
190
  end
280
191
  end
281
-
192
+
282
193
  # Returns the formula at (row,col).
283
194
  # Returns nil if there is no formula.
284
195
  # The method #formula? checks if there is a formula.
@@ -314,25 +225,10 @@ end
314
225
  theformulas << f
315
226
  end
316
227
  }
317
- }
228
+ }
318
229
  theformulas
319
230
  end
320
231
 
321
- # # returns all values in this row as an array
322
- # # row numbers are 1,2,3,... like in the spreadsheet
323
- # def row_old(rownumber,sheet=nil)
324
- # sheet = @default_sheet unless sheet
325
- # result = []
326
- # 1.upto(GOOGLE_MAX_ROWS) { |col| # TODO: maximum size of x-coordinate of google spreadsheet
327
- # result[col] = cell(rownumber,col,sheet)
328
- # }
329
- # result = result[1..-1]
330
- # while result[-1] == '' #TODO: besser?
331
- # result = result[0..-2]
332
- # end
333
- # result
334
- # end
335
-
336
232
  # returns all values in this row as an array
337
233
  # row numbers are 1,2,3,... like in the spreadsheet
338
234
  def row(rownumber,sheet=nil)
@@ -346,15 +242,15 @@ end
346
242
  y = y.to_i
347
243
  if y == rownumber
348
244
  tmp_arr[x] = value
349
- end
350
- }
245
+ end
246
+ }
351
247
  result = tmp_arr[1..-1]
352
- while result[-1] == nil
248
+ while result[-1] == nil
353
249
  result = result[0..-2]
354
- end
250
+ end
355
251
  result
356
- end
357
-
252
+ end
253
+
358
254
  # true, if the cell is empty
359
255
  def empty?(row, col, sheet=nil)
360
256
  value = cell(row, col, sheet)
@@ -363,7 +259,7 @@ end
363
259
  return false if value.class == Float
364
260
  value.empty?
365
261
  end
366
-
262
+
367
263
  # returns all values in this column as an array
368
264
  # column numbers are 1,2,3,... like in the spreadsheet
369
265
  #--
@@ -379,7 +275,7 @@ end
379
275
  result << cell(row,columnnumber,sheet)
380
276
  end
381
277
  result
382
- end
278
+ end
383
279
 
384
280
  # sets the cell to the content of 'value'
385
281
  # a formula can be set in the form of '=SUM(...)'
@@ -407,7 +303,7 @@ end
407
303
  return @last_row[sheet]
408
304
  end
409
305
 
410
- # returns the first non-empty column in a sheet
306
+ # returns the first non-empty column in a sheet
411
307
  def first_column(sheet=nil)
412
308
  sheet = @default_sheet unless sheet
413
309
  unless @first_column[sheet]
@@ -417,7 +313,7 @@ end
417
313
  return @first_column[sheet]
418
314
  end
419
315
 
420
- # returns the last non-empty column in a sheet
316
+ # returns the last non-empty column in a sheet
421
317
  def last_column(sheet=nil)
422
318
  sheet = @default_sheet unless sheet
423
319
  unless @last_column[sheet]
@@ -441,8 +337,8 @@ end
441
337
  end
442
338
  true
443
339
  end
444
-
445
-
340
+
341
+
446
342
  # find a row either by row number or a condition
447
343
  # Caution: this works only within the default sheet -> set default_sheet before you call this method
448
344
  # (experimental. see examples in the test_roo.rb file)
@@ -479,11 +375,11 @@ end
479
375
  x = key
480
376
  end
481
377
  }
482
- tmp[x] = cell(rownum,j)
483
- }
378
+ tmp[x] = cell(rownum,j)
379
+ }
484
380
  result = [ tmp ] # row(rownum)
485
381
  #-- :all
486
- elsif args[0] == :all
382
+ elsif args[0] == :all
487
383
  if args[1].class == Hash
488
384
  args[1].each {|key,val|
489
385
  if key == :conditions
@@ -512,8 +408,8 @@ end
512
408
  x = key
513
409
  end
514
410
  }
515
- tmp[x] = cell(i,j)
516
- }
411
+ tmp[x] = cell(i,j)
412
+ }
517
413
  if result_array
518
414
  result << self.row(i)
519
415
  else
@@ -529,38 +425,9 @@ end
529
425
  end
530
426
  private
531
427
 
532
- # def read_cells_old(sheet=nil) #TODO:
533
- # sheet = @default_sheet unless sheet
534
- # sheet_found = true # TODO:
535
- # #TODO: raise ArgumentError falls sheet nicht existiert - siehe openoffice
536
- # #TODO: boundaries !!!
537
- # 1.upto(25) { |y|
538
- # 1.upto(20) { |x|
539
- # key = "#{y},#{x}"
540
- # @cell[sheet] = {} unless @cell[sheet]
541
- # value = cell(y,x,sheet)
542
- # @cell[sheet][key] = value unless value == "" or value == nil
543
- # }
544
- # }
545
- # if !sheet_found
546
- # raise RangeErrror, "invalid sheet name"
547
- # end
548
- # @cells_read[sheet] = true
549
- # end
550
-
551
- # read all cells in a sheet
428
+ # read all cells in a sheet
552
429
  def read_cells(sheet=nil)
553
430
  sheet = @default_sheet unless sheet
554
- # sheet_no = sheets.index(sheet) + 1
555
- # @first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] = @gs.oben_unten_links_rechts(sheet_no)
556
- #@first_row[sheet].upto(@last_row[sheet]) { |y|
557
- # @first_column[sheet].upto(@last_column[sheet]) { |x|
558
- # key = "#{y},#{x}"
559
- # @cell[sheet] = {} unless @cell[sheet]
560
- # value = cell(y,x,sheet)
561
- # @cell[sheet][key] = value unless value == "" or value == nil
562
- # }
563
- #}
564
431
  sheet_no = sheets.index(sheet)+1
565
432
  doc = @gs.fulldoc(sheet_no)
566
433
  (doc/"gs:cell").each {|item|
@@ -568,29 +435,23 @@ end
568
435
  col = item['col']
569
436
  value = item['inputvalue']
570
437
  numericvalue = item['numericvalue']
571
- # puts numericvalue
572
- # puts value
573
- # puts value[0,1]
574
438
  if value[0,1] == '='
575
439
  formula = value
576
- # $log.debug("formula: <#{formula}>")
577
- # puts "Formel gefunden"
440
+ # $log.debug("formula: <#{formula}>")
578
441
  else
579
442
  formula = nil
580
443
  end
581
- # puts formula
582
- #--
583
444
  @cell_type[sheet] = {} unless @cell_type[sheet]
584
- if formula
445
+ if formula
585
446
  ty = :formula
586
- if numeric?(numericvalue)
587
- value = numericvalue.to_f
588
- else
589
- value = numericvalue
590
- end
447
+ if numeric?(numericvalue)
448
+ value = numericvalue.to_f
449
+ else
450
+ value = numericvalue
451
+ end
591
452
  elsif Google.date?(value)
592
453
  ty = :date
593
- elsif numeric?(value) # or o.class ???
454
+ elsif numeric?(value) # or o.class ???
594
455
  ty = :float
595
456
  value = value.to_f
596
457
  else
@@ -600,13 +461,13 @@ end
600
461
  @cell[sheet] = {} unless @cell[sheet]
601
462
  if ty == :date
602
463
  dd,mm,yyyy = value.split('/')
603
- @cell[sheet][key] = sprintf("%04d-%02d-%02d",yyyy.to_i,mm.to_i,dd.to_i)
464
+ @cell[sheet][key] = sprintf("%04d-%02d-%02d",yyyy.to_i,mm.to_i,dd.to_i)
604
465
  else
605
466
  @cell[sheet][key] = value unless value == "" or value == nil
606
467
  end
607
468
  @cell_type[sheet][key] = ty # Openoffice.oo_type_2_roo_type(vt)
608
469
  @formula[sheet] = {} unless @formula[sheet]
609
- # $log.debug("formula vor belegen @formula: <#{formula}>") if formula
470
+ # $log.debug("formula vor belegen @formula: <#{formula}>") if formula
610
471
  @formula[sheet][key] = formula if formula
611
472
  # $log.debug("@formula[#{sheet}][#{key}] = #{formula}") if formula
612
473
  # $log.debug("#{@formula[sheet][key]}") if formula
@@ -616,12 +477,12 @@ end
616
477
  @cells_read[sheet] = true
617
478
  end
618
479
 
619
- # Checks if the default_sheet exists. Otherwise a RangeError exception is
480
+ # Checks if the default_sheet exists. Otherwise a RangeError exception is
620
481
  # raised
621
482
  def check_default_sheet
622
483
  sheet_found = false
623
484
  raise ArgumentError, "Error: default_sheet not set" if @default_sheet == nil
624
- if sheets.index(@default_sheet)
485
+ if sheets.index(@default_sheet)
625
486
  sheet_found = true
626
487
  end
627
488
  if ! sheet_found
@@ -662,10 +523,10 @@ end
662
523
  #TODO: refactor to Generic....
663
524
  def one_cell_output(onecelltype,onecell,empty)
664
525
  str = ""
665
- if empty
526
+ if empty
666
527
  str += ''
667
528
  else
668
- case onecelltype
529
+ case onecelltype
669
530
  when :string
670
531
  if onecell == ""
671
532
  str << ''
@@ -37,13 +37,13 @@ class Openoffice < GenericSpreadsheet
37
37
  @@nr += 1
38
38
  @file_nr = @@nr
39
39
  extract_content
40
- file = File.new(File.join(@tmpdir, @file_nr.to_s+"_roo_content.xml"))
40
+ file = File.new(File.join(@tmpdir, @file_nr.to_s+"_roo_content.xml"))
41
41
  @doc = REXML::Document.new file
42
42
  file.close
43
43
  #if ENV["roo_local"] != "thomas-p"
44
44
  FileUtils::rm_r(@tmpdir)
45
45
  #end
46
- @default_sheet = nil
46
+ @default_sheet = nil
47
47
  # no need to set default_sheet if there is only one sheet in the document
48
48
  if self.sheets.size == 1
49
49
  @default_sheet = self.sheets.first
@@ -122,12 +122,12 @@ class Openoffice < GenericSpreadsheet
122
122
  set_type(row,col,:string,sheet)
123
123
  else
124
124
  raise ArgumentError, "Type for "+value.to_s+" not set"
125
- end
125
+ end
126
126
  end
127
127
 
128
128
  # returns the type of a cell:
129
- # * :float
130
- # * :string,
129
+ # * :float
130
+ # * :string,
131
131
  # * :date
132
132
  # * :percentage
133
133
  def celltype(row,col,sheet=nil)
@@ -179,7 +179,7 @@ class Openoffice < GenericSpreadsheet
179
179
 
180
180
  alias set_default_sheet default_sheet=
181
181
 
182
- # version of the openoffice document
182
+ # version of the openoffice document
183
183
  # at 2007 this is always "1.0"
184
184
  def officeversion
185
185
  # read_cells(false) unless @cells_read
@@ -216,7 +216,7 @@ class Openoffice < GenericSpreadsheet
216
216
  end
217
217
  result
218
218
  end
219
-
219
+
220
220
  # returns all values in this column as an array
221
221
  # column numbers are 1,2,3,... like in the spreadsheet
222
222
  def column(columnnumber,sheet=nil)
@@ -230,14 +230,14 @@ class Openoffice < GenericSpreadsheet
230
230
  result << cell(row,columnnumber,sheet)
231
231
  end
232
232
  result
233
- end
233
+ end
234
234
 
235
235
  # save spreadsheet
236
236
  def save #:nodoc:
237
237
  42
238
238
  end
239
239
 
240
- # evaluate the formula at this cell
240
+ # evaluate the formula at this cell
241
241
  # experimental: DO NOT USE THIS!
242
242
  def solve(row,col) #:nodoc:
243
243
  parser = SpreadsheetParser.new
@@ -264,12 +264,12 @@ class Openoffice < GenericSpreadsheet
264
264
  theformulas << f
265
265
  end
266
266
  }
267
- }
267
+ }
268
268
  theformulas
269
269
  end
270
-
270
+
271
271
  # write the current spreadsheet to stdout or into a file
272
- #TODO: refactoring --> GenericSpreadsheet
272
+ #TODO: refactoring --> GenericSpreadsheet
273
273
 
274
274
  def to_csv(filename=nil,sheet=nil)
275
275
  sheet = @default_sheet unless sheet
@@ -313,11 +313,11 @@ class Openoffice < GenericSpreadsheet
313
313
  x = key
314
314
  end
315
315
  }
316
- tmp[x] = cell(rownum,j)
317
- }
316
+ tmp[x] = cell(rownum,j)
317
+ }
318
318
  result = [ tmp ] # row(rownum)
319
319
  #-- :all
320
- elsif args[0] == :all
320
+ elsif args[0] == :all
321
321
  if args[1].class == Hash
322
322
  args[1].each {|key,val|
323
323
  if key == :conditions
@@ -346,8 +346,8 @@ class Openoffice < GenericSpreadsheet
346
346
  x = key
347
347
  end
348
348
  }
349
- tmp[x] = cell(i,j)
350
- }
349
+ tmp[x] = cell(i,j)
350
+ }
351
351
  if result_array
352
352
  result << self.row(i)
353
353
  else
@@ -362,7 +362,7 @@ class Openoffice < GenericSpreadsheet
362
362
  result
363
363
  end
364
364
 
365
-
365
+
366
366
  private
367
367
 
368
368
  # read the version of the OO-Version
@@ -377,22 +377,22 @@ class Openoffice < GenericSpreadsheet
377
377
  def set_cell_values(sheet,x,y,i,v,vt,formula,tr,str_v)
378
378
  key = "#{y},#{x+i}"
379
379
  @cell_type[sheet] = {} unless @cell_type[sheet]
380
- @cell_type[sheet][key] = Openoffice.oo_type_2_roo_type(vt)
380
+ @cell_type[sheet][key] = Openoffice.oo_type_2_roo_type(vt)
381
381
  @formula[sheet] = {} unless @formula[sheet]
382
382
  @formula[sheet][key] = formula if formula
383
383
  @cell[sheet] = {} unless @cell[sheet]
384
- case @cell_type[sheet][key]
384
+ case @cell_type[sheet][key]
385
385
  when :float
386
- @cell[sheet][key] = v.to_f
386
+ @cell[sheet][key] = v.to_f
387
387
  when :string
388
- @cell[sheet][key] = str_v
388
+ @cell[sheet][key] = str_v
389
389
  when :date
390
- @cell[sheet][key] = tr.attributes['date-value']
390
+ @cell[sheet][key] = tr.attributes['date-value']
391
391
  when :percentage
392
- @cell[sheet][key] = v.to_f
392
+ @cell[sheet][key] = v.to_f
393
393
  else
394
- @cell[sheet][key] = v
395
- end
394
+ @cell[sheet][key] = v
395
+ end
396
396
  end
397
397
 
398
398
  # read all cells in the selected sheet
@@ -425,7 +425,7 @@ class Openoffice < GenericSpreadsheet
425
425
  rep = te.attributes["number-columns-repeated"]
426
426
  elsif te.name == "table-row"
427
427
  if te.attributes['number-rows-repeated']
428
- skip_y = te.attributes['number-rows-repeated'].to_i
428
+ skip_y = te.attributes['number-rows-repeated'].to_i
429
429
  y = y + skip_y - 1 # minus 1 because this line will be counted as a line element
430
430
  end
431
431
  te.each_element do |tr|
@@ -472,7 +472,7 @@ class Openoffice < GenericSpreadsheet
472
472
  x = 1
473
473
  end
474
474
  end
475
- end # sheet
475
+ end # sheet
476
476
  end
477
477
  end
478
478
  end
@@ -480,13 +480,13 @@ class Openoffice < GenericSpreadsheet
480
480
  end
481
481
  end
482
482
  end
483
- if !sheet_found
484
- raise RangeError
483
+ if !sheet_found
484
+ raise RangeError
485
485
  end
486
486
  @cells_read[sheet] = true
487
487
  end
488
488
 
489
- # Checks if the default_sheet exists. If not an RangeError exception is
489
+ # Checks if the default_sheet exists. If not an RangeError exception is
490
490
  # raised
491
491
  def check_default_sheet
492
492
  sheet_found = false
@@ -502,7 +502,7 @@ class Openoffice < GenericSpreadsheet
502
502
  if se.name == "table"
503
503
  if se.attributes['name'] == @default_sheet
504
504
  sheet_found = true
505
- end # sheet
505
+ end # sheet
506
506
  end
507
507
  end
508
508
  end
@@ -519,17 +519,17 @@ class Openoffice < GenericSpreadsheet
519
519
  if zip.file.file? path
520
520
  if path == "content.xml"
521
521
  open(@tmpdir+'/'+@file_nr.to_s+'_roo_content.xml','wb') {|f|
522
- f << zip.read(path)
522
+ f << zip.read(path)
523
523
  }
524
- end
524
+ end
525
525
  else
526
526
  unless path.empty?
527
- path += '/'
528
- end
527
+ path += '/'
528
+ end
529
529
  zip.dir.foreach(path) do |filename|
530
530
  process_zipfile(zip, path+filename)
531
- end
532
- end
531
+ end
532
+ end
533
533
  end
534
534
 
535
535
  def extract_content
@@ -559,7 +559,7 @@ class Openoffice < GenericSpreadsheet
559
559
  return A_ROO_TYPE[ootype]
560
560
  end
561
561
 
562
-
562
+
563
563
  #TODO: refactoring to GenericSpreadsheet?
564
564
  def write_csv_content(file=nil,sheet=nil)
565
565
  file = STDOUT unless file
@@ -576,13 +576,13 @@ class Openoffice < GenericSpreadsheet
576
576
  end
577
577
  end
578
578
 
579
- #TODO: refactor to Generic...
579
+ #TODO: refactor to Generic...
580
580
  def one_cell_output(onecelltype,onecell,empty)
581
581
  str = ""
582
- if empty
582
+ if empty
583
583
  str += ''
584
584
  else
585
- case onecelltype
585
+ case onecelltype
586
586
  when :string
587
587
  if onecell == ""
588
588
  str << ''
@@ -623,7 +623,7 @@ class Openoffice < GenericSpreadsheet
623
623
  str
624
624
  end
625
625
 
626
- # helper method to convert compressed spaces and other elements within
626
+ # helper method to convert compressed spaces and other elements within
627
627
  # an text into a string
628
628
  def children_to_string(children)
629
629
  result = ''
data/lib/roo/version.rb CHANGED
@@ -2,7 +2,7 @@ module Roo #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 8
5
- TINY = 0
5
+ TINY = 1
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
Binary file
data/test/bbu.ods ADDED
Binary file
data/test/bbu.xls ADDED
Binary file
Binary file
Binary file
data/test/test_roo.rb CHANGED
@@ -20,13 +20,14 @@ def local_only
20
20
  end
21
21
 
22
22
  DISPLAY_LOG = false
23
- DB_LOG = true
23
+ DB_LOG = false
24
24
 
25
25
  if DB_LOG
26
26
  # gem 'activerecord', '< 2.0.0'
27
27
  # require 'activerecord'
28
- require_gem 'activerecord', '< 2.0.0'
29
- #require 'activerecord'
28
+ # require_gem 'activerecord', '< 2.0.0'
29
+ gem 'activerecord', '< 2.0.0'
30
+ require 'activerecord'
30
31
  end
31
32
 
32
33
  include FileUtils
@@ -125,7 +126,7 @@ class TestRoo < Test::Unit::TestCase
125
126
  GOOGLE = true # do Google-Spreadsheet Tests?
126
127
 
127
128
  OPENOFFICEWRITE = false # experimental: write access with OO-Documents
128
- ONLINE = false
129
+ ONLINE = true
129
130
  LONG_RUN = false
130
131
  GLOBAL_TIMEOUT = 2*12*60 # seconds
131
132
 
@@ -2416,4 +2417,80 @@ end
2416
2417
  assert_equal "hello from the tests", oo.cell(1,1)
2417
2418
  end
2418
2419
  end
2420
+
2421
+ def test_bug_bbu_openoffice
2422
+ oo = Openoffice.new(File.join('test','bbu.ods'))
2423
+ assert_nothing_raised() {
2424
+ assert_equal "File: test/bbu.ods
2425
+ Number of sheets: 3
2426
+ Sheets: 2007_12, Tabelle2, Tabelle3
2427
+ Sheet 1:
2428
+ First row: 1
2429
+ Last row: 4
2430
+ First column: A
2431
+ Last column: F
2432
+ Sheet 2:
2433
+ - empty -
2434
+ Sheet 3:
2435
+ - empty -", oo.info
2436
+ }
2437
+
2438
+ oo.default_sheet = oo.sheets[1] # empty sheet
2439
+ assert_nil oo.first_row
2440
+ assert_nil oo.last_row
2441
+ assert_nil oo.first_column
2442
+ assert_nil oo.last_column
2443
+ end
2444
+
2445
+ def test_bug_bbu_excel
2446
+ oo = Excel.new(File.join('test','bbu.xls'))
2447
+ assert_nothing_raised() {
2448
+ assert_equal "File: test/bbu.xls
2449
+ Number of sheets: 3
2450
+ Sheets: 2007_12, Tabelle2, Tabelle3
2451
+ Sheet 1:
2452
+ First row: 1
2453
+ Last row: 4
2454
+ First column: A
2455
+ Last column: F
2456
+ Sheet 2:
2457
+ - empty -
2458
+ Sheet 3:
2459
+ - empty -", oo.info
2460
+ }
2461
+
2462
+ oo.default_sheet = oo.sheets[1] # empty sheet
2463
+ assert_nil oo.first_row
2464
+ assert_nil oo.last_row
2465
+ assert_nil oo.first_column
2466
+ assert_nil oo.last_column
2467
+ end
2468
+
2469
+ if false
2470
+ # there is no google spreadsheet for this test
2471
+ def test_bug_bbu_google
2472
+ oo = Excel.new(key_of('bbu'))
2473
+ assert_nothing_raised() {
2474
+ assert_equal "File: test/bbu.xls
2475
+ Number of sheets: 3
2476
+ Sheets: 2007_12, Tabelle2, Tabelle3
2477
+ Sheet 1:
2478
+ First row: 1
2479
+ Last row: 4
2480
+ First column: A
2481
+ Last column: F
2482
+ Sheet 2:
2483
+ - empty -
2484
+ Sheet 3:
2485
+ - empty -", oo.info
2486
+ }
2487
+
2488
+ oo.default_sheet = oo.sheets[1] # empty sheet
2489
+ assert_nil oo.first_row
2490
+ assert_nil oo.last_row
2491
+ assert_nil oo.first_column
2492
+ assert_nil oo.last_column
2493
+ end
2494
+ end # false
2495
+
2419
2496
  end # class
data/website/index.html CHANGED
@@ -33,7 +33,7 @@
33
33
  <h1>roo</h1>
34
34
  <div id="version" class="clickable" onclick='document.location = "http://rubyforge.org/projects/roo"; return false'>
35
35
  Get Version
36
- <a href="http://rubyforge.org/projects/roo" class="numbers">0.8.0</a>
36
+ <a href="http://rubyforge.org/projects/roo" class="numbers">0.8.1</a>
37
37
  </div>
38
38
  <h2>What</h2>
39
39
 
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: roo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
5
- platform: ""
4
+ version: 0.8.1
5
+ platform: ruby
6
6
  authors:
7
7
  - Thomas Preymesser
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2007-12-16 00:00:00 +01:00
12
+ date: 2007-12-22 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -78,6 +78,13 @@ files:
78
78
  - lib/roo/google.rb
79
79
  - scripts/txt2html
80
80
  - setup.rb
81
+ - test/false_encoding.xls
82
+ - test/Bibelbund1.ods
83
+ - test/bbu.xls
84
+ - test/bbu.ods
85
+ - test/simple_spreadsheet.ods
86
+ - test/simple_spreadsheet_from_italo.ods
87
+ - test/simple_spreadsheet_from_italo.xls
81
88
  - test/test_helper.rb
82
89
  - test/test_roo.rb
83
90
  - test/numbers1.ods
@@ -119,7 +126,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
119
126
  requirements: []
120
127
 
121
128
  rubyforge_project: roo
122
- rubygems_version: 0.9.5
129
+ rubygems_version: 1.0.1
123
130
  signing_key:
124
131
  specification_version: 2
125
132
  summary: roo can access the contents of OpenOffice-, Excel- or Google-Spreadsheets