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/History.txt
CHANGED
@@ -1,3 +1,23 @@
|
|
1
|
+
== 1.9.2 2009-?????
|
2
|
+
|
3
|
+
* 1 bugfix
|
4
|
+
* double quoting of '"' fixed
|
5
|
+
|
6
|
+
== 1.9.1 2009-11-10
|
7
|
+
|
8
|
+
* 2 bugfixes
|
9
|
+
* syntax in nokogiri methods
|
10
|
+
* missing dependency ...rubyzip
|
11
|
+
|
12
|
+
== 1.9.0 2009-10-29
|
13
|
+
|
14
|
+
* 4 enhancements
|
15
|
+
* Ruby 1.9 compatible
|
16
|
+
* oo.aa42 as a shortcut of oo.cell('aa',42)
|
17
|
+
* oo.aa42('sheet1') as a shortcut of oo.cell('aa',42,'sheet1')
|
18
|
+
* oo.anton as a reference to a cell labelled 'anton' (or any other label name)
|
19
|
+
(currently only for Openoffice spreadsheets)
|
20
|
+
|
1
21
|
== 1.2.3 2009-01-04
|
2
22
|
|
3
23
|
* bugfix
|
@@ -89,8 +109,8 @@
|
|
89
109
|
* some methods common to more than one class were factored out to the GenericSpreadsheet (virtual) class
|
90
110
|
== 0.7.0 2007-11-23
|
91
111
|
* 6 enhancements:
|
92
|
-
* Openoffice/Excel: the most methods can be called with an option 'sheet'
|
93
|
-
parameter which will be used instead of the default sheet
|
112
|
+
* Openoffice/Excel: the most methods can be called with an option 'sheet'
|
113
|
+
parameter which will be used instead of the default sheet
|
94
114
|
* Excel: improved the speed of CVS output
|
95
115
|
* Openoffice/Excel: new method #column
|
96
116
|
* Openoffice/Excel: new method #find
|
@@ -118,7 +138,7 @@
|
|
118
138
|
== 0.5.1 2007-08-26
|
119
139
|
* 4 enhancements:
|
120
140
|
* Openoffice: Exception if an illegal sheet-name is selected
|
121
|
-
* Openoffice/Excel: no need to set a default_sheet if there is only one in
|
141
|
+
* Openoffice/Excel: no need to set a default_sheet if there is only one in
|
122
142
|
the document
|
123
143
|
* Excel: can now read zip-ed files
|
124
144
|
* Excel: can now read files from http://-URL over the net
|
@@ -136,7 +156,7 @@
|
|
136
156
|
== 0.4.0 2007-06-27
|
137
157
|
* 7 enhancements:
|
138
158
|
* robustness: Exception if no default_sheet was set
|
139
|
-
* new method reload() implemented
|
159
|
+
* new method reload() implemented
|
140
160
|
* about 15 % more method documentation
|
141
161
|
* optimization: huge increase of speed (no need to use fixed borders anymore)
|
142
162
|
* added the method 'formulas' which gives you all formulas in a spreadsheet
|
@@ -158,7 +178,7 @@
|
|
158
178
|
|
159
179
|
== 0.2.6 2007-06-19
|
160
180
|
* 1 bugfix:
|
161
|
-
* Openoffice: two or more consecutive cells with string content failed
|
181
|
+
* Openoffice: two or more consecutive cells with string content failed
|
162
182
|
|
163
183
|
== 0.2.5 2007-06-17
|
164
184
|
|
@@ -188,7 +208,7 @@
|
|
188
208
|
|
189
209
|
== 0.2.2 2007-06-01
|
190
210
|
* 1 bugfix:
|
191
|
-
* incorrect dependencies fixed
|
211
|
+
* incorrect dependencies fixed
|
192
212
|
|
193
213
|
== 0.2.0 2007-06-01
|
194
214
|
* 1 major enhancement:
|
data/lib/roo/excel.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
+
require 'rubygems'
|
1
2
|
require 'spreadsheet'
|
3
|
+
#require 'lib/roo/generic_spreadsheet'
|
4
|
+
#require 'parseexcel'
|
2
5
|
CHARGUESS = begin
|
3
6
|
require 'charguess'
|
4
7
|
true
|
@@ -9,6 +12,26 @@ end
|
|
9
12
|
# The Spreadsheet library has a bug in handling Excel
|
10
13
|
# base dates so if the file is a 1904 base date then
|
11
14
|
# dates are off by a day. 1900 base dates work fine
|
15
|
+
module Spreadsheet
|
16
|
+
module Excel
|
17
|
+
class Row < Spreadsheet::Row
|
18
|
+
def _date data # :nodoc:
|
19
|
+
return data if data.is_a?(Date)
|
20
|
+
date = @worksheet.date_base + data.to_i
|
21
|
+
if LEAP_ERROR > @worksheet.date_base
|
22
|
+
date -= 1
|
23
|
+
end
|
24
|
+
date
|
25
|
+
end
|
26
|
+
public :_datetime
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
#=====================================================================
|
32
|
+
# TODO:
|
33
|
+
# redefinition of this method, the method in the spreadsheet gem has a bug
|
34
|
+
# redefinition can be removed, if spreadsheet does it in the correct way
|
12
35
|
module Spreadsheet
|
13
36
|
module Excel
|
14
37
|
class Row < Spreadsheet::Row
|
@@ -38,45 +61,10 @@ module Spreadsheet
|
|
38
61
|
end
|
39
62
|
DateTime.new(date.year, date.month, date.day, hour, min, sec)
|
40
63
|
end
|
41
|
-
public :_date
|
42
|
-
public :_datetime
|
43
|
-
end
|
44
|
-
# patch for ruby-spreadsheet parsing formulas
|
45
|
-
class Reader
|
46
|
-
def read_formula worksheet, addr, work
|
47
|
-
row, column, xf, rtype, rval, rcheck, opts = work.unpack 'v3CxCx3v2'
|
48
|
-
formula = Formula.new
|
49
|
-
formula.shared = (opts & 0x08) > 0
|
50
|
-
formula.data = work[20..-1]
|
51
|
-
if rcheck != 0xffff || rtype > 3
|
52
|
-
value, = work.unpack 'x6E'
|
53
|
-
unless value
|
54
|
-
# on architectures where sizeof(double) > 8
|
55
|
-
value, = work.unpack 'x6e'
|
56
|
-
end
|
57
|
-
formula.value = value
|
58
|
-
elsif rtype == 0
|
59
|
-
pos, op, len, work = get_next_chunk
|
60
|
-
if op == :string
|
61
|
-
formula.value = client read_string(work, 2), @workbook.encoding
|
62
|
-
else
|
63
|
-
# This seems to work but I don't know why :). It at least
|
64
|
-
# seems to correct the case we saw but doubtful it's the right fix
|
65
|
-
formula.value = client read_string(work[10..-1], 2), @workbook.encoding
|
66
|
-
end
|
67
|
-
elsif rtype == 1
|
68
|
-
formula.value = rval > 0
|
69
|
-
elsif rtype == 2
|
70
|
-
formula.value = Error.new rval
|
71
|
-
else
|
72
|
-
# leave the Formula value blank
|
73
|
-
end
|
74
|
-
set_cell worksheet, row, column, xf, formula
|
75
|
-
end
|
76
64
|
end
|
77
65
|
end
|
78
66
|
end
|
79
|
-
|
67
|
+
#=====================================================================
|
80
68
|
|
81
69
|
# ruby-spreadsheet has a font object so we're extending it
|
82
70
|
# with our own functionality but still providing full access
|
@@ -86,9 +74,9 @@ module ExcelFontExtensions
|
|
86
74
|
#From ruby-spreadsheet doc: 100 <= weight <= 1000, bold => 700, normal => 400
|
87
75
|
case weight
|
88
76
|
when 700
|
89
|
-
|
77
|
+
true
|
90
78
|
else
|
91
|
-
|
79
|
+
false
|
92
80
|
end
|
93
81
|
end
|
94
82
|
|
@@ -134,6 +122,7 @@ class Excel < GenericSpreadsheet
|
|
134
122
|
#end
|
135
123
|
end
|
136
124
|
@cell = Hash.new
|
125
|
+
@read_first_100_rows = Hash.new
|
137
126
|
@cell_type = Hash.new
|
138
127
|
@formula = Hash.new
|
139
128
|
@first_row = Hash.new
|
@@ -158,8 +147,11 @@ class Excel < GenericSpreadsheet
|
|
158
147
|
def cell(row,col,sheet=nil)
|
159
148
|
sheet = @default_sheet unless sheet
|
160
149
|
raise ArgumentError unless sheet
|
161
|
-
|
162
|
-
|
150
|
+
unless @cells_read[sheet] or (@read_first_100_rows[sheet] and row < 100)
|
151
|
+
read_cells(sheet)
|
152
|
+
raise "should be read" unless @cells_read[sheet]
|
153
|
+
end
|
154
|
+
|
163
155
|
row,col = normalize(row,col)
|
164
156
|
if celltype(row,col,sheet) == :date
|
165
157
|
yyyy,mm,dd = @cell[sheet][[row,col]].split('-')
|
@@ -182,7 +174,9 @@ class Excel < GenericSpreadsheet
|
|
182
174
|
# * :datetime
|
183
175
|
def celltype(row,col,sheet=nil)
|
184
176
|
sheet = @default_sheet unless sheet
|
185
|
-
|
177
|
+
unless @cells_read[sheet] or (@read_first_100_rows[sheet] and row < 100)
|
178
|
+
read_cells(sheet)
|
179
|
+
end
|
186
180
|
row,col = normalize(row,col)
|
187
181
|
begin
|
188
182
|
if @formula[sheet][[row,col]]
|
@@ -227,6 +221,41 @@ class Excel < GenericSpreadsheet
|
|
227
221
|
@cell[sheet].inspect
|
228
222
|
end
|
229
223
|
|
224
|
+
# returns the row,col values of the labelled cell
|
225
|
+
# (nil,nil) if label is not defined
|
226
|
+
# sheet parameter is not really needed because label names are global
|
227
|
+
# to the whole spreadsheet
|
228
|
+
def label(labelname,sheet=nil)
|
229
|
+
sheet = @default_sheet unless sheet
|
230
|
+
read_cells(sheet) unless @cells_read[sheet]
|
231
|
+
if @labels.has_key? labelname
|
232
|
+
return @labels[labelname][1].to_i,
|
233
|
+
GenericSpreadsheet.letter_to_number(@labels[labelname][2]),
|
234
|
+
@labels[labelname][0]
|
235
|
+
else
|
236
|
+
return nil,nil,nil
|
237
|
+
end
|
238
|
+
end
|
239
|
+
def first_row(sheet=nil)
|
240
|
+
if sheet == nil
|
241
|
+
sheet = @default_sheet
|
242
|
+
end
|
243
|
+
read_first_100_rows(sheet) unless @read_first_100_rows[sheet] or @cells_read[sheet]
|
244
|
+
if @first_row[sheet]
|
245
|
+
return @first_row[sheet]
|
246
|
+
end
|
247
|
+
impossible_value = 999_999 # more than a spreadsheet can hold
|
248
|
+
result = impossible_value
|
249
|
+
@cell[sheet].each_pair {|key,value|
|
250
|
+
y,x = key # _to_string(key).split(',')
|
251
|
+
y = y.to_i
|
252
|
+
result = [result, y].min if value
|
253
|
+
} if @cell[sheet]
|
254
|
+
result = nil if result == impossible_value
|
255
|
+
@first_row[sheet] = result
|
256
|
+
result
|
257
|
+
end
|
258
|
+
|
230
259
|
private
|
231
260
|
|
232
261
|
# converts name of a sheet to index (0,1,2,..)
|
@@ -338,9 +367,14 @@ class Excel < GenericSpreadsheet
|
|
338
367
|
@cell[sheet][key] = v
|
339
368
|
end
|
340
369
|
end
|
341
|
-
|
370
|
+
|
371
|
+
def read_first_100_rows(sheet=nil)
|
372
|
+
read_cells(sheet, 100)
|
373
|
+
@cells_read[sheet] = false
|
374
|
+
@read_first_100_rows[sheet] = true
|
375
|
+
end
|
342
376
|
# read all cells in the selected sheet
|
343
|
-
def read_cells(sheet=nil)
|
377
|
+
def read_cells(sheet=nil, limit=nil)
|
344
378
|
sheet = @default_sheet unless sheet
|
345
379
|
raise ArgumentError, "Error: sheet '#{sheet||'nil'}' not valid" if @default_sheet == nil and sheet==nil
|
346
380
|
raise RangeError unless self.sheets.include? sheet
|
@@ -353,6 +387,7 @@ class Excel < GenericSpreadsheet
|
|
353
387
|
row_index=1
|
354
388
|
worksheet.each(0) do |row|
|
355
389
|
(0..row.size).each do |cell_index|
|
390
|
+
|
356
391
|
cell = row.at(cell_index)
|
357
392
|
next if cell.nil? #skip empty cells
|
358
393
|
next if cell.class == Spreadsheet::Formula && cell.value.nil? # skip empty formla cells
|
@@ -368,6 +403,9 @@ class Excel < GenericSpreadsheet
|
|
368
403
|
set_cell_values(sheet,row_index,col_index,0,v,vt,formula,tr,font)
|
369
404
|
end #row
|
370
405
|
row_index += 1
|
406
|
+
unless limit.nil? or (row_index < limit )
|
407
|
+
break
|
408
|
+
end
|
371
409
|
end # worksheet
|
372
410
|
@cells_read[sheet] = true
|
373
411
|
end
|
@@ -414,8 +452,8 @@ class Excel < GenericSpreadsheet
|
|
414
452
|
datetime = row.datetime(idx)
|
415
453
|
end
|
416
454
|
if datetime.hour != 0 or
|
417
|
-
|
418
|
-
|
455
|
+
datetime.min != 0 or
|
456
|
+
datetime.sec != 0
|
419
457
|
value_type = :datetime
|
420
458
|
value = datetime
|
421
459
|
else
|