saxlsx 0.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 +7 -0
- data/.gitignore +18 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +23 -0
- data/README.md +45 -0
- data/Rakefile +6 -0
- data/lib/saxlsx.rb +5 -0
- data/lib/saxlsx/boolean_parser.rb +11 -0
- data/lib/saxlsx/column_name_generator.rb +34 -0
- data/lib/saxlsx/file_system.rb +34 -0
- data/lib/saxlsx/rows_collection.rb +20 -0
- data/lib/saxlsx/rows_collection_parser.rb +66 -0
- data/lib/saxlsx/sax_parser.rb +11 -0
- data/lib/saxlsx/shared_string_collection.rb +15 -0
- data/lib/saxlsx/shared_string_collection_parser.rb +28 -0
- data/lib/saxlsx/sheet.rb +27 -0
- data/lib/saxlsx/sheet_collection.rb +16 -0
- data/lib/saxlsx/sheet_collection_parser.rb +33 -0
- data/lib/saxlsx/version.rb +3 -0
- data/lib/saxlsx/workbook.rb +39 -0
- data/saxlsx.gemspec +28 -0
- data/spec/column_name_generator_spec.rb +24 -0
- data/spec/data/Spec.xlsx +0 -0
- data/spec/sheet_spec.rb +81 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/workbook_spec.rb +53 -0
- metadata +159 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 493aa54cbea97ddfacf6c77b8bd4c44abe564a63
|
|
4
|
+
data.tar.gz: c7a03d3dd6feb9ec91951c6f8b54a75c2a1782d9
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: a9dcbd399886455139b7934253031930fbb14653e6da0257e338b07e753d286df6a61bc556f94cc620d144cfe8d00b5afaa30b82646e8414b541f69431a21c1b
|
|
7
|
+
data.tar.gz: 1dc10e83453b15fa55f93ef22404fe66cdcc6f974b37f9be35f8c47772d143725d7864d07595947889180dbe1776b76f913ec3d7520bfad9ec4a49540a30ff55
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Copyright (c) 2014 MAK IT
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
23
|
+
|
data/README.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Saxlsx
|
|
2
|
+
|
|
3
|
+
[](https://travis-ci.org/mak-it/saxlsx)
|
|
4
|
+
|
|
5
|
+
Fast XLSX reader on top of Ox SAX parser.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
Add this line to your application's Gemfile:
|
|
10
|
+
|
|
11
|
+
```ruby
|
|
12
|
+
gem 'saxlsx'
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
And then execute:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
$ bundle
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Or install it yourself as:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
$ gem install saxlsx
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
Saxslsx::Workbook.open filename do |w|
|
|
31
|
+
w.sheets.each do |s|
|
|
32
|
+
s.rows.each do |r|
|
|
33
|
+
puts r.inspect
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Contributing
|
|
40
|
+
|
|
41
|
+
1. Fork it
|
|
42
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
43
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
44
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
|
45
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/lib/saxlsx.rb
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module Saxlsx
|
|
2
|
+
class BooleanParser
|
|
3
|
+
|
|
4
|
+
def self.parse(string)
|
|
5
|
+
return true if string == true || string =~ (/(true|t|yes|y|1)$/i)
|
|
6
|
+
return false if string == false || string.nil? || string =~ (/(false|f|no|n|0)$/i)
|
|
7
|
+
raise ArgumentError.new("Invalid value for Boolean: \"#{string}\"")
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module Saxlsx
|
|
2
|
+
class ColumnNameGenerator
|
|
3
|
+
|
|
4
|
+
FIRST = 'A'
|
|
5
|
+
LAST = 'Z'
|
|
6
|
+
|
|
7
|
+
def self.next_to(previous)
|
|
8
|
+
cache previous do
|
|
9
|
+
parts = (previous || '').chars.to_a
|
|
10
|
+
char = parts.pop
|
|
11
|
+
|
|
12
|
+
if char.nil? || char.empty?
|
|
13
|
+
FIRST
|
|
14
|
+
elsif char < LAST
|
|
15
|
+
parts << (char.ord + 1).chr
|
|
16
|
+
parts.join
|
|
17
|
+
else
|
|
18
|
+
"#{next_to(parts.join)}A"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def self.cache(key, &block)
|
|
26
|
+
@cache ||= {}
|
|
27
|
+
|
|
28
|
+
return @cache[key] if @cache.has_key? key
|
|
29
|
+
|
|
30
|
+
@cache[key] = block.call
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module Saxlsx
|
|
2
|
+
class FileSystem
|
|
3
|
+
|
|
4
|
+
def self.open(filename)
|
|
5
|
+
begin
|
|
6
|
+
file_system = self.new(filename)
|
|
7
|
+
yield file_system
|
|
8
|
+
ensure
|
|
9
|
+
file_system.close
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def initialize(filename)
|
|
14
|
+
@zip = Zip::File.open filename
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def close
|
|
18
|
+
@zip.close
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def workbook
|
|
22
|
+
@zip.read('xl/workbook.xml').match(/<sheets>.*<\/sheets>/).to_s
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def shared_strings
|
|
26
|
+
@zip.read('xl/sharedStrings.xml')
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def sheets
|
|
30
|
+
@zip.glob('xl/worksheets/sheet*.xml').sort.map{ |f| @zip.read(f).match(/<sheetData>.*<\/sheetData>/).to_s }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Saxlsx
|
|
2
|
+
class RowsCollection
|
|
3
|
+
|
|
4
|
+
include Enumerable
|
|
5
|
+
|
|
6
|
+
def initialize(index, file_system, shared_strings)
|
|
7
|
+
@index = index
|
|
8
|
+
@file_system = file_system
|
|
9
|
+
@shared_strings = shared_strings
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def each(&block)
|
|
13
|
+
RowsCollectionParser.parse @index, @file_system, @shared_strings, &block
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def [](value)
|
|
17
|
+
to_a[value]
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
module Saxlsx
|
|
2
|
+
class RowsCollectionParser < Ox::Sax
|
|
3
|
+
|
|
4
|
+
def self.parse(index, file_system, shared_strings, &block)
|
|
5
|
+
SaxParser.parse self.new(shared_strings, &block), file_system.sheets[index]
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def initialize(shared_strings, &block)
|
|
9
|
+
@shared_strings = shared_strings
|
|
10
|
+
@block = block
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def start_element(name)
|
|
14
|
+
@current_element = name
|
|
15
|
+
|
|
16
|
+
if name == :row
|
|
17
|
+
@current_row = []
|
|
18
|
+
@next_column = 'A'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
@current_type = nil if name == :c
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def end_element(name)
|
|
25
|
+
if name == :row
|
|
26
|
+
@block.call @current_row
|
|
27
|
+
@current_row = nil
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def attr(name, value)
|
|
32
|
+
if @current_element == :c
|
|
33
|
+
@current_type = value if name == :t
|
|
34
|
+
@current_column = value.gsub(/\d/, '') if name == :r
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def text(value)
|
|
39
|
+
if @current_row && @current_element == :v
|
|
40
|
+
while @next_column != @current_column
|
|
41
|
+
@current_row << nil
|
|
42
|
+
@next_column = ColumnNameGenerator.next_to(@next_column)
|
|
43
|
+
end
|
|
44
|
+
@current_row << value_of(value)
|
|
45
|
+
@next_column = ColumnNameGenerator.next_to(@next_column)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
def value_of(text)
|
|
52
|
+
case @current_type
|
|
53
|
+
when 's'
|
|
54
|
+
@shared_strings[text.to_i]
|
|
55
|
+
when 'b'
|
|
56
|
+
BooleanParser.parse text
|
|
57
|
+
when 'n'
|
|
58
|
+
text.to_f
|
|
59
|
+
else
|
|
60
|
+
text
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module Saxlsx
|
|
2
|
+
class SharedStringCollectionParser < Ox::Sax
|
|
3
|
+
|
|
4
|
+
def self.parse(file_system, &block)
|
|
5
|
+
SaxParser.parse self.new(&block), file_system.shared_strings
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def initialize(&block)
|
|
9
|
+
@block = block
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def start_element(name)
|
|
13
|
+
@current_string = '' if name == :si
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def end_element(name)
|
|
17
|
+
if name == :si
|
|
18
|
+
@block.call @current_string
|
|
19
|
+
@current_string = nil
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def text(value)
|
|
24
|
+
@current_string << CGI.unescapeHTML(value) if @current_string
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
end
|
data/lib/saxlsx/sheet.rb
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Saxlsx
|
|
2
|
+
class Sheet
|
|
3
|
+
|
|
4
|
+
attr_reader :name
|
|
5
|
+
|
|
6
|
+
def initialize(name, index, file_system, shared_strings)
|
|
7
|
+
@name = name
|
|
8
|
+
@index = index
|
|
9
|
+
@file_system = file_system
|
|
10
|
+
@shared_strings = shared_strings
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def rows
|
|
14
|
+
@rows ||= RowsCollection.new(@index, @file_system, @shared_strings)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def to_csv(path)
|
|
18
|
+
FileUtils.mkpath path unless Dir.exists? path
|
|
19
|
+
File.open("#{path}/#{name}.csv", 'w') do |f|
|
|
20
|
+
rows.each do |row|
|
|
21
|
+
f.puts row.map{|c| "\"#{c}\""}.join(',')
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Saxlsx
|
|
2
|
+
class SheetCollection
|
|
3
|
+
|
|
4
|
+
include Enumerable
|
|
5
|
+
|
|
6
|
+
def initialize(file_system, shared_strings)
|
|
7
|
+
@file_system = file_system
|
|
8
|
+
@shared_strings = shared_strings
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def each(&block)
|
|
12
|
+
SheetCollectionParser.parse @file_system, @shared_strings, &block
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Saxlsx
|
|
2
|
+
class SheetCollectionParser < Ox::Sax
|
|
3
|
+
|
|
4
|
+
CurrentSheet = Struct.new :index, :name
|
|
5
|
+
|
|
6
|
+
def self.parse(file_system, shared_strings, &block)
|
|
7
|
+
SaxParser.parse self.new(file_system, shared_strings, &block), file_system.workbook
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def initialize(file_system, shared_strings, &block)
|
|
11
|
+
@file_system = file_system
|
|
12
|
+
@shared_strings = shared_strings
|
|
13
|
+
@block = block
|
|
14
|
+
@index = -1
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def start_element(name)
|
|
18
|
+
@current_sheet = CurrentSheet.new(@index += 1) if name == :sheet
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def end_element(name)
|
|
22
|
+
if name == :sheet
|
|
23
|
+
@block.call Sheet.new(@current_sheet.name, @current_sheet.index, @file_system, @shared_strings)
|
|
24
|
+
@current_sheet = nil
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def attr(name, value)
|
|
29
|
+
@current_sheet.name = value if @current_sheet && name == :name
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module Saxlsx
|
|
2
|
+
class Workbook
|
|
3
|
+
|
|
4
|
+
def self.open(filename)
|
|
5
|
+
begin
|
|
6
|
+
workbook = self.new(filename)
|
|
7
|
+
yield workbook
|
|
8
|
+
ensure
|
|
9
|
+
workbook.close
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def initialize(filename)
|
|
14
|
+
@file_system = FileSystem.new filename
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def close
|
|
18
|
+
@file_system.close
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def sheets(name=nil)
|
|
22
|
+
@sheets ||= SheetCollection.new(@file_system, shared_strings).to_a
|
|
23
|
+
name.nil? ? @sheets : @sheets.detect { |s| s.name == name }
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def sheet_names
|
|
27
|
+
sheets.map(&:name)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def shared_strings
|
|
31
|
+
@shared_strings ||= SharedStringCollection.new(@file_system).to_a
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def to_csv(path)
|
|
35
|
+
sheets.each { |s| s.to_csv path }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
39
|
+
end
|
data/saxlsx.gemspec
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'saxlsx/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "saxlsx"
|
|
8
|
+
spec.version = Saxlsx::VERSION
|
|
9
|
+
spec.authors = ["Edgars Beigarts"]
|
|
10
|
+
spec.email = ["edgars.beigarts@makit.lv"]
|
|
11
|
+
spec.description = 'Fast xlsx reader on top of Ox SAX parser'
|
|
12
|
+
spec.summary = 'Fast xlsx reader on top of Ox SAX parser'
|
|
13
|
+
spec.homepage = "https://github.com/mak-it/saxlsx"
|
|
14
|
+
spec.license = "MIT"
|
|
15
|
+
|
|
16
|
+
spec.files = `git ls-files`.split($/)
|
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
18
|
+
spec.test_files = spec.files.grep(%r{^spec/})
|
|
19
|
+
spec.require_paths = ["lib"]
|
|
20
|
+
|
|
21
|
+
spec.add_dependency 'rubyzip', '~> 1.0'
|
|
22
|
+
spec.add_dependency 'ox', '~> 2.1'
|
|
23
|
+
|
|
24
|
+
spec.add_development_dependency 'bundler', "~> 1.5"
|
|
25
|
+
spec.add_development_dependency 'rake', '~> 10.1'
|
|
26
|
+
spec.add_development_dependency 'rspec', '~> 2.14'
|
|
27
|
+
spec.add_development_dependency 'simplecov', '~> 0.8'
|
|
28
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe ColumnNameGenerator do
|
|
4
|
+
|
|
5
|
+
it 'First char' do
|
|
6
|
+
ColumnNameGenerator::FIRST.should eq 'A'
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it 'Last char' do
|
|
10
|
+
ColumnNameGenerator::LAST.should eq 'Z'
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it 'Next value' do
|
|
14
|
+
ColumnNameGenerator.tap do |g|
|
|
15
|
+
g.next_to(nil).should eq 'A'
|
|
16
|
+
g.next_to('F').should eq 'G'
|
|
17
|
+
g.next_to('DM').should eq 'DN'
|
|
18
|
+
g.next_to('RZ').should eq 'SA'
|
|
19
|
+
g.next_to('ZZ').should eq 'AAA'
|
|
20
|
+
g.next_to('EDT').should eq 'EDU'
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
data/spec/data/Spec.xlsx
ADDED
|
Binary file
|
data/spec/sheet_spec.rb
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
|
|
4
|
+
describe Sheet do
|
|
5
|
+
|
|
6
|
+
let(:filename) { "#{File.dirname(__FILE__)}/data/Spec.xlsx" }
|
|
7
|
+
let(:tmp_path) { "#{File.dirname(__FILE__)}/../tmp" }
|
|
8
|
+
|
|
9
|
+
before :each do
|
|
10
|
+
FileUtils.rm_rf tmp_path if Dir.exists? tmp_path
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it 'Rows count' do
|
|
14
|
+
Workbook.open filename do |w|
|
|
15
|
+
w.sheets[0].should have(7).rows
|
|
16
|
+
w.sheets[1].should have(9).rows
|
|
17
|
+
w.sheets[2].should have(3).rows
|
|
18
|
+
w.sheets[3].should have(2).rows
|
|
19
|
+
w.sheets[4].should have(3).rows
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it 'Rows collection' do
|
|
24
|
+
Workbook.open filename do |w|
|
|
25
|
+
w.sheets[0].rows.should be_an_instance_of RowsCollection
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'Rows content' do
|
|
30
|
+
Workbook.open filename do |w|
|
|
31
|
+
w.sheets[0].tap do |s|
|
|
32
|
+
s.rows[0].should eq ['LevenshteinDistance', 0]
|
|
33
|
+
s.rows[1].should eq ['Case sensitive', false]
|
|
34
|
+
s.rows[2].should eq ['Fields', 'Type', 'URL Mining']
|
|
35
|
+
s.rows[3].should eq ['autor', 'text', false]
|
|
36
|
+
s.rows[4].should eq ['texto', 'text', false]
|
|
37
|
+
s.rows[5].should eq ['url', 'text', false]
|
|
38
|
+
s.rows[6].should eq ['comentario', 'text', false]
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it 'Rows content skipping cells' do
|
|
44
|
+
Workbook.open filename do |w|
|
|
45
|
+
w.sheets[3].tap do |s|
|
|
46
|
+
s.rows[0].should eq [nil, 'en', 'es', 'pt', 'un']
|
|
47
|
+
s.rows[1].should eq ['default', 30, 50, 15, 5]
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it 'Rows content with tag separators (>)' do
|
|
53
|
+
Workbook.open filename do |w|
|
|
54
|
+
w.sheets[4].tap do |s|
|
|
55
|
+
s.rows[0].should eq ['Especificacion', 'Concepto/RegExp/Pair', 'ClienteTexto_Campos', 'ClienteTexto_Especificacion']
|
|
56
|
+
s.rows[1].should eq ['Discriminación > Sexual | Insulto', 'puto', 'texto', 'TST_RechAuto_Insulto_SE_Normal']
|
|
57
|
+
s.rows[2].should eq ['Insulto', 'boludo', 'texto', 'TST_ModMan_Insulto_SU_Normal']
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it 'Export to CSV' do
|
|
63
|
+
Workbook.open filename do |w|
|
|
64
|
+
csv_file = "#{tmp_path}/#{w.sheets[0].name}.csv"
|
|
65
|
+
|
|
66
|
+
File.should_not be_exists csv_file
|
|
67
|
+
|
|
68
|
+
w.sheets[0].to_csv tmp_path
|
|
69
|
+
|
|
70
|
+
csv = File.open(csv_file, 'r') { |f| f.readlines }
|
|
71
|
+
csv[0].should eq "\"LevenshteinDistance\",\"0.0\"\n"
|
|
72
|
+
csv[1].should eq "\"Case sensitive\",\"false\"\n"
|
|
73
|
+
csv[2].should eq "\"Fields\",\"Type\",\"URL Mining\"\n"
|
|
74
|
+
csv[3].should eq "\"autor\",\"text\",\"false\"\n"
|
|
75
|
+
csv[4].should eq "\"texto\",\"text\",\"false\"\n"
|
|
76
|
+
csv[5].should eq "\"url\",\"text\",\"false\"\n"
|
|
77
|
+
csv[6].should eq "\"comentario\",\"text\",\"false\"\n"
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Workbook do
|
|
4
|
+
|
|
5
|
+
let(:filename) { "#{File.dirname(__FILE__)}/data/Spec.xlsx" }
|
|
6
|
+
|
|
7
|
+
it 'Sheets count' do
|
|
8
|
+
Workbook.open filename do |w|
|
|
9
|
+
w.should have(5).sheets
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it 'Sheet names' do
|
|
14
|
+
Workbook.open filename do |w|
|
|
15
|
+
w.sheet_names.should eq %w(test_otros test_spec test_param Lenguajes ont_demo)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'Find sheet by index' do
|
|
20
|
+
Workbook.open filename do |w|
|
|
21
|
+
w.sheets[0].name.should eq 'test_otros'
|
|
22
|
+
w.sheets[1].name.should eq 'test_spec'
|
|
23
|
+
w.sheets[2].name.should eq 'test_param'
|
|
24
|
+
w.sheets[3].name.should eq 'Lenguajes'
|
|
25
|
+
w.sheets[4].name.should eq 'ont_demo'
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'Find sheet by name' do
|
|
30
|
+
Workbook.open filename do |w|
|
|
31
|
+
w.sheets('test_otros').name.should eq 'test_otros'
|
|
32
|
+
w.sheets('test_spec').name.should eq 'test_spec'
|
|
33
|
+
w.sheets('test_param').name.should eq 'test_param'
|
|
34
|
+
w.sheets('Lenguajes').name.should eq 'Lenguajes'
|
|
35
|
+
w.sheets('ont_demo').name.should eq 'ont_demo'
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'Shared strings' do
|
|
40
|
+
Workbook.open filename do |w|
|
|
41
|
+
w.should have(56).shared_strings
|
|
42
|
+
w.shared_strings[0].should eq 'LevenshteinDistance'
|
|
43
|
+
w.shared_strings[55].should eq 'TST_ModMan_Insulto_SU_Normal'
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it 'Export to CSV' do
|
|
48
|
+
Workbook.open filename do |w|
|
|
49
|
+
w.sheets.each { |s| s.should_receive(:to_csv).with(Dir.pwd) }
|
|
50
|
+
w.to_csv Dir.pwd
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: saxlsx
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Edgars Beigarts
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2014-02-12 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: rubyzip
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '1.0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '1.0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: ox
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '2.1'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '2.1'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: bundler
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '1.5'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '1.5'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: rake
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '10.1'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '10.1'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: rspec
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "~>"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '2.14'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - "~>"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '2.14'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: simplecov
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - "~>"
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0.8'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - "~>"
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0.8'
|
|
97
|
+
description: Fast xlsx reader on top of Ox SAX parser
|
|
98
|
+
email:
|
|
99
|
+
- edgars.beigarts@makit.lv
|
|
100
|
+
executables: []
|
|
101
|
+
extensions: []
|
|
102
|
+
extra_rdoc_files: []
|
|
103
|
+
files:
|
|
104
|
+
- ".gitignore"
|
|
105
|
+
- ".travis.yml"
|
|
106
|
+
- Gemfile
|
|
107
|
+
- LICENSE.txt
|
|
108
|
+
- README.md
|
|
109
|
+
- Rakefile
|
|
110
|
+
- lib/saxlsx.rb
|
|
111
|
+
- lib/saxlsx/boolean_parser.rb
|
|
112
|
+
- lib/saxlsx/column_name_generator.rb
|
|
113
|
+
- lib/saxlsx/file_system.rb
|
|
114
|
+
- lib/saxlsx/rows_collection.rb
|
|
115
|
+
- lib/saxlsx/rows_collection_parser.rb
|
|
116
|
+
- lib/saxlsx/sax_parser.rb
|
|
117
|
+
- lib/saxlsx/shared_string_collection.rb
|
|
118
|
+
- lib/saxlsx/shared_string_collection_parser.rb
|
|
119
|
+
- lib/saxlsx/sheet.rb
|
|
120
|
+
- lib/saxlsx/sheet_collection.rb
|
|
121
|
+
- lib/saxlsx/sheet_collection_parser.rb
|
|
122
|
+
- lib/saxlsx/version.rb
|
|
123
|
+
- lib/saxlsx/workbook.rb
|
|
124
|
+
- saxlsx.gemspec
|
|
125
|
+
- spec/column_name_generator_spec.rb
|
|
126
|
+
- spec/data/Spec.xlsx
|
|
127
|
+
- spec/sheet_spec.rb
|
|
128
|
+
- spec/spec_helper.rb
|
|
129
|
+
- spec/workbook_spec.rb
|
|
130
|
+
homepage: https://github.com/mak-it/saxlsx
|
|
131
|
+
licenses:
|
|
132
|
+
- MIT
|
|
133
|
+
metadata: {}
|
|
134
|
+
post_install_message:
|
|
135
|
+
rdoc_options: []
|
|
136
|
+
require_paths:
|
|
137
|
+
- lib
|
|
138
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
139
|
+
requirements:
|
|
140
|
+
- - ">="
|
|
141
|
+
- !ruby/object:Gem::Version
|
|
142
|
+
version: '0'
|
|
143
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
144
|
+
requirements:
|
|
145
|
+
- - ">="
|
|
146
|
+
- !ruby/object:Gem::Version
|
|
147
|
+
version: '0'
|
|
148
|
+
requirements: []
|
|
149
|
+
rubyforge_project:
|
|
150
|
+
rubygems_version: 2.2.0.rc.1
|
|
151
|
+
signing_key:
|
|
152
|
+
specification_version: 4
|
|
153
|
+
summary: Fast xlsx reader on top of Ox SAX parser
|
|
154
|
+
test_files:
|
|
155
|
+
- spec/column_name_generator_spec.rb
|
|
156
|
+
- spec/data/Spec.xlsx
|
|
157
|
+
- spec/sheet_spec.rb
|
|
158
|
+
- spec/spec_helper.rb
|
|
159
|
+
- spec/workbook_spec.rb
|