roo 0.3.0 → 0.4.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 +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:
|