sheet2hash 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+
19
+ .project
20
+ *.DS_Store
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in sheet2hash.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,13 @@
1
+ Copyright 2013 Wei-Ming Wu
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License"); you
4
+ may not use this file except in compliance with the License. You may
5
+ obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12
+ implied. See the License for the specific language governing
13
+ permissions and limitations under the License.
data/README.md ADDED
@@ -0,0 +1,62 @@
1
+ # Sheet2hash
2
+
3
+ Convert Excel or Spreadsheet to Ruby hash
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'sheet2hash'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install sheet2hash
18
+
19
+ ## Usage
20
+
21
+ Basic:
22
+
23
+ wb = Sheet2hash.workbook.new 'path/to/your/excel_or_spreadsheet'
24
+ wb.to_a # convert default sheet to array of hash
25
+ # [{ field1 => data, field2 => data, ...}, { field1 => data, field2 => data, ...}, ...]
26
+ # each hash is a row of sheet
27
+ # the first row is used to be the keys of hash
28
+ wb.to_h # convert all sheets to hash
29
+ # the output will be { 'name_of_sheet' => [{ field => data, ... }, ...] }
30
+
31
+ Advanced:
32
+
33
+ # All sheets are count from 1, NOT 0
34
+ wb.sheets # list all sheets in the workbook
35
+ wb.sheet # show the name of current workbook
36
+ wb.turn_to(2) # make sheet 2 as current sheet
37
+ wb.turn_to('name_of_the_3rd_sheet') # make sheet 3 as current sheet
38
+
39
+ Options:
40
+
41
+ # All rows, columns are count from 1, NOT 0
42
+ wb = Sheet2hash.workbook.new 'path/to/your/excel_or_spreadsheet',
43
+ :header => 3, # use specific row as header
44
+ :header => ['col1', 'col2', ...], # use self-defined header
45
+ :start => 4, # start at row 4
46
+ :end => 20, # end at row 20
47
+ :keep_row => [4, 5], # only convert row 4 and 5
48
+ :skip_row => [6, 7], # skip row 6 and 7
49
+ :keep_col => [1], # only convert column 1
50
+ :skip_col => [2, 3] # skip column 2 and 3
51
+
52
+ wb.turn_to(2, :herder => 3, ...) # global options can be overrided by passing options to specfic sheet
53
+ # global options will still affect after turning to another sheet
54
+
55
+
56
+ ## Contributing
57
+
58
+ 1. Fork it
59
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
60
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
61
+ 4. Push to the branch (`git push origin my-new-feature`)
62
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
@@ -0,0 +1,4 @@
1
+ module Sheet2hash
2
+ class SheetNotFoundError < Exception ; end
3
+ class InvalidHeaderError < Exception ; end
4
+ end
@@ -0,0 +1,16 @@
1
+ module Sheet2hash
2
+ module Options
3
+ def process_options(opts)
4
+ regulate_options opts
5
+ opts
6
+ end
7
+
8
+ private
9
+ def regulate_options(opts)
10
+ opts[:keep_row] = Array(opts[:keep_row]) if opts[:keep_row]
11
+ opts[:skip_row] = Array(opts[:skip_row]) if opts[:skip_row]
12
+ opts[:keep_col] = Array(opts[:keep_col]) if opts[:keep_col]
13
+ opts[:skip_col] = Array(opts[:skip_col]) if opts[:skip_col]
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,7 @@
1
+ module Sheet2hash
2
+ MAJOR = 0
3
+ MINOR = 1
4
+ PATCH = 0
5
+
6
+ VERSION = [MAJOR, MINOR, PATCH].compact.join('.')
7
+ end
data/lib/sheet2hash.rb ADDED
@@ -0,0 +1,162 @@
1
+ require 'roo'
2
+ require 'sheet2hash/errors'
3
+ require 'sheet2hash/options'
4
+
5
+ module Sheet2hash
6
+ class Workbook
7
+ include Options
8
+
9
+ def initialize(path, opts = {})
10
+ @workbook = Roo::Spreadsheet.open path
11
+ @opts = process_options opts
12
+ @sheet_opts = {}
13
+ set_sheet_attributes
14
+ end
15
+
16
+ def turn_to(sheet, sheet_opts = {})
17
+ if sheet.kind_of?(Integer) && sheet <= sheets.size
18
+ @workbook.default_sheet = sheets[sheet - 1]
19
+ @sheet_opts = process_options sheet_opts
20
+ set_sheet_attributes
21
+ elsif sheet.kind_of?(String) && sheets.include?(sheet)
22
+ @workbook.default_sheet = sheet
23
+ @sheet_opts = process_options sheet_opts
24
+ set_sheet_attributes
25
+ else
26
+ raise SheetNotFoundError
27
+ end
28
+ end
29
+
30
+ def sheets
31
+ @workbook.sheets
32
+ end
33
+
34
+ def sheet
35
+ @workbook.default_sheet
36
+ end
37
+
38
+ def to_h
39
+ hash = {}
40
+ sheets.each do |sheet|
41
+ turn_to sheet
42
+ hash[sheet] = to_a
43
+ end
44
+ hash
45
+ end
46
+
47
+ def to_a
48
+ ary = []
49
+ @rows.each do |row|
50
+ record = []
51
+ @columns.each { |col| record << trim_int_cell(@workbook.cell(row, col)) }
52
+ ary << Hash[ @header.zip record ]
53
+ end
54
+ ary
55
+ end
56
+
57
+ private
58
+ def set_sheet_attributes
59
+ @header = header
60
+ @rows = rows
61
+ @columns = columns
62
+ end
63
+
64
+ def trim_int_cell(cell)
65
+ cell.kind_of?(Numeric) && cell % 1 == 0 ? cell.to_i : cell
66
+ end
67
+
68
+ def columns
69
+ columns = (@workbook.first_column..@workbook.last_column).to_a
70
+ if @sheet_opts[:skip_col] || @sheet_opts[:keep_col]
71
+ collect_columns columns, @sheet_opts
72
+ elsif @opts[:skip_col] || @opts[:keep_col]
73
+ collect_columns columns, @opts
74
+ else
75
+ columns
76
+ end
77
+ end
78
+
79
+ def collect_columns(columns, opts)
80
+ columns.keep_if { |col| opts[:keep_col].include? col } if opts[:keep_col]
81
+ columns = columns - opts[:skip_col] if opts[:skip_col]
82
+ columns
83
+ end
84
+
85
+ def first_row
86
+ first_row = @sheet_opts[:start] || @opts[:start]
87
+ first_row || @workbook.first_row
88
+ end
89
+
90
+ def last_row
91
+ last_row = @sheet_opts[:end] || @opts[:end]
92
+ last_row || @workbook.last_row
93
+ end
94
+
95
+ def rows
96
+ rows = (first_row..last_row).to_a
97
+ if @sheet_opts[:keep_row] || @sheet_opts[:skip_row]
98
+ rows = collect_rows rows, @sheet_opts
99
+ rows - [@sheet_opts[:header]]
100
+ elsif @opts[:keep_row] || @opts[:skip_row]
101
+ rows = collect_rows rows, @opts
102
+ rows - [@opts[:header]]
103
+ else
104
+ rows - [@workbook.first_row]
105
+ end
106
+ end
107
+
108
+ def collect_rows(rows, opts)
109
+ rows.keep_if { |row| opts[:keep_row].include? row } if opts[:keep_row]
110
+ rows = rows - opts[:skip_row] if opts[:skip_row]
111
+ rows
112
+ end
113
+
114
+ def header
115
+ header = @sheet_opts[:header] || @opts[:header]
116
+ if header
117
+ header = process_header header
118
+ else
119
+ header = header_from_row @workbook.first_row
120
+ end
121
+ match_header_with_columns header
122
+ end
123
+
124
+ def match_header_with_columns(header)
125
+ header.each_with_index.select { |h, i| columns.include?(i + 1) }.map { |i| i.first }
126
+ end
127
+
128
+ def process_header(header)
129
+ if header.kind_of? Array
130
+ unique_header header
131
+ elsif header.kind_of? Integer
132
+ header_from_row header
133
+ else
134
+ raise InvalidHeaderError
135
+ end
136
+ end
137
+
138
+ def header_from_row(row)
139
+ header = []
140
+ (@workbook.first_column..@workbook.last_column).each { |col| header << @workbook.cell(row, col) }
141
+ unique_header header
142
+ end
143
+
144
+ def unique_header(header)
145
+ header.reverse!
146
+ dup_header = header.dup
147
+ header = header.map do |field|
148
+ count = dup_header.count field
149
+ if count == 2
150
+ dup_header.delete_at dup_header.find_index(field)
151
+ "#{field}_dup"
152
+ elsif count > 1
153
+ dup_header.delete_at dup_header.find_index(field)
154
+ "#{field}_dup#{count - 1}"
155
+ else
156
+ field
157
+ end
158
+ end
159
+ header.reverse!
160
+ end
161
+ end
162
+ end
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'sheet2hash/version'
5
+ require 'date'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "sheet2hash"
9
+ spec.version = Sheet2hash::VERSION
10
+ spec.authors = ["Wei-Ming Wu"]
11
+ spec.email = ["wnameless@gmail.com"]
12
+ spec.description = %q{Convert Excel or Spreadsheet to Ruby hash}
13
+ spec.date = "#{Date.today.to_s}"
14
+ spec.summary = "sheet2hash-#{Sheet2hash::VERSION}"
15
+ spec.homepage = "http://github.com/wnameless/sheet2hash"
16
+ spec.license = "Apache License, Version 2.0"
17
+
18
+ spec.files = `git ls-files`.split($/)
19
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_dependency "roo"
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.3"
26
+ spec.add_development_dependency "rake"
27
+ end
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sheet2hash
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Wei-Ming Wu
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-30 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: roo
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: bundler
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '1.3'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '1.3'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rake
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: Convert Excel or Spreadsheet to Ruby hash
63
+ email:
64
+ - wnameless@gmail.com
65
+ executables: []
66
+ extensions: []
67
+ extra_rdoc_files: []
68
+ files:
69
+ - .gitignore
70
+ - Gemfile
71
+ - LICENSE.txt
72
+ - README.md
73
+ - Rakefile
74
+ - lib/sheet2hash.rb
75
+ - lib/sheet2hash/errors.rb
76
+ - lib/sheet2hash/options.rb
77
+ - lib/sheet2hash/version.rb
78
+ - sheet2hash.gemspec
79
+ homepage: http://github.com/wnameless/sheet2hash
80
+ licenses:
81
+ - Apache License, Version 2.0
82
+ post_install_message:
83
+ rdoc_options: []
84
+ require_paths:
85
+ - lib
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ segments:
93
+ - 0
94
+ hash: 1249836198874523190
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - '>='
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ segments:
102
+ - 0
103
+ hash: 1249836198874523190
104
+ requirements: []
105
+ rubyforge_project:
106
+ rubygems_version: 1.8.25
107
+ signing_key:
108
+ specification_version: 3
109
+ summary: sheet2hash-0.1.0
110
+ test_files: []