roo 1.3.11 → 1.9.0
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 +15 -6
- data/Manifest.txt +53 -0
- data/README.txt +97 -0
- data/Rakefile +45 -0
- data/bin/roo +8 -0
- data/lib/roo.rb +55 -9
- data/lib/roo/excel.rb +44 -40
- data/lib/roo/excelx.rb +99 -60
- data/lib/roo/generic_spreadsheet.rb +29 -1
- data/lib/roo/google.rb +71 -117
- data/lib/roo/openoffice.rb +79 -27
- data/lib/roo/version.rb +9 -9
- data/tasks/ann.rake +80 -0
- data/tasks/bones.rake +20 -0
- data/tasks/gem.rake +201 -0
- data/tasks/git.rake +40 -0
- data/tasks/notes.rake +27 -0
- data/tasks/post_load.rake +34 -0
- data/tasks/rdoc.rake +51 -0
- data/tasks/rubyforge.rake +55 -0
- data/tasks/setup.rb +292 -0
- data/tasks/spec.rake +54 -0
- data/tasks/svn.rake +47 -0
- data/tasks/test.rake +40 -0
- data/tasks/zentest.rake +36 -0
- data/test/1900_base.xls +0 -0
- data/test/1904_base.xls +0 -0
- data/test/Bibelbund.csv +0 -0
- data/test/bode-v1.ods.zip +0 -0
- data/test/bode-v1.xls.zip +0 -0
- data/test/boolean.xls +0 -0
- data/test/datetime.xls +0 -0
- data/test/named_cells.ods +0 -0
- data/test/numbers1.csv +0 -0
- data/test/{bad_excel_date.xls → prova.xls} +0 -0
- data/test/test_helper.rb +1 -1
- data/test/test_roo.rb +365 -256
- data/test/whitespace.xls +0 -0
- metadata +48 -30
- data/README.markdown +0 -55
- data/examples/roo_soap_client.rb +0 -53
- data/examples/roo_soap_server.rb +0 -29
- data/examples/write_me.rb +0 -33
- data/test/formula_parse_error.xls +0 -0
- data/test/skipped_tests.rb +0 -789
data/lib/roo/excelx.rb
CHANGED
@@ -1,11 +1,15 @@
|
|
1
|
-
require 'xml'
|
1
|
+
#TODO: require 'xml'
|
2
2
|
require 'fileutils'
|
3
3
|
require 'zip/zipfilesystem'
|
4
4
|
require 'date'
|
5
|
+
require 'rubygems'
|
6
|
+
require 'nokogiri'
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
-
|
8
|
+
if RUBY_VERSION < '1.9.0'
|
9
|
+
class String
|
10
|
+
def end_with?(str)
|
11
|
+
self[-str.length,str.length] == str
|
12
|
+
end
|
9
13
|
end
|
10
14
|
end
|
11
15
|
|
@@ -100,27 +104,33 @@ class Excelx < GenericSpreadsheet
|
|
100
104
|
@file_nr = @@nr
|
101
105
|
extract_content(@filename)
|
102
106
|
file = File.new(File.join(@tmpdir, @file_nr.to_s+"_roo_workbook.xml"))
|
103
|
-
@workbook_doc = XML::Parser.io(file).parse
|
107
|
+
# TODO: @workbook_doc = XML::Parser.io(file).parse
|
108
|
+
@workbook_doc = Nokogiri::XML(file)
|
109
|
+
|
110
|
+
|
104
111
|
file.close
|
105
112
|
@shared_table = []
|
106
113
|
if File.exist?(File.join(@tmpdir, @file_nr.to_s+'_roo_sharedStrings.xml'))
|
107
114
|
file = File.new(File.join(@tmpdir, @file_nr.to_s+'_roo_sharedStrings.xml'))
|
108
|
-
@sharedstring_doc = XML::Parser.io(file).parse
|
115
|
+
#TODO: @sharedstring_doc = XML::Parser.io(file).parse
|
116
|
+
@sharedstring_doc = Nokogiri::XML(file)
|
109
117
|
file.close
|
110
118
|
read_shared_strings(@sharedstring_doc)
|
111
119
|
end
|
112
120
|
@styles_table = []
|
113
|
-
@style_definitions = Array.new { |h,k| h[k] = {} }
|
121
|
+
@style_definitions = Array.new # TODO: ??? { |h,k| h[k] = {} }
|
114
122
|
if File.exist?(File.join(@tmpdir, @file_nr.to_s+'_roo_styles.xml'))
|
115
123
|
file = File.new(File.join(@tmpdir, @file_nr.to_s+'_roo_styles.xml'))
|
116
|
-
@styles_doc = XML::Parser.io(file).parse
|
124
|
+
#TODO: @styles_doc = XML::Parser.io(file).parse
|
125
|
+
@styles_doc = Nokogiri::XML(file)
|
117
126
|
file.close
|
118
127
|
read_styles(@styles_doc)
|
119
128
|
end
|
120
129
|
@sheet_doc = []
|
121
130
|
@sheet_files.each_with_index do |item, i|
|
122
131
|
file = File.new(item)
|
123
|
-
@sheet_doc[i] = XML::Parser.io(file).parse
|
132
|
+
#TODO: @sheet_doc[i] = XML::Parser.io(file).parse
|
133
|
+
@sheet_doc[i] = Nokogiri::XML(file)
|
124
134
|
file.close
|
125
135
|
end
|
126
136
|
ensure
|
@@ -192,7 +202,7 @@ class Excelx < GenericSpreadsheet
|
|
192
202
|
end
|
193
203
|
|
194
204
|
def italic?
|
195
|
-
|
205
|
+
@italic == true
|
196
206
|
end
|
197
207
|
|
198
208
|
def underline?
|
@@ -202,13 +212,13 @@ class Excelx < GenericSpreadsheet
|
|
202
212
|
|
203
213
|
# Given a cell, return the cell's style
|
204
214
|
def font(row, col, sheet=nil)
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
215
|
+
sheet = @default_sheet unless sheet
|
216
|
+
read_cells(sheet) unless @cells_read[sheet]
|
217
|
+
row,col = normalize(row,col)
|
218
|
+
s_attribute = @s_attribute[sheet][[row,col]]
|
219
|
+
s_attribute ||= 0
|
220
|
+
s_attribute = s_attribute.to_i
|
221
|
+
@style_definitions[s_attribute]
|
212
222
|
end
|
213
223
|
|
214
224
|
# set a cell to a certain value
|
@@ -281,8 +291,10 @@ class Excelx < GenericSpreadsheet
|
|
281
291
|
# returns an array of sheet names in the spreadsheet
|
282
292
|
def sheets
|
283
293
|
return_sheets = []
|
284
|
-
@workbook_doc.find("//*[local-name()='sheet']").each do |sheet|
|
285
|
-
|
294
|
+
#TODO: @workbook_doc.find("//*[local-name()='sheet']").each do |sheet|
|
295
|
+
@workbook_doc.xpath("//*[local-name()='sheet']").each do |sheet|
|
296
|
+
#TODO: return_sheets << sheet.attributes.to_h['name']
|
297
|
+
return_sheets << sheet['name']
|
286
298
|
end
|
287
299
|
return_sheets
|
288
300
|
end
|
@@ -374,8 +386,8 @@ class Excelx < GenericSpreadsheet
|
|
374
386
|
return x,y
|
375
387
|
end
|
376
388
|
|
377
|
-
# read all cells in the selected sheet
|
378
389
|
def format2type(format)
|
390
|
+
format = format.to_s # weil von Typ Nokogiri::XML::Attr
|
379
391
|
if FORMATS.has_key? format
|
380
392
|
FORMATS[format]
|
381
393
|
else
|
@@ -390,22 +402,34 @@ class Excelx < GenericSpreadsheet
|
|
390
402
|
raise ArgumentError, "Error: sheet '#{sheet||'nil'}' not valid" if @default_sheet == nil and sheet==nil
|
391
403
|
raise RangeError unless self.sheets.include? sheet
|
392
404
|
n = self.sheets.index(sheet)
|
393
|
-
@sheet_doc[n].find("//*[local-name()='c']").each do |c|
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
405
|
+
#TODO: @sheet_doc[n].find("//*[local-name()='c']").each do |c|
|
406
|
+
@sheet_doc[n].xpath("//*[local-name()='c']").each do |c|
|
407
|
+
#TODO: s_attribute = c.attributes.to_h['s'].to_i # should be here
|
408
|
+
s_attribute = c['s'].to_i # should be here
|
409
|
+
#TODO: if (c.attributes.to_h['t'] == 's')
|
410
|
+
# c: <c r="A5" s="2">
|
411
|
+
# <v>22606</v>
|
412
|
+
# </c>, format: , tmp_type: float
|
413
|
+
|
414
|
+
if c['t'] == 's'
|
415
|
+
tmp_type = :shared
|
416
|
+
#TODO: elsif (c.attributes.to_h['t'] == 'b')
|
417
|
+
elsif c['t'] == 'b'
|
418
|
+
tmp_type = :boolean
|
419
|
+
else
|
420
|
+
#s_attribute = c.attributes.to_h['s'].to_i # was here
|
421
|
+
s_attribute = c['s'].to_i # was here
|
422
|
+
format = attribute2format(s_attribute)
|
423
|
+
tmp_type = format2type(format)
|
424
|
+
end
|
404
425
|
formula = nil
|
405
|
-
c.each_element do |cell|
|
426
|
+
#TODO: c.each_element do |cell|
|
427
|
+
c.children.each do |cell|
|
428
|
+
#TODO: if cell.name == 'f'
|
406
429
|
if cell.name == 'f'
|
407
430
|
formula = cell.content
|
408
431
|
end
|
432
|
+
#TODO: if cell.name == 'v'
|
409
433
|
if cell.name == 'v'
|
410
434
|
if tmp_type == :time or tmp_type == :datetime
|
411
435
|
if cell.content.to_f >= 1.0
|
@@ -417,7 +441,7 @@ class Excelx < GenericSpreadsheet
|
|
417
441
|
else
|
418
442
|
end
|
419
443
|
end
|
420
|
-
excelx_type = [:numeric_or_formula,format]
|
444
|
+
excelx_type = [:numeric_or_formula,format.to_s]
|
421
445
|
excelx_value = cell.content
|
422
446
|
if tmp_type == :shared
|
423
447
|
vt = :string
|
@@ -443,7 +467,8 @@ class Excelx < GenericSpreadsheet
|
|
443
467
|
v = cell.content
|
444
468
|
end
|
445
469
|
#puts "vt: #{vt}" if cell.text.include? "22606.5120"
|
446
|
-
x,y = split_coordinate(c.attributes.to_h['r'])
|
470
|
+
#TODO: x,y = split_coordinate(c.attributes.to_h['r'])
|
471
|
+
x,y = split_coordinate(c['r'])
|
447
472
|
tr=nil #TODO: ???s
|
448
473
|
set_cell_values(sheet,x,y,0,v,vt,formula,tr,str_v,excelx_type,excelx_value,s_attribute)
|
449
474
|
end
|
@@ -523,17 +548,19 @@ class Excelx < GenericSpreadsheet
|
|
523
548
|
|
524
549
|
# read the shared strings xml document
|
525
550
|
def read_shared_strings(doc)
|
526
|
-
doc.find("//*[local-name()='si']").each do |si|
|
551
|
+
#TODO: doc.find("//*[local-name()='si']").each do |si|
|
552
|
+
doc.xpath("//*[local-name()='si']").each do |si|
|
527
553
|
shared_table_entry = ''
|
528
|
-
si.each_element do |elem|
|
529
|
-
|
554
|
+
#TODO: si.each_element do |elem|
|
555
|
+
si.children.each do |elem|
|
556
|
+
if elem.name == 'r'
|
530
557
|
elem.each_element do |r_elem|
|
531
|
-
if
|
558
|
+
if r_elem.name == 't'
|
532
559
|
shared_table_entry << r_elem.content
|
533
560
|
end
|
534
561
|
end
|
535
562
|
end
|
536
|
-
if
|
563
|
+
if elem.name == 't'
|
537
564
|
shared_table_entry = elem.content
|
538
565
|
end
|
539
566
|
end
|
@@ -547,37 +574,46 @@ class Excelx < GenericSpreadsheet
|
|
547
574
|
@cellXfs = []
|
548
575
|
fonts = []
|
549
576
|
|
550
|
-
doc.find("//*[local-name()='numFmt']").each do |numFmt|
|
551
|
-
|
552
|
-
|
577
|
+
#TODO: doc.find("//*[local-name()='numFmt']").each do |numFmt|
|
578
|
+
doc.xpath("//*[local-name()='numFmt']").each do |numFmt|
|
579
|
+
# TODO: numFmtId = numFmt.attributes.to_h['numFmtId']
|
580
|
+
numFmtId = numFmt.attributes['numFmtId']
|
581
|
+
#TODO: formatCode = numFmt.attributes.to_h['formatCode']
|
582
|
+
formatCode = numFmt.attributes['formatCode']
|
553
583
|
@numFmts << [numFmtId, formatCode]
|
554
584
|
end
|
555
|
-
doc.find("//*[local-name()='fonts']").each do |fonts_el|
|
556
|
-
|
557
|
-
|
585
|
+
#TODO: doc.find("//*[local-name()='fonts']").each do |fonts_el|
|
586
|
+
doc.xpath("//*[local-name()='fonts']").each do |fonts_el|
|
587
|
+
#TODO: fonts_el.each_element do |font_el|
|
588
|
+
fonts_el.children.each do |font_el|
|
589
|
+
#TODO: if font_el.name == 'font'
|
590
|
+
if font_el == 'font'
|
558
591
|
font = Excelx::Font.new
|
559
592
|
font_el.each_element do |font_sub_el|
|
560
593
|
case font_sub_el.name
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
594
|
+
when 'b'
|
595
|
+
font.bold = true
|
596
|
+
when 'i'
|
597
|
+
font.italic = true
|
598
|
+
when 'u'
|
599
|
+
font.underline = true
|
600
|
+
end
|
568
601
|
end
|
569
602
|
fonts << font
|
570
603
|
end
|
571
604
|
end
|
572
605
|
end
|
573
606
|
|
574
|
-
doc.find("//*[local-name()='cellXfs']").each do |xfs|
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
607
|
+
#TODO: doc.find("//*[local-name()='cellXfs']").each do |xfs|
|
608
|
+
doc.xpath("//*[local-name()='cellXfs']").each do |xfs|
|
609
|
+
xfs.children.each do |xf|
|
610
|
+
#TODO: numFmtId = xf.attributes.to_h['numFmtId']
|
611
|
+
numFmtId = xf['numFmtId']
|
612
|
+
@cellXfs << [numFmtId]
|
613
|
+
#TODO: fontId = xf.attributes.to_h['fontId'].to_i
|
614
|
+
fontId = xf['fontId'].to_i
|
615
|
+
@style_definitions << fonts[fontId]
|
616
|
+
end
|
581
617
|
end
|
582
618
|
end
|
583
619
|
|
@@ -585,7 +621,10 @@ class Excelx < GenericSpreadsheet
|
|
585
621
|
def attribute2format(s)
|
586
622
|
result = nil
|
587
623
|
@numFmts.each {|nf|
|
588
|
-
if nf.first == @cellXfs[s.to_i].first
|
624
|
+
#TODO: if nf.first == @cellXfs[s.to_i].first
|
625
|
+
# to_s weil das eine Nokogiri::XML::Attr und das
|
626
|
+
# andere ein String ist
|
627
|
+
if nf.first.to_s == @cellXfs[s.to_i].first
|
589
628
|
result = nf[1]
|
590
629
|
break
|
591
630
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# encoding: utf-8
|
1
2
|
require 'rubygems'
|
2
3
|
require 'builder'
|
3
4
|
|
@@ -313,7 +314,7 @@ class GenericSpreadsheet
|
|
313
314
|
def info
|
314
315
|
result = "File: #{File.basename(@filename)}\n"+
|
315
316
|
"Number of sheets: #{sheets.size}\n"+
|
316
|
-
"Sheets: #{sheets.
|
317
|
+
"Sheets: #{sheets.join(', ')}\n"
|
317
318
|
n = 1
|
318
319
|
sheets.each {|sheet|
|
319
320
|
self.default_sheet = sheet
|
@@ -359,6 +360,33 @@ class GenericSpreadsheet
|
|
359
360
|
xml_document
|
360
361
|
end
|
361
362
|
|
363
|
+
# when a method like spreadsheet.a42 is called
|
364
|
+
# convert it to a call of spreadsheet.cell('a',42)
|
365
|
+
def method_missing(m, *args)
|
366
|
+
# #aa42 => #cell('aa',42)
|
367
|
+
# #aa42('Sheet1') => #cell('aa',42,'Sheet1')
|
368
|
+
if m =~ /^([a-z]+)(\d)$/
|
369
|
+
col = GenericSpreadsheet.letter_to_number($1)
|
370
|
+
row = $2.to_i
|
371
|
+
if args.size > 0
|
372
|
+
return cell(row,col,args[0])
|
373
|
+
else
|
374
|
+
return cell(row,col)
|
375
|
+
end
|
376
|
+
# else
|
377
|
+
# geht noch nicht, weil label unterhalb (in Openoffice) dieser Klasse
|
378
|
+
# es definiert ist
|
379
|
+
# p "Label #{m} angesprochen?"
|
380
|
+
# row,col,sheet = label('anton')
|
381
|
+
# # row,col,sheet = label(m)
|
382
|
+
# p "row: #{row}"
|
383
|
+
# p "col: #{col}"
|
384
|
+
# p "sheet: #{sheet}"
|
385
|
+
# return cell(row,col)
|
386
|
+
end
|
387
|
+
raise ArgumentError, "Method #{m} missing. Args: #{args}"
|
388
|
+
end
|
389
|
+
|
362
390
|
protected
|
363
391
|
|
364
392
|
def file_type_check(filename, ext, name)
|
data/lib/roo/google.rb
CHANGED
@@ -1,100 +1,10 @@
|
|
1
|
-
require '
|
2
|
-
require
|
1
|
+
#require 'xml'
|
2
|
+
require "google_spreadsheet"
|
3
3
|
|
4
4
|
class GoogleHTTPError < RuntimeError; end
|
5
5
|
class GoogleReadError < RuntimeError; end
|
6
6
|
class GoogleWriteError < RuntimeError; end
|
7
7
|
|
8
|
-
# overwrite some methods from the gdata-gem:
|
9
|
-
module GData
|
10
|
-
class Spreadsheet < GData::Base
|
11
|
-
|
12
|
-
def visibility
|
13
|
-
@headers ? "private" : "public"
|
14
|
-
end
|
15
|
-
|
16
|
-
def projection
|
17
|
-
@headers ? "full" : "values"
|
18
|
-
end
|
19
|
-
|
20
|
-
#-- modified
|
21
|
-
def evaluate_cell(cell, sheet_no=1)
|
22
|
-
raise ArgumentError, "invalid cell: #{cell}" unless cell
|
23
|
-
raise ArgumentError, "invalid sheet_no: #{sheet_no}" unless sheet_no >0 and sheet_no.class == Fixnum
|
24
|
-
path = "/feeds/cells/#{@spreadsheet_id}/#{sheet_no}/#{visibility}/#{projection}/#{cell}"
|
25
|
-
doc = Hpricot(request(path))
|
26
|
-
result = (doc/"content").inner_html
|
27
|
-
end
|
28
|
-
|
29
|
-
#-- new
|
30
|
-
def sheetlist
|
31
|
-
path = "/feeds/worksheets/#{@spreadsheet_id}/#{visibility}/#{projection}"
|
32
|
-
doc = Hpricot(request(path))
|
33
|
-
result = []
|
34
|
-
(doc/"content").each { |elem|
|
35
|
-
result << elem.inner_html
|
36
|
-
}
|
37
|
-
if result.size == 0
|
38
|
-
if (doc/"h2").inner_html =~ /Error/
|
39
|
-
raise GoogleHTTPError, "#{(doc/'h2').inner_html}: #{(doc/'title').inner_html} [key '#{@spreadsheet_id}']"
|
40
|
-
else
|
41
|
-
raise GoogleReadError, "#{doc} [key '#{@spreadsheet_id}']"
|
42
|
-
end
|
43
|
-
end
|
44
|
-
result
|
45
|
-
end
|
46
|
-
|
47
|
-
#-- new
|
48
|
-
#@@ added sheet_no to definition
|
49
|
-
def save_entry_roo(entry, sheet_no)
|
50
|
-
raise GoogleWriteError, "unable to write to public spreadsheets" if visibility == 'public'
|
51
|
-
path = "/feeds/cells/#{@spreadsheet_id}/#{sheet_no}/#{visibility}/#{projection}"
|
52
|
-
post(path, entry)
|
53
|
-
end
|
54
|
-
|
55
|
-
#-- new
|
56
|
-
def entry_roo(formula, row=1, col=1)
|
57
|
-
<<-XML
|
58
|
-
<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gs='http://schemas.google.com/spreadsheets/2006'>
|
59
|
-
<gs:cell row='#{row}' col='#{col}' inputValue='#{formula}' />
|
60
|
-
</entry>
|
61
|
-
XML
|
62
|
-
end
|
63
|
-
|
64
|
-
#-- new
|
65
|
-
#@@ added sheet_no to definition
|
66
|
-
def add_to_cell_roo(row,col,value, sheet_no=1)
|
67
|
-
save_entry_roo(entry_roo(value,row,col), sheet_no)
|
68
|
-
end
|
69
|
-
|
70
|
-
#-- new
|
71
|
-
def get_one_sheet
|
72
|
-
path = "/feeds/cells/#{@spreadsheet_id}/1/#{visibility}/#{projection}"
|
73
|
-
doc = Hpricot(request(path))
|
74
|
-
end
|
75
|
-
|
76
|
-
#new
|
77
|
-
def oben_unten_links_rechts(sheet_no)
|
78
|
-
path = "/feeds/cells/#{@spreadsheet_id}/#{sheet_no}/#{visibility}/#{projection}"
|
79
|
-
doc = Hpricot(request(path))
|
80
|
-
rows = []
|
81
|
-
cols = []
|
82
|
-
(doc/"gs:cell").each {|item|
|
83
|
-
rows.push item['row'].to_i
|
84
|
-
cols.push item['col'].to_i
|
85
|
-
}
|
86
|
-
return rows.min, rows.max, cols.min, cols.max
|
87
|
-
end
|
88
|
-
|
89
|
-
def fulldoc(sheet_no)
|
90
|
-
path = "/feeds/cells/#{@spreadsheet_id}/#{sheet_no}/#{visibility}/#{projection}"
|
91
|
-
doc = Hpricot(request(path))
|
92
|
-
return doc
|
93
|
-
end
|
94
|
-
|
95
|
-
end # class
|
96
|
-
end # module
|
97
|
-
|
98
8
|
class Google < GenericSpreadsheet
|
99
9
|
attr_accessor :date_format, :datetime_format
|
100
10
|
|
@@ -122,10 +32,13 @@ class Google < GenericSpreadsheet
|
|
122
32
|
@date_format = '%d/%m/%Y'
|
123
33
|
@datetime_format = '%d/%m/%Y %H:%M:%S'
|
124
34
|
@time_format = '%H:%M:%S'
|
125
|
-
|
126
|
-
@
|
127
|
-
@
|
35
|
+
session = GoogleSpreadsheet.login(user, password)
|
36
|
+
@sheetlist = []
|
37
|
+
session.spreadsheet_by_key(@spreadsheetkey).worksheets.each { |sheet|
|
38
|
+
@sheetlist << sheet.title
|
39
|
+
}
|
128
40
|
@default_sheet = self.sheets.first
|
41
|
+
@worksheets = session.spreadsheet_by_key(@spreadsheetkey).worksheets
|
129
42
|
end
|
130
43
|
|
131
44
|
# returns an array of sheet names in the spreadsheet
|
@@ -182,6 +95,8 @@ class Google < GenericSpreadsheet
|
|
182
95
|
value = @cell[sheet]["#{row},#{col}"]
|
183
96
|
if celltype(row,col,sheet) == :date
|
184
97
|
begin
|
98
|
+
$log.debug "cell() value: #{value} @date_format: #{@date_format}"
|
99
|
+
$log.debug "returns #{Date.strptime(value, @date_format).inspect}"
|
185
100
|
return Date.strptime(value, @date_format)
|
186
101
|
rescue ArgumentError
|
187
102
|
raise "Invalid Date #{sheet}[#{row},#{col}] #{value} using format '{@date_format}'"
|
@@ -276,7 +191,7 @@ class Google < GenericSpreadsheet
|
|
276
191
|
raise RangeError, "invalid sheet '"+sheet.to_s+"'"
|
277
192
|
end
|
278
193
|
row,col = normalize(row,col)
|
279
|
-
|
194
|
+
add_to_cell_roo(row,col,value,sheet_no)
|
280
195
|
# re-read the portion of the document that has changed
|
281
196
|
if @cells_read[sheet]
|
282
197
|
key = "#{row},#{col}"
|
@@ -291,7 +206,8 @@ class Google < GenericSpreadsheet
|
|
291
206
|
sheet = @default_sheet unless sheet
|
292
207
|
unless @first_row[sheet]
|
293
208
|
sheet_no = sheets.index(sheet) + 1
|
294
|
-
@first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
|
209
|
+
@first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
|
210
|
+
oben_unten_links_rechts(sheet_no)
|
295
211
|
end
|
296
212
|
return @first_row[sheet]
|
297
213
|
end
|
@@ -301,7 +217,8 @@ class Google < GenericSpreadsheet
|
|
301
217
|
sheet = @default_sheet unless sheet
|
302
218
|
unless @last_row[sheet]
|
303
219
|
sheet_no = sheets.index(sheet) + 1
|
304
|
-
@first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
|
220
|
+
@first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
|
221
|
+
oben_unten_links_rechts(sheet_no)
|
305
222
|
end
|
306
223
|
return @last_row[sheet]
|
307
224
|
end
|
@@ -311,7 +228,8 @@ class Google < GenericSpreadsheet
|
|
311
228
|
sheet = @default_sheet unless sheet
|
312
229
|
unless @first_column[sheet]
|
313
230
|
sheet_no = sheets.index(sheet) + 1
|
314
|
-
@first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
|
231
|
+
@first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
|
232
|
+
oben_unten_links_rechts(sheet_no)
|
315
233
|
end
|
316
234
|
return @first_column[sheet]
|
317
235
|
end
|
@@ -321,7 +239,8 @@ class Google < GenericSpreadsheet
|
|
321
239
|
sheet = @default_sheet unless sheet
|
322
240
|
unless @last_column[sheet]
|
323
241
|
sheet_no = sheets.index(sheet) + 1
|
324
|
-
@first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
|
242
|
+
@first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
|
243
|
+
oben_unten_links_rechts(sheet_no)
|
325
244
|
end
|
326
245
|
return @last_column[sheet]
|
327
246
|
end
|
@@ -332,25 +251,37 @@ class Google < GenericSpreadsheet
|
|
332
251
|
def read_cells(sheet=nil)
|
333
252
|
sheet = @default_sheet unless sheet
|
334
253
|
raise RangeError, "illegal sheet <#{sheet}>" unless sheets.index(sheet)
|
335
|
-
sheet_no = sheets.index(sheet)
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
254
|
+
sheet_no = sheets.index(sheet)
|
255
|
+
$log.debug "sheet: #{sheet}"
|
256
|
+
$log.debug "sheet_no: #{sheet_no}"
|
257
|
+
ws = @worksheets[sheet_no]
|
258
|
+
$log.debug "#{ws.inspect}"
|
259
|
+
for row in 1..ws.num_rows
|
260
|
+
for col in 1..ws.num_cols
|
261
|
+
key = "#{row},#{col}"
|
262
|
+
string_value = ws.input_value(row,col) # item['inputvalue'] || item['inputValue']
|
263
|
+
numeric_value = ws[row,col] #item['numericvalue'] || item['numericValue']
|
264
|
+
(value, value_type) = determine_datatype(string_value, numeric_value)
|
265
|
+
@cell[sheet][key] = value unless value == "" or value == nil
|
266
|
+
if value_type == :date
|
267
|
+
$log.debug "date erkannt. value: #{value}"
|
268
|
+
end
|
269
|
+
@cell_type[sheet][key] = value_type
|
270
|
+
@formula[sheet] = {} unless @formula[sheet]
|
271
|
+
@formula[sheet][key] = string_value if value_type == :formula
|
272
|
+
############
|
273
|
+
#$log.debug("key: #{key}")
|
274
|
+
#$log.debug "#{ws[row,col].inspect}"
|
275
|
+
#@cell[sheet][key] = ws[row,col]
|
276
|
+
#$log.debug "@cell[sheet][key]: #{@cell[sheet][key]}"
|
277
|
+
############
|
278
|
+
end
|
349
279
|
end
|
350
280
|
@cells_read[sheet] = true
|
351
281
|
end
|
352
282
|
|
353
283
|
def determine_datatype(val, numval=nil)
|
284
|
+
# $log.debug "val: #{val} numval: #{numval}"
|
354
285
|
if val.nil? || val[0,1] == '='
|
355
286
|
ty = :formula
|
356
287
|
if numeric?(numval)
|
@@ -372,8 +303,31 @@ class Google < GenericSpreadsheet
|
|
372
303
|
else
|
373
304
|
ty = :string
|
374
305
|
end
|
375
|
-
end
|
306
|
+
end
|
307
|
+
$log.debug "val: #{val} ty: #{ty}" if ty == :date
|
376
308
|
return val, ty
|
377
309
|
end
|
378
|
-
|
379
|
-
|
310
|
+
|
311
|
+
def add_to_cell_roo(row,col,value, sheet_no=1)
|
312
|
+
sheet_no -= 1
|
313
|
+
@worksheets[sheet_no][row,col] = value
|
314
|
+
@worksheets[sheet_no].save
|
315
|
+
end
|
316
|
+
def entry_roo(value,row,col)
|
317
|
+
return value,row,col
|
318
|
+
end
|
319
|
+
|
320
|
+
def oben_unten_links_rechts(sheet_no)
|
321
|
+
ws = @worksheets[sheet_no-1]
|
322
|
+
rows = []
|
323
|
+
cols = []
|
324
|
+
for row in 1..ws.num_rows
|
325
|
+
for col in 1..ws.num_cols
|
326
|
+
rows << row if ws[row,col] and ws[row,col] != '' #TODO: besser?
|
327
|
+
cols << col if ws[row,col] and ws[row,col] != '' #TODO: besser?
|
328
|
+
end
|
329
|
+
end
|
330
|
+
return rows.min, rows.max, cols.min, cols.max
|
331
|
+
end
|
332
|
+
|
333
|
+
end # class
|