robust_excel_ole 0.2.0 → 0.2.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/README.rdoc +165 -57
- data/lib/robust_excel_ole/book.rb +11 -14
- data/lib/robust_excel_ole/excel_app.rb +12 -14
- data/lib/robust_excel_ole/version.rb +1 -1
- data/spec/book_spec.rb +10 -10
- data/version.rb +2 -0
- metadata +4 -3
data/.gitignore
CHANGED
data/README.rdoc
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
This is a simple fork from tomiacannondale's wrap_excel adapted to Ruby 1.8.6.
|
4
4
|
The functionality of wrap_excel is optimised and extended by new features.
|
5
5
|
|
6
|
+
This is work in progress.
|
6
7
|
|
7
8
|
== Description
|
8
9
|
|
@@ -18,91 +19,101 @@ RobustExcelOle wraps the win32ole, and uses the Excel operations with ruby.
|
|
18
19
|
gem install robust_excel_ole
|
19
20
|
|
20
21
|
== Usage
|
21
|
-
=== access book
|
22
22
|
|
23
|
-
|
23
|
+
=== open a book
|
24
|
+
|
25
|
+
Open a book.
|
26
|
+
|
27
|
+
book = RobustExcelOle::Book.open('./sample.xls')
|
28
|
+
|
29
|
+
Open a book with a block.
|
24
30
|
|
25
31
|
RobustExcelOle::Book.open('./sample.xls') do |book|
|
26
32
|
# do something
|
27
33
|
end
|
28
34
|
|
29
|
-
|
35
|
+
Options are the following:
|
30
36
|
|
31
|
-
|
32
|
-
|
37
|
+
[:reuse] boolean (default true) use an already open Excel-application
|
38
|
+
[:read_only] boolean (default false) open in read-only mode
|
39
|
+
[:displayalerts] boolean (default false) allow display alerts in Excel
|
40
|
+
[:visible] boolean (default false) make visibe in Excel
|
41
|
+
[:if_unsaved] :raise (default), :accept, :forget, :new_app, :excel
|
42
|
+
if an unsaved book with the same name is open
|
43
|
+
|
44
|
+
:raise
|
33
45
|
|
34
|
-
|
46
|
+
Raise an exception. Don't open the book.
|
35
47
|
|
36
|
-
|
37
|
-
[displayalerts] boolean(default false)
|
38
|
-
[visible] boolean(default false)
|
48
|
+
:accept
|
39
49
|
|
40
|
-
|
50
|
+
Let the unsaved book open.
|
51
|
+
|
52
|
+
:forget
|
41
53
|
|
42
|
-
|
54
|
+
Close the unsaved book, open the new book.
|
43
55
|
|
44
|
-
|
56
|
+
:new_app
|
45
57
|
|
46
|
-
|
58
|
+
Open the new book in a new Excel application.
|
47
59
|
|
48
|
-
|
60
|
+
:excel
|
49
61
|
|
50
|
-
|
62
|
+
Give control to Excel.
|
51
63
|
|
52
|
-
Sheet object is included enumerable. Use Sheet#each_column or Sheet#each_row or Sheet#each method.
|
53
64
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
65
|
+
[:if_unsaved_other_book] :raise (default), :save, :forget, :new_app
|
66
|
+
if an unsaved book with same name in a different path is open,
|
67
|
+
|
68
|
+
:raise
|
58
69
|
|
59
|
-
|
60
|
-
# do something with row_range
|
61
|
-
end
|
70
|
+
Raise an exception. Don't open the book.
|
62
71
|
|
63
|
-
|
64
|
-
# do something with column_range
|
65
|
-
end
|
72
|
+
:save
|
66
73
|
|
67
|
-
|
74
|
+
Save and close the unsaved book and open the new book.
|
68
75
|
|
69
|
-
|
76
|
+
:forget
|
70
77
|
|
71
|
-
|
78
|
+
Close the unsaved book, open the new book
|
79
|
+
|
80
|
+
:new_app
|
72
81
|
|
73
|
-
|
82
|
+
Open the new book in a new Excel application
|
74
83
|
|
75
|
-
row_range[0] => first cell in row_range
|
76
|
-
column_range[1] => second cell in column_range
|
77
84
|
|
78
|
-
|
85
|
+
Examples:
|
79
86
|
|
80
|
-
|
87
|
+
Open a book.
|
81
88
|
|
82
|
-
|
89
|
+
book = RobustExcelOle::Book.open('./sample.xls')
|
83
90
|
|
84
|
-
|
91
|
+
Open another book in the same Excel application.
|
85
92
|
|
86
|
-
|
87
|
-
# do something
|
88
|
-
book.save '.\sample.xls'
|
89
|
-
end
|
93
|
+
new_book = RobustExcelOle::Book.open('./different.xls')
|
90
94
|
|
91
|
-
|
95
|
+
Open another book in a new Excel applications.
|
92
96
|
|
93
|
-
|
94
|
-
book.save '.\sample.xls'
|
95
|
-
book.close
|
97
|
+
new_book = RobustExcelOle::Book.open('./different.xls', :reuse => false)
|
96
98
|
|
97
|
-
|
99
|
+
Change the book (see below).
|
98
100
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
101
|
+
sheet = book[0]
|
102
|
+
book.add_sheet(sheet, :as => 'copyed_name')
|
103
|
+
|
104
|
+
Let the unsaved book open, when open a book while a book with the same name is unsaved and open.
|
105
|
+
|
106
|
+
new_book = RobustExcelOle::Book.open('./sample.xls', :if_unsaved => accept)
|
107
|
+
|
108
|
+
=== save a book
|
109
|
+
|
110
|
+
Save a book.
|
103
111
|
|
112
|
+
book.save
|
104
113
|
|
105
|
-
Save
|
114
|
+
Save a book with a file name.
|
115
|
+
|
116
|
+
book.save_as('./another_sample.xls')
|
106
117
|
|
107
118
|
Options are the following:
|
108
119
|
|
@@ -118,22 +129,119 @@ Give the control to Excel.
|
|
118
129
|
|
119
130
|
:raise
|
120
131
|
|
121
|
-
|
132
|
+
Raise an exception. Don't write the file.
|
122
133
|
|
123
134
|
Example:
|
124
135
|
|
125
|
-
|
126
|
-
|
127
|
-
|
136
|
+
Overwrite a book with the same name.
|
137
|
+
|
138
|
+
book.save('./another_sample.xls', :if_exists => :overwrite)
|
139
|
+
|
140
|
+
=== == (equal)
|
141
|
+
|
142
|
+
Check whether two books are identical.
|
143
|
+
|
144
|
+
Example.
|
145
|
+
|
146
|
+
if (book == new_book) then
|
147
|
+
puts "the books are identical"
|
148
|
+
end
|
149
|
+
|
150
|
+
=== alive?
|
151
|
+
|
152
|
+
Check whether the book is alive.
|
153
|
+
|
154
|
+
book.alive?
|
155
|
+
|
156
|
+
Example.
|
157
|
+
|
158
|
+
if book.alive? then
|
159
|
+
puts "the book is alive"
|
160
|
+
end
|
161
|
+
|
162
|
+
=== filename
|
163
|
+
|
164
|
+
Get the file name of the book.
|
165
|
+
|
166
|
+
book.filename
|
167
|
+
|
168
|
+
=== close a book
|
169
|
+
|
170
|
+
Close a book
|
171
|
+
|
172
|
+
book.close
|
173
|
+
|
174
|
+
Options are the following:
|
175
|
+
|
176
|
+
[:if_unsaved] :raise (default), :save, :forget, :excel
|
177
|
+
if the book is unsaved
|
178
|
+
|
179
|
+
:raise
|
180
|
+
|
181
|
+
Raise an exception. Don't close the book
|
182
|
+
|
183
|
+
:save
|
184
|
+
|
185
|
+
Save the book before closing it.
|
186
|
+
|
187
|
+
:forget
|
188
|
+
|
189
|
+
Close the book.
|
190
|
+
|
191
|
+
:excel
|
192
|
+
|
193
|
+
Give control to Excel
|
194
|
+
|
195
|
+
|
196
|
+
|
197
|
+
=== access sheet
|
198
|
+
|
199
|
+
A sheet object can be accessed with a Book#[] method.
|
200
|
+
|
201
|
+
sheet = book[0]
|
202
|
+
|
203
|
+
Access a sheet object with the sheet name.
|
204
|
+
|
205
|
+
book['Sheet1']
|
206
|
+
|
207
|
+
=== access row or column
|
208
|
+
|
209
|
+
A sheet object is enumerable. Use the methods Sheet#each_column, Sheet#each_row or Sheet#each.
|
210
|
+
|
211
|
+
sheet.each do |cell|
|
212
|
+
# do something with cell
|
213
|
+
# read every row every column
|
214
|
+
end
|
215
|
+
|
216
|
+
sheet.each_row do |row|
|
217
|
+
# do something with row_range
|
218
|
+
end
|
219
|
+
|
220
|
+
sheet.each_column do |column_range|
|
221
|
+
# do something with column_range
|
128
222
|
end
|
129
223
|
|
224
|
+
=== access cell
|
225
|
+
|
226
|
+
Read a cell from a sheet object.
|
227
|
+
|
228
|
+
sheet[0, 0] => first cell.
|
229
|
+
|
230
|
+
Read a cell from a range object.
|
231
|
+
|
232
|
+
row_range[0] => first cell in row_range
|
233
|
+
column_range[1] => second cell in column_range
|
234
|
+
|
235
|
+
|
236
|
+
|
130
237
|
=== Want to do more things
|
131
238
|
|
132
|
-
All RobustExcelOle
|
239
|
+
All RobustExcelOle objects include the win32ole instance.
|
240
|
+
If you want to do something that not provide a function, you can use win32ole methods.
|
133
241
|
|
134
242
|
== Support
|
135
243
|
|
136
|
-
|
244
|
+
This is work in progress. Please don't hesitate to contact us and to report issues and feature requests to github Issues. https://github.com/Thomas008/robust_excel_ole/issues
|
137
245
|
|
138
246
|
== Collaborate
|
139
247
|
|
@@ -141,7 +249,7 @@ Please pull request on github.
|
|
141
249
|
|
142
250
|
== Author
|
143
251
|
|
144
|
-
thomas mailto:
|
252
|
+
thomas mailto:Thomas.Raths@gmx.net
|
145
253
|
|
146
254
|
== License
|
147
255
|
|
@@ -45,7 +45,7 @@ module RobustExcelOle
|
|
45
45
|
if not File.exist?(file)
|
46
46
|
raise ExcelErrorOpen, "file #{file} not found"
|
47
47
|
end
|
48
|
-
@excel_app = ExcelApp.new(excel_app_options)
|
48
|
+
@excel_app = ExcelApp.new(excel_app_options) # :nodoc:
|
49
49
|
workbooks = @excel_app.Workbooks
|
50
50
|
@workbook = workbooks.Item(File.basename(file)) rescue nil
|
51
51
|
if @workbook then
|
@@ -78,8 +78,8 @@ module RobustExcelOle
|
|
78
78
|
when :forget
|
79
79
|
@workbook.Close
|
80
80
|
when :excel
|
81
|
-
old_displayalerts = @excel_app.DisplayAlerts
|
82
|
-
@excel_app.DisplayAlerts = true
|
81
|
+
old_displayalerts = @excel_app.DisplayAlerts # :nodoc:
|
82
|
+
@excel_app.DisplayAlerts = true # :nodoc:
|
83
83
|
when :new_app
|
84
84
|
@options[:reuse] = false
|
85
85
|
@excel_app = ExcelApp.new(@options)
|
@@ -102,7 +102,7 @@ module RobustExcelOle
|
|
102
102
|
end
|
103
103
|
ensure
|
104
104
|
if @options[:if_unsaved] == :excel then
|
105
|
-
@excel_app.DisplayAlerts = old_displayalerts
|
105
|
+
@excel_app.DisplayAlerts = old_displayalerts # :nodoc:
|
106
106
|
end
|
107
107
|
end
|
108
108
|
if block
|
@@ -137,8 +137,8 @@ module RobustExcelOle
|
|
137
137
|
when :forget
|
138
138
|
#nothing
|
139
139
|
when :excel
|
140
|
-
old_displayalerts = @excel_app.DisplayAlerts
|
141
|
-
@excel_app.DisplayAlerts = true
|
140
|
+
old_displayalerts = @excel_app.DisplayAlerts # :nodoc:
|
141
|
+
@excel_app.DisplayAlerts = true # :nodoc:
|
142
142
|
else
|
143
143
|
raise ExcelErrorClose, ":if_unsaved: invalid option"
|
144
144
|
end
|
@@ -149,7 +149,7 @@ module RobustExcelOle
|
|
149
149
|
raise ExcelUserCanceled, "close: canceled by user" if alive? && @options[:if_unsaved] == :excel && (not @workbook.Saved)
|
150
150
|
ensure
|
151
151
|
if @options[:if_unsaved] == :excel then
|
152
|
-
@excel_app.DisplayAlerts = old_displayalerts
|
152
|
+
@excel_app.DisplayAlerts = old_displayalerts # :nodoc:
|
153
153
|
end
|
154
154
|
end
|
155
155
|
#@excel_app.Workbooks.Close
|
@@ -218,8 +218,8 @@ module RobustExcelOle
|
|
218
218
|
File.delete(file)
|
219
219
|
#File.delete(absolute_path(File.join(dirname, basename)))
|
220
220
|
when :excel
|
221
|
-
old_displayalerts = @excel_app.DisplayAlerts
|
222
|
-
@excel_app.DisplayAlerts = true
|
221
|
+
old_displayalerts = @excel_app.DisplayAlerts # :nodoc:
|
222
|
+
@excel_app.DisplayAlerts = true # :nodoc:
|
223
223
|
when :raise
|
224
224
|
raise ExcelErrorSave, "book already exists: #{basename}"
|
225
225
|
else
|
@@ -230,9 +230,8 @@ module RobustExcelOle
|
|
230
230
|
@workbook.SaveAs(absolute_path(File.join(dirname, basename)), file_format)
|
231
231
|
rescue WIN32OLERuntimeError => msg
|
232
232
|
if msg.message =~ /SaveAs/ and msg.message =~ /Workbook/ then
|
233
|
-
#toDo: more condition for cancel. if user cancels: raise an exception
|
234
233
|
if opts[:if_exists] == :excel then
|
235
|
-
raise
|
234
|
+
raise ExcelErrorSave, "not saved or canceled by user"
|
236
235
|
else
|
237
236
|
return nil
|
238
237
|
end
|
@@ -242,7 +241,7 @@ module RobustExcelOle
|
|
242
241
|
end
|
243
242
|
ensure
|
244
243
|
if opts[:if_exists] == :excel then
|
245
|
-
@excel_app.DisplayAlerts = old_displayalerts
|
244
|
+
@excel_app.DisplayAlerts = old_displayalerts # :nodoc:
|
246
245
|
end
|
247
246
|
end
|
248
247
|
true
|
@@ -260,7 +259,6 @@ module RobustExcelOle
|
|
260
259
|
end
|
261
260
|
end
|
262
261
|
|
263
|
-
# adds a sheet
|
264
262
|
def add_sheet(sheet = nil, opts = { })
|
265
263
|
if sheet.is_a? Hash
|
266
264
|
opts = sheet
|
@@ -278,7 +276,6 @@ module RobustExcelOle
|
|
278
276
|
new_sheet
|
279
277
|
end
|
280
278
|
|
281
|
-
# absolute path of the file
|
282
279
|
def absolute_path(file)
|
283
280
|
file = File.expand_path(file)
|
284
281
|
file = RobustExcelOle::Cygwin.cygpath('-w', file) if RUBY_PLATFORM =~ /cygwin/
|
@@ -8,7 +8,7 @@ module RobustExcelOle
|
|
8
8
|
|
9
9
|
@@hwnd2app = {}
|
10
10
|
|
11
|
-
# closes one
|
11
|
+
# closes one Excel application
|
12
12
|
def self.close_one_app
|
13
13
|
excel = running_app
|
14
14
|
if excel then
|
@@ -67,7 +67,7 @@ module RobustExcelOle
|
|
67
67
|
puts "went through #{anz_objekte} OLE objects"
|
68
68
|
end
|
69
69
|
|
70
|
-
# closes all
|
70
|
+
# closes all Excel applications
|
71
71
|
def self.close_all
|
72
72
|
while running_app do
|
73
73
|
close_one_app
|
@@ -77,7 +77,7 @@ module RobustExcelOle
|
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
80
|
-
# returns a running
|
80
|
+
# returns a running Excel application, if a working Excel appication exists, nil otherwise
|
81
81
|
def self.running_app
|
82
82
|
result = WIN32OLE.connect('Excel.Application') rescue nil
|
83
83
|
if result
|
@@ -91,21 +91,21 @@ module RobustExcelOle
|
|
91
91
|
result
|
92
92
|
end
|
93
93
|
|
94
|
-
# creates a new
|
94
|
+
# creates a new Excel application
|
95
95
|
def self.create
|
96
96
|
new(:reuse => false)
|
97
97
|
end
|
98
98
|
|
99
|
-
# uses a running
|
99
|
+
# uses a running Excel application, if such an application exists
|
100
100
|
# creates a new one, otherwise
|
101
101
|
def self.reuse_if_possible
|
102
102
|
new(:reuse => true)
|
103
103
|
end
|
104
104
|
|
105
|
-
# returns an
|
105
|
+
# returns an Excel application
|
106
106
|
#
|
107
107
|
# options:
|
108
|
-
# :reuse (boolean) use an already running
|
108
|
+
# :reuse (boolean) use an already running Excel application (default: true)
|
109
109
|
# :displayalerts (boolean) allow display alerts in Excel (default: false)
|
110
110
|
# :visible (boolean) make visible in Excel (default: false)
|
111
111
|
def self.new(options= {})
|
@@ -115,7 +115,6 @@ module RobustExcelOle
|
|
115
115
|
if options[:reuse] then
|
116
116
|
ole_app = running_app
|
117
117
|
if ole_app
|
118
|
-
#p "bestehende Applikation wird wieder benutzt"
|
119
118
|
ole_app.DisplayAlerts = options[:displayalerts] unless options[:displayalerts]==nil
|
120
119
|
ole_app.Visible = options[:visible] unless options[:visible]==nil
|
121
120
|
end
|
@@ -125,7 +124,6 @@ module RobustExcelOle
|
|
125
124
|
:displayalerts => false,
|
126
125
|
:visible => false,
|
127
126
|
}.merge(options)
|
128
|
-
#p "kreiere neue application"
|
129
127
|
unless ole_app
|
130
128
|
ole_app = WIN32OLE.new('Excel.application')
|
131
129
|
ole_app.DisplayAlerts = options[:displayalerts]
|
@@ -147,7 +145,7 @@ module RobustExcelOle
|
|
147
145
|
end
|
148
146
|
|
149
147
|
|
150
|
-
def initialize(options= {})
|
148
|
+
def initialize(options= {}) # :nodoc:
|
151
149
|
end
|
152
150
|
|
153
151
|
|
@@ -155,17 +153,17 @@ module RobustExcelOle
|
|
155
153
|
self.HWnd #rescue Win32 nil
|
156
154
|
end
|
157
155
|
|
158
|
-
# returns true, if the
|
156
|
+
# returns true, if the Excel applications are identical, false otherwise
|
159
157
|
def == other_app
|
160
158
|
self.hwnd == other_app.hwnd if other_app.is_a?(ExcelApp)
|
161
159
|
end
|
162
160
|
|
163
|
-
# set this
|
164
|
-
def die
|
161
|
+
# set this Excel application to nil
|
162
|
+
def die # :nodoc:
|
165
163
|
@ole_app = nil
|
166
164
|
end
|
167
165
|
|
168
|
-
# returns true, if the
|
166
|
+
# returns true, if the Excel application is alive, false otherwise
|
169
167
|
def alive?
|
170
168
|
@ole_app.Name
|
171
169
|
true
|
data/spec/book_spec.rb
CHANGED
@@ -19,7 +19,7 @@ describe RobustExcelOle::Book do
|
|
19
19
|
before do
|
20
20
|
@dir = create_tmpdir
|
21
21
|
@simple_file = @dir + '/simple.xls'
|
22
|
-
@simple_save_file = @dir + '/
|
22
|
+
@simple_save_file = @dir + '/simple_save.xls'
|
23
23
|
end
|
24
24
|
|
25
25
|
after do
|
@@ -312,6 +312,7 @@ describe RobustExcelOle::Book do
|
|
312
312
|
end
|
313
313
|
end
|
314
314
|
|
315
|
+
|
315
316
|
describe "close" do
|
316
317
|
|
317
318
|
context "with saved book" do
|
@@ -586,29 +587,29 @@ describe RobustExcelOle::Book do
|
|
586
587
|
@key_sender.puts "{enter}"
|
587
588
|
@key_sender.puts "{enter}"
|
588
589
|
#@key_sender.puts "%{n}" #, :initial_wait => 0.2, :if_target_missing=>"Excel window not found")
|
589
|
-
|
590
|
+
expect{
|
591
|
+
@book.save_as(@simple_save_file, :if_exists => :excel)
|
592
|
+
}.to raise_error(ExcelErrorSave, "not saved or canceled by user")
|
590
593
|
File.exist?(@simple_save_file).should be_true
|
591
594
|
File.size?(@simple_save_file).should == @garbage_length
|
595
|
+
@book.excel_app.DisplayAlerts.should == displayalert_value
|
592
596
|
end
|
593
597
|
|
594
|
-
it "should not save
|
595
|
-
#
|
598
|
+
it "should not save if user answers 'cancel'" do
|
599
|
+
# 'Cancel' is right from 'yes'
|
596
600
|
# strangely, in the "no" case, the question will sometimes be repeated three times
|
597
601
|
@key_sender.puts "{right}{enter}"
|
598
602
|
@key_sender.puts "{right}{enter}"
|
599
603
|
@key_sender.puts "{right}{enter}"
|
604
|
+
#@key_sender.puts "%{n}" #, :initial_wait => 0.2, :if_target_missing=>"Excel window not found")
|
600
605
|
expect{
|
601
606
|
@book.save_as(@simple_save_file, :if_exists => :excel)
|
602
|
-
}.to raise_error(
|
607
|
+
}.to raise_error(ExcelErrorSave, "not saved or canceled by user")
|
603
608
|
File.exist?(@simple_save_file).should be_true
|
604
609
|
File.size?(@simple_save_file).should == @garbage_length
|
605
|
-
new_book = RobustExcelOle::Book.open(@simple_save_file)
|
606
|
-
new_book.should be_a RobustExcelOle::Book
|
607
610
|
@book.excel_app.DisplayAlerts.should == displayalert_value
|
608
|
-
new_book.close
|
609
611
|
end
|
610
612
|
|
611
|
-
|
612
613
|
it "should report save errors and leave DisplayAlerts unchanged" do
|
613
614
|
#@key_sender.puts "{left}{enter}" #, :initial_wait => 0.2, :if_target_missing=>"Excel window not found")
|
614
615
|
@book.workbook.Close
|
@@ -863,5 +864,4 @@ describe RobustExcelOle::Book do
|
|
863
864
|
}
|
864
865
|
end
|
865
866
|
end
|
866
|
-
|
867
867
|
end
|
data/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: robust_excel_ole
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 85
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
9
|
- 0
|
10
|
-
|
10
|
+
- 5
|
11
|
+
version: 0.2.0.5
|
11
12
|
platform: ruby
|
12
13
|
authors:
|
13
14
|
- traths
|
@@ -15,7 +16,7 @@ autorequire:
|
|
15
16
|
bindir: bin
|
16
17
|
cert_chain: []
|
17
18
|
|
18
|
-
date: 2014-09-
|
19
|
+
date: 2014-09-25 00:00:00 +02:00
|
19
20
|
default_executable:
|
20
21
|
dependencies:
|
21
22
|
- !ruby/object:Gem::Dependency
|