donibuchanan-roo 1.3.12 → 1.9.1.4
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 +26 -6
- data/lib/roo/excel.rb +83 -45
- data/lib/roo/excelx.rb +241 -69
- data/lib/roo/generic_spreadsheet.rb +34 -8
- data/lib/roo/google.rb +63 -117
- data/lib/roo/openoffice.rb +79 -27
- data/lib/roo/version.rb +9 -9
- data/lib/roo.rb +56 -13
- 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/numbers1.csv +0 -0
- data/test/test_helper.rb +1 -1
- data/test/test_roo.rb +381 -269
- data/test/whitespace.xls +0 -0
- metadata +2 -1
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
|
@@ -276,7 +189,7 @@ class Google < GenericSpreadsheet
|
|
276
189
|
raise RangeError, "invalid sheet '"+sheet.to_s+"'"
|
277
190
|
end
|
278
191
|
row,col = normalize(row,col)
|
279
|
-
|
192
|
+
add_to_cell_roo(row,col,value,sheet_no)
|
280
193
|
# re-read the portion of the document that has changed
|
281
194
|
if @cells_read[sheet]
|
282
195
|
key = "#{row},#{col}"
|
@@ -291,7 +204,8 @@ class Google < GenericSpreadsheet
|
|
291
204
|
sheet = @default_sheet unless sheet
|
292
205
|
unless @first_row[sheet]
|
293
206
|
sheet_no = sheets.index(sheet) + 1
|
294
|
-
@first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
|
207
|
+
@first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
|
208
|
+
oben_unten_links_rechts(sheet_no)
|
295
209
|
end
|
296
210
|
return @first_row[sheet]
|
297
211
|
end
|
@@ -301,7 +215,8 @@ class Google < GenericSpreadsheet
|
|
301
215
|
sheet = @default_sheet unless sheet
|
302
216
|
unless @last_row[sheet]
|
303
217
|
sheet_no = sheets.index(sheet) + 1
|
304
|
-
@first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
|
218
|
+
@first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
|
219
|
+
oben_unten_links_rechts(sheet_no)
|
305
220
|
end
|
306
221
|
return @last_row[sheet]
|
307
222
|
end
|
@@ -311,7 +226,8 @@ class Google < GenericSpreadsheet
|
|
311
226
|
sheet = @default_sheet unless sheet
|
312
227
|
unless @first_column[sheet]
|
313
228
|
sheet_no = sheets.index(sheet) + 1
|
314
|
-
@first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
|
229
|
+
@first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
|
230
|
+
oben_unten_links_rechts(sheet_no)
|
315
231
|
end
|
316
232
|
return @first_column[sheet]
|
317
233
|
end
|
@@ -321,7 +237,8 @@ class Google < GenericSpreadsheet
|
|
321
237
|
sheet = @default_sheet unless sheet
|
322
238
|
unless @last_column[sheet]
|
323
239
|
sheet_no = sheets.index(sheet) + 1
|
324
|
-
@first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
|
240
|
+
@first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
|
241
|
+
oben_unten_links_rechts(sheet_no)
|
325
242
|
end
|
326
243
|
return @last_column[sheet]
|
327
244
|
end
|
@@ -332,25 +249,31 @@ class Google < GenericSpreadsheet
|
|
332
249
|
def read_cells(sheet=nil)
|
333
250
|
sheet = @default_sheet unless sheet
|
334
251
|
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
|
-
|
252
|
+
sheet_no = sheets.index(sheet)
|
253
|
+
ws = @worksheets[sheet_no]
|
254
|
+
for row in 1..ws.num_rows
|
255
|
+
for col in 1..ws.num_cols
|
256
|
+
key = "#{row},#{col}"
|
257
|
+
string_value = ws.input_value(row,col) # item['inputvalue'] || item['inputValue']
|
258
|
+
numeric_value = ws[row,col] #item['numericvalue'] || item['numericValue']
|
259
|
+
(value, value_type) = determine_datatype(string_value, numeric_value)
|
260
|
+
@cell[sheet][key] = value unless value == "" or value == nil
|
261
|
+
@cell_type[sheet][key] = value_type
|
262
|
+
@formula[sheet] = {} unless @formula[sheet]
|
263
|
+
@formula[sheet][key] = string_value if value_type == :formula
|
264
|
+
############
|
265
|
+
#$log.debug("key: #{key}")
|
266
|
+
#$log.debug "#{ws[row,col].inspect}"
|
267
|
+
#@cell[sheet][key] = ws[row,col]
|
268
|
+
#$log.debug "@cell[sheet][key]: #{@cell[sheet][key]}"
|
269
|
+
############
|
270
|
+
end
|
349
271
|
end
|
350
272
|
@cells_read[sheet] = true
|
351
273
|
end
|
352
274
|
|
353
275
|
def determine_datatype(val, numval=nil)
|
276
|
+
# $log.debug "val: #{val} numval: #{numval}"
|
354
277
|
if val.nil? || val[0,1] == '='
|
355
278
|
ty = :formula
|
356
279
|
if numeric?(numval)
|
@@ -372,8 +295,31 @@ class Google < GenericSpreadsheet
|
|
372
295
|
else
|
373
296
|
ty = :string
|
374
297
|
end
|
375
|
-
end
|
298
|
+
end
|
299
|
+
#$log.debug "val: #{val} ty: #{ty}" if ty == :date
|
376
300
|
return val, ty
|
377
301
|
end
|
378
|
-
|
379
|
-
|
302
|
+
|
303
|
+
def add_to_cell_roo(row,col,value, sheet_no=1)
|
304
|
+
sheet_no -= 1
|
305
|
+
@worksheets[sheet_no][row,col] = value
|
306
|
+
@worksheets[sheet_no].save
|
307
|
+
end
|
308
|
+
def entry_roo(value,row,col)
|
309
|
+
return value,row,col
|
310
|
+
end
|
311
|
+
|
312
|
+
def oben_unten_links_rechts(sheet_no)
|
313
|
+
ws = @worksheets[sheet_no-1]
|
314
|
+
rows = []
|
315
|
+
cols = []
|
316
|
+
for row in 1..ws.num_rows
|
317
|
+
for col in 1..ws.num_cols
|
318
|
+
rows << row if ws[row,col] and ws[row,col] != '' #TODO: besser?
|
319
|
+
cols << col if ws[row,col] and ws[row,col] != '' #TODO: besser?
|
320
|
+
end
|
321
|
+
end
|
322
|
+
return rows.min, rows.max, cols.min, cols.max
|
323
|
+
end
|
324
|
+
|
325
|
+
end # class
|
data/lib/roo/openoffice.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
require '
|
1
|
+
require 'rubygems'
|
2
2
|
require 'fileutils'
|
3
3
|
require 'zip/zipfilesystem'
|
4
4
|
require 'date'
|
5
5
|
require 'base64'
|
6
|
-
require '
|
6
|
+
require 'nokogiri'
|
7
7
|
|
8
8
|
class Openoffice < GenericSpreadsheet
|
9
9
|
|
@@ -36,7 +36,8 @@ class Openoffice < GenericSpreadsheet
|
|
36
36
|
@file_nr = @@nr
|
37
37
|
extract_content
|
38
38
|
file = File.new(File.join(@tmpdir, @file_nr.to_s+"_roo_content.xml"))
|
39
|
-
@doc = XML::Parser.io(file).parse
|
39
|
+
#TODO: @doc = XML::Parser.io(file).parse
|
40
|
+
@doc = Nokogiri::XML(file)
|
40
41
|
file.close
|
41
42
|
ensure
|
42
43
|
#if ENV["roo_local"] != "thomas-p"
|
@@ -55,6 +56,7 @@ class Openoffice < GenericSpreadsheet
|
|
55
56
|
@style_defaults = Hash.new { |h,k| h[k] = [] }
|
56
57
|
@style_definitions = Hash.new
|
57
58
|
@header_line = 1
|
59
|
+
@labels = {}
|
58
60
|
end
|
59
61
|
|
60
62
|
# creates a new empty openoffice-spreadsheet file
|
@@ -78,7 +80,8 @@ class Openoffice < GenericSpreadsheet
|
|
78
80
|
read_cells(sheet) unless @cells_read[sheet]
|
79
81
|
row,col = normalize(row,col)
|
80
82
|
if celltype(row,col,sheet) == :date
|
81
|
-
yyyy,mm,dd = @cell[sheet][[row,col]].split('-')
|
83
|
+
#TODO: yyyy,mm,dd = @cell[sheet][[row,col]].split('-')
|
84
|
+
yyyy,mm,dd = @cell[sheet][[row,col]].to_s.split('-')
|
82
85
|
return Date.new(yyyy.to_i,mm.to_i,dd.to_i)
|
83
86
|
end
|
84
87
|
@cell[sheet][[row,col]]
|
@@ -170,8 +173,10 @@ class Openoffice < GenericSpreadsheet
|
|
170
173
|
|
171
174
|
def sheets
|
172
175
|
return_sheets = []
|
173
|
-
@doc.find("//*[local-name()='table']").each do |sheet|
|
174
|
-
|
176
|
+
#TODO: @doc.find("//*[local-name()='table']").each do |sheet|
|
177
|
+
@doc.xpath("//*[local-name()='table']").each do |sheet|
|
178
|
+
#TODO: return_sheets << sheet.attributes['name']
|
179
|
+
return_sheets << sheet['name']
|
175
180
|
end
|
176
181
|
return_sheets
|
177
182
|
end
|
@@ -213,12 +218,29 @@ class Openoffice < GenericSpreadsheet
|
|
213
218
|
theformulas
|
214
219
|
end
|
215
220
|
|
221
|
+
# returns the row,col values of the labelled cell
|
222
|
+
# (nil,nil) if label is not defined
|
223
|
+
# sheet parameter is not really needed because label names are global
|
224
|
+
# to the whole spreadsheet
|
225
|
+
def label(labelname,sheet=nil)
|
226
|
+
sheet = @default_sheet unless sheet
|
227
|
+
read_cells(sheet) unless @cells_read[sheet]
|
228
|
+
if @labels.has_key? labelname
|
229
|
+
return @labels[labelname][1].to_i,
|
230
|
+
GenericSpreadsheet.letter_to_number(@labels[labelname][2]),
|
231
|
+
@labels[labelname][0]
|
232
|
+
else
|
233
|
+
return nil,nil,nil
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
216
237
|
private
|
217
238
|
|
218
239
|
# read the version of the OO-Version
|
219
240
|
def oo_version
|
220
|
-
@doc.find("//*[local-name()='document-content']").each do |office|
|
221
|
-
|
241
|
+
#TODO: @doc.find("//*[local-name()='document-content']").each do |office|
|
242
|
+
@doc.xpath("//*[local-name()='document-content']").each do |office|
|
243
|
+
@officeversion = office.attributes['version'].to_s
|
222
244
|
end
|
223
245
|
end
|
224
246
|
|
@@ -238,10 +260,11 @@ class Openoffice < GenericSpreadsheet
|
|
238
260
|
when :string
|
239
261
|
@cell[sheet][key] = str_v
|
240
262
|
when :date
|
241
|
-
if table_cell.attributes['date-value'].size != "XXXX-XX-XX".size
|
263
|
+
#TODO: if table_cell.attributes['date-value'].size != "XXXX-XX-XX".size
|
264
|
+
if table_cell.attributes['date-value'].to_s.size != "XXXX-XX-XX".size
|
242
265
|
#-- dann ist noch eine Uhrzeit vorhanden
|
243
266
|
#-- "1961-11-21T12:17:18"
|
244
|
-
@cell[sheet][key] = DateTime.parse(table_cell.attributes['date-value'])
|
267
|
+
@cell[sheet][key] = DateTime.parse(table_cell.attributes['date-value'].to_s)
|
245
268
|
@cell_type[sheet][key] = :datetime
|
246
269
|
else
|
247
270
|
@cell[sheet][key] = table_cell.attributes['date-value']
|
@@ -267,31 +290,59 @@ class Openoffice < GenericSpreadsheet
|
|
267
290
|
raise ArgumentError, "Error: sheet '#{sheet||'nil'}' not valid" if @default_sheet == nil and sheet==nil
|
268
291
|
raise RangeError unless self.sheets.include? sheet
|
269
292
|
|
270
|
-
|
271
|
-
|
293
|
+
#-
|
294
|
+
# Labels
|
295
|
+
# should be factored out in separate method because labels are global
|
296
|
+
# to the whole spreadsheet file (and not to specific sheet)
|
297
|
+
#+
|
298
|
+
@doc.xpath("//table:named-range").each do |ne|
|
299
|
+
#-
|
300
|
+
# $Sheet1.$C$5
|
301
|
+
#+
|
302
|
+
name = ne.attribute('name').to_s
|
303
|
+
sheetname,coords = ne.attribute('cell-range-address').to_s.split('.')
|
304
|
+
col = coords.split('$')[1]
|
305
|
+
row = coords.split('$')[2]
|
306
|
+
sheetname = sheetname[1..-1] if sheetname[0,1] == '$'
|
307
|
+
@labels[name] = [sheetname,row,col]
|
308
|
+
end
|
309
|
+
|
310
|
+
#TODO: @doc.find("//*[local-name()='table']").each do |ws|
|
311
|
+
@doc.xpath("//*[local-name()='table']").each do |ws|
|
312
|
+
#TODO: if sheet == ws.attributes['name']
|
313
|
+
if sheet == ws['name']
|
272
314
|
sheet_found = true
|
273
315
|
col = 1
|
274
316
|
row = 1
|
275
|
-
ws.each_element do |table_element|
|
317
|
+
#TODO: ws.each_element do |table_element|
|
318
|
+
ws.children.each do |table_element|
|
276
319
|
case table_element.name
|
277
320
|
when 'table-column'
|
278
321
|
@style_defaults[sheet] << table_element.attributes['default-cell-style-name']
|
279
322
|
when 'table-row'
|
280
323
|
if table_element.attributes['number-rows-repeated']
|
281
|
-
skip_row = table_element.attributes['number-rows-repeated'].to_i
|
324
|
+
#TODO: skip_row = table_element.attributes['number-rows-repeated'].to_i
|
325
|
+
skip_row = table_element.attributes['number-rows-repeated'].to_s.to_i
|
282
326
|
row = row + skip_row - 1
|
283
327
|
end
|
284
|
-
table_element.each_element do |cell|
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
328
|
+
#TODO: table_element.each_element do |cell|
|
329
|
+
table_element.children.each do |cell|
|
330
|
+
#TODO: skip_col = cell.attributes['number-columns-repeated']
|
331
|
+
skip_col = cell['number-columns-repeated']
|
332
|
+
#TODO: formula = cell.attributes['formula']
|
333
|
+
formula = cell['formula']
|
334
|
+
#TODO: vt = cell.attributes['value-type']
|
335
|
+
vt = cell['value-type']
|
336
|
+
#TODO: v = cell.attributes['value']
|
337
|
+
v = cell['value']
|
338
|
+
#TODO: style_name = cell.attributes['style-name']
|
339
|
+
style_name = cell['style-name']
|
290
340
|
if vt == 'string'
|
291
341
|
str_v = ''
|
292
342
|
# insert \n if there is more than one paragraph
|
293
343
|
para_count = 0
|
294
|
-
cell.each_element do |str|
|
344
|
+
#TODO: cell.each_element do |str|
|
345
|
+
cell.children.each do |str|
|
295
346
|
if str.name == 'p'
|
296
347
|
v = str.content
|
297
348
|
str_v += "\n" if para_count > 0
|
@@ -306,9 +357,10 @@ class Openoffice < GenericSpreadsheet
|
|
306
357
|
str_v.gsub!(/'/,"'") # special case not supported by unescapeHTML
|
307
358
|
str_v = CGI.unescapeHTML(str_v)
|
308
359
|
end # == 'p'
|
309
|
-
|
360
|
+
end
|
310
361
|
elsif vt == 'time'
|
311
|
-
cell.each_element do |str|
|
362
|
+
#TODO: cell.each_element do |str|
|
363
|
+
cell.children.each do |str|
|
312
364
|
if str.name == 'p'
|
313
365
|
v = str.content
|
314
366
|
end
|
@@ -322,8 +374,7 @@ class Openoffice < GenericSpreadsheet
|
|
322
374
|
elsif vt == 'float'
|
323
375
|
#
|
324
376
|
elsif vt == 'boolean'
|
325
|
-
v = cell.attributes['boolean-value']
|
326
|
-
#
|
377
|
+
v = cell.attributes['boolean-value'].to_s
|
327
378
|
else
|
328
379
|
# raise "unknown type #{vt}"
|
329
380
|
end
|
@@ -345,7 +396,8 @@ class Openoffice < GenericSpreadsheet
|
|
345
396
|
end
|
346
397
|
end
|
347
398
|
|
348
|
-
@doc.find("//*[local-name()='automatic-styles']").each do |style|
|
399
|
+
#TODO: @doc.find("//*[local-name()='automatic-styles']").each do |style|
|
400
|
+
@doc.xpath("//*[local-name()='automatic-styles']").each do |style|
|
349
401
|
read_styles(style)
|
350
402
|
end
|
351
403
|
if !sheet_found
|
@@ -434,7 +486,7 @@ class Openoffice < GenericSpreadsheet
|
|
434
486
|
result = result + child.content
|
435
487
|
else
|
436
488
|
if child.name == 's'
|
437
|
-
compressed_spaces = child.attributes['c'].to_i
|
489
|
+
compressed_spaces = child.attributes['c'].to_s.to_i
|
438
490
|
# no explicit number means a count of 1:
|
439
491
|
if compressed_spaces == 0
|
440
492
|
compressed_spaces = 1
|
data/lib/roo/version.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
module Roo #:nodoc:
|
2
|
-
module VERSION #:nodoc:
|
3
|
-
MAJOR = 1
|
4
|
-
MINOR = 3
|
5
|
-
TINY =
|
6
|
-
|
7
|
-
STRING = [MAJOR, MINOR, TINY].join('.')
|
8
|
-
end
|
9
|
-
end
|
1
|
+
#module Roo #:nodoc:
|
2
|
+
# module VERSION #:nodoc:
|
3
|
+
# MAJOR = 1
|
4
|
+
# MINOR = 3
|
5
|
+
# TINY = 6
|
6
|
+
#
|
7
|
+
# STRING = [MAJOR, MINOR, TINY].join('.')
|
8
|
+
# end
|
9
|
+
#end
|
data/lib/roo.rb
CHANGED
@@ -1,4 +1,48 @@
|
|
1
|
+
|
1
2
|
module Roo
|
3
|
+
|
4
|
+
# :stopdoc:
|
5
|
+
VERSION = '1.9.2'
|
6
|
+
LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
|
7
|
+
PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
|
8
|
+
# :startdoc:
|
9
|
+
|
10
|
+
# Returns the version string for the library.
|
11
|
+
#
|
12
|
+
def self.version
|
13
|
+
VERSION
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns the library path for the module. If any arguments are given,
|
17
|
+
# they will be joined to the end of the libray path using
|
18
|
+
# <tt>File.join</tt>.
|
19
|
+
#
|
20
|
+
def self.libpath( *args )
|
21
|
+
args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns the lpath for the module. If any arguments are given,
|
25
|
+
# they will be joined to the end of the path using
|
26
|
+
# <tt>File.join</tt>.
|
27
|
+
#
|
28
|
+
def self.path( *args )
|
29
|
+
args.empty? ? PATH : ::File.join(PATH, args.flatten)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Utility method used to require all files ending in .rb that lie in the
|
33
|
+
# directory below this file that has the same name as the filename passed
|
34
|
+
# in. Optionally, a specific _directory_ name can be passed in such that
|
35
|
+
# the _filename_ does not have to be equivalent to the directory.
|
36
|
+
#
|
37
|
+
def self.require_all_libs_relative_to( fname, dir = nil )
|
38
|
+
dir ||= ::File.basename(fname, '.*')
|
39
|
+
search_me = ::File.expand_path(
|
40
|
+
::File.join(::File.dirname(fname), dir, '**', '*.rb'))
|
41
|
+
Dir.glob(search_me).sort.each {|rb|
|
42
|
+
puts "DEBUG: require #{rb}"
|
43
|
+
require rb}
|
44
|
+
end
|
45
|
+
|
2
46
|
class Spreadsheet
|
3
47
|
class << self
|
4
48
|
def open(file)
|
@@ -9,24 +53,23 @@ module Roo
|
|
9
53
|
Excelx.new(file)
|
10
54
|
when '.ods'
|
11
55
|
Openoffice.new(file)
|
12
|
-
|
13
|
-
Excel2003XML.new(file)
|
14
|
-
when ''
|
15
|
-
Google.new(file)
|
56
|
+
# when ''
|
16
57
|
else
|
17
|
-
|
18
|
-
|
58
|
+
Google.new(file)
|
59
|
+
# else
|
60
|
+
# raise ArgumentError, "Don't know how to open file #{file}"
|
61
|
+
end
|
19
62
|
end
|
20
63
|
end
|
21
64
|
end
|
22
|
-
end
|
65
|
+
end # module Roo
|
23
66
|
|
24
|
-
require 'roo/
|
25
|
-
# require 'roo/spreadsheetparser' TODO:
|
26
|
-
require 'roo/generic_spreadsheet'
|
67
|
+
require 'roo/generic_spreadsheet'
|
27
68
|
require 'roo/openoffice'
|
28
69
|
require 'roo/excel'
|
29
70
|
require 'roo/excelx'
|
30
|
-
require 'roo/google'
|
31
|
-
|
32
|
-
|
71
|
+
#require 'roo/google'
|
72
|
+
|
73
|
+
#Roo.require_all_libs_relative_to(__FILE__)
|
74
|
+
|
75
|
+
# EOF
|
data/test/1900_base.xls
CHANGED
File without changes
|
data/test/1904_base.xls
CHANGED
File without changes
|
data/test/Bibelbund.csv
CHANGED
File without changes
|
data/test/bode-v1.ods.zip
CHANGED
File without changes
|
data/test/bode-v1.xls.zip
CHANGED
File without changes
|
data/test/boolean.xls
CHANGED
File without changes
|
data/test/datetime.xls
CHANGED
Binary file
|
data/test/numbers1.csv
CHANGED
File without changes
|
data/test/test_helper.rb
CHANGED