roo 1.3.11 → 1.9.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 +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
|