winexcel 0.0.1
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 -0
- data/Gemfile +4 -0
- data/README.md +156 -0
- data/Rakefile +7 -0
- data/examples/basic.rb +49 -0
- data/examples/extended.rb +73 -0
- data/examples/fixtures/a.xls +0 -0
- data/examples/fixtures/b.xlsx +0 -0
- data/examples/fixtures/template.xls +0 -0
- data/examples/my_basic_file.xls +0 -0
- data/examples/my_extended_file.xls +0 -0
- data/features/connect_to_open_excel_file.feature +32 -0
- data/features/create_excel_file_from_template_and_open.feature +35 -0
- data/features/fixtures/a.xls +0 -0
- data/features/fixtures/b.xlsx +0 -0
- data/features/open_excel_file.feature +41 -0
- data/features/step_definitions/excel_file_steps.rb +71 -0
- data/features/support/common.rb +37 -0
- data/features/support/env.rb +14 -0
- data/features/support/matchers.rb +9 -0
- data/lib/winexcel.rb +12 -0
- data/lib/winexcel/core_ext/object.rb +34 -0
- data/lib/winexcel/core_ext/ordered_hash.rb +100 -0
- data/lib/winexcel/excel/xl_file_format.rb +74 -0
- data/lib/winexcel/excel_file.rb +255 -0
- data/lib/winexcel/excel_file/common_methods.rb +422 -0
- data/lib/winexcel/excel_file/other_methods.rb +315 -0
- data/lib/winexcel/excel_file/write_2D_array.rb +169 -0
- data/lib/winexcel/fileutils_ext/backup_file.rb +25 -0
- data/lib/winexcel/fileutils_ext/create_dir_if_missing.rb +18 -0
- data/lib/winexcel/version.rb +3 -0
- data/lib/winexcel/win32olerot_ext/win32olerot.so +0 -0
- data/tasks/cucumber.rake +23 -0
- data/tasks/rspec.rake +9 -0
- data/winexcel.gemspec +26 -0
- metadata +163 -0
@@ -0,0 +1,169 @@
|
|
1
|
+
# excel_file.rb
|
2
|
+
#
|
3
|
+
# File based on Xls.rb being part of 'wwatf' project
|
4
|
+
# Copyright (C) 2010-2011 Sobieraj Kamil <ksob@dslowl.com>.
|
5
|
+
#
|
6
|
+
# This file is published under New BSD License
|
7
|
+
# You can redistribute and/or
|
8
|
+
# modify it under the terms of the New BSD License.
|
9
|
+
#
|
10
|
+
# New BSD License claims:
|
11
|
+
# Redistribution and use in source and binary forms, with or without
|
12
|
+
# modification, are permitted provided that the following conditions
|
13
|
+
# are met:
|
14
|
+
#
|
15
|
+
# 1. Redistributions of source code must retain the above copyright notice,
|
16
|
+
# this list of conditions and the following disclaimer.
|
17
|
+
#
|
18
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
19
|
+
# this list of conditions and the following disclaimer in the documentation
|
20
|
+
# and/or other materials provided with the distribution.
|
21
|
+
#
|
22
|
+
# 3. Neither the name of Zend Technologies USA, Inc. nor the names of its
|
23
|
+
# contributors may be used to endorse or promote products derived from this
|
24
|
+
# software without specific prior written permission.
|
25
|
+
#
|
26
|
+
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
27
|
+
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
28
|
+
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
29
|
+
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
30
|
+
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
31
|
+
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
32
|
+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
33
|
+
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
34
|
+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
35
|
+
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
36
|
+
|
37
|
+
|
38
|
+
require 'logger'
|
39
|
+
|
40
|
+
module WinExcel
|
41
|
+
|
42
|
+
class ExcelFile
|
43
|
+
|
44
|
+
#writes out the 2D Array *data* starting at the specified range *myRange* on the specified sheet
|
45
|
+
def write2DArray(data, myRange, sheet = nil)
|
46
|
+
@log.info("write2DArray(data='...',myRange='#{myRange}', sheet = '#{sheet})'")
|
47
|
+
worksheet = getWorksheet(sheet)
|
48
|
+
#get the actual excel range object
|
49
|
+
myRange = worksheet.Range(myRange)
|
50
|
+
|
51
|
+
# first check if there is any color information in the data
|
52
|
+
isAdditionalInfo = false
|
53
|
+
(0..data.length-1).each do |row|
|
54
|
+
(0..data[row].length-1).each do |col|
|
55
|
+
colorIdx = -1
|
56
|
+
colorLen = -1
|
57
|
+
begin
|
58
|
+
if /\A<<COLOUR=([A-Z]+)>>/.match(data[row][col])
|
59
|
+
colorLen = /\A<<COLOUR=([A-Z]+)>>/.match(data[row][col])[1].length
|
60
|
+
case /\A<<COLOUR=([A-Z]+)>>/.match(data[row][col])[1]
|
61
|
+
when 'BLACK'
|
62
|
+
colorIdx = 1
|
63
|
+
when 'RED'
|
64
|
+
colorIdx = 3
|
65
|
+
when 'YELLOW'
|
66
|
+
colorIdx = 6
|
67
|
+
when 'GREEN'
|
68
|
+
colorIdx = 10
|
69
|
+
end
|
70
|
+
end
|
71
|
+
if colorIdx > -1 or data[row][col] =~ /^=HYPERLINK/
|
72
|
+
isAdditionalInfo = true
|
73
|
+
break
|
74
|
+
end
|
75
|
+
rescue
|
76
|
+
end
|
77
|
+
end
|
78
|
+
if isAdditionalInfo == true
|
79
|
+
break
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
if not isAdditionalInfo
|
84
|
+
# find maximum row length (or column quantity) for the 'data' array,
|
85
|
+
# it would be column quantity of 2D array if we would put the 'data' array into one
|
86
|
+
maxWidth = 0
|
87
|
+
maxCellLength = 0
|
88
|
+
data.each do |row|
|
89
|
+
maxWidth = row.length if maxWidth < row.length
|
90
|
+
row.each do |cell|
|
91
|
+
maxCellLength = cell.to_s.length if cell and maxCellLength < cell.to_s.length
|
92
|
+
end
|
93
|
+
end
|
94
|
+
data.collect do |row|
|
95
|
+
while row.length < maxWidth
|
96
|
+
if not row.kind_of? Array
|
97
|
+
row = []
|
98
|
+
end
|
99
|
+
row << ''
|
100
|
+
end
|
101
|
+
end
|
102
|
+
if maxCellLength < 8204
|
103
|
+
myRange.Resize(data.length, maxWidth).Value = data if data and data.length > 0
|
104
|
+
else
|
105
|
+
(0..data.length-1).each do |row|
|
106
|
+
(0..data[row].length-1).each do |col|
|
107
|
+
myRange.Offset(row, col).value = data[row][col]
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
else
|
112
|
+
(0..data.length-1).each do |row|
|
113
|
+
(0..data[row].length-1).each do |col|
|
114
|
+
#puts data[row][col]
|
115
|
+
|
116
|
+
colorIdx = -1
|
117
|
+
colorLen = -1
|
118
|
+
begin
|
119
|
+
if /\A<<COLOUR=([A-Z]+)>>/.match(data[row][col])
|
120
|
+
colorLen = /\A<<COLOUR=([A-Z]+)>>/.match(data[row][col])[1].length
|
121
|
+
case /\A<<COLOUR=([A-Z]+)>>/.match(data[row][col])[1]
|
122
|
+
when 'BLACK'
|
123
|
+
colorIdx = 1
|
124
|
+
when 'RED'
|
125
|
+
colorIdx = 3
|
126
|
+
when 'YELLOW'
|
127
|
+
colorIdx = 6
|
128
|
+
when 'GREEN'
|
129
|
+
colorIdx = 10
|
130
|
+
end
|
131
|
+
end
|
132
|
+
rescue
|
133
|
+
end
|
134
|
+
|
135
|
+
#TODO: Excel bottleneck - it needs some deley here
|
136
|
+
#sleep(0.1)
|
137
|
+
|
138
|
+
val = ''
|
139
|
+
if colorIdx > -1 then
|
140
|
+
myRange.Offset(row, col).Interior.ColorIndex = colorIdx
|
141
|
+
beg = '<<COLOUR=>>'.length + colorLen
|
142
|
+
val = data[row][col][beg..data[row][col].length]
|
143
|
+
else
|
144
|
+
val = data[row][col]
|
145
|
+
end
|
146
|
+
|
147
|
+
begin
|
148
|
+
myRange.Offset(row, col).value = val
|
149
|
+
rescue
|
150
|
+
if val =~ /^=HYPERLINK/
|
151
|
+
if val[',']
|
152
|
+
val.gsub!(',', ';')
|
153
|
+
elsif val[';']
|
154
|
+
val.gsub!(';', ',')
|
155
|
+
end
|
156
|
+
|
157
|
+
myRange.Offset(row, col).value = val
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module FileUtils
|
4
|
+
|
5
|
+
def self.moveFileToBackupDir(sourceFile, backupDir=nil)
|
6
|
+
fileDir = File.dirname(sourceFile)
|
7
|
+
fileName = File.basename(sourceFile)
|
8
|
+
backupDir = fileDir + '/BACKUP/' if not backupDir
|
9
|
+
targetFileName = fileName
|
10
|
+
targetFile = ''
|
11
|
+
i = 0
|
12
|
+
begin
|
13
|
+
targetFile = backupDir + targetFileName
|
14
|
+
raise if File.exist?(targetFile)
|
15
|
+
rescue
|
16
|
+
i = i + 1
|
17
|
+
targetFileName = fileName[0..fileName.length-File.extname(fileName).length-1] + "_#{i}" + File.extname(fileName)
|
18
|
+
retry
|
19
|
+
end
|
20
|
+
createDirIfMissing File.dirname(targetFile)
|
21
|
+
FileUtils.mv(sourceFile, targetFile)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module FileUtils
|
4
|
+
|
5
|
+
# recursively create directories of a path given as argument
|
6
|
+
# accepts absolute paths as well as relative ones
|
7
|
+
#
|
8
|
+
def self.createDirIfMissing(dir)
|
9
|
+
if dir.unempty?
|
10
|
+
unless File.directory?(dir)
|
11
|
+
createDirIfMissing(File.dirname(dir))
|
12
|
+
Dir.mkdir(dir)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
Binary file
|
data/tasks/cucumber.rake
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
begin
|
2
|
+
namespace :cucumber do
|
3
|
+
require 'cucumber/rake/task'
|
4
|
+
Cucumber::Rake::Task.new(:wip, 'Run features that are being worked on') do |t|
|
5
|
+
t.cucumber_opts = "--tags @wip"
|
6
|
+
end
|
7
|
+
Cucumber::Rake::Task.new(:ok, 'Run features that should be working') do |t|
|
8
|
+
t.cucumber_opts = "--tags ~@wip"
|
9
|
+
end
|
10
|
+
task :all => [:ok, :wip]
|
11
|
+
end
|
12
|
+
|
13
|
+
desc 'Alias for cucumber:ok'
|
14
|
+
task :cucumber => 'cucumber:ok'
|
15
|
+
rescue LoadError
|
16
|
+
task :cucumber do
|
17
|
+
abort "Cucumber is not available. In order to run features, you must: gem install cucumber"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
desc 'Alias for cucumber'
|
22
|
+
task :features => 'cucumber'
|
23
|
+
|
data/tasks/rspec.rake
ADDED
data/winexcel.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "winexcel/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "winexcel"
|
7
|
+
s.version = WinExcel::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Kamil Sobieraj"]
|
10
|
+
s.email = ["ksob@rubyforge.org"]
|
11
|
+
s.homepage = ""
|
12
|
+
s.summary = %q{Access MS Excel from Ruby via Excel COM/Win32OLE interface}
|
13
|
+
s.description = %q{Makes it possible to access MS Excel from Ruby via Excel COM/Win32OLE interface. Enables to read and write from/to Excel files with the use of Excel's API. Requires MS Excel application to be installed.}
|
14
|
+
|
15
|
+
s.rubyforge_project = "winexcel"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_dependency('win32olerot')
|
23
|
+
s.add_development_dependency("rake", ["~> 0.8.7"])
|
24
|
+
s.add_development_dependency("cucumber", ["~> 0.10.2"])
|
25
|
+
s.add_development_dependency("rspec", ["~> 2.5.0"])
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: winexcel
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Kamil Sobieraj
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-05-05 00:00:00 +02:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: win32olerot
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: rake
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 49
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
- 8
|
47
|
+
- 7
|
48
|
+
version: 0.8.7
|
49
|
+
type: :development
|
50
|
+
version_requirements: *id002
|
51
|
+
- !ruby/object:Gem::Dependency
|
52
|
+
name: cucumber
|
53
|
+
prerelease: false
|
54
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ~>
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
hash: 51
|
60
|
+
segments:
|
61
|
+
- 0
|
62
|
+
- 10
|
63
|
+
- 2
|
64
|
+
version: 0.10.2
|
65
|
+
type: :development
|
66
|
+
version_requirements: *id003
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
name: rspec
|
69
|
+
prerelease: false
|
70
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
hash: 27
|
76
|
+
segments:
|
77
|
+
- 2
|
78
|
+
- 5
|
79
|
+
- 0
|
80
|
+
version: 2.5.0
|
81
|
+
type: :development
|
82
|
+
version_requirements: *id004
|
83
|
+
description: Makes it possible to access MS Excel from Ruby via Excel COM/Win32OLE interface. Enables to read and write from/to Excel files with the use of Excel's API. Requires MS Excel application to be installed.
|
84
|
+
email:
|
85
|
+
- ksob@rubyforge.org
|
86
|
+
executables: []
|
87
|
+
|
88
|
+
extensions: []
|
89
|
+
|
90
|
+
extra_rdoc_files: []
|
91
|
+
|
92
|
+
files:
|
93
|
+
- .gitignore
|
94
|
+
- Gemfile
|
95
|
+
- README.md
|
96
|
+
- Rakefile
|
97
|
+
- examples/basic.rb
|
98
|
+
- examples/extended.rb
|
99
|
+
- examples/fixtures/a.xls
|
100
|
+
- examples/fixtures/b.xlsx
|
101
|
+
- examples/fixtures/template.xls
|
102
|
+
- examples/my_basic_file.xls
|
103
|
+
- examples/my_extended_file.xls
|
104
|
+
- features/connect_to_open_excel_file.feature
|
105
|
+
- features/create_excel_file_from_template_and_open.feature
|
106
|
+
- features/fixtures/a.xls
|
107
|
+
- features/fixtures/b.xlsx
|
108
|
+
- features/open_excel_file.feature
|
109
|
+
- features/step_definitions/excel_file_steps.rb
|
110
|
+
- features/support/common.rb
|
111
|
+
- features/support/env.rb
|
112
|
+
- features/support/matchers.rb
|
113
|
+
- lib/winexcel.rb
|
114
|
+
- lib/winexcel/core_ext/object.rb
|
115
|
+
- lib/winexcel/core_ext/ordered_hash.rb
|
116
|
+
- lib/winexcel/excel/xl_file_format.rb
|
117
|
+
- lib/winexcel/excel_file.rb
|
118
|
+
- lib/winexcel/excel_file/common_methods.rb
|
119
|
+
- lib/winexcel/excel_file/other_methods.rb
|
120
|
+
- lib/winexcel/excel_file/write_2D_array.rb
|
121
|
+
- lib/winexcel/fileutils_ext/backup_file.rb
|
122
|
+
- lib/winexcel/fileutils_ext/create_dir_if_missing.rb
|
123
|
+
- lib/winexcel/version.rb
|
124
|
+
- lib/winexcel/win32olerot_ext/win32olerot.so
|
125
|
+
- tasks/cucumber.rake
|
126
|
+
- tasks/rspec.rake
|
127
|
+
- winexcel.gemspec
|
128
|
+
has_rdoc: true
|
129
|
+
homepage: ""
|
130
|
+
licenses: []
|
131
|
+
|
132
|
+
post_install_message:
|
133
|
+
rdoc_options: []
|
134
|
+
|
135
|
+
require_paths:
|
136
|
+
- lib
|
137
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
138
|
+
none: false
|
139
|
+
requirements:
|
140
|
+
- - ">="
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
hash: 3
|
143
|
+
segments:
|
144
|
+
- 0
|
145
|
+
version: "0"
|
146
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
147
|
+
none: false
|
148
|
+
requirements:
|
149
|
+
- - ">="
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
hash: 3
|
152
|
+
segments:
|
153
|
+
- 0
|
154
|
+
version: "0"
|
155
|
+
requirements: []
|
156
|
+
|
157
|
+
rubyforge_project: winexcel
|
158
|
+
rubygems_version: 1.5.2
|
159
|
+
signing_key:
|
160
|
+
specification_version: 3
|
161
|
+
summary: Access MS Excel from Ruby via Excel COM/Win32OLE interface
|
162
|
+
test_files: []
|
163
|
+
|