roo-xls 1.0.0 → 1.1.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.
- checksums.yaml +4 -4
- data/.travis.yml +5 -1
- data/Gemfile +3 -1
- data/README.md +5 -3
- data/lib/roo/xls/excel.rb +46 -42
- data/lib/roo/xls/excel_2003_xml.rb +4 -3
- data/lib/roo/xls/version.rb +1 -1
- data/roo-xls.gemspec +6 -1
- data/test/test_roo_excel.rb +10 -1
- metadata +13 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 72a5eeec41696350e22d685b1337489727f9211c
|
4
|
+
data.tar.gz: d149d0621aec472b1b64ef3b817ef167d7cfd785
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4c1534cb3cbe004cc8bfe510c88f9565adbf4e9e607c42961a49827dbc579ce06b630716eb9804d04076afb0ee79b5269a02b333eb0a096a97b4bbbfa417e4d
|
7
|
+
data.tar.gz: faf978fc060d3bf38ff0011bc8ff239ffa9067835ad2cee1fa9f7c09aeb64a181136c7365e70ddb7c5015e9ac24e076cd7473414e6d8fcec60feb5cb12dd1458
|
data/.travis.yml
CHANGED
@@ -1,11 +1,15 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
- 2.0
|
3
|
+
- 2.0
|
4
4
|
- 2.1
|
5
|
+
- 2.2
|
6
|
+
- 2.3
|
7
|
+
- 2.4.0
|
5
8
|
- ruby-head
|
6
9
|
- jruby-19mode # JRuby in 1.9 mode
|
7
10
|
- rbx-2
|
8
11
|
matrix:
|
9
12
|
allow_failures:
|
10
13
|
- rvm: ruby-head
|
14
|
+
- rvm: rbx-2
|
11
15
|
bundler_args: --without local_development
|
data/Gemfile
CHANGED
@@ -4,11 +4,13 @@ source 'https://rubygems.org'
|
|
4
4
|
gemspec
|
5
5
|
|
6
6
|
if ENV['TRAVIS']
|
7
|
-
gem 'roo', '>= 2.0.0beta1',
|
7
|
+
gem 'roo', '>= 2.0.0beta1', git: 'https://github.com/roo-rb/roo.git'
|
8
8
|
else
|
9
9
|
gem 'roo', '>= 2.0.0beta1', path: ::File.expand_path('../../roo', __FILE__)
|
10
10
|
end
|
11
11
|
|
12
|
+
gem 'activesupport', '~> 4.2.0' if RUBY_VERSION < '2.2'
|
13
|
+
|
12
14
|
group :test do
|
13
15
|
# additional testing libs
|
14
16
|
gem 'webmock'
|
data/README.md
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
# Roo::Xls
|
1
|
+
# Roo::Xls
|
2
|
+
|
3
|
+
[](https://travis-ci.org/roo-rb/roo-xls) [](https://codeclimate.com/github/roo-rb/roo-xls) [](https://coveralls.io/r/roo-rb/roo-xls) [](https://rubygems.org/gems/roo-xls)
|
2
4
|
|
3
5
|
This library extends Roo to add support for handling class Excel files, including:
|
4
6
|
|
@@ -10,7 +12,7 @@ of a formula but not the formula itself.
|
|
10
12
|
|
11
13
|
## License
|
12
14
|
|
13
|
-
While Roo and Roo::Xls are licensed under the MIT / Expat license, please note that the
|
15
|
+
While Roo and Roo::Xls are licensed under the MIT / Expat license, please note that the `spreadsheet` gem [is released under](https://github.com/zdavatz/spreadsheet/blob/master/LICENSE.txt) the GPLv3 license. Please be aware that the author of the `spreadsheet` gem [claims you need a commercial license](http://spreadsheet.ch/2014/10/24/using-ruby-spreadsheet-on-heroku-with-dynos/) to use it as part of a public-facing, closed-source service, an interpretation [at odds with the FSF's intent and interpretation of the license](http://www.gnu.org/licenses/gpl-faq.html#UnreleasedMods).
|
14
16
|
|
15
17
|
## Installation
|
16
18
|
|
@@ -34,7 +36,7 @@ TODO: Write usage instructions here
|
|
34
36
|
|
35
37
|
## Contributing
|
36
38
|
|
37
|
-
1. Fork it ( https://github.com/
|
39
|
+
1. Fork it ( https://github.com/roo-rb/roo-xls/fork )
|
38
40
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
39
41
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
40
42
|
4. Push to the branch (`git push origin my-new-feature`)
|
data/lib/roo/xls/excel.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
require 'roo/xls/version'
|
2
2
|
require 'roo/base'
|
3
3
|
require 'spreadsheet'
|
4
|
+
require 'tmpdir'
|
4
5
|
|
5
6
|
module Roo
|
6
7
|
# Class for handling Excel-Spreadsheets
|
7
8
|
class Excel < Roo::Base
|
8
|
-
FORMULAS_MESSAGE = 'the spreadsheet gem does not support
|
9
|
+
FORMULAS_MESSAGE = 'the spreadsheet gem does not support formulas, so roo can not.'
|
9
10
|
CHARGUESS =
|
10
11
|
begin
|
11
12
|
require 'charguess'
|
@@ -23,18 +24,25 @@ module Roo
|
|
23
24
|
file_warning = options[:file_warning] || :error
|
24
25
|
mode = options[:mode] || 'rb+'
|
25
26
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
27
|
+
if is_stream?(filename)
|
28
|
+
@workbook = ::Spreadsheet.open(filename, mode)
|
29
|
+
else
|
30
|
+
file_type_check(filename, '.xls', 'an Excel', file_warning, packed)
|
31
|
+
Dir.mktmpdir do |tmpdir|
|
32
|
+
filename = download_uri(filename, tmpdir) if uri?(filename)
|
33
|
+
if filename.is_a?(::String) && filename[0, 7] == 'stream:'
|
34
|
+
filename = open_from_stream(filename[7..-1], tmpdir)
|
35
|
+
end
|
36
|
+
filename = unzip(filename, tmpdir) if packed == :zip
|
31
37
|
|
32
|
-
|
33
|
-
|
34
|
-
|
38
|
+
@filename = filename
|
39
|
+
unless File.file?(@filename)
|
40
|
+
raise IOError, "file #{@filename} does not exist"
|
41
|
+
end
|
42
|
+
@workbook = ::Spreadsheet.open(filename, mode)
|
35
43
|
end
|
36
|
-
@workbook = ::Spreadsheet.open(filename, mode)
|
37
44
|
end
|
45
|
+
|
38
46
|
super(filename, options)
|
39
47
|
@formula = {}
|
40
48
|
@fonts = {}
|
@@ -57,7 +65,7 @@ module Roo
|
|
57
65
|
|
58
66
|
# this method lets you find the worksheet with the most data
|
59
67
|
def longest_sheet
|
60
|
-
sheet(worksheets.inject do|m, o|
|
68
|
+
sheet(worksheets.inject do |m, o|
|
61
69
|
o.row_count > m.row_count ? o : m
|
62
70
|
end.name)
|
63
71
|
end
|
@@ -67,20 +75,16 @@ module Roo
|
|
67
75
|
validate_sheet!(sheet)
|
68
76
|
|
69
77
|
read_cells(sheet)
|
70
|
-
|
78
|
+
raise 'should be read' unless @cells_read[sheet]
|
71
79
|
row, col = normalize(row, col)
|
72
80
|
if celltype(row, col, sheet) == :date
|
73
81
|
yyyy, mm, dd = @cell[sheet][[row, col]].split('-')
|
74
82
|
return Date.new(yyyy.to_i, mm.to_i, dd.to_i)
|
75
83
|
end
|
76
84
|
if celltype(row, col, sheet) == :string
|
77
|
-
|
85
|
+
platform_specific_encoding(@cell[sheet][[row, col]])
|
78
86
|
else
|
79
|
-
|
80
|
-
return @cell[sheet][[row, col]]
|
81
|
-
else
|
82
|
-
return nil
|
83
|
-
end
|
87
|
+
@cell[sheet] && @cell[sheet][[row, col]]
|
84
88
|
end
|
85
89
|
end
|
86
90
|
|
@@ -109,13 +113,13 @@ module Roo
|
|
109
113
|
|
110
114
|
# returns NO formula in excel spreadsheets
|
111
115
|
def formula(_row, _col, _sheet = nil)
|
112
|
-
|
116
|
+
raise NotImplementedError, FORMULAS_MESSAGE
|
113
117
|
end
|
114
118
|
alias_method :formula?, :formula
|
115
119
|
|
116
120
|
# returns NO formulas in excel spreadsheets
|
117
121
|
def formulas(_sheet = nil)
|
118
|
-
|
122
|
+
raise NotImplementedError, FORMULAS_MESSAGE
|
119
123
|
end
|
120
124
|
|
121
125
|
# Given a cell, return the cell's font
|
@@ -136,18 +140,18 @@ module Roo
|
|
136
140
|
|
137
141
|
# converts name of a sheet to index (0,1,2,..)
|
138
142
|
def sheet_no(name)
|
139
|
-
return name - 1 if name.is_a?(
|
143
|
+
return name - 1 if name.is_a?(Integer)
|
140
144
|
i = 0
|
141
145
|
worksheets.each do |worksheet|
|
142
146
|
return i if name == normalize_string(worksheet.name)
|
143
147
|
i += 1
|
144
148
|
end
|
145
|
-
|
149
|
+
raise StandardError, "sheet '#{name}' not found"
|
146
150
|
end
|
147
151
|
|
148
152
|
def normalize_string(value)
|
149
153
|
value = every_second_null?(value) ? remove_every_second_null(value) : value
|
150
|
-
if CHARGUESS && encoding = CharGuess.guess(value)
|
154
|
+
if CHARGUESS && (encoding = CharGuess.guess(value))
|
151
155
|
encoding.encode Encoding::UTF_8
|
152
156
|
else
|
153
157
|
platform_specific_encoding(value)
|
@@ -164,9 +168,7 @@ module Roo
|
|
164
168
|
else
|
165
169
|
value
|
166
170
|
end
|
167
|
-
if every_second_null?(result)
|
168
|
-
result = remove_every_second_null(result)
|
169
|
-
end
|
171
|
+
result = remove_every_second_null(result) if every_second_null?(result)
|
170
172
|
result
|
171
173
|
end
|
172
174
|
|
@@ -198,8 +200,8 @@ module Roo
|
|
198
200
|
@cell_type[sheet] = {} unless @cell_type[sheet]
|
199
201
|
@cell_type[sheet][key] = value_type
|
200
202
|
@formula[sheet] = {} unless @formula[sheet]
|
201
|
-
@formula[sheet][key] = formula
|
202
|
-
@cell[sheet]
|
203
|
+
@formula[sheet][key] = formula if formula
|
204
|
+
@cell[sheet] = {} unless @cell[sheet]
|
203
205
|
@fonts[sheet] = {} unless @fonts[sheet]
|
204
206
|
@fonts[sheet][key] = font
|
205
207
|
|
@@ -250,7 +252,7 @@ module Roo
|
|
250
252
|
worksheet.each(0) do |row|
|
251
253
|
(0..row.size).each do |cell_index|
|
252
254
|
cell = row.at(cell_index)
|
253
|
-
next if cell.nil?
|
255
|
+
next if cell.nil? # skip empty cells
|
254
256
|
next if cell.class == ::Spreadsheet::Formula && cell.value.nil? # skip empty formula cells
|
255
257
|
value_type, v =
|
256
258
|
if date_or_time?(row, cell_index)
|
@@ -299,17 +301,18 @@ module Roo
|
|
299
301
|
f = cell * 24.0 * 60.0 * 60.0
|
300
302
|
secs = f.round
|
301
303
|
h = (secs / 3600.0).floor
|
302
|
-
secs
|
304
|
+
secs -= 3600 * h
|
303
305
|
m = (secs / 60.0).floor
|
304
|
-
secs
|
306
|
+
secs -= 60 * m
|
305
307
|
s = secs
|
306
308
|
value = h * 3600 + m * 60 + s
|
307
309
|
else
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
310
|
+
datetime =
|
311
|
+
if row.at(idx).class == ::Spreadsheet::Formula
|
312
|
+
row.send(:_datetime, cell)
|
313
|
+
else
|
314
|
+
row.datetime(idx)
|
315
|
+
end
|
313
316
|
if datetime.hour != 0 ||
|
314
317
|
datetime.min != 0 ||
|
315
318
|
datetime.sec != 0
|
@@ -317,11 +320,12 @@ module Roo
|
|
317
320
|
value = datetime
|
318
321
|
else
|
319
322
|
value_type = :date
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
323
|
+
value =
|
324
|
+
if row.at(idx).class == ::Spreadsheet::Formula
|
325
|
+
row.send(:_date, cell)
|
326
|
+
else
|
327
|
+
row.date(idx)
|
328
|
+
end
|
325
329
|
value = sprintf('%04d-%02d-%02d', value.year, value.month, value.day)
|
326
330
|
end
|
327
331
|
end
|
@@ -333,7 +337,7 @@ module Roo
|
|
333
337
|
def read_cell(row, idx)
|
334
338
|
cell = read_cell_content(row, idx)
|
335
339
|
case cell
|
336
|
-
when Float, Integer
|
340
|
+
when Float, Integer
|
337
341
|
value_type = :float
|
338
342
|
value = cell.to_f
|
339
343
|
when ::Spreadsheet::Link
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'date'
|
2
2
|
require 'base64'
|
3
3
|
require 'nokogiri'
|
4
|
+
require 'tmpdir'
|
4
5
|
|
5
6
|
class Roo::Excel2003XML < Roo::Base
|
6
7
|
# initialization and opening of a spreadsheet file
|
@@ -9,14 +10,14 @@ class Roo::Excel2003XML < Roo::Base
|
|
9
10
|
packed = options[:packed]
|
10
11
|
file_warning = options[:file_warning] || :error
|
11
12
|
|
12
|
-
|
13
|
+
Dir.mktmpdir do |tmpdir|
|
13
14
|
filename = download_uri(filename, tmpdir) if uri?(filename)
|
14
15
|
filename = unzip(filename, tmpdir) if packed == :zip
|
15
16
|
|
16
17
|
file_type_check(filename, '.xml', 'an Excel 2003 XML', file_warning)
|
17
18
|
@filename = filename
|
18
19
|
unless File.file?(@filename)
|
19
|
-
|
20
|
+
raise IOError, "file #{@filename} does not exist"
|
20
21
|
end
|
21
22
|
@doc = ::Roo::Utils.load_xml(@filename)
|
22
23
|
end
|
@@ -240,7 +241,7 @@ class Roo::Excel2003XML < Roo::Base
|
|
240
241
|
end
|
241
242
|
end
|
242
243
|
unless sheet_found
|
243
|
-
|
244
|
+
raise RangeError, "Unable to find sheet #{sheet} for reading"
|
244
245
|
end
|
245
246
|
@cells_read[sheet] = true
|
246
247
|
end
|
data/lib/roo/xls/version.rb
CHANGED
data/roo-xls.gemspec
CHANGED
@@ -19,9 +19,14 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
21
|
spec.add_dependency "roo", ">= 2.0.0beta1", "< 3"
|
22
|
-
spec.add_dependency "nokogiri"
|
23
22
|
spec.add_dependency "spreadsheet", "> 0.9.0"
|
24
23
|
|
24
|
+
if RUBY_VERSION >= '2.1'
|
25
|
+
spec.add_dependency "nokogiri"
|
26
|
+
else
|
27
|
+
spec.add_dependency "nokogiri", "~> 1.6.0"
|
28
|
+
end
|
29
|
+
|
25
30
|
spec.add_development_dependency "bundler", ">= 1.7"
|
26
31
|
spec.add_development_dependency "rake", ">= 10.0"
|
27
32
|
end
|
data/test/test_roo_excel.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# -- encoding : utf-8 --
|
2
2
|
require 'test_helper'
|
3
|
+
require 'stringio'
|
3
4
|
|
4
5
|
class TestRooExcel < MiniTest::Test
|
5
6
|
def with_spreadsheet(name)
|
@@ -1034,7 +1035,7 @@ Sheet 3:
|
|
1034
1035
|
i += 1
|
1035
1036
|
end
|
1036
1037
|
if letter == '' || number == 0
|
1037
|
-
|
1038
|
+
raise ArgumentError
|
1038
1039
|
end
|
1039
1040
|
[letter, number]
|
1040
1041
|
end
|
@@ -1090,4 +1091,12 @@ Sheet 3:
|
|
1090
1091
|
# assert_equal 'ist "e" im Nenner von H(s)', excel.cell('b', 5)
|
1091
1092
|
# end
|
1092
1093
|
# end
|
1094
|
+
|
1095
|
+
def test_excel_via_stringio
|
1096
|
+
io = StringIO.new(
|
1097
|
+
File.read(File.join(TESTDIR, 'simple_spreadsheet.xls')))
|
1098
|
+
spreadsheet = ::Roo::Spreadsheet.open(io, extension: '.xls')
|
1099
|
+
spreadsheet.default_sheet = spreadsheet.sheets.first
|
1100
|
+
assert_equal 'Task 1', spreadsheet.cell('f', 4)
|
1101
|
+
end
|
1093
1102
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: roo-xls
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thomas Preymesser
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2017-05-27 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: roo
|
@@ -33,33 +33,33 @@ dependencies:
|
|
33
33
|
- !ruby/object:Gem::Version
|
34
34
|
version: '3'
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
|
-
name:
|
36
|
+
name: spreadsheet
|
37
37
|
requirement: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
|
-
- - "
|
39
|
+
- - ">"
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version:
|
41
|
+
version: 0.9.0
|
42
42
|
type: :runtime
|
43
43
|
prerelease: false
|
44
44
|
version_requirements: !ruby/object:Gem::Requirement
|
45
45
|
requirements:
|
46
|
-
- - "
|
46
|
+
- - ">"
|
47
47
|
- !ruby/object:Gem::Version
|
48
|
-
version:
|
48
|
+
version: 0.9.0
|
49
49
|
- !ruby/object:Gem::Dependency
|
50
|
-
name:
|
50
|
+
name: nokogiri
|
51
51
|
requirement: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
|
-
- - "
|
53
|
+
- - ">="
|
54
54
|
- !ruby/object:Gem::Version
|
55
|
-
version: 0
|
55
|
+
version: '0'
|
56
56
|
type: :runtime
|
57
57
|
prerelease: false
|
58
58
|
version_requirements: !ruby/object:Gem::Requirement
|
59
59
|
requirements:
|
60
|
-
- - "
|
60
|
+
- - ">="
|
61
61
|
- !ruby/object:Gem::Version
|
62
|
-
version: 0
|
62
|
+
version: '0'
|
63
63
|
- !ruby/object:Gem::Dependency
|
64
64
|
name: bundler
|
65
65
|
requirement: !ruby/object:Gem::Requirement
|
@@ -204,7 +204,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
204
204
|
version: '0'
|
205
205
|
requirements: []
|
206
206
|
rubyforge_project:
|
207
|
-
rubygems_version: 2.
|
207
|
+
rubygems_version: 2.5.1
|
208
208
|
signing_key:
|
209
209
|
specification_version: 4
|
210
210
|
summary: Roo::Excel can access the contents of classic xls files.
|