roo 1.3.11 → 1.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +15 -6
- data/Manifest.txt +53 -0
- data/README.txt +97 -0
- data/Rakefile +45 -0
- data/bin/roo +8 -0
- data/lib/roo.rb +55 -9
- data/lib/roo/excel.rb +44 -40
- data/lib/roo/excelx.rb +99 -60
- data/lib/roo/generic_spreadsheet.rb +29 -1
- data/lib/roo/google.rb +71 -117
- data/lib/roo/openoffice.rb +79 -27
- data/lib/roo/version.rb +9 -9
- data/tasks/ann.rake +80 -0
- data/tasks/bones.rake +20 -0
- data/tasks/gem.rake +201 -0
- data/tasks/git.rake +40 -0
- data/tasks/notes.rake +27 -0
- data/tasks/post_load.rake +34 -0
- data/tasks/rdoc.rake +51 -0
- data/tasks/rubyforge.rake +55 -0
- data/tasks/setup.rb +292 -0
- data/tasks/spec.rake +54 -0
- data/tasks/svn.rake +47 -0
- data/tasks/test.rake +40 -0
- data/tasks/zentest.rake +36 -0
- data/test/1900_base.xls +0 -0
- data/test/1904_base.xls +0 -0
- data/test/Bibelbund.csv +0 -0
- data/test/bode-v1.ods.zip +0 -0
- data/test/bode-v1.xls.zip +0 -0
- data/test/boolean.xls +0 -0
- data/test/datetime.xls +0 -0
- data/test/named_cells.ods +0 -0
- data/test/numbers1.csv +0 -0
- data/test/{bad_excel_date.xls → prova.xls} +0 -0
- data/test/test_helper.rb +1 -1
- data/test/test_roo.rb +365 -256
- data/test/whitespace.xls +0 -0
- metadata +48 -30
- data/README.markdown +0 -55
- data/examples/roo_soap_client.rb +0 -53
- data/examples/roo_soap_server.rb +0 -29
- data/examples/write_me.rb +0 -33
- data/test/formula_parse_error.xls +0 -0
- data/test/skipped_tests.rb +0 -789
data/History.txt
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
== 1.9.0 2009-10-29
|
2
|
+
|
3
|
+
* 4 enhancements
|
4
|
+
* Ruby 1.9 compatible
|
5
|
+
* oo.aa42 as a shortcut of oo.cell('aa',42)
|
6
|
+
* oo.aa42('sheet1') as a shortcut of oo.cell('aa',42,'sheet1')
|
7
|
+
* oo.anton as a reference to a cell labelled 'anton' (or any other label name)
|
8
|
+
(currently only for Openoffice spreadsheets)
|
9
|
+
|
1
10
|
== 1.2.3 2009-01-04
|
2
11
|
|
3
12
|
* bugfix
|
@@ -89,8 +98,8 @@
|
|
89
98
|
* some methods common to more than one class were factored out to the GenericSpreadsheet (virtual) class
|
90
99
|
== 0.7.0 2007-11-23
|
91
100
|
* 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
|
101
|
+
* Openoffice/Excel: the most methods can be called with an option 'sheet'
|
102
|
+
parameter which will be used instead of the default sheet
|
94
103
|
* Excel: improved the speed of CVS output
|
95
104
|
* Openoffice/Excel: new method #column
|
96
105
|
* Openoffice/Excel: new method #find
|
@@ -118,7 +127,7 @@
|
|
118
127
|
== 0.5.1 2007-08-26
|
119
128
|
* 4 enhancements:
|
120
129
|
* 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
|
130
|
+
* Openoffice/Excel: no need to set a default_sheet if there is only one in
|
122
131
|
the document
|
123
132
|
* Excel: can now read zip-ed files
|
124
133
|
* Excel: can now read files from http://-URL over the net
|
@@ -136,7 +145,7 @@
|
|
136
145
|
== 0.4.0 2007-06-27
|
137
146
|
* 7 enhancements:
|
138
147
|
* robustness: Exception if no default_sheet was set
|
139
|
-
* new method reload() implemented
|
148
|
+
* new method reload() implemented
|
140
149
|
* about 15 % more method documentation
|
141
150
|
* optimization: huge increase of speed (no need to use fixed borders anymore)
|
142
151
|
* added the method 'formulas' which gives you all formulas in a spreadsheet
|
@@ -158,7 +167,7 @@
|
|
158
167
|
|
159
168
|
== 0.2.6 2007-06-19
|
160
169
|
* 1 bugfix:
|
161
|
-
* Openoffice: two or more consecutive cells with string content failed
|
170
|
+
* Openoffice: two or more consecutive cells with string content failed
|
162
171
|
|
163
172
|
== 0.2.5 2007-06-17
|
164
173
|
|
@@ -188,7 +197,7 @@
|
|
188
197
|
|
189
198
|
== 0.2.2 2007-06-01
|
190
199
|
* 1 bugfix:
|
191
|
-
* incorrect dependencies fixed
|
200
|
+
* incorrect dependencies fixed
|
192
201
|
|
193
202
|
== 0.2.0 2007-06-01
|
194
203
|
* 1 major enhancement:
|
data/Manifest.txt
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
History.txt
|
2
|
+
License.txt
|
3
|
+
Manifest.txt
|
4
|
+
README.txt
|
5
|
+
Rakefile
|
6
|
+
base64include.rb
|
7
|
+
examples/roo_soap_server.rb
|
8
|
+
examples/roo_soap_client.rb
|
9
|
+
examples/write_me.rb
|
10
|
+
lib/roo.rb
|
11
|
+
lib/roo/version.rb
|
12
|
+
lib/roo/generic_spreadsheet.rb
|
13
|
+
lib/roo/openoffice.rb
|
14
|
+
lib/roo/excel.rb
|
15
|
+
lib/roo/google.rb
|
16
|
+
lib/roo/roo_rails_helper.rb
|
17
|
+
scripts/txt2html
|
18
|
+
setup.rb
|
19
|
+
test/false_encoding.xls
|
20
|
+
test/Bibelbund1.ods
|
21
|
+
test/Bibelbund.ods
|
22
|
+
test/Bibelbund.xls
|
23
|
+
test/Bibelbund.csv
|
24
|
+
test/bbu.xls
|
25
|
+
test/bbu.ods
|
26
|
+
test/no_spreadsheet_file.txt
|
27
|
+
test/simple_spreadsheet.ods
|
28
|
+
test/simple_spreadsheet.xls
|
29
|
+
test/simple_spreadsheet_from_italo.ods
|
30
|
+
test/simple_spreadsheet_from_italo.xls
|
31
|
+
test/test_helper.rb
|
32
|
+
test/test_roo.rb
|
33
|
+
test/time-test.ods
|
34
|
+
test/time-test.xls
|
35
|
+
test/time-test.csv
|
36
|
+
test/numbers1.csv
|
37
|
+
test/numbers1_excel.csv
|
38
|
+
test/numbers1.ods
|
39
|
+
test/numbers1.xls
|
40
|
+
test/borders.ods
|
41
|
+
test/borders.xls
|
42
|
+
test/formula.ods
|
43
|
+
test/formula.xls
|
44
|
+
test/only_one_sheet.ods
|
45
|
+
test/only_one_sheet.xls
|
46
|
+
test/bode-v1.xls.zip
|
47
|
+
test/bode-v1.ods.zip
|
48
|
+
test/ric.ods
|
49
|
+
website/index.html
|
50
|
+
website/index.txt
|
51
|
+
website/javascripts/rounded_corners_lite.inc.js
|
52
|
+
website/stylesheets/screen.css
|
53
|
+
website/template.rhtml
|
data/README.txt
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
roo
|
2
|
+
by Thomas Preymesser
|
3
|
+
http://thopre.wordpress.com
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
Roo can access the contents of various spreadsheet files. It can handle
|
8
|
+
* Openoffice
|
9
|
+
* Excel
|
10
|
+
* Google spreadsheets
|
11
|
+
* Excelx
|
12
|
+
|
13
|
+
|
14
|
+
== FEATURES/PROBLEMS:
|
15
|
+
|
16
|
+
You don't need to have an installation of Openoffice or Excel. All you need is
|
17
|
+
the spreadsheet file. It's platform independent so you can read an Excel file
|
18
|
+
under Linux without having to install the MS office suite.
|
19
|
+
|
20
|
+
Roo implements read access for all spreadsheet types and read/write access for
|
21
|
+
Google spreadsheets.
|
22
|
+
|
23
|
+
|
24
|
+
== SYNOPSIS:
|
25
|
+
|
26
|
+
require 'rubygems'
|
27
|
+
require 'roo'
|
28
|
+
|
29
|
+
s = Openoffice.new("myspreadsheet.ods") # creates an Openoffice Spreadsheet instance
|
30
|
+
s = Excel.new("myspreadsheet.xls") # creates an Excel Spreadsheet instance
|
31
|
+
s = Google.new("myspreadsheetkey_at_google") # creates an Google Spreadsheet instance
|
32
|
+
s = Excelx.new("myspreadsheet.xlsx") # creates an Excel Spreadsheet instance for Excel .xlsx files
|
33
|
+
|
34
|
+
s.default_sheet = s.sheets.first # first sheet in the spreadsheet file will be used
|
35
|
+
|
36
|
+
# s.sheet is an array which holds the names of the sheets within
|
37
|
+
# a spreadsheet.
|
38
|
+
# you can also write
|
39
|
+
# s.default_sheet = s.sheets[3] or
|
40
|
+
# s.default_sheet = 'Sheet 3'
|
41
|
+
|
42
|
+
s.cell(1,1) # returns the content of the first row/first cell in the sheet
|
43
|
+
s.cell('A',1) # same cell
|
44
|
+
s.cell(1,'A') # same cell
|
45
|
+
s.cell(1,'A',s.sheets[0]) # same cell
|
46
|
+
|
47
|
+
# almost all methods have an optional argument 'sheet'.
|
48
|
+
# If this parameter is omitted, the default_sheet will be used.
|
49
|
+
|
50
|
+
s.info # prints infos about the spreadsheet file
|
51
|
+
|
52
|
+
s.first_row # the number of the first row
|
53
|
+
s.last_row # the number of the last row
|
54
|
+
s.first_column # the number of the first column
|
55
|
+
s.last_column # the number of the last column
|
56
|
+
|
57
|
+
# limited font information is available
|
58
|
+
|
59
|
+
s.font(1,1).bold?
|
60
|
+
s.font(1,1).italic?
|
61
|
+
s.font(1,1).underline?
|
62
|
+
|
63
|
+
|
64
|
+
see http://roo.rubyforge.org for a more complete tutorial
|
65
|
+
|
66
|
+
== REQUIREMENTS:
|
67
|
+
|
68
|
+
All dependent gems will be automatically installed.
|
69
|
+
|
70
|
+
== INSTALL:
|
71
|
+
|
72
|
+
sudo gem install roo
|
73
|
+
|
74
|
+
== LICENSE:
|
75
|
+
|
76
|
+
(The MIT License)
|
77
|
+
|
78
|
+
Copyright (c) 2008 FIXME (different license?)
|
79
|
+
|
80
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
81
|
+
a copy of this software and associated documentation files (the
|
82
|
+
'Software'), to deal in the Software without restriction, including
|
83
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
84
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
85
|
+
permit persons to whom the Software is furnished to do so, subject to
|
86
|
+
the following conditions:
|
87
|
+
|
88
|
+
The above copyright notice and this permission notice shall be
|
89
|
+
included in all copies or substantial portions of the Software.
|
90
|
+
|
91
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
92
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
93
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
94
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
95
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
96
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
97
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# Look in the tasks/setup.rb file for the various options that can be
|
2
|
+
# configured in this Rakefile. The .rake files in the tasks directory
|
3
|
+
# are where the options are used.
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'bones'
|
7
|
+
Bones.setup
|
8
|
+
rescue LoadError
|
9
|
+
begin
|
10
|
+
load 'tasks/setup.rb'
|
11
|
+
rescue LoadError
|
12
|
+
raise RuntimeError, '### please install the "bones" gem ###'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
ensure_in_path 'lib'
|
17
|
+
module GData
|
18
|
+
class Base
|
19
|
+
end
|
20
|
+
end
|
21
|
+
require 'roo'
|
22
|
+
|
23
|
+
task :default => 'spec:run'
|
24
|
+
|
25
|
+
PROJ.name = 'roo'
|
26
|
+
PROJ.authors = 'Thomas Preymesser'
|
27
|
+
PROJ.email = 'thopre@gmail.com'
|
28
|
+
PROJ.url = 'http://roo.rubyforge.org/'
|
29
|
+
PROJ.version = Roo::VERSION
|
30
|
+
PROJ.rubyforge.name = 'roo'
|
31
|
+
PROJ.gem.dependencies = [
|
32
|
+
# ['xmlsimple', '>= 0.0.1'],
|
33
|
+
['spreadsheet', '> 0.6.4'],
|
34
|
+
#--
|
35
|
+
# rel. 0.6.4 causes an invalid Date error if we
|
36
|
+
# have a datetime value of 2006-02-02 10:00:00
|
37
|
+
#++
|
38
|
+
['nokogiri', '>= 0.0.1'],
|
39
|
+
['builder', '>= 2.1.2'],
|
40
|
+
['gimite-google-spreadsheet-ruby','>= 0.0.5'],
|
41
|
+
]
|
42
|
+
|
43
|
+
PROJ.spec.opts << '--color'
|
44
|
+
|
45
|
+
# EOF
|
data/bin/roo
ADDED
data/lib/roo.rb
CHANGED
@@ -1,4 +1,48 @@
|
|
1
|
+
|
1
2
|
module Roo
|
3
|
+
|
4
|
+
# :stopdoc:
|
5
|
+
VERSION = '1.9.0'
|
6
|
+
LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
|
7
|
+
PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
|
8
|
+
# :startdoc:
|
9
|
+
|
10
|
+
# Returns the version string for the library.
|
11
|
+
#
|
12
|
+
def self.version
|
13
|
+
VERSION
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns the library path for the module. If any arguments are given,
|
17
|
+
# they will be joined to the end of the libray path using
|
18
|
+
# <tt>File.join</tt>.
|
19
|
+
#
|
20
|
+
def self.libpath( *args )
|
21
|
+
args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns the lpath for the module. If any arguments are given,
|
25
|
+
# they will be joined to the end of the path using
|
26
|
+
# <tt>File.join</tt>.
|
27
|
+
#
|
28
|
+
def self.path( *args )
|
29
|
+
args.empty? ? PATH : ::File.join(PATH, args.flatten)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Utility method used to require all files ending in .rb that lie in the
|
33
|
+
# directory below this file that has the same name as the filename passed
|
34
|
+
# in. Optionally, a specific _directory_ name can be passed in such that
|
35
|
+
# the _filename_ does not have to be equivalent to the directory.
|
36
|
+
#
|
37
|
+
def self.require_all_libs_relative_to( fname, dir = nil )
|
38
|
+
dir ||= ::File.basename(fname, '.*')
|
39
|
+
search_me = ::File.expand_path(
|
40
|
+
::File.join(::File.dirname(fname), dir, '**', '*.rb'))
|
41
|
+
Dir.glob(search_me).sort.each {|rb|
|
42
|
+
puts "DEBUG: require #{rb}"
|
43
|
+
require rb}
|
44
|
+
end
|
45
|
+
|
2
46
|
class Spreadsheet
|
3
47
|
class << self
|
4
48
|
def open(file)
|
@@ -9,21 +53,23 @@ module Roo
|
|
9
53
|
Excelx.new(file)
|
10
54
|
when '.ods'
|
11
55
|
Openoffice.new(file)
|
12
|
-
|
13
|
-
Google.new(file)
|
56
|
+
# when ''
|
14
57
|
else
|
15
|
-
|
16
|
-
|
58
|
+
Google.new(file)
|
59
|
+
# else
|
60
|
+
# raise ArgumentError, "Don't know how to open file #{file}"
|
61
|
+
end
|
17
62
|
end
|
18
63
|
end
|
19
64
|
end
|
20
|
-
end
|
65
|
+
end # module Roo
|
21
66
|
|
22
|
-
require 'roo/
|
23
|
-
# require 'roo/spreadsheetparser' TODO:
|
24
|
-
require 'roo/generic_spreadsheet'
|
67
|
+
require 'roo/generic_spreadsheet'
|
25
68
|
require 'roo/openoffice'
|
26
69
|
require 'roo/excel'
|
27
70
|
require 'roo/excelx'
|
28
71
|
require 'roo/google'
|
29
|
-
|
72
|
+
|
73
|
+
#Roo.require_all_libs_relative_to(__FILE__)
|
74
|
+
|
75
|
+
# EOF
|
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
|
|
@@ -227,6 +215,22 @@ class Excel < GenericSpreadsheet
|
|
227
215
|
@cell[sheet].inspect
|
228
216
|
end
|
229
217
|
|
218
|
+
# returns the row,col values of the labelled cell
|
219
|
+
# (nil,nil) if label is not defined
|
220
|
+
# sheet parameter is not really needed because label names are global
|
221
|
+
# to the whole spreadsheet
|
222
|
+
def label(labelname,sheet=nil)
|
223
|
+
sheet = @default_sheet unless sheet
|
224
|
+
read_cells(sheet) unless @cells_read[sheet]
|
225
|
+
if @labels.has_key? labelname
|
226
|
+
return @labels[labelname][1].to_i,
|
227
|
+
GenericSpreadsheet.letter_to_number(@labels[labelname][2]),
|
228
|
+
@labels[labelname][0]
|
229
|
+
else
|
230
|
+
return nil,nil,nil
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
230
234
|
private
|
231
235
|
|
232
236
|
# converts name of a sheet to index (0,1,2,..)
|
@@ -414,8 +418,8 @@ class Excel < GenericSpreadsheet
|
|
414
418
|
datetime = row.datetime(idx)
|
415
419
|
end
|
416
420
|
if datetime.hour != 0 or
|
417
|
-
|
418
|
-
|
421
|
+
datetime.min != 0 or
|
422
|
+
datetime.sec != 0
|
419
423
|
value_type = :datetime
|
420
424
|
value = datetime
|
421
425
|
else
|