sheets 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.
- data/.gitignore +4 -1
- data/.travis.yml +6 -0
- data/README.md +12 -4
- data/Rakefile +51 -3
- data/lib/sheets/parsers/excel_parser.rb +16 -0
- data/lib/sheets/parsers/nokogiri_ods_parser.rb +47 -0
- data/lib/sheets/parsers/nokogiri_xlsx_parser.rb +79 -0
- data/lib/sheets/version.rb +1 -1
- data/sheets.gemspec +2 -4
- data/test/data/simple.csv +10 -10
- data/test/parsers/basic_parsers_test.rb +27 -2
- data/test/renderers/basic_renderers_test.rb +1 -1
- data/test/results.json +13 -0
- metadata +31 -76
- data/lib/sheets/parsers/roo_parser.rb +0 -29
- data/lib/sheets/parsers/roo_patches.rb +0 -5
- data/lib/sheets/parsers/roo_patches/roo_patch_28885.rb +0 -116
- data/lib/sheets/parsers/roo_patches/roo_patch_29045.rb +0 -2
- data/test/parsers/roo_parser_test.rb +0 -8
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -14,7 +14,7 @@ Your application only needs to care about the layout of the spreadsheet, and the
|
|
14
14
|
Usage
|
15
15
|
----------
|
16
16
|
|
17
|
-
Install via Rubygems:
|
17
|
+
Install via Rubygems:
|
18
18
|
|
19
19
|
gem install sheets
|
20
20
|
|
@@ -80,6 +80,13 @@ Renderers subclass Sheets::Renderers::Base, live in the Sheets::Renderers namesp
|
|
80
80
|
|
81
81
|
Renderers are given access to the results of Sheets::Base#to_array as @data. See lib/sheets/renderers/* for examples.
|
82
82
|
|
83
|
+
Test Suite Results
|
84
|
+
-----
|
85
|
+
|
86
|
+
Sheets uses Travis-CI for Continuous Integration.
|
87
|
+
|
88
|
+
[](http://travis-ci.org/bspaulding/Sheets)
|
89
|
+
|
83
90
|
License
|
84
91
|
----------
|
85
92
|
|
@@ -90,7 +97,8 @@ Please note that Sheets is dependent upon the Spreadsheet gem, which is licensed
|
|
90
97
|
Credits
|
91
98
|
----------
|
92
99
|
|
93
|
-
Sheets takes
|
100
|
+
Sheets takes advantage of the work done in these gems:
|
94
101
|
|
95
|
-
* [
|
96
|
-
* [
|
102
|
+
* [spreadsheet](http://rubygems.org/gems/spreadsheet)
|
103
|
+
* [rubyzip](http://rubygems.org/gems/rubyzip)
|
104
|
+
* [nokogiri](http://rubygems.org/gems/nokogiri)
|
data/Rakefile
CHANGED
@@ -1,7 +1,55 @@
|
|
1
|
+
# require 'rubygems'
|
1
2
|
require 'bundler'
|
2
3
|
Bundler::GemHelper.install_tasks
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
5
|
+
testing_rubies = %w[1.8.7 1.9.2 ree ree-1.8.7-2010.01 jruby rbx]
|
6
|
+
|
7
|
+
task :default => :test
|
8
|
+
|
9
|
+
namespace :test do
|
10
|
+
task :current do
|
11
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), 'test', 'test_helper.rb')
|
12
|
+
Dir[ File.join(File.expand_path(File.dirname(__FILE__)), 'test', '**', '*_test.rb') ].each {|file| require file }
|
13
|
+
end
|
14
|
+
|
15
|
+
task :all do
|
16
|
+
File.delete('test/results.json') if File.exists?('test/results.json')
|
17
|
+
system "rvm --json #{testing_rubies.join(',')} rake test > test/results.json"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
task :test => ['test:current']
|
22
|
+
|
23
|
+
namespace :install do
|
24
|
+
def ruby_installed?(ruby)
|
25
|
+
!%x[rvm use #{ruby}].include?('not installed')
|
26
|
+
end
|
27
|
+
|
28
|
+
task :rubies do
|
29
|
+
testing_rubies.each do |ruby|
|
30
|
+
puts ruby
|
31
|
+
puts "----------"
|
32
|
+
|
33
|
+
ruby_installed?(ruby) ? puts('- Installed.') : system("rvm install #{ruby}")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
task :bundles => :rubies do
|
38
|
+
testing_rubies.each do |ruby|
|
39
|
+
puts ruby
|
40
|
+
puts "----------"
|
41
|
+
|
42
|
+
puts '- Installing bundler...'
|
43
|
+
system "rvm #{ruby} gem install --no-rdoc --no-ri bundler"
|
44
|
+
|
45
|
+
puts '- Installing bundle...'
|
46
|
+
system "rvm #{ruby} exec bundle install"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
namespace :clean do
|
52
|
+
task :rbx do
|
53
|
+
Dir[ File.join(File.expand_path(File.dirname(__FILE__)), '**', '*.rbc') ].each {|file| File.delete(file) }
|
54
|
+
end
|
7
55
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spreadsheet'
|
2
|
+
|
3
|
+
class Sheets::Parsers::ExcelParser < Sheets::Parsers::Base
|
4
|
+
parses :xls
|
5
|
+
|
6
|
+
def to_array
|
7
|
+
workbook = Spreadsheet.open(@file_path)
|
8
|
+
worksheet = workbook.worksheet(0)
|
9
|
+
# worksheet.collect {|row| row.collect {|cell| cell } }
|
10
|
+
worksheet.collect do |row|
|
11
|
+
cells = []
|
12
|
+
row.count.times {|cell_index| cells << row[cell_index].to_s }
|
13
|
+
cells
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'zip/zip'
|
3
|
+
|
4
|
+
class Sheets::Parsers::NokogiriOdsParser < Sheets::Parsers::Base
|
5
|
+
parses :ods
|
6
|
+
|
7
|
+
def to_array
|
8
|
+
rows.collect do |row|
|
9
|
+
table_cells = []
|
10
|
+
row.xpath('table:table-cell').each do |cell|
|
11
|
+
repeat = cell.attributes["number-columns-repeated"].text.to_i if cell.attributes["number-columns-repeated"]
|
12
|
+
repeat ||= 1
|
13
|
+
repeat.times { table_cells << cell }
|
14
|
+
end
|
15
|
+
|
16
|
+
table_cells.collect {|cell| value_for_cell(cell) }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
# returns the zipfile object for the document
|
23
|
+
def zipfile
|
24
|
+
@zipfile ||= Zip::ZipFile.open( @file_path )
|
25
|
+
end
|
26
|
+
|
27
|
+
def content_doc
|
28
|
+
@content_doc ||= Nokogiri::XML( zipfile.read('content.xml') )
|
29
|
+
end
|
30
|
+
|
31
|
+
def rows
|
32
|
+
@rows ||= content_doc.xpath('//table:table/table:table-row')
|
33
|
+
end
|
34
|
+
|
35
|
+
def value_for_cell(cell_element)
|
36
|
+
value_type = cell_element.attributes["value-type"]
|
37
|
+
send("#{value_type}_value_for_cell", cell_element)
|
38
|
+
end
|
39
|
+
|
40
|
+
def string_value_for_cell(cell_element)
|
41
|
+
cell_element.xpath('text:p').text
|
42
|
+
end
|
43
|
+
|
44
|
+
def float_value_for_cell(cell_element)
|
45
|
+
cell_element.xpath('text:p').text.to_f.to_s
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'zip/zip'
|
3
|
+
|
4
|
+
class Sheets::Parsers::NokogiriXlsxParser < Sheets::Parsers::Base
|
5
|
+
parses :xlsx
|
6
|
+
|
7
|
+
def to_array
|
8
|
+
# Create Matrices
|
9
|
+
matrices = worksheets.collect do |worksheet|
|
10
|
+
worksheet.css('sheetData>row').collect do |row|
|
11
|
+
row.css('c').collect do |cell|
|
12
|
+
cell_value = cell.css('v').text
|
13
|
+
|
14
|
+
if cell.attribute('t')
|
15
|
+
celltype = cell.attribute('t').value
|
16
|
+
if celltype == 's'
|
17
|
+
# Load Shared String Value
|
18
|
+
cell_value = shared_strings[cell_value.to_i]
|
19
|
+
elsif celltype == 'b'
|
20
|
+
cell_value = (cell_value == "1") ? "TRUE" : "FALSE"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
if cell.attribute('s') && cell.attribute('s').value == "1"
|
25
|
+
cell_value = (base_date + cell_value.to_f).strftime('%Y-%m-%d') # Date conversion
|
26
|
+
end
|
27
|
+
|
28
|
+
if cell_value.match(/\A[0-9]+\.?[0-9]*\Z/)
|
29
|
+
cell_value = cell_value.to_f.to_s
|
30
|
+
end
|
31
|
+
|
32
|
+
cell_value
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
matrices.first
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
# returns the zipfile object for the document
|
43
|
+
def zipfile
|
44
|
+
@zipfile ||= Zip::ZipFile.open( @file_path )
|
45
|
+
end
|
46
|
+
|
47
|
+
# returns a nokogiri document for the workbook
|
48
|
+
def workbook
|
49
|
+
@workbook ||= Nokogiri::XML( zipfile.read("xl/workbook.xml") )
|
50
|
+
end
|
51
|
+
|
52
|
+
# returns an array of strings for the sharedStrings.
|
53
|
+
def shared_strings
|
54
|
+
@shared_strings ||= Nokogiri::XML( zipfile.read("xl/sharedStrings.xml") ).css('si>t').collect(&:text)
|
55
|
+
end
|
56
|
+
|
57
|
+
# returns an array of strings containing the worksheet ids from the workbook
|
58
|
+
def worksheet_ids
|
59
|
+
@sheet_ids ||= workbook.css('sheets>sheet').collect {|sheet| sheet.attribute('sheetId').value }
|
60
|
+
end
|
61
|
+
|
62
|
+
# returns an array of nokogiri documents for each worksheet
|
63
|
+
def worksheets
|
64
|
+
@worksheets ||= worksheet_ids.collect {|sheet_id| Nokogiri::XML( zipfile.read("xl/worksheets/sheet#{sheet_id}.xml") ) }
|
65
|
+
end
|
66
|
+
|
67
|
+
# returns a date object representing the start of the serial date system for this sheet
|
68
|
+
# Either 1900-01-01 or 1904-01-01
|
69
|
+
def base_date
|
70
|
+
@base_date ||= lambda do
|
71
|
+
date_base_element = workbook.search('workbookPr').attribute('date1904')
|
72
|
+
if date_base_element && date_base_element.value.to_i == 1
|
73
|
+
Date.parse('1904-01-01')
|
74
|
+
else
|
75
|
+
Date.parse('1900-01-01')
|
76
|
+
end
|
77
|
+
end.call
|
78
|
+
end
|
79
|
+
end
|
data/lib/sheets/version.rb
CHANGED
data/sheets.gemspec
CHANGED
@@ -15,12 +15,10 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.rubyforge_project = "sheets"
|
16
16
|
|
17
17
|
s.add_dependency('spreadsheet', '>= 0.6.5.2')
|
18
|
-
s.add_dependency('roo', '= 1.9.3')
|
19
|
-
# These are the dependencies roo forgot:
|
20
|
-
s.add_dependency('builder', '>= 3.0.0')
|
21
18
|
s.add_dependency('rubyzip', '>= 0.9.4')
|
22
19
|
s.add_dependency('nokogiri', '>= 1.4.3.1')
|
23
|
-
|
20
|
+
|
21
|
+
s.add_development_dependency('rake', '0.9.2')
|
24
22
|
|
25
23
|
s.files = `git ls-files`.split("\n")
|
26
24
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
data/test/data/simple.csv
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
Date,Impressions,Clicks,Actions
|
2
|
-
2011-01-01,10,10,10
|
3
|
-
2011-01-02,10,10,10
|
4
|
-
2011-01-03,10,10,10
|
5
|
-
2011-01-04,10,10,10
|
6
|
-
2011-01-05,10,10,10
|
7
|
-
2011-01-06,10,10,10
|
8
|
-
2011-01-07,10,10,10
|
9
|
-
2011-01-08,10,10,10
|
10
|
-
2011-01-09,10,10,10
|
11
|
-
2011-01-10,10,10,10
|
2
|
+
2011-01-01,10.0,10.0,10.0
|
3
|
+
2011-01-02,10.0,10.0,10.0
|
4
|
+
2011-01-03,10.0,10.0,10.0
|
5
|
+
2011-01-04,10.0,10.0,10.0
|
6
|
+
2011-01-05,10.0,10.0,10.0
|
7
|
+
2011-01-06,10.0,10.0,10.0
|
8
|
+
2011-01-07,10.0,10.0,10.0
|
9
|
+
2011-01-08,10.0,10.0,10.0
|
10
|
+
2011-01-09,10.0,10.0,10.0
|
11
|
+
2011-01-10,10.0,10.0,10.0
|
@@ -1,4 +1,4 @@
|
|
1
|
-
parser_classes = (Sheets::Parsers.constants - ["Base"]).map {|constant_name| Sheets::Parsers.const_get(constant_name) }
|
1
|
+
parser_classes = (Sheets::Parsers.constants.map(&:to_s) - ["Base"]).map {|constant_name| Sheets::Parsers.const_get(constant_name) }
|
2
2
|
|
3
3
|
test_classes_for_collection parser_classes do |parser_class|
|
4
4
|
define_method :test_provides_formats do
|
@@ -10,9 +10,34 @@ test_classes_for_collection parser_classes do |parser_class|
|
|
10
10
|
end
|
11
11
|
|
12
12
|
parser_class.formats.each do |format|
|
13
|
-
define_method "test_#{format}
|
13
|
+
define_method "test_#{format}_responds_to_to_array" do
|
14
14
|
parser = parser_class.new([], format, nil)
|
15
15
|
assert parser.respond_to?("to_array"), "#{parser.inspect} doesn't respond to to_array"
|
16
16
|
end
|
17
|
+
|
18
|
+
define_method "test_#{format}_to_array_matches_sample_data" do
|
19
|
+
example_data = [
|
20
|
+
[ "Date", "Impressions", "Clicks", "Actions" ],
|
21
|
+
[ "2011-01-01", "10.0", "10.0", "10.0" ],
|
22
|
+
[ "2011-01-02", "10.0", "10.0", "10.0" ],
|
23
|
+
[ "2011-01-03", "10.0", "10.0", "10.0" ],
|
24
|
+
[ "2011-01-04", "10.0", "10.0", "10.0" ],
|
25
|
+
[ "2011-01-05", "10.0", "10.0", "10.0" ],
|
26
|
+
[ "2011-01-06", "10.0", "10.0", "10.0" ],
|
27
|
+
[ "2011-01-07", "10.0", "10.0", "10.0" ],
|
28
|
+
[ "2011-01-08", "10.0", "10.0", "10.0" ],
|
29
|
+
[ "2011-01-09", "10.0", "10.0", "10.0" ],
|
30
|
+
[ "2011-01-10", "10.0", "10.0", "10.0" ]
|
31
|
+
]
|
32
|
+
|
33
|
+
file_path = File.expand_path( File.join('test', 'data', "simple.#{format}") )
|
34
|
+
parser = parser_class.new( File.read(file_path), format, file_path )
|
35
|
+
result = parser.to_array
|
36
|
+
|
37
|
+
# Normalize to parsed dates to avoid Date type conflict 'failures'
|
38
|
+
result[1..-1].collect {|row| row[0] = Date.parse(row[0]).strftime('%Y-%m-%d') }
|
39
|
+
|
40
|
+
assert_equal example_data, result, "#{parser_class}#to_array for format #{format} doesn't match example data."
|
41
|
+
end
|
17
42
|
end
|
18
43
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
renderer_classes = (Sheets::Renderers.constants - ["Base"]).map {|constant_name| Sheets::Renderers.const_get(constant_name) }
|
1
|
+
renderer_classes = (Sheets::Renderers.constants.map(&:to_s) - ["Base"]).map {|constant_name| Sheets::Renderers.const_get(constant_name) }
|
2
2
|
|
3
3
|
test_classes_for_collection renderer_classes do |renderer_class|
|
4
4
|
define_method :test_provides_formats do
|
data/test/results.json
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
{
|
2
|
+
"totals": { "rubies": 6, "successes": 6, "errors": 0 },
|
3
|
+
"successful": ["ruby-1.8.7-p334", "ruby-1.9.2-p180", "ree-1.8.7-2011.03", "ree-1.8.7-2010.01", "jruby-1.6.1", "rbx-head"],
|
4
|
+
"errors": [],
|
5
|
+
"rubies": {
|
6
|
+
{"ruby-1.8.7-p334": 0},
|
7
|
+
{"ruby-1.9.2-p180": 0},
|
8
|
+
{"ree-1.8.7-2011.03": 0},
|
9
|
+
{"ree-1.8.7-2010.01": 0},
|
10
|
+
{"jruby-1.6.1": 0},
|
11
|
+
{"rbx-head": 0}
|
12
|
+
}
|
13
|
+
}
|
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sheets
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
4
|
+
prerelease: false
|
6
5
|
segments:
|
7
6
|
- 1
|
7
|
+
- 1
|
8
8
|
- 0
|
9
|
-
|
10
|
-
version: 1.0.0
|
9
|
+
version: 1.1.0
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- Bradley J. Spaulding
|
@@ -15,107 +14,67 @@ autorequire:
|
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
16
|
|
18
|
-
date: 2011-
|
17
|
+
date: 2011-11-29 00:00:00 -05:00
|
19
18
|
default_executable:
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|
22
|
-
|
23
|
-
prerelease: false
|
24
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
21
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
26
22
|
requirements:
|
27
23
|
- - ">="
|
28
24
|
- !ruby/object:Gem::Version
|
29
|
-
hash: 111
|
30
25
|
segments:
|
31
26
|
- 0
|
32
27
|
- 6
|
33
28
|
- 5
|
34
29
|
- 2
|
35
30
|
version: 0.6.5.2
|
36
|
-
|
37
|
-
|
38
|
-
- !ruby/object:Gem::Dependency
|
39
|
-
name: roo
|
40
|
-
prerelease: false
|
41
|
-
requirement: &id002 !ruby/object:Gem::Requirement
|
42
|
-
none: false
|
43
|
-
requirements:
|
44
|
-
- - "="
|
45
|
-
- !ruby/object:Gem::Version
|
46
|
-
hash: 53
|
47
|
-
segments:
|
48
|
-
- 1
|
49
|
-
- 9
|
50
|
-
- 3
|
51
|
-
version: 1.9.3
|
52
|
-
type: :runtime
|
53
|
-
version_requirements: *id002
|
54
|
-
- !ruby/object:Gem::Dependency
|
55
|
-
name: builder
|
31
|
+
requirement: *id001
|
32
|
+
name: spreadsheet
|
56
33
|
prerelease: false
|
57
|
-
requirement: &id003 !ruby/object:Gem::Requirement
|
58
|
-
none: false
|
59
|
-
requirements:
|
60
|
-
- - ">="
|
61
|
-
- !ruby/object:Gem::Version
|
62
|
-
hash: 7
|
63
|
-
segments:
|
64
|
-
- 3
|
65
|
-
- 0
|
66
|
-
- 0
|
67
|
-
version: 3.0.0
|
68
34
|
type: :runtime
|
69
|
-
version_requirements: *id003
|
70
35
|
- !ruby/object:Gem::Dependency
|
71
|
-
|
72
|
-
prerelease: false
|
73
|
-
requirement: &id004 !ruby/object:Gem::Requirement
|
74
|
-
none: false
|
36
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
75
37
|
requirements:
|
76
38
|
- - ">="
|
77
39
|
- !ruby/object:Gem::Version
|
78
|
-
hash: 51
|
79
40
|
segments:
|
80
41
|
- 0
|
81
42
|
- 9
|
82
43
|
- 4
|
83
44
|
version: 0.9.4
|
45
|
+
requirement: *id002
|
46
|
+
name: rubyzip
|
47
|
+
prerelease: false
|
84
48
|
type: :runtime
|
85
|
-
version_requirements: *id004
|
86
49
|
- !ruby/object:Gem::Dependency
|
87
|
-
|
88
|
-
prerelease: false
|
89
|
-
requirement: &id005 !ruby/object:Gem::Requirement
|
90
|
-
none: false
|
50
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
91
51
|
requirements:
|
92
52
|
- - ">="
|
93
53
|
- !ruby/object:Gem::Version
|
94
|
-
hash: 113
|
95
54
|
segments:
|
96
55
|
- 1
|
97
56
|
- 4
|
98
57
|
- 3
|
99
58
|
- 1
|
100
59
|
version: 1.4.3.1
|
60
|
+
requirement: *id003
|
61
|
+
name: nokogiri
|
62
|
+
prerelease: false
|
101
63
|
type: :runtime
|
102
|
-
version_requirements: *id005
|
103
64
|
- !ruby/object:Gem::Dependency
|
104
|
-
|
105
|
-
prerelease: false
|
106
|
-
requirement: &id006 !ruby/object:Gem::Requirement
|
107
|
-
none: false
|
65
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
108
66
|
requirements:
|
109
|
-
- - "
|
67
|
+
- - "="
|
110
68
|
- !ruby/object:Gem::Version
|
111
|
-
hash: 25
|
112
69
|
segments:
|
113
70
|
- 0
|
114
|
-
-
|
115
|
-
-
|
116
|
-
version: 0.
|
117
|
-
|
118
|
-
|
71
|
+
- 9
|
72
|
+
- 2
|
73
|
+
version: 0.9.2
|
74
|
+
requirement: *id004
|
75
|
+
name: rake
|
76
|
+
prerelease: false
|
77
|
+
type: :development
|
119
78
|
description: Work with spreadsheets easily in a native ruby format.
|
120
79
|
email:
|
121
80
|
- brad.spaulding@gmail.com
|
@@ -127,6 +86,7 @@ extra_rdoc_files: []
|
|
127
86
|
|
128
87
|
files:
|
129
88
|
- .gitignore
|
89
|
+
- .travis.yml
|
130
90
|
- Gemfile
|
131
91
|
- LICENSE.txt
|
132
92
|
- README.md
|
@@ -136,10 +96,9 @@ files:
|
|
136
96
|
- lib/sheets/parseable.rb
|
137
97
|
- lib/sheets/parsers/base.rb
|
138
98
|
- lib/sheets/parsers/csv_parser.rb
|
139
|
-
- lib/sheets/parsers/
|
140
|
-
- lib/sheets/parsers/
|
141
|
-
- lib/sheets/parsers/
|
142
|
-
- lib/sheets/parsers/roo_patches/roo_patch_29045.rb
|
99
|
+
- lib/sheets/parsers/excel_parser.rb
|
100
|
+
- lib/sheets/parsers/nokogiri_ods_parser.rb
|
101
|
+
- lib/sheets/parsers/nokogiri_xlsx_parser.rb
|
143
102
|
- lib/sheets/renderable.rb
|
144
103
|
- lib/sheets/renderers/base.rb
|
145
104
|
- lib/sheets/renderers/csv_renderer.rb
|
@@ -156,11 +115,11 @@ files:
|
|
156
115
|
- test/parseable_test.rb
|
157
116
|
- test/parsers/basic_parsers_test.rb
|
158
117
|
- test/parsers/csv_parser_test.rb
|
159
|
-
- test/parsers/roo_parser_test.rb
|
160
118
|
- test/renderable_test.rb
|
161
119
|
- test/renderers/basic_renderers_test.rb
|
162
120
|
- test/renderers/csv_renderer_test.rb
|
163
121
|
- test/renderers/excel_renderer_test.rb
|
122
|
+
- test/results.json
|
164
123
|
- test/test_helper.rb
|
165
124
|
has_rdoc: true
|
166
125
|
homepage: https://github.com/bspaulding/Sheets
|
@@ -172,27 +131,23 @@ rdoc_options: []
|
|
172
131
|
require_paths:
|
173
132
|
- lib
|
174
133
|
required_ruby_version: !ruby/object:Gem::Requirement
|
175
|
-
none: false
|
176
134
|
requirements:
|
177
135
|
- - ">="
|
178
136
|
- !ruby/object:Gem::Version
|
179
|
-
hash: 3
|
180
137
|
segments:
|
181
138
|
- 0
|
182
139
|
version: "0"
|
183
140
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
184
|
-
none: false
|
185
141
|
requirements:
|
186
142
|
- - ">="
|
187
143
|
- !ruby/object:Gem::Version
|
188
|
-
hash: 3
|
189
144
|
segments:
|
190
145
|
- 0
|
191
146
|
version: "0"
|
192
147
|
requirements: []
|
193
148
|
|
194
149
|
rubyforge_project: sheets
|
195
|
-
rubygems_version: 1.
|
150
|
+
rubygems_version: 1.3.6
|
196
151
|
signing_key:
|
197
152
|
specification_version: 3
|
198
153
|
summary: Sheets provides a Facade for importing spreadsheets that gives the application control. Any Spreadsheet can be represented as either (1) a two dimensional array, or (2) an array of hashes. Sheets' goal is to convert any spreadsheet format to one of these native Ruby data structures.
|
@@ -207,9 +162,9 @@ test_files:
|
|
207
162
|
- test/parseable_test.rb
|
208
163
|
- test/parsers/basic_parsers_test.rb
|
209
164
|
- test/parsers/csv_parser_test.rb
|
210
|
-
- test/parsers/roo_parser_test.rb
|
211
165
|
- test/renderable_test.rb
|
212
166
|
- test/renderers/basic_renderers_test.rb
|
213
167
|
- test/renderers/csv_renderer_test.rb
|
214
168
|
- test/renderers/excel_renderer_test.rb
|
169
|
+
- test/results.json
|
215
170
|
- test/test_helper.rb
|
@@ -1,29 +0,0 @@
|
|
1
|
-
require 'roo'
|
2
|
-
require File.join( File.expand_path(File.dirname(__FILE__)), 'roo_patches.rb' )
|
3
|
-
|
4
|
-
class Sheets::Parsers::RooParser < Sheets::Parsers::Base
|
5
|
-
parses :xls, :xlsx, :ods
|
6
|
-
|
7
|
-
ROO_CLASS = {
|
8
|
-
:xls => Excel,
|
9
|
-
:xlsx => Excelx,
|
10
|
-
:ods => Openoffice
|
11
|
-
}
|
12
|
-
|
13
|
-
def to_array
|
14
|
-
array = []
|
15
|
-
(spreadsheet.first_row..spreadsheet.last_row).each do |row_num|
|
16
|
-
row = []
|
17
|
-
(spreadsheet.first_column..spreadsheet.last_column).each do |column_num|
|
18
|
-
row << spreadsheet.cell(row_num, column_num).to_s
|
19
|
-
end
|
20
|
-
array << row
|
21
|
-
end
|
22
|
-
array
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
def spreadsheet
|
27
|
-
ROO_CLASS[@format.to_sym].new(@file_path)
|
28
|
-
end
|
29
|
-
end
|
@@ -1,116 +0,0 @@
|
|
1
|
-
# RubyForge Patch: 28885 - Fixes to Honor XLSX Base Date Format
|
2
|
-
# NOTE: This fix is *highly* brittle. If roo updates, this may break roo.
|
3
|
-
|
4
|
-
class Excelx
|
5
|
-
|
6
|
-
def initialize(filename, packed=nil, file_warning = :error) #, create = false)
|
7
|
-
super()
|
8
|
-
@file_warning = file_warning
|
9
|
-
@tmpdir = "oo_"+$$.to_s
|
10
|
-
@tmpdir = File.join(ENV['ROO_TMP'], @tmpdir) if ENV['ROO_TMP']
|
11
|
-
unless File.exists?(@tmpdir)
|
12
|
-
FileUtils::mkdir(@tmpdir)
|
13
|
-
end
|
14
|
-
filename = open_from_uri(filename) if filename[0,7] == "http://"
|
15
|
-
filename = unzip(filename) if packed and packed == :zip
|
16
|
-
begin
|
17
|
-
file_type_check(filename,'.xlsx','an Excel-xlsx')
|
18
|
-
@cells_read = Hash.new
|
19
|
-
@filename = filename
|
20
|
-
unless File.file?(@filename)
|
21
|
-
raise IOError, "file #{@filename} does not exist"
|
22
|
-
end
|
23
|
-
@@nr += 1
|
24
|
-
@file_nr = @@nr
|
25
|
-
extract_content(@filename)
|
26
|
-
file = File.new(File.join(@tmpdir, @file_nr.to_s+"_roo_workbook.xml"))
|
27
|
-
# TODO: @workbook_doc = XML::Parser.io(file).parse
|
28
|
-
@workbook_doc = Nokogiri::XML(file)
|
29
|
-
|
30
|
-
# Set the base date, could be 1900 or 1904 depending on the system of origin.
|
31
|
-
date_base_element = @workbook_doc.search('workbookPr').attribute('date1904')
|
32
|
-
if date_base_element && date_base_element.value.to_i == 1
|
33
|
-
@base_date = Date.parse('1904-01-01')
|
34
|
-
else
|
35
|
-
@base_date = Date.parse('1900-01-01')
|
36
|
-
end
|
37
|
-
@base_datetime = DateTime.parse( @base_date.strftime("%Y-%m-%d") )
|
38
|
-
|
39
|
-
file.close
|
40
|
-
@shared_table = []
|
41
|
-
if File.exist?(File.join(@tmpdir, @file_nr.to_s+'_roo_sharedStrings.xml'))
|
42
|
-
file = File.new(File.join(@tmpdir, @file_nr.to_s+'_roo_sharedStrings.xml'))
|
43
|
-
#TODO: @sharedstring_doc = XML::Parser.io(file).parse
|
44
|
-
@sharedstring_doc = Nokogiri::XML(file)
|
45
|
-
file.close
|
46
|
-
read_shared_strings(@sharedstring_doc)
|
47
|
-
end
|
48
|
-
@styles_table = []
|
49
|
-
@style_definitions = Array.new # TODO: ??? { |h,k| h[k] = {} }
|
50
|
-
if File.exist?(File.join(@tmpdir, @file_nr.to_s+'_roo_styles.xml'))
|
51
|
-
file = File.new(File.join(@tmpdir, @file_nr.to_s+'_roo_styles.xml'))
|
52
|
-
#TODO: @styles_doc = XML::Parser.io(file).parse
|
53
|
-
@styles_doc = Nokogiri::XML(file)
|
54
|
-
file.close
|
55
|
-
read_styles(@styles_doc)
|
56
|
-
end
|
57
|
-
@sheet_doc = []
|
58
|
-
@sheet_files.each_with_index do |item, i|
|
59
|
-
file = File.new(item)
|
60
|
-
#TODO: @sheet_doc[i] = XML::Parser.io(file).parse
|
61
|
-
@sheet_doc[i] = Nokogiri::XML(file)
|
62
|
-
file.close
|
63
|
-
end
|
64
|
-
ensure
|
65
|
-
#if ENV["roo_local"] != "thomas-p"
|
66
|
-
FileUtils::rm_r(@tmpdir)
|
67
|
-
#end
|
68
|
-
end
|
69
|
-
@default_sheet = self.sheets.first
|
70
|
-
@cell = Hash.new
|
71
|
-
@cell_type = Hash.new
|
72
|
-
@formula = Hash.new
|
73
|
-
@first_row = Hash.new
|
74
|
-
@last_row = Hash.new
|
75
|
-
@first_column = Hash.new
|
76
|
-
@last_column = Hash.new
|
77
|
-
@header_line = 1
|
78
|
-
@excelx_type = Hash.new
|
79
|
-
@excelx_value = Hash.new
|
80
|
-
@s_attribute = Hash.new # TODO: ggf. wieder entfernen nur lokal benoetigt
|
81
|
-
end
|
82
|
-
|
83
|
-
def set_cell_values(sheet,x,y,i,v,vt,formula,tr,str_v,
|
84
|
-
excelx_type=nil,
|
85
|
-
excelx_value=nil,
|
86
|
-
s_attribute=nil)
|
87
|
-
key = [y,x+i]
|
88
|
-
@cell_type[sheet] = {} unless @cell_type[sheet]
|
89
|
-
@cell_type[sheet][key] = vt
|
90
|
-
@formula[sheet] = {} unless @formula[sheet]
|
91
|
-
@formula[sheet][key] = formula if formula
|
92
|
-
@cell[sheet] = {} unless @cell[sheet]
|
93
|
-
case @cell_type[sheet][key]
|
94
|
-
when :float
|
95
|
-
@cell[sheet][key] = v.to_f
|
96
|
-
when :string
|
97
|
-
@cell[sheet][key] = str_v
|
98
|
-
when :date
|
99
|
-
@cell[sheet][key] = (@base_date+v.to_i).strftime("%Y-%m-%d")
|
100
|
-
when :datetime
|
101
|
-
@cell[sheet][key] = (@base_datetime+v.to_f).strftime("%Y-%m-%d %H:%M:%S")
|
102
|
-
when :percentage
|
103
|
-
@cell[sheet][key] = v.to_f
|
104
|
-
when :time
|
105
|
-
@cell[sheet][key] = v.to_f*(24*60*60)
|
106
|
-
else
|
107
|
-
@cell[sheet][key] = v
|
108
|
-
end
|
109
|
-
@excelx_type[sheet] = {} unless @excelx_type[sheet]
|
110
|
-
@excelx_type[sheet][key] = excelx_type
|
111
|
-
@excelx_value[sheet] = {} unless @excelx_value[sheet]
|
112
|
-
@excelx_value[sheet][key] = excelx_value
|
113
|
-
@s_attribute[sheet] = {} unless @s_attribute[sheet]
|
114
|
-
@s_attribute[sheet][key] = s_attribute
|
115
|
-
end
|
116
|
-
end
|