princess 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2011 Robert Scott Reis
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/lib/ext_string.rb ADDED
@@ -0,0 +1,13 @@
1
+ class String
2
+
3
+ def to_excel_col
4
+ alphabet = ('A'..'Z').to_a
5
+ col = 0
6
+ letters = self.split(//).reverse
7
+ letters.each_index do |power|
8
+ col += (26 ** power) * (alphabet.index(letters[power]) + 1)
9
+ end
10
+ col
11
+ end
12
+
13
+ end
@@ -0,0 +1,34 @@
1
+ module Princess
2
+ class ExcelReader
3
+
4
+ def initialize(filename)
5
+ @book = Spreadsheet.open(filename)
6
+ @sheet = @book.worksheet(0)
7
+ end
8
+
9
+ # load a sheet for reading
10
+ def active_sheet(sheet_num)
11
+ raise 'invalid argument' if !sheet_num.is_a?(Integer)
12
+ @sheet = @book.worksheet(sheet_num)
13
+ end
14
+
15
+ # iterate through the spreadsheet rows
16
+ def each
17
+ @sheet.each do |row|
18
+ yield Row.new(row.inject([]){|vals, cell|vals<<cell})
19
+ end
20
+ end
21
+
22
+ # return the specified row
23
+ def row(num)
24
+ raise 'invalid argument' if !num.is_a?(Integer)
25
+ Row.new(@sheet.row(num - 1).inject([]){|vals, cell|vals<<cell})
26
+ end
27
+
28
+ # return the specified cell content
29
+ def cell(coord)
30
+ row(coord.scan(/\d+/).first.to_i).cell(coord.scan(/\D+/).first)
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,94 @@
1
+ module Princess
2
+ class ExcelxReader
3
+
4
+ def initialize(filename)
5
+ @filename = filename
6
+ active_sheet(1)
7
+ end
8
+
9
+ # load a sheet for reading
10
+ def active_sheet(sheet_num)
11
+ raise 'invalid argument' if !sheet_num.is_a?(Integer)
12
+
13
+ Zip::ZipFile.open(@filename) do |zipfile|
14
+
15
+ # grab shared strings
16
+ noko_shared_strings = Nokogiri::XML(zipfile.read('xl/sharedStrings.xml'))
17
+ noko_shared_strings.remove_namespaces!
18
+ @shared_strings = noko_shared_strings.xpath('//sst/si/t').map(&:content)
19
+
20
+ # grab spreadsheet content
21
+ doc = Nokogiri::XML(zipfile.read("xl/worksheets/sheet#{sheet_num}.xml"))
22
+ doc.remove_namespaces!
23
+ ref = doc.xpath('//dimension').first.attr('ref')
24
+ @rows = Array.new(ref.split(':').last.scan(/\d+/).first.to_i)
25
+ doc.xpath('//sheetData/row').each do |row|
26
+ row_num = row.attr('r').to_i - 1
27
+ @rows[row_num] = row
28
+ end
29
+
30
+ end
31
+ end
32
+
33
+ # iterate through the spreadsheet rows
34
+ def each
35
+ @rows.each do |noko_row|
36
+ if noko_row.nil?
37
+ yield nil
38
+ else
39
+ yield Row.new(extract_row_values(noko_row))
40
+ end
41
+ end
42
+ end
43
+
44
+ # return the specified row
45
+ def row(num)
46
+ raise 'invalid argument' if !num.is_a?(Integer)
47
+ return nil if @rows[num - 1].nil?
48
+ Row.new(extract_row_values(@rows[num - 1]))
49
+ end
50
+
51
+ # return the specified cell content
52
+ def cell(coord)
53
+ row(coord.scan(/\d+/).first.to_i).cell(coord.scan(/\D+/).first)
54
+ end
55
+
56
+ private
57
+
58
+ # turn a row into translated content in a row object
59
+ def extract_row_values(noko_row)
60
+
61
+ # create new array with number of columns in row
62
+ values = Array.new(noko_row.attr('spans').split(':').last.to_i)
63
+
64
+ # iterate through the cells with content
65
+ noko_row.xpath('.//c').each do |cell|
66
+ col = cell.attr('r').scan(/\D+/).first.to_excel_col - 1
67
+ values[col] = extract_cell_value(cell)
68
+ end
69
+
70
+ values
71
+ end
72
+
73
+ # turn a nokogiri cell into translated content
74
+ def extract_cell_value(noko_cell)
75
+
76
+ # grab cell value
77
+ cell_value = noko_cell.xpath('.//v').first.content
78
+
79
+ # handle string cells
80
+ if noko_cell.attr('t') == 's'
81
+ @shared_strings[cell_value.to_i]
82
+
83
+ # handle date cells
84
+ elsif noko_cell.attr('s') == '2'
85
+ Date.new(1899,12,30) + cell_value.to_i
86
+
87
+ # handle numeric cells
88
+ else
89
+ cell_value.to_f
90
+ end
91
+ end
92
+
93
+ end
94
+ end
@@ -0,0 +1,26 @@
1
+ module Princess
2
+ class Row
3
+
4
+ attr_accessor :values
5
+
6
+ def initialize(values)
7
+ raise 'invalid argument' if !values.is_a?(Array)
8
+ @values = values
9
+ end
10
+
11
+ def to_s
12
+ @values.to_s
13
+ end
14
+
15
+ def cell(num)
16
+ if num.is_a?(String)
17
+ @values[num.to_excel_col - 1]
18
+ elsif num.is_a?(Integer)
19
+ @values[num]
20
+ else
21
+ raise 'invalid argument'
22
+ end
23
+ end
24
+
25
+ end
26
+ end
data/lib/princess.rb ADDED
@@ -0,0 +1,11 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'nokogiri'
4
+ require 'spreadsheet'
5
+ require 'zip/zipfilesystem'
6
+ require 'date'
7
+
8
+ require File.join(File.dirname(__FILE__),'ext_string.rb')
9
+ require File.join(File.dirname(__FILE__),'princess','excelx_reader.rb')
10
+ require File.join(File.dirname(__FILE__),'princess','excel_reader.rb')
11
+ require File.join(File.dirname(__FILE__),'princess','row.rb')
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: princess
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - R. Scott Reis
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-08-04 00:00:00 -05:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description:
23
+ email:
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
30
+ files:
31
+ - LICENSE
32
+ - lib/ext_string.rb
33
+ - lib/princess/excelx_reader.rb
34
+ - lib/princess/excel_reader.rb
35
+ - lib/princess/row.rb
36
+ - lib/princess.rb
37
+ has_rdoc: true
38
+ homepage:
39
+ licenses: []
40
+
41
+ post_install_message:
42
+ rdoc_options: []
43
+
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ none: false
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ hash: 3
52
+ segments:
53
+ - 0
54
+ version: "0"
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ hash: 3
61
+ segments:
62
+ - 0
63
+ version: "0"
64
+ requirements: []
65
+
66
+ rubyforge_project:
67
+ rubygems_version: 1.3.7
68
+ signing_key:
69
+ specification_version: 3
70
+ summary: Princess is an Excel and Excelx spreadsheet reader
71
+ test_files: []
72
+