roo 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +14 -0
- data/Manifest.txt +1 -0
- data/Rakefile +1 -0
- data/lib/roo/excel.rb +37 -13
- data/lib/roo/openoffice.rb +172 -75
- data/lib/roo/spreadsheetparser.rb +91 -0
- data/lib/roo/version.rb +1 -1
- data/test/numbers1.xls +0 -0
- data/test/test_roo.rb +171 -58
- data/website/index.html +76 -6
- data/website/index.txt +45 -4
- metadata +12 -2
data/History.txt
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
* 7 enhancements:
|
2
|
+
* robustness: Exception if no default_sheet was set
|
3
|
+
* new method reload() implemented
|
4
|
+
* about 15 % more method documentation
|
5
|
+
* optimization: huge increase of speed (no need to use fixed borders anymore)
|
6
|
+
* added the method 'formulas' which gives you all formulas in a spreadsheet
|
7
|
+
* added the method 'set' which can set cells to a certain value
|
8
|
+
* added the method 'to_yaml' which can produce output for importing in a (rails) database
|
9
|
+
* 4 bugfixes
|
10
|
+
* ..row_as_letter methods were nonsense - removed
|
11
|
+
* @cells_read should be reset if the default_sheet is changed
|
12
|
+
* error in excel-part: strings are now converted to utf-8 (the parsexcel-gem gave me an error with my test data, which could not converted to .to_s using latin1 encoding)
|
13
|
+
* fixed bug when default_sheet is changed
|
14
|
+
|
1
15
|
== 0.3.0 2007-06-20
|
2
16
|
* 1 enhancement:
|
3
17
|
* Openoffice: formula support
|
data/Manifest.txt
CHANGED
data/Rakefile
CHANGED
data/lib/roo/excel.rb
CHANGED
@@ -4,8 +4,13 @@ require 'parseexcel'
|
|
4
4
|
class Excel < Openoffice
|
5
5
|
|
6
6
|
def initialize(filename)
|
7
|
+
if filename[-4..-1] != ".xls"
|
8
|
+
warn "are you sure, this is an excel file?"
|
9
|
+
end
|
10
|
+
@filename = filename
|
7
11
|
@workbook = Spreadsheet::ParseExcel.parse(filename)
|
8
12
|
@default_sheet = nil
|
13
|
+
@first_row = @last_row = @first_column = @last_column = nil
|
9
14
|
end
|
10
15
|
|
11
16
|
# TODO: waiting for
|
@@ -26,16 +31,19 @@ class Excel < Openoffice
|
|
26
31
|
# im Excel-Bereich muesste man wahrscheinlich intern mit Nummern arbeiten
|
27
32
|
# von aussen arbeite ich mit (1,2,3... intern wird Index 0,1,2,...
|
28
33
|
# verwendet.
|
29
|
-
|
30
34
|
def default_sheet=(n)
|
31
35
|
unless n.kind_of?(Fixnum)
|
32
36
|
fail ArgumentError.new("Number expected")
|
33
37
|
end
|
34
38
|
@default_sheet = n-1
|
39
|
+
@first_row = @last_row = @first_column = @last_column = nil
|
40
|
+
@cells_read = false
|
35
41
|
end
|
36
42
|
|
43
|
+
# returns the content of a cell. The upper left corner is (1,1) or ('A',1)
|
37
44
|
def cell(row,col)
|
38
45
|
row,col = normalize(row,col)
|
46
|
+
default_sheet_check
|
39
47
|
worksheet = @workbook.worksheet(@default_sheet)
|
40
48
|
skip = 0
|
41
49
|
line = 1
|
@@ -45,23 +53,23 @@ class Excel < Openoffice
|
|
45
53
|
return nil
|
46
54
|
end
|
47
55
|
cell = row_par.at(col-1)
|
48
|
-
# p "celltype: "
|
49
|
-
# p cell.type
|
50
56
|
return nil unless cell
|
51
57
|
case cell.type
|
52
58
|
when :numeric then return cell.to_f
|
53
|
-
when :text then return cell.to_s('
|
59
|
+
when :text then return cell.to_s('utf-8')
|
54
60
|
when :date then return cell.date
|
55
61
|
else
|
56
|
-
return cell.to_s
|
62
|
+
return cell.to_s('utf-8')
|
57
63
|
end
|
58
64
|
end
|
59
65
|
line += 1
|
60
66
|
}
|
61
67
|
end
|
62
68
|
|
69
|
+
# returns the type of a cell: "float", "string", "date"
|
63
70
|
def celltype(row,col)
|
64
71
|
row,col = normalize(row,col)
|
72
|
+
default_sheet_check
|
65
73
|
worksheet = @workbook.worksheet(@default_sheet)
|
66
74
|
skip = 0
|
67
75
|
line = 1
|
@@ -80,17 +88,20 @@ class Excel < Openoffice
|
|
80
88
|
}
|
81
89
|
end
|
82
90
|
|
91
|
+
# return this row a an array off cells
|
83
92
|
def row(rownumber)
|
93
|
+
default_sheet_check
|
84
94
|
worksheet = @workbook.worksheet(@default_sheet)
|
85
95
|
therow = worksheet.row(rownumber-1)
|
86
96
|
result = []
|
87
97
|
therow.each {|cell|
|
88
98
|
case cell.type
|
89
99
|
when :numeric then result << cell.to_i
|
90
|
-
when :text then result << cell.to_s('
|
100
|
+
when :text then result << cell.to_s('utf-8')
|
91
101
|
when :date then result << cell.date
|
92
102
|
else
|
93
|
-
|
103
|
+
#p cell.type
|
104
|
+
return result << cell.to_s('utf-8')
|
94
105
|
end
|
95
106
|
|
96
107
|
#result << cell.value
|
@@ -98,42 +109,51 @@ class Excel < Openoffice
|
|
98
109
|
return result
|
99
110
|
end
|
100
111
|
|
112
|
+
# returns the first non empty column
|
101
113
|
def first_column
|
114
|
+
return @first_column if @first_column
|
102
115
|
fr, lr, fc, lc = get_firsts_lasts
|
103
116
|
fc
|
104
117
|
end
|
105
118
|
|
119
|
+
# returns the last non empty column
|
106
120
|
def last_column
|
121
|
+
return @last_column if @last_column
|
107
122
|
fr, lr, fc, lc = get_firsts_lasts
|
108
123
|
lc
|
109
124
|
end
|
110
125
|
|
126
|
+
# returns the first non empty row
|
111
127
|
def first_row
|
128
|
+
return @first_row if @first_row
|
112
129
|
fr, lr, fc, lc = get_firsts_lasts
|
113
130
|
fr
|
114
131
|
end
|
115
132
|
|
133
|
+
# returns the last non empty row
|
116
134
|
def last_row
|
135
|
+
return @last_row if @last_row
|
117
136
|
fr, lr, fc, lc = get_firsts_lasts
|
118
137
|
lr
|
119
138
|
end
|
120
139
|
|
140
|
+
# true if a cell is empty
|
121
141
|
def empty?(row, col)
|
122
142
|
row,col = normalize(row,col)
|
123
143
|
return true if row < first_row || row > last_row || col < first_column || col > last_column
|
124
|
-
# read_cells unless @cells_read
|
125
144
|
return true unless cell(row, col)
|
126
|
-
# p celltype(row,col)
|
127
|
-
#p cell(row,col)
|
128
145
|
return true if celltype(row, col) == "string" && cell(row, col) == ""
|
129
|
-
#when :text then return cell.to_s('latin1')
|
130
|
-
# p celltype(row,col)
|
131
|
-
# return true if cell(row, col) == ""
|
132
146
|
false
|
133
147
|
end
|
134
148
|
|
135
149
|
private
|
136
150
|
|
151
|
+
# check if default_sheet was set
|
152
|
+
def default_sheet_check
|
153
|
+
raise ArgumentError, "Error: default_sheet not set" if @default_sheet == nil
|
154
|
+
end
|
155
|
+
|
156
|
+
# determine the first and last boundaries
|
137
157
|
def get_firsts_lasts
|
138
158
|
fr = fc = 999_999
|
139
159
|
lr = lc = -999_999
|
@@ -159,6 +179,10 @@ private
|
|
159
179
|
end
|
160
180
|
line += 1
|
161
181
|
}
|
182
|
+
@first_row = fr
|
183
|
+
@last_row = lr
|
184
|
+
@first_column = fc
|
185
|
+
@last_column = lc
|
162
186
|
return fr, lr, fc, lc
|
163
187
|
end
|
164
188
|
|
data/lib/roo/openoffice.rb
CHANGED
@@ -4,18 +4,18 @@ require 'rexml/document'
|
|
4
4
|
require 'fileutils'
|
5
5
|
require 'zip/zipfilesystem'
|
6
6
|
require 'date'
|
7
|
+
require 'llip'
|
7
8
|
|
8
|
-
|
9
|
-
def as_letter
|
10
|
-
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"[self-1,1]
|
11
|
-
end
|
12
|
-
end
|
9
|
+
require 'lib/roo/spreadsheetparser'
|
13
10
|
|
14
11
|
class Openoffice
|
15
12
|
|
16
13
|
@@nr = 0
|
17
14
|
|
18
15
|
def initialize(filename)
|
16
|
+
if filename[-4..-1] != ".ods"
|
17
|
+
warn "are you sure, this is an openoffice file?"
|
18
|
+
end
|
19
19
|
@cells_read = false
|
20
20
|
@filename = filename
|
21
21
|
@tmpdir = "oo_"+$$.to_s
|
@@ -31,13 +31,16 @@ class Openoffice
|
|
31
31
|
@cell = Hash.new
|
32
32
|
@cell_type = Hash.new
|
33
33
|
@formula = Hash.new
|
34
|
-
if
|
34
|
+
# if ENV["roo_local"] != "thomas-p"
|
35
35
|
FileUtils::rm_r(@tmpdir)
|
36
|
-
end
|
36
|
+
# end
|
37
37
|
@default_sheet = nil
|
38
|
+
@first_column = @last_column = nil
|
39
|
+
@first_row = @last_row = nil
|
38
40
|
end
|
39
41
|
|
40
42
|
# reopens and read a spreadsheet document
|
43
|
+
if false
|
41
44
|
def reload
|
42
45
|
@cells_read = false
|
43
46
|
@tmpdir = "oo_"+$$.to_s
|
@@ -52,9 +55,20 @@ class Openoffice
|
|
52
55
|
@cell_type = Hash.new
|
53
56
|
FileUtils::rm_r(@tmpdir)
|
54
57
|
@default_sheet = nil
|
58
|
+
@first_column = @last_column = nil
|
59
|
+
@first_row = @last_row = nil
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def reload
|
64
|
+
default_sheet = @default_sheet
|
65
|
+
initialize(@filename)
|
66
|
+
self.default_sheet = default_sheet
|
67
|
+
@first_row = @last_row = @first_column = @last_column = nil
|
68
|
+
|
55
69
|
end
|
56
70
|
|
57
|
-
#
|
71
|
+
# returns the content of a spreadsheet-cell
|
58
72
|
# (1,1) is the upper left corner
|
59
73
|
# (1,1), (1,'A'), ('A',1), ('a',1) all refers to the
|
60
74
|
# cell at first line, first row
|
@@ -69,6 +83,7 @@ class Openoffice
|
|
69
83
|
end
|
70
84
|
|
71
85
|
# returns the formula at (row,col)
|
86
|
+
# nil if there is no formula
|
72
87
|
def formula(row,col)
|
73
88
|
read_cells unless @cells_read
|
74
89
|
row,col = normalize(row,col)
|
@@ -79,21 +94,33 @@ class Openoffice
|
|
79
94
|
end
|
80
95
|
end
|
81
96
|
|
97
|
+
# true, if there is a formula
|
82
98
|
def formula?(row,col)
|
99
|
+
read_cells unless @cells_read
|
100
|
+
row,col = normalize(row,col)
|
83
101
|
formula(row,col) != nil
|
84
102
|
end
|
85
103
|
|
104
|
+
# set a cell to a certain value
|
105
|
+
# (this will not be saved back to the spreadsheet file!)
|
86
106
|
def set(row,col,value)
|
87
|
-
|
88
|
-
|
107
|
+
row,col = normalize(row,col)
|
108
|
+
set_value(row,col,value)
|
109
|
+
if value.class == Fixnum
|
110
|
+
set_type(row,col,:float)
|
111
|
+
elsif value.class == String
|
112
|
+
set_type(row,col,:string)
|
113
|
+
elsif value.class == Float
|
114
|
+
set_type(row,col,:string)
|
115
|
+
else
|
116
|
+
raise ArgumentError, "Typ fuer "+value.to_s+" nicht gesetzt"
|
117
|
+
end
|
89
118
|
end
|
90
119
|
|
91
120
|
# returns the open-office type of a cell
|
92
121
|
def celltype(row,col)
|
93
122
|
read_cells unless @cells_read
|
94
123
|
row,col = normalize(row,col)
|
95
|
-
|
96
|
-
# p @formula["#{row},#{col}"]
|
97
124
|
if @formula["#{row},#{col}"]
|
98
125
|
return :formula
|
99
126
|
else
|
@@ -101,8 +128,7 @@ class Openoffice
|
|
101
128
|
end
|
102
129
|
end
|
103
130
|
|
104
|
-
|
105
|
-
# returns an array of sheets in the spreadsheet
|
131
|
+
# returns an array of sheet names in the spreadsheet
|
106
132
|
def sheets
|
107
133
|
return_sheets = []
|
108
134
|
oo_document_count = 0
|
@@ -130,11 +156,17 @@ class Openoffice
|
|
130
156
|
# set the working sheet in the document
|
131
157
|
def default_sheet=(s)
|
132
158
|
@default_sheet = s
|
159
|
+
@first_row = @last_row = @first_column = @last_column = nil
|
160
|
+
@cells_read = false
|
161
|
+
@cell = Hash.new
|
162
|
+
@cell_type = Hash.new
|
163
|
+
@formula = Hash.new
|
133
164
|
end
|
134
165
|
|
135
166
|
# version of the openoffice document
|
167
|
+
# at 2007 this is always "1.0"
|
136
168
|
def officeversion
|
137
|
-
read_cells unless @cells_read
|
169
|
+
read_cells(:ignore_default_sheet => true) unless @cells_read
|
138
170
|
@officeversion
|
139
171
|
end
|
140
172
|
|
@@ -152,7 +184,6 @@ class Openoffice
|
|
152
184
|
result = []
|
153
185
|
tmp_arr = []
|
154
186
|
@cell.each_pair {|key,value|
|
155
|
-
|
156
187
|
y,x = key.split(',')
|
157
188
|
x = x.to_i
|
158
189
|
y = y.to_i
|
@@ -170,81 +201,86 @@ class Openoffice
|
|
170
201
|
# returns the number of the last non-empty row
|
171
202
|
def last_row
|
172
203
|
read_cells unless @cells_read
|
173
|
-
|
204
|
+
if @last_row
|
205
|
+
return @last_row
|
206
|
+
end
|
207
|
+
impossible_value = 0
|
208
|
+
result = impossible_value
|
174
209
|
@cell.each_pair {|key,value|
|
175
210
|
y,x = key.split(',')
|
176
211
|
y = y.to_i
|
177
212
|
result = [result, y].max if value
|
178
213
|
}
|
214
|
+
result = nil if result == impossible_value
|
215
|
+
@last_row = result
|
179
216
|
result
|
180
217
|
end
|
181
218
|
|
182
219
|
# returns the number of the last non-empty column
|
183
220
|
def last_column
|
184
221
|
read_cells unless @cells_read
|
185
|
-
|
222
|
+
if @last_column
|
223
|
+
return @last_column
|
224
|
+
end
|
225
|
+
impossible_value = 0
|
226
|
+
result = impossible_value
|
186
227
|
@cell.each_pair {|key,value|
|
187
228
|
y,x = key.split(',')
|
188
229
|
x = x.to_i
|
189
230
|
result = [result, x].max if value
|
190
231
|
}
|
232
|
+
result = nil if result == impossible_value
|
233
|
+
@last_column = result
|
191
234
|
result
|
192
235
|
end
|
193
236
|
|
194
237
|
# returns the number of the first non-empty row
|
195
238
|
def first_row
|
196
239
|
read_cells unless @cells_read
|
197
|
-
|
240
|
+
if @first_row
|
241
|
+
return @first_row
|
242
|
+
end
|
243
|
+
impossible_value = 999_999 # more than a spreadsheet can hold
|
244
|
+
result = impossible_value
|
198
245
|
@cell.each_pair {|key,value|
|
199
246
|
y,x = key.split(',')
|
200
247
|
y = y.to_i
|
201
248
|
result = [result, y].min if value
|
202
249
|
}
|
250
|
+
result = nil if result == impossible_value
|
251
|
+
@first_row = result
|
203
252
|
result
|
204
253
|
end
|
205
254
|
|
206
255
|
# returns the number of the first non-empty column
|
207
256
|
def first_column
|
208
257
|
read_cells unless @cells_read
|
209
|
-
|
258
|
+
if @first_column
|
259
|
+
return @first_column
|
260
|
+
end
|
261
|
+
impossible_value = 999_999 # more than a spreadsheet can hold
|
262
|
+
result = impossible_value
|
210
263
|
@cell.each_pair {|key,value|
|
211
264
|
y,x = key.split(',')
|
212
265
|
x = x.to_i
|
213
266
|
result = [result, x].min if value
|
214
267
|
}
|
268
|
+
result = nil if result == impossible_value
|
269
|
+
@first_column = result
|
215
270
|
result
|
216
271
|
end
|
217
272
|
|
273
|
+
# first non-empty column as a letter
|
218
274
|
def first_column_as_letter
|
219
|
-
number_to_letter(first_column)
|
275
|
+
Openoffice.number_to_letter(first_column)
|
220
276
|
end
|
221
277
|
|
278
|
+
# last non-empty column as a letter
|
222
279
|
def last_column_as_letter
|
223
|
-
number_to_letter(last_column)
|
224
|
-
end
|
225
|
-
|
226
|
-
def first_row_as_letter
|
227
|
-
number_to_letter(first_row)
|
228
|
-
end
|
229
|
-
|
230
|
-
def last_row_as_letter
|
231
|
-
number_to_letter(last_row)
|
232
|
-
end
|
233
|
-
|
234
|
-
def as_letter(n)
|
235
|
-
number_to_letter(last_row)
|
236
|
-
end
|
237
|
-
|
238
|
-
def number_to_letter(n)
|
239
|
-
letters=""
|
240
|
-
while n > 0
|
241
|
-
num = n%26
|
242
|
-
letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[num-1,1] + letters
|
243
|
-
n = n.div(26)
|
244
|
-
end
|
245
|
-
letters
|
280
|
+
Openoffice.number_to_letter(last_column)
|
246
281
|
end
|
247
282
|
|
283
|
+
# true if cell is empty
|
248
284
|
def empty?(row, col)
|
249
285
|
read_cells unless @cells_read
|
250
286
|
return true unless cell(row, col)
|
@@ -252,25 +288,72 @@ class Openoffice
|
|
252
288
|
false
|
253
289
|
end
|
254
290
|
|
255
|
-
|
256
|
-
|
257
|
-
while letters && letters.length > 0
|
258
|
-
character = letters[0,1].upcase
|
259
|
-
num = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".index(character)+1
|
260
|
-
result = result * 26 + num
|
261
|
-
letters = letters[1..-1]
|
262
|
-
end
|
263
|
-
result
|
264
|
-
end
|
265
|
-
|
291
|
+
=begin
|
292
|
+
# save spreadsheet
|
266
293
|
def save
|
267
294
|
42
|
268
295
|
end
|
296
|
+
=end
|
297
|
+
|
298
|
+
# evaluate the formula at this cell
|
299
|
+
# experimental: DO NOT USE THIS!
|
300
|
+
def solve(row,col)
|
301
|
+
parser = SpreadsheetParser.new
|
302
|
+
visitor = Visitor.new
|
303
|
+
#puts cell(row,col)
|
304
|
+
puts formula(row,col)
|
305
|
+
formula = formula(row,col)[1..-1] # .downcase
|
306
|
+
puts formula
|
307
|
+
#eval formula
|
308
|
+
#parser.parse(formula)
|
309
|
+
parser.parse(formula).accept(visitor)
|
310
|
+
end
|
311
|
+
|
312
|
+
# returns each formula in the selected sheet as an array of elements
|
313
|
+
# [row, col, formula]
|
314
|
+
def formulas
|
315
|
+
theformulas = Array.new
|
316
|
+
read_cells unless @cells_read
|
317
|
+
first_row.upto(last_row) {|row|
|
318
|
+
first_column.upto(last_column) {|col|
|
319
|
+
if formula?(row,col)
|
320
|
+
f = [row, col, formula(row,col)]
|
321
|
+
theformulas << f
|
322
|
+
end
|
323
|
+
}
|
324
|
+
}
|
325
|
+
theformulas
|
326
|
+
end
|
327
|
+
|
328
|
+
# returns a rectangular area (default: all cells) as yaml-output
|
329
|
+
# you can add additional attributes with the prefix parameter like:
|
330
|
+
# oo.to_yaml({"file"=>"flightdata_2007-06-26", "sheet" => "1"})
|
331
|
+
def to_yaml(prefix={}, from_row=nil, from_column=nil, to_row=nil, to_column=nil)
|
332
|
+
result = "--- \n"
|
333
|
+
(from_row||first_row).upto(to_row||last_row) do |row|
|
334
|
+
(from_column||first_column).upto(to_column||last_column) do |col|
|
335
|
+
unless self.empty?(row,col)
|
336
|
+
result << "cell_#{row}_#{col}: \n"
|
337
|
+
prefix.each {|k,v|
|
338
|
+
result << " #{k}: #{v} \n"
|
339
|
+
}
|
340
|
+
result << " row: #{row} \n"
|
341
|
+
result << " col: #{col} \n"
|
342
|
+
result << " celltype: #{self.celltype(row,col)} \n"
|
343
|
+
result << " value: #{self.cell(row,col)} \n"
|
344
|
+
end
|
345
|
+
end
|
346
|
+
end
|
347
|
+
result
|
348
|
+
end
|
269
349
|
|
270
350
|
private
|
271
351
|
|
272
352
|
# read all cells in the selected sheet
|
273
|
-
def read_cells
|
353
|
+
def read_cells(*args)
|
354
|
+
if :ignore_default_sheet == false
|
355
|
+
raise ArgumentError, "Error: default_sheet not set" if @default_sheet == nil
|
356
|
+
end
|
274
357
|
oo_document_count = 0
|
275
358
|
@doc.each_element do |oo_document|
|
276
359
|
@officeversion = oo_document.attributes['version']
|
@@ -278,35 +361,24 @@ private
|
|
278
361
|
oo_element_count = 0
|
279
362
|
oo_document.each_element do |oo_element|
|
280
363
|
oo_element_count += 1
|
281
|
-
# p oo_element.name
|
282
364
|
if oo_element.name == "body"
|
283
|
-
# puts "Body gefunden "
|
284
365
|
oo_element.each_element do |be|
|
285
|
-
# p be.name
|
286
366
|
if be.name == "spreadsheet"
|
287
367
|
be.each_element do |se|
|
288
|
-
# p se
|
289
368
|
if se.name == "table"
|
290
369
|
if se.attributes['name']==@default_sheet
|
291
370
|
|
292
371
|
x=1
|
293
372
|
y=1
|
294
|
-
# puts "table gefunden"
|
295
|
-
#se.each_element
|
296
373
|
se.each_element do |te|
|
297
|
-
# p te.name
|
298
374
|
if te.name == "table-column"
|
299
|
-
# p te.attributes
|
300
375
|
rep = te.attributes["number-columns-repeated"]
|
301
|
-
# p "rep = "+rep.to_s
|
302
376
|
elsif te.name == "table-row"
|
303
377
|
if te.attributes['number-rows-repeated']
|
304
378
|
skip_y = te.attributes['number-rows-repeated'].to_i
|
305
379
|
y = y + skip_y - 1 # minus 1 because this line will be counted as a line element
|
306
380
|
end
|
307
|
-
# p te
|
308
381
|
te.each_element do |tr|
|
309
|
-
# p tr
|
310
382
|
if tr.name == 'table-cell'
|
311
383
|
skip = tr.attributes['number-columns-repeated']
|
312
384
|
formula = tr.attributes['formula']
|
@@ -329,14 +401,7 @@ private
|
|
329
401
|
if @cell_type["#{y},#{x+i}"] == 'float'
|
330
402
|
@cell["#{y},#{x+i}"] = v.to_f
|
331
403
|
elsif @cell_type["#{y},#{x+i}"] == 'string'
|
332
|
-
# puts "in string zweig..."
|
333
|
-
#tr.each_element do |str|
|
334
|
-
# if str.name == 'p'
|
335
|
-
# @cell["#{y},#{x+i}"] = str.text
|
336
|
-
# end
|
337
|
-
#end
|
338
404
|
@cell["#{y},#{x+i}"] = v
|
339
|
-
|
340
405
|
elsif @cell_type["#{y},#{x+i}"] == 'date'
|
341
406
|
@cell["#{y},#{x+i}"] = tr.attributes['date-value']
|
342
407
|
else
|
@@ -420,4 +485,36 @@ private
|
|
420
485
|
return row,col
|
421
486
|
end
|
422
487
|
|
423
|
-
|
488
|
+
# convert a number to something like this: 'AB'
|
489
|
+
def Openoffice.number_to_letter(n)
|
490
|
+
letters=""
|
491
|
+
while n > 0
|
492
|
+
num = n%26
|
493
|
+
letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[num-1,1] + letters
|
494
|
+
n = n.div(26)
|
495
|
+
end
|
496
|
+
letters
|
497
|
+
end
|
498
|
+
|
499
|
+
# convert letters like 'AB' to a number
|
500
|
+
def Openoffice.letter_to_number(letters)
|
501
|
+
result = 0
|
502
|
+
while letters && letters.length > 0
|
503
|
+
character = letters[0,1].upcase
|
504
|
+
num = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".index(character)+1
|
505
|
+
result = result * 26 + num
|
506
|
+
letters = letters[1..-1]
|
507
|
+
end
|
508
|
+
result
|
509
|
+
end
|
510
|
+
|
511
|
+
|
512
|
+
def set_value(row,col,value)
|
513
|
+
@cell["#{row},#{col}"] = value
|
514
|
+
end
|
515
|
+
|
516
|
+
def set_type(row,col,type)
|
517
|
+
@cell_type["#{row},#{col}"] = type
|
518
|
+
end
|
519
|
+
|
520
|
+
end # class
|
@@ -0,0 +1,91 @@
|
|
1
|
+
=begin
|
2
|
+
This is experimental. Please do not use it. IT WILL NOT WORK
|
3
|
+
I don't know if i will extend the work on the evaluation of formulas.
|
4
|
+
You can access all formulas as a string and do whatever you want with this.
|
5
|
+
=end
|
6
|
+
|
7
|
+
require 'llip'
|
8
|
+
require 'llip/visitable'
|
9
|
+
|
10
|
+
class Formula
|
11
|
+
include LLIP::Visitable
|
12
|
+
|
13
|
+
attr_accessor :name
|
14
|
+
attr_accessor :params
|
15
|
+
end
|
16
|
+
|
17
|
+
class Param
|
18
|
+
include LLIP::Visitable
|
19
|
+
|
20
|
+
attr_accessor :column_name
|
21
|
+
end
|
22
|
+
|
23
|
+
class Visitor
|
24
|
+
def visit_formula(formula)
|
25
|
+
puts " -- " + formula.name
|
26
|
+
formula.params.each { |p| p.accept(self) }
|
27
|
+
end
|
28
|
+
|
29
|
+
def visit_param(param)
|
30
|
+
puts " |-- " + param.column_name
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class SpreadsheetParser < LLIP::Parser
|
35
|
+
letters = ("A".."Z").to_a.join("|")
|
36
|
+
|
37
|
+
token :id, "(#{letters})+"
|
38
|
+
|
39
|
+
token :"(", '\('
|
40
|
+
|
41
|
+
token :")", '\)'
|
42
|
+
|
43
|
+
token :"[", '['
|
44
|
+
token :"]", ']'
|
45
|
+
token :".", '.'
|
46
|
+
|
47
|
+
num = (1..9).to_a.join("|")
|
48
|
+
token :num , "(#{num})(#{num}|0)*"
|
49
|
+
|
50
|
+
token :sep, ":"
|
51
|
+
|
52
|
+
scope :formula
|
53
|
+
|
54
|
+
production :formula do |p|
|
55
|
+
p.token(:id) do |result,scanner,parser|
|
56
|
+
result = Formula.new
|
57
|
+
result.name = scanner.current
|
58
|
+
puts "<"+result.name+">"
|
59
|
+
raise unless scanner.next == :"("
|
60
|
+
raise unless scanner.next == :"["
|
61
|
+
scanner.next
|
62
|
+
result.params = parser.parse_params
|
63
|
+
raise unless scanner.current == :"]"
|
64
|
+
raise unless scanner.current == :")"
|
65
|
+
scanner.next
|
66
|
+
result
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
production :params, :recursive do |p|
|
71
|
+
p.default do |scanner, parser|
|
72
|
+
[]
|
73
|
+
end
|
74
|
+
|
75
|
+
p.token(:id) do |result, scanner, parser|
|
76
|
+
param = Param.new
|
77
|
+
param.column_name = scanner.current.to_s
|
78
|
+
raise unless scanner.next == :"."
|
79
|
+
raise unless scanner.next == :num
|
80
|
+
param.column_name += scanner.current.to_s
|
81
|
+
scanner.next
|
82
|
+
result << param
|
83
|
+
end
|
84
|
+
|
85
|
+
p.token(:sep) do |result,scanner,parser|
|
86
|
+
scanner.next
|
87
|
+
result
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
data/lib/roo/version.rb
CHANGED
data/test/numbers1.xls
CHANGED
Binary file
|
data/test/test_roo.rb
CHANGED
@@ -190,6 +190,7 @@ end
|
|
190
190
|
|
191
191
|
assert_equal "thisisd9", oo.cell('d',9)
|
192
192
|
assert_equal "thisisa11", oo.cell('a',11)
|
193
|
+
#assert_equal "lulua", oo.cell('b',10)
|
193
194
|
end
|
194
195
|
|
195
196
|
if GOOGLE
|
@@ -430,8 +431,6 @@ end
|
|
430
431
|
assert_equal 5, oo.first_row
|
431
432
|
assert_equal 'E', oo.last_column_as_letter
|
432
433
|
assert_equal 14, oo.last_row
|
433
|
-
assert_equal 'E', oo.first_row_as_letter
|
434
|
-
assert_equal 'N', oo.last_row_as_letter
|
435
434
|
if EXCEL
|
436
435
|
#-- Excel
|
437
436
|
oo = Excel.new(File.join("test","numbers1.xls"))
|
@@ -441,8 +440,6 @@ end
|
|
441
440
|
assert_equal 5, oo.first_row
|
442
441
|
assert_equal 'E', oo.last_column_as_letter
|
443
442
|
assert_equal 14, oo.last_row
|
444
|
-
assert_equal 'E', oo.first_row_as_letter
|
445
|
-
assert_equal 'N', oo.last_row_as_letter
|
446
443
|
end
|
447
444
|
end
|
448
445
|
|
@@ -537,14 +534,22 @@ end
|
|
537
534
|
end
|
538
535
|
|
539
536
|
def test_reload
|
540
|
-
|
541
|
-
|
542
|
-
|
537
|
+
if OPENOFFICE
|
538
|
+
oo = Openoffice.new(File.join("test","numbers1.ods"))
|
539
|
+
oo.default_sheet = oo.sheets.first
|
540
|
+
assert_equal 1, oo.cell(1,1)
|
543
541
|
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
542
|
+
oo.reload
|
543
|
+
assert_equal 1, oo.cell(1,1)
|
544
|
+
end
|
545
|
+
if EXCEL
|
546
|
+
oo = Excel.new(File.join("test","numbers1.xls"))
|
547
|
+
oo.default_sheet = 1 # oo.sheets.first
|
548
|
+
assert_equal 1, oo.cell(1,1)
|
549
|
+
|
550
|
+
oo.reload
|
551
|
+
assert_equal 1, oo.cell(1,1)
|
552
|
+
end
|
548
553
|
end
|
549
554
|
|
550
555
|
def test_bug_contiguous_cells
|
@@ -687,59 +692,167 @@ end
|
|
687
692
|
end
|
688
693
|
end
|
689
694
|
|
695
|
+
def myfunc(n)
|
696
|
+
puts "#{n} Euro"
|
697
|
+
end
|
690
698
|
|
691
699
|
def test_formula
|
700
|
+
if OPENOFFICE
|
701
|
+
oo = Openoffice.new(File.join("test","formula.ods"))
|
702
|
+
oo.default_sheet = oo.sheets.first
|
703
|
+
assert_equal 1, oo.cell('A',1)
|
704
|
+
assert_equal 2, oo.cell('A',2)
|
705
|
+
assert_equal 3, oo.cell('A',3)
|
706
|
+
assert_equal 4, oo.cell('A',4)
|
707
|
+
assert_equal 5, oo.cell('A',5)
|
708
|
+
assert_equal 6, oo.cell('A',6)
|
709
|
+
assert_equal 21, oo.cell('A',7)
|
710
|
+
assert_equal :formula, oo.celltype('A',7)
|
711
|
+
assert_equal "=[Sheet2.A1]", oo.formula('C',7)
|
712
|
+
assert_nil oo.formula('A',6)
|
713
|
+
assert_equal [[7, 1, "=SUM([.A1:.A6])"],
|
714
|
+
[7, 2, "=SUM([.$A$1:.B6])"],
|
715
|
+
[7, 3, "=[Sheet2.A1]"],
|
716
|
+
[8, 2, "=SUM([.$A$1:.B7])"],
|
717
|
+
], oo.formulas
|
692
718
|
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
719
|
+
if DateTime.now > Date.new(2007,6,25)
|
720
|
+
# setting a cell
|
721
|
+
oo.set('A',15, 41)
|
722
|
+
assert_equal 41, oo.cell('A',15)
|
723
|
+
oo.set('A',16, "41")
|
724
|
+
assert_equal "41", oo.cell('A',16)
|
725
|
+
oo.set('A',17, 42.5)
|
726
|
+
assert_equal 42.5, oo.cell('A',17)
|
727
|
+
end
|
728
|
+
if DateTime.now > Date.new(2007,6,30)
|
729
|
+
assert_equal 21, oo.solve('a',7)
|
730
|
+
end
|
731
|
+
|
732
|
+
oo = Openoffice.new(File.join("test","external1.ods"))
|
733
|
+
# each spreadsheet, each row, each column
|
734
|
+
oo.sheets.each {|sheet|
|
735
|
+
oo.default_sheet = sheet
|
736
|
+
if oo.first_row
|
737
|
+
oo.first_row.upto(oo.last_row) do |row|
|
738
|
+
oo.first_column.upto(oo.last_column) do |col|
|
739
|
+
value = oo.cell(row,col)
|
740
|
+
# is it a formula?
|
741
|
+
if oo.formula?(row,col)
|
742
|
+
# formula
|
743
|
+
puts oo.formula(row,col)
|
744
|
+
# value
|
745
|
+
puts value if value
|
746
|
+
else
|
747
|
+
puts value if value
|
748
|
+
end
|
749
|
+
end
|
724
750
|
end
|
725
751
|
end
|
726
|
-
|
727
|
-
}
|
728
|
-
if false
|
729
|
-
oo = Excel.new(File.join("test","formula.xls"))
|
730
|
-
oo.default_sheet = 1 # oo.sheets.first
|
731
|
-
assert_equal 1, oo.cell('A',1)
|
732
|
-
assert_equal 2, oo.cell('A',2)
|
733
|
-
assert_equal 3, oo.cell('A',3)
|
734
|
-
assert_equal 4, oo.cell('A',4)
|
735
|
-
assert_equal 5, oo.cell('A',5)
|
736
|
-
assert_equal 6, oo.cell('A',6)
|
737
|
-
assert_equal 21, oo.cell('A',7), oo.cell('A',7).to_yaml
|
738
|
-
assert_equal :formula, oo.celltype('A',7)
|
739
|
-
assert_equal "=SUM(A1:A6)", oo.formula('A',7)
|
740
|
-
assert_equal "=SUM(A1:A6)", oo.formula('B',7)
|
741
|
-
assert_nil oo.formula('A',6)
|
752
|
+
}
|
742
753
|
end
|
754
|
+
end
|
755
|
+
|
756
|
+
|
757
|
+
def test_borders_sheets
|
758
|
+
if OPENOFFICE
|
759
|
+
oo = Openoffice.new(File.join("test","borders.ods"))
|
760
|
+
oo.default_sheet = oo.sheets[1]
|
761
|
+
assert_equal 6, oo.first_row
|
762
|
+
assert_equal 11, oo.last_row
|
763
|
+
assert_equal 4, oo.first_column
|
764
|
+
assert_equal 8, oo.last_column
|
743
765
|
|
766
|
+
oo.default_sheet = oo.sheets.first
|
767
|
+
#assert_nil oo.first_row
|
768
|
+
assert_equal 5, oo.first_row
|
769
|
+
#assert_nil oo.last_row
|
770
|
+
assert_equal 10, oo.last_row
|
771
|
+
assert_equal 3, oo.first_column
|
772
|
+
#assert_nil oo.first_column
|
773
|
+
assert_equal 7, oo.last_column
|
774
|
+
#assert_nil oo.last_column
|
775
|
+
|
776
|
+
oo.default_sheet = oo.sheets[2]
|
777
|
+
assert_equal 7, oo.first_row
|
778
|
+
assert_equal 12, oo.last_row
|
779
|
+
assert_equal 5, oo.first_column
|
780
|
+
assert_equal 9, oo.last_column
|
781
|
+
end
|
782
|
+
if EXCEL
|
783
|
+
oo = Excel.new(File.join("test","borders.xls"))
|
784
|
+
oo.default_sheet = 2 # oo.sheets[1]
|
785
|
+
assert_equal 6, oo.first_row
|
786
|
+
assert_equal 11, oo.last_row
|
787
|
+
assert_equal 4, oo.first_column
|
788
|
+
assert_equal 8, oo.last_column
|
789
|
+
|
790
|
+
oo.default_sheet = 1 # oo.sheets.first
|
791
|
+
#assert_nil oo.first_row
|
792
|
+
assert_equal 5, oo.first_row
|
793
|
+
#assert_nil oo.last_row
|
794
|
+
assert_equal 10, oo.last_row
|
795
|
+
assert_equal 3, oo.first_column
|
796
|
+
#assert_nil oo.first_column
|
797
|
+
assert_equal 7, oo.last_column
|
798
|
+
#assert_nil oo.last_column
|
799
|
+
|
800
|
+
oo.default_sheet = 3 # oo.sheets[2]
|
801
|
+
assert_equal 7, oo.first_row
|
802
|
+
assert_equal 12, oo.last_row
|
803
|
+
assert_equal 5, oo.first_column
|
804
|
+
assert_equal 9, oo.last_column
|
805
|
+
end
|
806
|
+
|
744
807
|
end
|
808
|
+
|
809
|
+
def yaml_entry(row,col,type,value)
|
810
|
+
"cell_#{row}_#{col}: \n row: #{row} \n col: #{col} \n celltype: #{type} \n value: #{value} \n"
|
811
|
+
end
|
812
|
+
|
813
|
+
def test_to_yaml
|
814
|
+
if OPENOFFICE
|
815
|
+
oo = Openoffice.new(File.join("test","numbers1.ods"))
|
816
|
+
oo.default_sheet = oo.sheets.first
|
817
|
+
assert_equal "--- \n"+yaml_entry(5,1,"date","1961-11-21"), oo.to_yaml({}, 5,1,5,1)
|
818
|
+
assert_equal "--- \n"+yaml_entry(8,3,"string","thisisc8"), oo.to_yaml({}, 8,3,8,3)
|
819
|
+
assert_equal "--- \n"+yaml_entry(12,3,"float",43.0), oo.to_yaml({}, 12,3,12,3)
|
820
|
+
assert_equal \
|
821
|
+
"--- \n"+yaml_entry(12,3,"float",43.0) +
|
822
|
+
yaml_entry(12,4,"float",44.0) +
|
823
|
+
yaml_entry(12,5,"float",45.0), oo.to_yaml({}, 12,3,12)
|
824
|
+
assert_equal \
|
825
|
+
"--- \n"+yaml_entry(12,3,"float",43.0)+
|
826
|
+
yaml_entry(12,4,"float",44.0)+
|
827
|
+
yaml_entry(12,5,"float",45.0)+
|
828
|
+
yaml_entry(15,3,"float",43.0)+
|
829
|
+
yaml_entry(15,4,"float",44.0)+
|
830
|
+
yaml_entry(15,5,"float",45.0)+
|
831
|
+
yaml_entry(16,3,"string","dreiundvierzig")+
|
832
|
+
yaml_entry(16,4,"string","vierundvierzig")+
|
833
|
+
yaml_entry(16,5,"string","fuenfundvierzig"), oo.to_yaml({}, 12,3)
|
834
|
+
end
|
835
|
+
if EXCEL
|
836
|
+
oo = Excel.new(File.join("test","numbers1.xls"))
|
837
|
+
oo.default_sheet = 1
|
838
|
+
assert_equal "--- \n"+yaml_entry(5,1,"date","1961-11-21"), oo.to_yaml({}, 5,1,5,1)
|
839
|
+
assert_equal "--- \n"+yaml_entry(8,3,"string","thisisc8"), oo.to_yaml({}, 8,3,8,3)
|
840
|
+
assert_equal "--- \n"+yaml_entry(12,3,"float",43.0), oo.to_yaml({}, 12,3,12,3)
|
841
|
+
assert_equal \
|
842
|
+
"--- \n"+yaml_entry(12,3,"float",43.0) +
|
843
|
+
yaml_entry(12,4,"float",44.0) +
|
844
|
+
yaml_entry(12,5,"float",45.0), oo.to_yaml({}, 12,3,12)
|
845
|
+
assert_equal \
|
846
|
+
"--- \n"+yaml_entry(12,3,"float",43.0)+
|
847
|
+
yaml_entry(12,4,"float",44.0)+
|
848
|
+
yaml_entry(12,5,"float",45.0)+
|
849
|
+
yaml_entry(15,3,"float",43.0)+
|
850
|
+
yaml_entry(15,4,"float",44.0)+
|
851
|
+
yaml_entry(15,5,"float",45.0)+
|
852
|
+
yaml_entry(16,3,"string","dreiundvierzig")+
|
853
|
+
yaml_entry(16,4,"string","vierundvierzig")+
|
854
|
+
yaml_entry(16,5,"string","fuenfundvierzig"), oo.to_yaml({}, 12,3)
|
855
|
+
end
|
856
|
+
end
|
857
|
+
|
745
858
|
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.
|
36
|
+
<a href="http://rubyforge.org/projects/roo" class="numbers">0.4.0</a>
|
37
37
|
</div>
|
38
38
|
<h2>What</h2>
|
39
39
|
|
@@ -146,16 +146,49 @@
|
|
146
146
|
<p>oo.celltype(row,col) returns :formula if there is a formula in this cell.</p>
|
147
147
|
|
148
148
|
|
149
|
-
<p>oo.formula(row,col) returns
|
150
|
-
|
149
|
+
<p>oo.formula?(row,col) returns true if there is a formula</p>
|
150
|
+
|
151
|
+
|
152
|
+
<p>oo.formula(row,col) returns the formula in this cell in a string variable (like ”=<acronym title="[.A1:.M13]">SUM</acronym>”). You can do whatever you want with this expression.
|
153
|
+
If there is no formula in this cell nil is returned.</p>
|
151
154
|
|
152
155
|
|
153
156
|
<p>oo.cell(row,col) returns the computed result of the formula (as it was saved in the file, no recalculation is done in this Gem).</p>
|
154
157
|
|
155
158
|
|
159
|
+
<p>oo.formulas returns all formulas in the selected spreadsheet in an array like this:</p>
|
160
|
+
|
161
|
+
|
162
|
+
<p>Each entry consists of the elements row, col, formual.</p>
|
163
|
+
|
164
|
+
|
165
|
+
<p>Note: oo.cell(row,col) is the same for ordinary cells and formulas. So you can use the computated value of a formula. If you have to distinguish if a cell is a formula use #formula?</p>
|
166
|
+
|
167
|
+
|
156
168
|
<p>Please note: formulas in Excel-Spreadsheets cannot be handled (this is another gem, see: “Thanks”)</p>
|
157
169
|
|
158
170
|
|
171
|
+
<h3><span class="caps">YAML</span>-Output</h3>
|
172
|
+
|
173
|
+
|
174
|
+
<p>You can generate <span class="caps">YAML</span>-Output from your spreadsheet data. The method is called:</p>
|
175
|
+
|
176
|
+
|
177
|
+
<p>oo.to_yaml # => produces <span class="caps">YAML</span> output from the entire default spreadsheet
|
178
|
+
oo.to_yaml({“myattribute1” => “myvalue1”, “myattribute2” => “myvalue2”)
|
179
|
+
# => <span class="caps">YAML</span> output with additional attributes
|
180
|
+
oo.to_yaml({..}, 2,10, 300,10) # => only the rectangle from row 2, column 10 to row 300, column 10 will be returned</p>
|
181
|
+
|
182
|
+
|
183
|
+
<p>If you omit one or more parameters the maximum boundaries of your spreadsheet will be used.</p>
|
184
|
+
|
185
|
+
|
186
|
+
<p>With the <span class="caps">YAML</span> output you can import your data in a Ruby on Rails application in a manner that spreadsheet data can accessed in a Rails application.</p>
|
187
|
+
|
188
|
+
|
189
|
+
<p>This is not limited to a Rails application – you can also do further evaluations with your data.</p>
|
190
|
+
|
191
|
+
|
159
192
|
<h3>Using MS-Excel spreadsheets</h3>
|
160
193
|
|
161
194
|
|
@@ -169,11 +202,40 @@ Replace Openoffice with
|
|
169
202
|
</code>
|
170
203
|
</pre>
|
171
204
|
|
172
|
-
<p>
|
205
|
+
<p>All methode are the same for OpenOffice and Excel-objects. The only difference
|
173
206
|
is the setting of the default-worksheet. OpenOffice uses the name of the worksheet whereas Excel needs the index of the worksheet (1,2,3,..).</p>
|
174
207
|
|
175
208
|
|
176
|
-
<p>Formulas
|
209
|
+
<p>Formulas can only be handled in OpenOffice-spreadsheets.</p>
|
210
|
+
|
211
|
+
|
212
|
+
<p>Features in OpenOffice and Excel:</p>
|
213
|
+
|
214
|
+
|
215
|
+
<table class="border:1px solid black">
|
216
|
+
<tr>
|
217
|
+
<td>feature</td>
|
218
|
+
<td>Open Office</td>
|
219
|
+
<td>Excel</td>
|
220
|
+
</tr>
|
221
|
+
<tr>
|
222
|
+
<td>default_sheet</td>
|
223
|
+
<td>as name</td>
|
224
|
+
<td>as number</td>
|
225
|
+
</tr>
|
226
|
+
<tr>
|
227
|
+
<td>formulas</td>
|
228
|
+
<td>yes</td>
|
229
|
+
<td>no</td>
|
230
|
+
</tr>
|
231
|
+
<tr>
|
232
|
+
<td>to_yaml</td>
|
233
|
+
<td>yes</td>
|
234
|
+
<td>yes</td>
|
235
|
+
</tr>
|
236
|
+
</table>
|
237
|
+
|
238
|
+
|
177
239
|
|
178
240
|
|
179
241
|
<h2>Where is it used?</h2>
|
@@ -182,9 +244,17 @@ is the setting of the default-worksheet. OpenOffice uses the name of the workshe
|
|
182
244
|
<p>How do you use roo? What are you doing with roo?</p>
|
183
245
|
|
184
246
|
|
247
|
+
<ul>
|
248
|
+
<li>The author of this gem uses roo for the generation of weekly reports which are (automatically) sent to his customers (Thomas Preymesser, Homepage: www.thopre.com, Blog: thopre.wordpress.com, email me: thopre@gmail.com)</li>
|
249
|
+
</ul>
|
250
|
+
|
251
|
+
|
185
252
|
<p>If you have an interesting application where you use roo then write me a short description of your project and i will publish it here (write, if your email-address should be published or not).</p>
|
186
253
|
|
187
254
|
|
255
|
+
<p>Or you can write directly in the project wiki at <a href="http://roo.rubyforge.org/wiki/wiki.pl?Who's_Using_Roo">http://roo.rubyforge.org/wiki/wiki.pl?Who’s_Using_Roo</a></p>
|
256
|
+
|
257
|
+
|
188
258
|
<p>If you don’t want to publish the details you can also write me an email and state, that it should not be published – i am just curious to hear, where it is used.</p>
|
189
259
|
|
190
260
|
|
@@ -233,7 +303,7 @@ is the setting of the default-worksheet. OpenOffice uses the name of the workshe
|
|
233
303
|
<li>Dirk Huth fürs Testen unter Windows</li>
|
234
304
|
</ul>
|
235
305
|
<p class="coda">
|
236
|
-
<a href="mailto:drnicwilliams@gmail.com">Dr Nic</a>,
|
306
|
+
<a href="mailto:drnicwilliams@gmail.com">Dr Nic</a>, 26th June 2007<br>
|
237
307
|
Theme extended from <a href="http://rb2js.rubyforge.org/">Paul Battley</a>
|
238
308
|
</p>
|
239
309
|
</div>
|
data/website/index.txt
CHANGED
@@ -93,13 +93,40 @@ Formulas in Openoffice-Spreadsheets can be handled.
|
|
93
93
|
|
94
94
|
oo.celltype(row,col) returns :formula if there is a formula in this cell.
|
95
95
|
|
96
|
-
oo.formula(row,col) returns
|
97
|
-
|
96
|
+
oo.formula?(row,col) returns true if there is a formula
|
97
|
+
|
98
|
+
oo.formula(row,col) returns the formula in this cell in a string variable (like "=SUM([.A1:.M13])"). You can do whatever you want with this expression.
|
99
|
+
If there is no formula in this cell nil is returned.
|
98
100
|
|
99
101
|
oo.cell(row,col) returns the computed result of the formula (as it was saved in the file, no recalculation is done in this Gem).
|
100
102
|
|
103
|
+
oo.formulas returns all formulas in the selected spreadsheet in an array like this:
|
104
|
+
|
105
|
+
[[1,2,"=SUM(.A1:.B1)"],
|
106
|
+
[1,3,"=SIN(.C3)"],
|
107
|
+
[1,4,"=COS(.D4)"]]
|
108
|
+
|
109
|
+
Each entry consists of the elements row, col, formual.
|
110
|
+
|
111
|
+
Note: oo.cell(row,col) is the same for ordinary cells and formulas. So you can use the computated value of a formula. If you have to distinguish if a cell is a formula use #formula?
|
112
|
+
|
101
113
|
Please note: formulas in Excel-Spreadsheets cannot be handled (this is another gem, see: "Thanks")
|
102
114
|
|
115
|
+
h3. YAML-Output
|
116
|
+
|
117
|
+
You can generate YAML-Output from your spreadsheet data. The method is called:
|
118
|
+
|
119
|
+
oo.to_yaml # => produces YAML output from the entire default spreadsheet
|
120
|
+
oo.to_yaml({"myattribute1" => "myvalue1", "myattribute2" => "myvalue2")
|
121
|
+
# => YAML output with additional attributes
|
122
|
+
oo.to_yaml({..}, 2,10, 300,10) # => only the rectangle from row 2, column 10 to row 300, column 10 will be returned
|
123
|
+
|
124
|
+
If you omit one or more parameters the maximum boundaries of your spreadsheet will be used.
|
125
|
+
|
126
|
+
With the YAML output you can import your data in a Ruby on Rails application in a manner that spreadsheet data can accessed in a Rails application.
|
127
|
+
|
128
|
+
This is not limited to a Rails application - you can also do further evaluations with your data.
|
129
|
+
|
103
130
|
h3. Using MS-Excel spreadsheets
|
104
131
|
|
105
132
|
You can also access MS-Excel spreadsheat.
|
@@ -111,18 +138,32 @@ Replace Openoffice with
|
|
111
138
|
</code>
|
112
139
|
</pre>
|
113
140
|
|
114
|
-
|
141
|
+
All methode are the same for OpenOffice and Excel-objects. The only difference
|
115
142
|
is the setting of the default-worksheet. OpenOffice uses the name of the worksheet whereas Excel needs the index of the worksheet (1,2,3,..).
|
116
143
|
|
117
|
-
Formulas
|
144
|
+
Formulas can only be handled in OpenOffice-spreadsheets.
|
145
|
+
|
146
|
+
Features in OpenOffice and Excel:
|
147
|
+
|
148
|
+
table(border:1px solid black).
|
149
|
+
|feature|Open Office|Excel|
|
150
|
+
|default_sheet|as name|as number|
|
151
|
+
|formulas|yes|no|
|
152
|
+
|to_yaml|yes|yes|
|
118
153
|
|
119
154
|
|
120
155
|
h2. Where is it used?
|
121
156
|
|
122
157
|
How do you use roo? What are you doing with roo?
|
123
158
|
|
159
|
+
* The author of this gem uses roo for the generation of weekly reports which are (automatically) sent to his customers (Thomas Preymesser, Homepage: www.thopre.com, Blog: thopre.wordpress.com, email me: thopre@gmail.com)
|
160
|
+
|
161
|
+
|
124
162
|
If you have an interesting application where you use roo then write me a short description of your project and i will publish it here (write, if your email-address should be published or not).
|
125
163
|
|
164
|
+
Or you can write directly in the project wiki at "http://roo.rubyforge.org/wiki/wiki.pl?Who's_Using_Roo":http://roo.rubyforge.org/wiki/wiki.pl?Who's_Using_Roo
|
165
|
+
|
166
|
+
|
126
167
|
If you don't want to publish the details you can also write me an email and state, that it should not be published - i am just curious to hear, where it is used.
|
127
168
|
|
128
169
|
h2. Documentation
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
|
|
3
3
|
specification_version: 1
|
4
4
|
name: roo
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2007-06-
|
6
|
+
version: 0.4.0
|
7
|
+
date: 2007-06-27 00:00:00 +02:00
|
8
8
|
summary: roo can access the contents of OpenOffice-Spreadsheets
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -39,6 +39,7 @@ files:
|
|
39
39
|
- lib/roo/openoffice.rb
|
40
40
|
- lib/roo/excel.rb
|
41
41
|
- lib/roo/google.rb
|
42
|
+
- lib/roo/spreadsheetparser.rb
|
42
43
|
- scripts/txt2html
|
43
44
|
- setup.rb
|
44
45
|
- test/test_helper.rb
|
@@ -96,3 +97,12 @@ dependencies:
|
|
96
97
|
- !ruby/object:Gem::Version
|
97
98
|
version: "0.5"
|
98
99
|
version:
|
100
|
+
- !ruby/object:Gem::Dependency
|
101
|
+
name: llip
|
102
|
+
version_requirement:
|
103
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: 0.0.1
|
108
|
+
version:
|