robust_excel_ole 0.2.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 +8 -0
- data/Gemfile +4 -0
- data/Guardfile +10 -0
- data/LICENSE +7 -0
- data/README.rdoc +148 -0
- data/Rakefile +9 -0
- data/lib/robust_excel_ole.rb +13 -0
- data/lib/robust_excel_ole/book.rb +310 -0
- data/lib/robust_excel_ole/cell.rb +19 -0
- data/lib/robust_excel_ole/cygwin.rb +40 -0
- data/lib/robust_excel_ole/excel_app.rb +182 -0
- data/lib/robust_excel_ole/range.rb +38 -0
- data/lib/robust_excel_ole/robustexcelole.sublime-project +8 -0
- data/lib/robust_excel_ole/robustexcelole.sublime-workspace +347 -0
- data/lib/robust_excel_ole/sheet.rb +103 -0
- data/lib/robust_excel_ole/sp +3 -0
- data/lib/robust_excel_ole/version.rb +3 -0
- data/lib/spec_helper.rb +35 -0
- data/robust_excel_ole.gemspec +32 -0
- data/robust_excel_ole_example.rb +29 -0
- data/spec/book_spec.rb +867 -0
- data/spec/cell_spec.rb +66 -0
- data/spec/cygwin_spec.rb +42 -0
- data/spec/data/book_with_blank.xls +0 -0
- data/spec/data/different_simple.xls +0 -0
- data/spec/data/merge_cells.xls +0 -0
- data/spec/data/more_data/simple.xls +0 -0
- data/spec/data/protected_sheet.xls +0 -0
- data/spec/data/simple.xls +0 -0
- data/spec/data/simple.xlsm +0 -0
- data/spec/data/simple.xlsx +0 -0
- data/spec/excel_app_spec.rb +168 -0
- data/spec/helpers/key_sender.rb +68 -0
- data/spec/range_spec.rb +120 -0
- data/spec/sheet_spec.rb +355 -0
- data/spec/spec_helper.rb +35 -0
- data/version.rb +3 -0
- metadata +203 -0
data/spec/cell_spec.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require File.join(File.dirname(__FILE__), './spec_helper')
|
3
|
+
|
4
|
+
describe RobustExcelOle::Cell do
|
5
|
+
before do
|
6
|
+
@dir = create_tmpdir
|
7
|
+
end
|
8
|
+
|
9
|
+
after do
|
10
|
+
rm_tmp(@dir)
|
11
|
+
end
|
12
|
+
|
13
|
+
context "open simple.xls" do
|
14
|
+
before do
|
15
|
+
@book = RobustExcelOle::Book.open(@dir + '/simple.xls')
|
16
|
+
@sheet = @book[1]
|
17
|
+
@cell = @sheet[0, 0]
|
18
|
+
end
|
19
|
+
|
20
|
+
after do
|
21
|
+
@book.close
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#value" do
|
25
|
+
it "get cell's value" do
|
26
|
+
@cell.value.should eq 'simple'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#value=" do
|
31
|
+
it "change cell data to 'fooooo'" do
|
32
|
+
@cell.value = 'fooooo'
|
33
|
+
@cell.value.should eq 'fooooo'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#method_missing" do
|
38
|
+
context "unknown method" do
|
39
|
+
it { expect { @cell.hogehogefoo }.to raise_error }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
context "open merge_cells.xls" do
|
46
|
+
before do
|
47
|
+
@book = RobustExcelOle::Book.open(@dir + '/merge_cells.xls')
|
48
|
+
@sheet = @book[0]
|
49
|
+
end
|
50
|
+
|
51
|
+
after do
|
52
|
+
@book.close
|
53
|
+
end
|
54
|
+
|
55
|
+
it "merged cell get same value" do
|
56
|
+
@sheet[0, 0].value.should be_nil
|
57
|
+
@sheet[1, 0].value.should eq 'first merged'
|
58
|
+
end
|
59
|
+
|
60
|
+
it "set merged cell" do
|
61
|
+
@sheet[1, 0].value = "set merge cell"
|
62
|
+
@sheet[1, 0].value.should eq "set merge cell"
|
63
|
+
@sheet[1, 1].value.should eq "set merge cell"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/spec/cygwin_spec.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require File.join(File.dirname(__FILE__), './spec_helper')
|
3
|
+
|
4
|
+
describe "on cygwin", :if => RUBY_PLATFORM =~ /cygwin/ do
|
5
|
+
describe ".cygpath" do
|
6
|
+
context "cygwin path is '/cygdrive/c/Users'" do
|
7
|
+
context "with '-w' options" do
|
8
|
+
it { RobustExcelOle::Cygwin.cygpath('-w', '/cygdrive/c/Users').should eq 'C:\\Users' }
|
9
|
+
end
|
10
|
+
|
11
|
+
context "with '-wa' options" do
|
12
|
+
it { RobustExcelOle::Cygwin.cygpath('-wa', '/cygdrive/c/Users').should eq 'C:\\Users' }
|
13
|
+
end
|
14
|
+
|
15
|
+
context "with '-ws' options" do
|
16
|
+
it { RobustExcelOle::Cygwin.cygpath('-ws', '/cygdrive/c/Users').should eq 'C:\\Users' }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context "windows path is 'C:\\Users'" do
|
21
|
+
context "with '-u option" do
|
22
|
+
it { RobustExcelOle::Cygwin.cygpath('-u', 'C:\\Users').should eq '/cygdrive/c/Users'}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "cygwin path is './'" do
|
27
|
+
context "with '-u' options" do
|
28
|
+
it { RobustExcelOle::Cygwin.cygpath('-u', './').should eq './' }
|
29
|
+
end
|
30
|
+
|
31
|
+
context "with '-ua' options" do
|
32
|
+
it { RobustExcelOle::Cygwin.cygpath('-ua', './').should eq File.expand_path('./') + '/' }
|
33
|
+
end
|
34
|
+
|
35
|
+
context "with '-us' options" do
|
36
|
+
it { RobustExcelOle::Cygwin.cygpath('-us', './').should eq './' }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,168 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require File.join(File.dirname(__FILE__), './spec_helper')
|
4
|
+
|
5
|
+
$VERBOSE = nil
|
6
|
+
|
7
|
+
module RobustExcelOle
|
8
|
+
|
9
|
+
describe ExcelApp do
|
10
|
+
before do
|
11
|
+
@dir = create_tmpdir
|
12
|
+
@simple_file = @dir + '/simple.xls'
|
13
|
+
end
|
14
|
+
|
15
|
+
after do
|
16
|
+
rm_tmp(@dir)
|
17
|
+
end
|
18
|
+
|
19
|
+
save_path = "C:" + "/" + "simple_save.xls"
|
20
|
+
|
21
|
+
context "app creation" do
|
22
|
+
after do
|
23
|
+
ExcelApp.close_all
|
24
|
+
end
|
25
|
+
|
26
|
+
def creation_ok?
|
27
|
+
@app.alive?.should == true
|
28
|
+
@app.Visible.should == false
|
29
|
+
@app.DisplayAlerts.should == false
|
30
|
+
@app.Name.should == "Microsoft Excel"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should work with 'new' " do
|
34
|
+
@app = ExcelApp.new
|
35
|
+
creation_ok?
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should work with 'new' " do
|
39
|
+
@app = ExcelApp.new(:reuse => false)
|
40
|
+
creation_ok?
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should work with 'create' " do
|
44
|
+
@app = ExcelApp.create
|
45
|
+
creation_ok?
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
context "with existing app" do
|
53
|
+
|
54
|
+
before do
|
55
|
+
ExcelApp.close_all
|
56
|
+
@app1 = ExcelApp.create
|
57
|
+
end
|
58
|
+
|
59
|
+
after do
|
60
|
+
ExcelApp.close_all
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should create different app" do
|
64
|
+
app2 = ExcelApp.create
|
65
|
+
#puts "@app1 #{@app1.Hwnd}"
|
66
|
+
#puts "app2 #{app2.Hwnd}"
|
67
|
+
app2.Hwnd.should_not == @app1.Hwnd
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should reuse existing app" do
|
71
|
+
app2 = ExcelApp.reuse_if_possible
|
72
|
+
#puts "@app1 #{@app1.Hwnd}"
|
73
|
+
#puts "app2 #{app2.Hwnd}"
|
74
|
+
app2.Hwnd.should == @app1.Hwnd
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should reuse existing app with default options for 'new'" do
|
78
|
+
app2 = ExcelApp.new
|
79
|
+
#puts "@app1 #{@app1.Hwnd}"
|
80
|
+
#puts "app2 #{app2.Hwnd}"
|
81
|
+
app2.Hwnd.should == @app1.Hwnd
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
context "close excel instances" do
|
87
|
+
def direct_excel_creation_helper
|
88
|
+
expect { WIN32OLE.connect("Excel.Application") }.to raise_error
|
89
|
+
sleep 0.1
|
90
|
+
exl1 = WIN32OLE.new("Excel.Application")
|
91
|
+
exl1.Workbooks.Add
|
92
|
+
exl2 = WIN32OLE.new("Excel.Application")
|
93
|
+
exl2.Workbooks.Add
|
94
|
+
expect { WIN32OLE.connect("Excel.Application") }.to_not raise_error
|
95
|
+
end
|
96
|
+
|
97
|
+
it "simple file with default" do
|
98
|
+
RobustExcelOle::ExcelApp.close_all
|
99
|
+
direct_excel_creation_helper
|
100
|
+
RobustExcelOle::ExcelApp.close_all
|
101
|
+
sleep 0.1
|
102
|
+
expect { WIN32OLE.connect("Excel.Application") }.to raise_error
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
describe "==" do
|
107
|
+
before do
|
108
|
+
ExcelApp.close_all
|
109
|
+
@app1 = ExcelApp.create
|
110
|
+
end
|
111
|
+
|
112
|
+
after do
|
113
|
+
ExcelApp.close_all
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should be true with two identical excel applications" do
|
117
|
+
app2 = ExcelApp.reuse_if_possible
|
118
|
+
app2.should == @app1
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should be false with two different excel applications" do
|
122
|
+
app2 = ExcelApp.create
|
123
|
+
app2.should_not == @app1
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should be false with non-ExcelApp objects" do
|
127
|
+
@app1.should_not == "hallo"
|
128
|
+
@app1.should_not == 7
|
129
|
+
@app1.should_not == nil
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
context "with Visible and DisplayAlerts" do
|
135
|
+
|
136
|
+
before do
|
137
|
+
ExcelApp.close_all
|
138
|
+
end
|
139
|
+
|
140
|
+
after (:each) do
|
141
|
+
ExcelApp.close_all
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should be visible" do
|
145
|
+
app = ExcelApp.new(:visible => true)
|
146
|
+
app.Visible.should == true
|
147
|
+
app.DisplayAlerts.should == false
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should displayalerts" do
|
151
|
+
app = ExcelApp.new(:displayalerts => true)
|
152
|
+
app.DisplayAlerts.should == true
|
153
|
+
app.Visible.should == false
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should visible and displayalerts" do
|
157
|
+
app = ExcelApp.new(:visible => true)
|
158
|
+
app.Visible.should == true
|
159
|
+
app.DisplayAlerts.should == false
|
160
|
+
app2 = ExcelApp.new(:displayalerts => true)
|
161
|
+
app2.Visible.should == true
|
162
|
+
app2.DisplayAlerts.should == true
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
|
2
|
+
require 'win32ole'
|
3
|
+
|
4
|
+
class KeySender
|
5
|
+
def initialize(window_name, options={})
|
6
|
+
@window_name = window_name
|
7
|
+
@wsh = WIN32OLE.new('Wscript.Shell')
|
8
|
+
@initial_wait = options[:initial_wait] || 0.2
|
9
|
+
end
|
10
|
+
|
11
|
+
# options:
|
12
|
+
# :timeout, :initial_wait, :if_target_missing, :silent,
|
13
|
+
def send(key_seq, options={})
|
14
|
+
initial_wait = options[:initial_wait] || @initial_wait
|
15
|
+
timeout = options[:timeout] || 5
|
16
|
+
start_time = Time.now
|
17
|
+
sleep initial_wait
|
18
|
+
|
19
|
+
ready_to_send = if @window_name
|
20
|
+
loop do
|
21
|
+
akt = @wsh.AppActivate(@window_name)
|
22
|
+
break akt if akt
|
23
|
+
break false if Time.now - start_time > timeout
|
24
|
+
sleep 0.3
|
25
|
+
print "-" unless options[:silent]
|
26
|
+
end
|
27
|
+
else
|
28
|
+
true # Keine Window_name, immer senden'
|
29
|
+
end
|
30
|
+
|
31
|
+
if ready_to_send
|
32
|
+
@wsh.SendKeys(key_seq) if key_seq
|
33
|
+
yield if block_given?
|
34
|
+
else
|
35
|
+
else_aktion = options[:if_target_missing]
|
36
|
+
case else_aktion
|
37
|
+
when Proc
|
38
|
+
else_aktion.call
|
39
|
+
when nil
|
40
|
+
else
|
41
|
+
raise else_aktion
|
42
|
+
end
|
43
|
+
end
|
44
|
+
ready_to_send
|
45
|
+
end
|
46
|
+
|
47
|
+
def wait_for_window(windowname, timeout=30)
|
48
|
+
break_time = Time.now + timeout
|
49
|
+
loop do
|
50
|
+
windowname.each do |window_name|
|
51
|
+
ready_to_send = @wsh.AppActivate(window_name)
|
52
|
+
return window_name if ready_to_send
|
53
|
+
end
|
54
|
+
break false if Time.now > break_time
|
55
|
+
|
56
|
+
print " (noch #{'%.1f'%(break_time - Time.now)}s) " unless options[:silent]
|
57
|
+
sleep 0.813
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
if __FILE__ == $0
|
63
|
+
key_sender = KeySender.new(ARGV[1])
|
64
|
+
while not $stdin.eof? do
|
65
|
+
key_sequence = $stdin.gets.chomp
|
66
|
+
key_sender.send key_sequence
|
67
|
+
end
|
68
|
+
end
|
data/spec/range_spec.rb
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require File.join(File.dirname(__FILE__), './spec_helper')
|
3
|
+
|
4
|
+
describe RobustExcelOle::Range do
|
5
|
+
before do
|
6
|
+
@dir = create_tmpdir
|
7
|
+
@book = RobustExcelOle::Book.open(@dir + '/simple.xls')
|
8
|
+
@sheet = @book[1]
|
9
|
+
@range = RobustExcelOle::Range.new(@sheet.sheet.UsedRange.Rows(1))
|
10
|
+
end
|
11
|
+
|
12
|
+
after do
|
13
|
+
@book.close
|
14
|
+
rm_tmp(@dir)
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "#each" do
|
18
|
+
it "items is RobustExcelOle::Cell" do
|
19
|
+
@range.each do |cell|
|
20
|
+
cell.should be_kind_of RobustExcelOle::Cell
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#values" do
|
26
|
+
context "with (0..2)" do
|
27
|
+
it { @range.values(0..2).should eq ['simple', 'file', 'sheet2'] }
|
28
|
+
end
|
29
|
+
|
30
|
+
context "with (1..2)" do
|
31
|
+
it { @range.values(1..2).should eq ['file', 'sheet2'] }
|
32
|
+
end
|
33
|
+
|
34
|
+
context "with (2..2)" do
|
35
|
+
it { @range.values(2..2).should eq ['sheet2'] }
|
36
|
+
end
|
37
|
+
|
38
|
+
context "with no arguments" do
|
39
|
+
it { @range.values.should eq ['simple', 'file', 'sheet2'] }
|
40
|
+
end
|
41
|
+
|
42
|
+
context "when instance is column range" do
|
43
|
+
before do
|
44
|
+
@sheet = @book[0]
|
45
|
+
@range = RobustExcelOle::Range.new(@sheet.sheet.UsedRange.Columns(1))
|
46
|
+
end
|
47
|
+
it { @range.values.should eq ['simple', 'foo', 'matz'] }
|
48
|
+
end
|
49
|
+
|
50
|
+
context "read 'merge_cells.xls'" do
|
51
|
+
before do
|
52
|
+
@merge_cells_book = RobustExcelOle::Book.open("#{@dir}/merge_cells.xls")
|
53
|
+
@merge_cells_sheet = @merge_cells_book[0]
|
54
|
+
end
|
55
|
+
|
56
|
+
after do
|
57
|
+
@merge_cells_book.close
|
58
|
+
end
|
59
|
+
|
60
|
+
context "only merged_cell" do
|
61
|
+
before do
|
62
|
+
@only_merged_range = @merge_cells_sheet.row_range(3)
|
63
|
+
end
|
64
|
+
|
65
|
+
context "without argument" do
|
66
|
+
it { @only_merged_range.values.should eq ['merged', 'merged', 'merged', 'merged'] }
|
67
|
+
end
|
68
|
+
|
69
|
+
context "with (1..2)" do
|
70
|
+
it { @only_merged_range.values(1..2).should eq ['merged', 'merged'] }
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
context "mix merged cell and no merge cell" do
|
76
|
+
before do
|
77
|
+
@mix_merged_no_merged_range = @merge_cells_sheet.row_range(1)
|
78
|
+
end
|
79
|
+
|
80
|
+
context "without argument" do
|
81
|
+
it { @mix_merged_no_merged_range.values.should eq ['first merged', 'first merged', 'first merged', nil] }
|
82
|
+
end
|
83
|
+
|
84
|
+
context "with (2..3)" do
|
85
|
+
it { @mix_merged_no_merged_range.values(2..3).should eq ['first merged', nil] }
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "#[]" do
|
93
|
+
context "access [0]" do
|
94
|
+
it { @range[0].should be_kind_of RobustExcelOle::Cell }
|
95
|
+
it { @range[0].value.should eq 'simple' }
|
96
|
+
end
|
97
|
+
|
98
|
+
context "access [2]" do
|
99
|
+
it { @range[2].value.should eq 'sheet2' }
|
100
|
+
end
|
101
|
+
|
102
|
+
context "access [0] and [1] and [2]" do
|
103
|
+
it "should get every values" do
|
104
|
+
@range[0].value.should eq 'simple'
|
105
|
+
@range[1].value.should eq 'file'
|
106
|
+
@range[2].value.should eq 'sheet2'
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe "#method_missing" do
|
112
|
+
it "can access COM method" do
|
113
|
+
@range.Range(@range.Cells.Item(1), @range.Cells.Item(3)).value.should eq [@range.values(0..2)]
|
114
|
+
end
|
115
|
+
|
116
|
+
context "unknown method" do
|
117
|
+
it { expect { @range.hogehogefoo}.to raise_error }
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|