roo 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,99 +1,180 @@
1
+ require 'rubygems' #TODO:
2
+ require 'gdata/spreadsheet'
3
+ #require 'log4r'
1
4
 
2
- #require 'net/http'
3
- #require 'net/https'
4
- #require 'uri'
5
- require 'rubygems'
6
- #require 'hpricot'
7
- require 'timeout'
8
- #require 'GData'
9
- require 'gdata'
10
-
11
- # Make it easy to use some of the convenience methods using https
12
- #
13
- #module Net class HTTPS < HTTP
14
- # def initialize(address, port = nil)
15
- # super(address, port)
16
- # self.use_ssl = true
17
- # end
18
- # end
19
- #end
20
- #
21
- #class GoogleSpreadSheet
22
- # GOOGLE_LOGIN_URL = URI.parse('https://www.google.com/accounts/ClientLogin')
23
- #
24
- # def initialize(spreadsheet_key)
25
- # @spreadsheet_key = spreadsheet_key
26
- # @headers = nil
27
- # @default_sheet = nil
28
- # end
29
- #
30
- # def default_sheet=(numberofsheet)
31
- # @default_sheet = numberofsheet
32
- # end
33
- #
34
- # def authenticate(email, password)
35
- # $VERBOSE = nil
36
- # response = Net::HTTPS.post_form(GOOGLE_LOGIN_URL,
37
- # {'Email' => email,
38
- # 'Passwd' => password,
39
- # 'source' => "formula",
40
- # 'service' => 'wise' })
41
- # @headers = { 'Authorization' => "GoogleLogin auth=#{response.body.split(/=/).last}",
42
- # 'Content-Type' => 'application/atom+xml'
43
- # }
44
- # end
45
- #
46
- # def evaluate_cell(cell)
47
- # path = "/feeds/cells/#{@spreadsheet_key}/#{@default_sheet}/#{@headers ? "private" : "public"}/basic/#{cell}"
48
- #
49
- # doc = Hpricot(request(path))
50
- # result = (doc/"content[@type='text']").inner_html
51
- # end
52
- #
53
- # def set_entry(entry)
54
- # path = "/feeds/cells/#{@spreadsheet_key}/#{@default_sheet}/#{@headers ? 'private' : 'public'}/full"
55
- #
56
- # post(path, entry)
57
- # end
58
- #
59
- # def entry(formula, row=1, col=1)
60
- # <<XML
61
- #<?xml version='1.0' ?>
62
- #<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gs='http://schemas.google.com/spreadsheets/2006'>
63
- # <gs:cell row='#{row}' col='#{col}' inputValue='=#{formula}' />
64
- #</entry>
65
- #XML
66
- # end
67
- #
68
- # def add_to_cell(formula) #puts entry(formula)
69
- # set_entry(entry(formula))
70
- # end
71
- #
72
- # private
73
- # def request(path)
74
- # response, data = get_http.get(path, @headers)
75
- # data
76
- # end
77
- #
78
- # def post(path, entry)
79
- # get_http.post(path, entry, @headers)
80
- # end
81
- #
82
- # def get_http
83
- # http = Net::HTTP.new('spreadsheets.google.com', 80)
84
- # #http.set_debug_output $stderr
85
- # http
86
- # end
87
- #end
5
+ # overwrite some methods from the gdata-gem:
6
+ module GData
7
+ class Spreadsheet < GData::Base
8
+ #-- modified
9
+ def evaluate_cell(cell, sheet_no=1)
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
12
+ path = "/feeds/cells/#{@spreadsheet_id}/#{sheet_no}/#{@headers ? "private" : "public"}/basic/#{cell}"
13
+
14
+ doc = Hpricot(request(path))
15
+ result = (doc/"content").inner_html
16
+ end
88
17
 
89
- class Google < Openoffice #:nodoc:
18
+ #-- new
19
+ def sheetlist
20
+ path = "/feeds/worksheets/#{@spreadsheet_id}/private/basic"
21
+ doc = Hpricot(request(path))
22
+ result = []
23
+ (doc/"content").each { |elem|
24
+ result << elem.inner_html
25
+ }
26
+ result
27
+ end
28
+
29
+ # #-- new (testing only)
30
+ # def raw_url(url)
31
+ # path = "/feeds/worksheets/#{@spreadsheet_id}/private/basic"
32
+ # path = url
33
+ # doc = Hpricot(request(path))
34
+ # end
35
+
36
+ #-- new
37
+ def save_entry_roo(entry)
38
+ path = "/feeds/cells/#{@spreadsheet_id}/1/#{@headers ? 'private' : 'public'}/full"
39
+ post(path, entry)
40
+ end
41
+
42
+ #-- new
43
+ def entry_roo(formula, row=1, col=1)
44
+ <<XML
45
+ <entry xmlns='http://www.w3.org/2005/Atom' xmlns:gs='http://schemas.google.com/spreadsheets/2006'>
46
+ <gs:cell row='#{row}' col='#{col}' inputValue='#{formula}' />
47
+ </entry>
48
+ XML
49
+ end
50
+
51
+ #-- new
52
+ def add_to_cell_roo(row,col,value)
53
+ save_entry_roo(entry_roo(value,row,col))
54
+ end
55
+
56
+ #-- new
57
+ def get_one_sheet
58
+ ath = "/feeds/worksheets/#{@spreadsheet_id}/private/basic"
59
+ path = "/feeds/cells/#{@spreadsheet_id}/1/private/full"
60
+ 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
+ end
73
+
74
+ #new
75
+ def oben_unten_links_rechts(sheet_no)
76
+ #sheet_no = sheets.index(sheet) + 1
77
+ path = "/feeds/cells/#{@spreadsheet_id}/#{sheet_no}/private/full"
78
+ doc = Hpricot(request(path))
79
+ #(doc/"entry").each {|item|
80
+ rows = []
81
+ cols = []
82
+ (doc/"gs:cell").each {|item|
83
+ # p item
84
+ #p item['row']
85
+ rows.push item['row'].to_i
86
+ #p item['col']
87
+ cols.push item['col'].to_i
88
+ }
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
+ return rows.min, rows.max, cols.min, cols.max
94
+ end
95
+
96
+ def fulldoc(sheet_no)
97
+ path = "/feeds/cells/#{@spreadsheet_id}/#{sheet_no}/private/full"
98
+ doc = Hpricot(request(path))
99
+ 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
+ end
116
+ end # class
117
+ end # module
90
118
 
91
- TIMEOUT_IN_SECONDS = 2
119
+ class Google < GenericSpreadsheet
120
+ #include Log4r
121
+
122
+ attr_accessor :header_line
92
123
 
93
- def initialize(user, password, spreadsheetkey, spreadsheetname)
94
- @cells_read = false
124
+ # TIMEOUT_IN_SECONDS = 42
125
+ # GOOGLE_MAX_ROWS = 99
126
+ # GOOGLE_MAX_COLS = 10 # TODO:
127
+
128
+ # Creates a new Google spreadsheet object.
129
+ def initialize(spreadsheetkey,user=nil,password=nil)
130
+ @filename = spreadsheetkey
131
+ # $log = Logger.new("my_log")
132
+ # $log.outputters = FileOutputter.new("f1", :filename => "roo.log")
133
+
134
+ # $log.debug("created a new Google-object")
135
+ @spreadsheetkey = spreadsheetkey
136
+ @user = user
137
+ @password = password
138
+ unless user
139
+ user = ENV['GOOGLE_MAIL']
140
+ end
141
+ unless password
142
+ password = ENV['GOOGLE_PASSWORD']
143
+ end
144
+ #p spreadsheetkey
145
+ #p user
146
+ #p password
147
+ #spreadsheetkey = ENV['GOOGLE_KEY']
148
+ @default_sheet = nil
95
149
  @cell = Hash.new
96
150
  @cell_type = Hash.new
151
+ @formula = Hash.new
152
+ @first_row = Hash.new
153
+ @last_row = Hash.new
154
+ @first_column = Hash.new
155
+ @last_column = Hash.new
156
+ @cells_read = Hash.new
157
+ @header_line = 1
158
+ #??? @sheets = Array.new
159
+
160
+ @gs = GData::Spreadsheet.new(spreadsheetkey)
161
+ #@column = FromGData::Spreadsheet.new(spreadsheetkey)
162
+ @gs.authenticate(user, password)
163
+
164
+ #--Test only
165
+ #@gs.get_one_sheet
166
+ #@gs.oben_unten_links_rechts
167
+ #--
168
+ #-- ----------------------------------------------------------------------
169
+ #-- Behandlung von Berechtigungen hier noch einbauen
170
+ #-- ----------------------------------------------------------------------
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
+
97
178
  #Timeout.timeout(TIMEOUT_IN_SECONDS) {
98
179
  # @gs = GoogleSpreadSheet.new(spreadsheetkey)
99
180
  # @gs.authenticate(user, password)
@@ -105,90 +186,524 @@ class Google < Openoffice #:nodoc:
105
186
  # @spreadsheet= spreadsheet[spreadsheetname]
106
187
 
107
188
  #gb = GData::Base.new
108
- #gb.authenticate("thopre@gmail.com","nora3033")
189
+ #gb.authenticate("thopre@gmail.com","secret")
109
190
 
110
- g = GData::Spreadsheet.new("ttt")
111
- @default_sheet = nil
191
+ #g = GData::Spreadsheet.new("ttt")
192
+ #@default_sheet = nil
193
+ if self.sheets.size == 1
194
+ @default_sheet = self.sheets.first
195
+ end
112
196
  end
113
197
 
198
+ #def gssheetlist
199
+ # @gs.sheetlist
200
+ #end
201
+
202
+ # returns an array of sheet names in the spreadsheet
114
203
  def sheets
115
- # http://spreadsheets.google.com/feeds/worksheets/ptu6bbahNZpYrdGHwteUNCw/private/full
116
- #if DateTime.now < Date.new(2007,6,15)
117
- # return ["Sheet eins","Sheet zwei","Sheet drei"]
118
- #else
119
- # return []
120
- #end
121
- @spreadsheet
204
+ #if @sheets == []
205
+ # @sheets = @gs.sheetlist
206
+ #end
207
+ #return @sheets
208
+ #p gssheetlist
209
+ return @gs.sheetlist
122
210
  end
123
211
 
124
- def default_sheet=(numberofsheet)
125
- @gs.default_sheet = numberofsheet
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
+ # set the working sheet in the document
221
+ #--
222
+ # TODO: eigenlich identisch mit Openoffice => refactoring
223
+ def default_sheet=(sheet)
224
+ #puts "DEBUG: default_sheet=#{sheet}"
225
+ if ! sheet.kind_of?(String)
226
+ raise TypeError, "what are you trying to set as default sheet?"
227
+ end
228
+ @default_sheet = sheet
229
+ check_default_sheet
230
+ @first_row[sheet] = @last_row[sheet] = @first_column[sheet] = @last_column[sheet] = nil
231
+ #--TODO: @cells_read[sheet] = false
232
+ end
233
+
234
+ # is String a date with format DD/MM/YYYY
235
+ def Google.date?(string)
236
+ return false if string.class == Float
237
+ return true if string.class == Date
238
+ return string.strip =~ /^([0-9]+)\/([0-9]+)\/([0-9]+)$/
126
239
  end
127
240
 
128
- def cell(row, col)
241
+ # Returns the content of a spreadsheet-cell.
242
+ # (1,1) is the upper left corner.
243
+ # (1,1), (1,'A'), ('A',1), ('a',1) all refers to the
244
+ # cell at the first line and first row.
245
+ def cell(row, col, sheet=nil)
246
+ sheet = @default_sheet unless sheet
247
+ check_default_sheet #TODO: 2007-12-16
248
+ read_cells(sheet) unless @cells_read[sheet]
129
249
  row,col = normalize(row,col)
130
- # formula = 42 || 'sin(0.2)'
131
-
132
- # gs = GoogleSpreadSheet.new("ptu6bbahNZpYrdGHwteUNCw")
133
- # gs.authenticate('thopre@gmail.com', 'nora3033')
134
- # gs.add_to_cell formula
135
- cellname = number_to_letter(col)+row.to_s
136
- Timeout.timeout(TIMEOUT_IN_SECONDS) {
137
- return @gs.evaluate_cell(cellname) # 'A1')
138
- }
250
+
251
+ if celltype(row,col,sheet) == :date
252
+ # $log.debug("splitte Datumsfeld auf (#{row},#{col}): #{ @cell[sheet]["#{row},#{col}"]}")
253
+ yyyy,mm,dd = @cell[sheet]["#{row},#{col}"].split('-')
254
+ # $log.debug(yyyy)
255
+ # $log.debug(mm)
256
+ # $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
261
+ return Date.new(yyyy.to_i,mm.to_i,dd.to_i)
262
+ end
263
+ return @cell[sheet]["#{row},#{col}"]
264
+ end
265
+
266
+ # returns the type of a cell:
267
+ # * :float
268
+ # * :string,
269
+ # * :date
270
+ # * :percentage
271
+ def celltype(row, col, sheet=nil)
272
+ sheet = @default_sheet unless sheet
273
+ read_cells(sheet) unless @cells_read[sheet]
274
+ row,col = normalize(row,col)
275
+ if @formula[sheet]["#{row},#{col}"]
276
+ return :formula
277
+ else
278
+ @cell_type[sheet]["#{row},#{col}"]
279
+ end
280
+ end
281
+
282
+ # Returns the formula at (row,col).
283
+ # Returns nil if there is no formula.
284
+ # The method #formula? checks if there is a formula.
285
+ def formula(row,col,sheet=nil)
286
+ sheet = @default_sheet unless sheet
287
+ read_cells(sheet) unless @cells_read[sheet]
288
+ row,col = normalize(row,col)
289
+ if @formula[sheet]["#{row},#{col}"] == nil
290
+ return nil
291
+ else
292
+ return @formula[sheet]["#{row},#{col}"] #TODO: ["oooc:".length..-1]
293
+ end
294
+ end
295
+
296
+ # true, if there is a formula
297
+ def formula?(row,col,sheet=nil)
298
+ sheet = @default_sheet unless sheet
299
+ read_cells unless @cells_read[sheet]
300
+ row,col = normalize(row,col)
301
+ formula(row,col) != nil
302
+ end
303
+
304
+ # returns each formula in the selected sheet as an array of elements
305
+ # [row, col, formula]
306
+ def formulas(sheet=nil)
307
+ theformulas = Array.new
308
+ sheet = @default_sheet unless sheet
309
+ read_cells(sheet) unless @cells_read[sheet]
310
+ first_row(sheet).upto(last_row(sheet)) {|row|
311
+ first_column(sheet).upto(last_column(sheet)) {|col|
312
+ if formula?(row,col,sheet)
313
+ f = [row, col, formula(row,col,sheet)]
314
+ theformulas << f
315
+ end
316
+ }
317
+ }
318
+ theformulas
319
+ end
320
+
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
+ # returns all values in this row as an array
337
+ # row numbers are 1,2,3,... like in the spreadsheet
338
+ def row(rownumber,sheet=nil)
339
+ sheet = @default_sheet unless sheet
340
+ read_cells(sheet) unless @cells_read[sheet]
341
+ result = []
342
+ tmp_arr = []
343
+ @cell[sheet].each_pair {|key,value|
344
+ y,x = key.split(',')
345
+ x = x.to_i
346
+ y = y.to_i
347
+ if y == rownumber
348
+ tmp_arr[x] = value
349
+ end
350
+ }
351
+ result = tmp_arr[1..-1]
352
+ while result[-1] == nil
353
+ result = result[0..-2]
354
+ end
355
+ result
356
+ end
357
+
358
+ # true, if the cell is empty
359
+ def empty?(row, col, sheet=nil)
360
+ value = cell(row, col, sheet)
361
+ return true unless value
362
+ return false if value.class == Date # a date is never empty
363
+ return false if value.class == Float
364
+ value.empty?
139
365
  end
366
+
367
+ # returns all values in this column as an array
368
+ # column numbers are 1,2,3,... like in the spreadsheet
369
+ #--
370
+ #TODO: refactoring nach GenericSpreadsheet?
371
+ def column(columnnumber, sheet=nil)
372
+ if columnnumber.class == String
373
+ columnnumber = GenericSpreadsheet.letter_to_number(columnnumber)
374
+ end
375
+ sheet = @default_sheet unless sheet
376
+ read_cells(sheet) unless @cells_read[sheet]
377
+ result = []
378
+ first_row(sheet).upto(last_row(sheet)) do |row|
379
+ result << cell(row,columnnumber,sheet)
380
+ end
381
+ result
382
+ end
140
383
 
141
- def celltype(row, col)
142
- "string"
384
+ # sets the cell to the content of 'value'
385
+ # a formula can be set in the form of '=SUM(...)'
386
+ def set_value(row,col,value)
387
+ @gs.add_to_cell_roo(row,col,value)
388
+ end
389
+
390
+ # returns the first non-empty row in a sheet
391
+ def first_row(sheet=nil)
392
+ sheet = @default_sheet unless sheet
393
+ unless @first_row[sheet]
394
+ sheet_no = sheets.index(sheet) + 1
395
+ @first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] = @gs.oben_unten_links_rechts(sheet_no)
396
+ end
397
+ return @first_row[sheet]
398
+ end
399
+
400
+ # returns the last non-empty row in a sheet
401
+ def last_row(sheet=nil)
402
+ sheet = @default_sheet unless sheet
403
+ unless @last_row[sheet]
404
+ sheet_no = sheets.index(sheet) + 1
405
+ @first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] = @gs.oben_unten_links_rechts(sheet_no)
406
+ end
407
+ return @last_row[sheet]
408
+ end
409
+
410
+ # returns the first non-empty column in a sheet
411
+ def first_column(sheet=nil)
412
+ sheet = @default_sheet unless sheet
413
+ unless @first_column[sheet]
414
+ sheet_no = sheets.index(sheet) + 1
415
+ @first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] = @gs.oben_unten_links_rechts(sheet_no)
416
+ end
417
+ return @first_column[sheet]
418
+ end
419
+
420
+ # returns the last non-empty column in a sheet
421
+ def last_column(sheet=nil)
422
+ sheet = @default_sheet unless sheet
423
+ unless @last_column[sheet]
424
+ sheet_no = sheets.index(sheet) + 1
425
+ @first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] = @gs.oben_unten_links_rechts(sheet_no)
426
+ end
427
+ return @last_column[sheet]
428
+ end
429
+
430
+ # write the current spreadsheet to stdout or into a file
431
+ #--
432
+ #TODO: refactoring --> GenericSpreadsheet
433
+ def to_csv(filename=nil,sheet=nil)
434
+ sheet = @default_sheet unless sheet
435
+ if filename
436
+ file = File.open(filename,"w") # do |file|
437
+ write_csv_content(file,sheet)
438
+ file.close
439
+ else
440
+ write_csv_content(STDOUT,sheet)
441
+ end
442
+ true
143
443
  end
144
444
 
145
- def empty?(row, col)
146
- cell(row, col).empty?
147
- end
148
-
149
- def read_cells
150
- # http://spreadsheets.google.com/feeds/list/ptu6bbahNZpYrdGHwteUNCw/1/private/full
151
- file = File.new("/home/tp/aaa.xml")
152
- @doc = REXML::Document.new file
153
- file.close
154
- @doc.each_element do |element|
155
- if element.name == "feed"
156
- p "feed gefunden"
157
- element.each_element do |feed|
158
- p feed
159
- feed.each_element do |fe|
160
- p fe.name
445
+
446
+ # find a row either by row number or a condition
447
+ # Caution: this works only within the default sheet -> set default_sheet before you call this method
448
+ # (experimental. see examples in the test_roo.rb file)
449
+ #--
450
+ # -----------------------------------------------------
451
+ # !!!TODO: should be factored out to GenericSpreadsheet
452
+ # also in Openofiffe
453
+ # -----------------------------------------------------
454
+ #++
455
+ def find(*args)
456
+ result_array = false
457
+ args.each {|arg,val|
458
+ if arg.class == Hash
459
+ arg.each { |hkey,hval|
460
+ if hkey == :array and hval == true
461
+ result_array = true
161
462
  end
162
- end
463
+ }
464
+ end
465
+ }
466
+ column_with = {}
467
+ 1.upto(last_column) do |col|
468
+ column_with[cell(@header_line,col)] = col
469
+ end
470
+ result = Array.new
471
+ #-- id
472
+ if args[0].class == Fixnum
473
+ rownum = args[0]
474
+ tmp = {}
475
+ 1.upto(self.row(rownum).size) {|j|
476
+ x = ''
477
+ column_with.each { |key,val|
478
+ if val == j
479
+ x = key
480
+ end
481
+ }
482
+ tmp[x] = cell(rownum,j)
483
+ }
484
+ result = [ tmp ] # row(rownum)
485
+ #-- :all
486
+ elsif args[0] == :all
487
+ if args[1].class == Hash
488
+ args[1].each {|key,val|
489
+ if key == :conditions
490
+ column_with = {}
491
+ 1.upto(last_column) do |col|
492
+ column_with[cell(@header_line,col)] = col
493
+ end
494
+ conditions = val
495
+ first_row.upto(last_row) do |i|
496
+ # are all conditions met?
497
+ found = 1
498
+ conditions.each { |key,val|
499
+ if cell(i,column_with[key]) == val
500
+ found *= 1
501
+ else
502
+ found *= 0
503
+ end
504
+ }
505
+ # p self.row(i) if found > 0
506
+ if found > 0
507
+ tmp = {}
508
+ 1.upto(self.row(i).size) {|j|
509
+ x = ''
510
+ column_with.each { |key,val|
511
+ if val == j
512
+ x = key
513
+ end
514
+ }
515
+ tmp[x] = cell(i,j)
516
+ }
517
+ if result_array
518
+ result << self.row(i)
519
+ else
520
+ result << tmp
521
+ end
522
+ end
523
+ end
524
+ end # :conditions
525
+ }
163
526
  end
164
-
165
527
  end
166
- # @cell["1,2"] = 42
167
- # @cell_type["1,2"] = "string"
168
- # @cells_read = true
169
- # return
528
+ result
529
+ end
530
+ private
531
+
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
170
550
 
171
- #TODO: die Grenzen sind noch fix
172
- 1.upto(10) do |y|
173
- Openoffice.letter_to_number('A').upto(Openoffice.letter_to_number('H')) do |x|
174
- # p x.to_s+", "+y.to_s
175
- # unless empty?(y,x)
176
- # @cell["#{y},#{x}"] = cell(y,x)
177
- # @cell_type["#{y},#{x}"] = cell(y,x)
178
- # end
551
+ # read all cells in a sheet
552
+ def read_cells(sheet=nil)
553
+ 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
+ sheet_no = sheets.index(sheet)+1
565
+ doc = @gs.fulldoc(sheet_no)
566
+ (doc/"gs:cell").each {|item|
567
+ row = item['row']
568
+ col = item['col']
569
+ value = item['inputvalue']
570
+ numericvalue = item['numericvalue']
571
+ # puts numericvalue
572
+ # puts value
573
+ # puts value[0,1]
574
+ if value[0,1] == '='
575
+ formula = value
576
+ # $log.debug("formula: <#{formula}>")
577
+ # puts "Formel gefunden"
578
+ else
579
+ formula = nil
580
+ end
581
+ # puts formula
582
+ #--
583
+ @cell_type[sheet] = {} unless @cell_type[sheet]
584
+ if formula
585
+ ty = :formula
586
+ if numeric?(numericvalue)
587
+ value = numericvalue.to_f
588
+ else
589
+ value = numericvalue
590
+ end
591
+ elsif Google.date?(value)
592
+ ty = :date
593
+ elsif numeric?(value) # or o.class ???
594
+ ty = :float
595
+ value = value.to_f
596
+ else
597
+ ty = :string
598
+ end
599
+ key = "#{row},#{col}"
600
+ @cell[sheet] = {} unless @cell[sheet]
601
+ if ty == :date
602
+ dd,mm,yyyy = value.split('/')
603
+ @cell[sheet][key] = sprintf("%04d-%02d-%02d",yyyy.to_i,mm.to_i,dd.to_i)
604
+ else
605
+ @cell[sheet][key] = value unless value == "" or value == nil
179
606
  end
180
- end
181
- @cells_read = true
607
+ @cell_type[sheet][key] = ty # Openoffice.oo_type_2_roo_type(vt)
608
+ @formula[sheet] = {} unless @formula[sheet]
609
+ # $log.debug("formula vor belegen @formula: <#{formula}>") if formula
610
+ @formula[sheet][key] = formula if formula
611
+ # $log.debug("@formula[#{sheet}][#{key}] = #{formula}") if formula
612
+ # $log.debug("#{@formula[sheet][key]}") if formula
613
+
614
+
615
+ }
616
+ @cells_read[sheet] = true
617
+ end
618
+
619
+ # Checks if the default_sheet exists. Otherwise a RangeError exception is
620
+ # raised
621
+ def check_default_sheet
622
+ sheet_found = false
623
+ raise ArgumentError, "Error: default_sheet not set" if @default_sheet == nil
624
+ if sheets.index(@default_sheet)
625
+ sheet_found = true
626
+ end
627
+ if ! sheet_found
628
+ raise RangeError, "sheet '#{@default_sheet}' not found"
629
+ end
182
630
  end
183
631
 
184
- def first_row
185
- read_cells unless @cells_read
186
- 1
632
+ def numeric?(string)
633
+ string =~ /^[0-9]+[\.]*[0-9]*$/
187
634
  end
188
635
 
189
- def last_row
190
- read_cells unless @cells_read
191
- 100
636
+ # convert string DD/MM/YYYY into a Date-object
637
+ #TODO: was ist mit verschiedenen Typen der Datumseingabe bei Google?
638
+ def Google.to_date(string)
639
+ if string.strip =~ /^([0-9]+)\/([0-9]+)\/([0-9]+)$/
640
+ return Date.new($3.to_i,$2.to_i,$1.to_i)
641
+ else
642
+ return nil
643
+ end
644
+ end
645
+
646
+ #TODO: refactoring to GenericSpreadsheet?
647
+ def write_csv_content(file=nil,sheet=nil)
648
+ file = STDOUT unless file
649
+ if first_row # sheet is not empty
650
+ first_row(sheet).upto(last_row(sheet)) do |row|
651
+ 1.upto(last_column(sheet)) do |col|
652
+ file.print(",") if col > 1
653
+ onecell = cell(row,col,sheet)
654
+ onecelltype = celltype(row,col,sheet)
655
+ file.print one_cell_output(onecelltype,onecell,empty?(row,col,sheet))
656
+ end
657
+ file.print("\n")
658
+ end # sheet not empty
659
+ end
660
+ end
661
+
662
+ #TODO: refactor to Generic....
663
+ def one_cell_output(onecelltype,onecell,empty)
664
+ str = ""
665
+ if empty
666
+ str += ''
667
+ else
668
+ case onecelltype
669
+ when :string
670
+ if onecell == ""
671
+ str << ''
672
+ else
673
+ onecell.gsub!(/"/,'""')
674
+ str << ('"'+onecell+'"')
675
+ end
676
+ when :float,:percentage
677
+ if onecell == onecell.to_i
678
+ str << onecell.to_i.to_s
679
+ else
680
+ str << onecell.to_s
681
+ end
682
+ when :formula
683
+ if onecell.class == String
684
+ if onecell == ""
685
+ str << ''
686
+ else
687
+ onecell.gsub!(/"/,'""')
688
+ str << '"'+onecell+'"'
689
+ end
690
+ elsif onecell.class == Float
691
+ if onecell == onecell.to_i
692
+ str << onecell.to_i.to_s
693
+ else
694
+ str << onecell.to_s
695
+ end
696
+ else
697
+ raise "unhandled onecell-class "+onecell.class.to_s
698
+ end
699
+ when :date
700
+ str << '"'+onecell.to_s+'"'
701
+ else
702
+ raise "unhandled celltype "+onecelltype.to_s
703
+ end
704
+ end
705
+ #cells << onecell
706
+ str
192
707
  end
193
708
 
194
709
  end # class