aio_elin 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.
- checksums.yaml +7 -0
- data/LICENSE.txt +675 -0
- data/README.md +9 -0
- data/config.rb +39 -0
- data/lib/aio/base/debug.rb +30 -0
- data/lib/aio/base/toolkit/array.rb +24 -0
- data/lib/aio/base/toolkit/date.rb +46 -0
- data/lib/aio/base/toolkit/deep_clone.rb +10 -0
- data/lib/aio/base/toolkit/diff.rb +104 -0
- data/lib/aio/base/toolkit/excel_office.rb +421 -0
- data/lib/aio/base/toolkit/excel_wps.rb +437 -0
- data/lib/aio/base/toolkit/excel_wps.rb.bak +299 -0
- data/lib/aio/base/toolkit/ipaddr.rb +28 -0
- data/lib/aio/base/toolkit/os.rb +26 -0
- data/lib/aio/base/toolkit/regexp.rb +32 -0
- data/lib/aio/base/toolkit/string.rb +28 -0
- data/lib/aio/base/toolkit/table.rb +441 -0
- data/lib/aio/base/toolkit/test_diff.rb +9 -0
- data/lib/aio/base/toolkit/test_excel.rb +118 -0
- data/lib/aio/base/toolkit/test_word.rb +58 -0
- data/lib/aio/base/toolkit/word_wps.rb +492 -0
- data/lib/aio/base/toolkit.rb +18 -0
- data/lib/aio/base.rb +10 -0
- data/lib/aio/core/device/cisco.rb +13 -0
- data/lib/aio/core/device/cmd_switch.rb +113 -0
- data/lib/aio/core/device/h3c.rb +12 -0
- data/lib/aio/core/device/huawei.rb +10 -0
- data/lib/aio/core/device/juniper.rb +10 -0
- data/lib/aio/core/device/maipu.rb +11 -0
- data/lib/aio/core/device/methods.rb +233 -0
- data/lib/aio/core/device/methods.rb.bak +199 -0
- data/lib/aio/core/device/parent_device.rb +275 -0
- data/lib/aio/core/device.rb +15 -0
- data/lib/aio/core/device_manager.rb +207 -0
- data/lib/aio/core/module/cmd.rb +160 -0
- data/lib/aio/core/module/description.rb +67 -0
- data/lib/aio/core/module/input_style.rb +98 -0
- data/lib/aio/core/module/output_style.rb +80 -0
- data/lib/aio/core/module/platform.rb +30 -0
- data/lib/aio/core/module/ranking.rb +24 -0
- data/lib/aio/core/module/special_style.rb +30 -0
- data/lib/aio/core/module/template.rb +13 -0
- data/lib/aio/core/module.rb +15 -0
- data/lib/aio/core/module_loader.rb +161 -0
- data/lib/aio/core/module_loader.rb.bak +148 -0
- data/lib/aio/core/module_manager.rb +112 -0
- data/lib/aio/core/module_manager.rb.bak +78 -0
- data/lib/aio/core/parse/file.rb +19 -0
- data/lib/aio/core/parse/parser.rb +91 -0
- data/lib/aio/core/parse/parser_machine/bak/has_cmd_state.rb +14 -0
- data/lib/aio/core/parse/parser_machine/bak/has_context_state.rb +11 -0
- data/lib/aio/core/parse/parser_machine/bak/no_cmd_state.rb +11 -0
- data/lib/aio/core/parse/parser_machine/bak/no_context_state.rb +11 -0
- data/lib/aio/core/parse/parser_machine/full_state.rb +12 -0
- data/lib/aio/core/parse/parser_machine/has_device_state.rb +44 -0
- data/lib/aio/core/parse/parser_machine/no_device_state.rb +12 -0
- data/lib/aio/core/parse/parser_machine/parent_state.rb +26 -0
- data/lib/aio/core/parse/parser_machine.rb +47 -0
- data/lib/aio/core/parse.rb +6 -0
- data/lib/aio/core/text/context.rb +211 -0
- data/lib/aio/core/text/line_string.rb +74 -0
- data/lib/aio/core/text/warning.rb +179 -0
- data/lib/aio/core/text.rb +7 -0
- data/lib/aio/core/warning/description.rb +47 -0
- data/lib/aio/core/warning/warning_summarize.rb +232 -0
- data/lib/aio/core/warning.rb +6 -0
- data/lib/aio/core.rb +32 -0
- data/lib/aio/license.rb +687 -0
- data/lib/aio/resource/cover_picture.png +0 -0
- data/lib/aio/resource/line.png +0 -0
- data/lib/aio/resource/logo.png +0 -0
- data/lib/aio/ui/banner.rb +85 -0
- data/lib/aio/ui/readable_text.rb +75 -0
- data/lib/aio/ui/verbose.rb +29 -0
- data/lib/aio/ui/version.rb +9 -0
- data/lib/aio/ui.rb +138 -0
- data/lib/aio.rb +13 -0
- data/lib/modules/cmd/cisco/show_clock.rb +32 -0
- data/lib/modules/cmd/cisco/show_cpu.rb +32 -0
- data/lib/modules/cmd/cisco/show_env.rb +71 -0
- data/lib/modules/cmd/cisco/show_failover.rb +39 -0
- data/lib/modules/cmd/cisco/show_interface_ip_brief.rb +24 -0
- data/lib/modules/cmd/cisco/show_interfaces.rb +177 -0
- data/lib/modules/cmd/cisco/show_inv.rb +43 -0
- data/lib/modules/cmd/cisco/show_ip_interface_brief.rb +42 -0
- data/lib/modules/cmd/cisco/show_ip_ospf_nei.rb +38 -0
- data/lib/modules/cmd/cisco/show_ip_route_summary.rb +81 -0
- data/lib/modules/cmd/cisco/show_memory.rb +27 -0
- data/lib/modules/cmd/cisco/show_process_cpu.rb +35 -0
- data/lib/modules/cmd/cisco/show_process_memory.rb +63 -0
- data/lib/modules/cmd/cisco/show_version.rb +97 -0
- data/lib/modules/cmd/h3c/display_clock.rb +32 -0
- data/lib/modules/cmd/h3c/display_cpu.rb +51 -0
- data/lib/modules/cmd/h3c/display_device_manuinfo.rb +45 -0
- data/lib/modules/cmd/h3c/display_fan.rb +91 -0
- data/lib/modules/cmd/h3c/display_interface.rb +203 -0
- data/lib/modules/cmd/h3c/display_ip_interface_brief.rb +34 -0
- data/lib/modules/cmd/h3c/display_ip_routing.rb +68 -0
- data/lib/modules/cmd/h3c/display_ip_routing_stat.rb +90 -0
- data/lib/modules/cmd/h3c/display_memory.rb +35 -0
- data/lib/modules/cmd/h3c/display_ospf_peer.rb +38 -0
- data/lib/modules/cmd/h3c/display_power.rb +90 -0
- data/lib/modules/cmd/h3c/display_version.rb +54 -0
- data/lib/modules/cmd/h3c/display_vrrp_verbose.rb +86 -0
- data/lib/modules/cmd/maipu/show_env.rb +34 -0
- data/lib/modules/cmd/maipu/show_ip_route.rb +74 -0
- data/lib/modules/cmd/maipu/show_ip_route_statistic.rb +36 -0
- data/lib/modules/cmd/maipu/show_memory.rb +31 -0
- data/lib/modules/cmd/maipu/show_system_fan.rb +66 -0
- data/lib/modules/cmd/maipu/show_system_power.rb +66 -0
- data/lib/modules/cmd/maipu/show_version.rb +50 -0
- data/lib/modules/description/style/crc.rb +22 -0
- data/lib/modules/description/style/input_errors.rb +22 -0
- data/lib/modules/description/style/overrun.rb +22 -0
- data/lib/modules/description/style/proc_ratio.rb +22 -0
- data/lib/modules/description/style/protocol.rb +22 -0
- data/lib/modules/description/style/register.rb +22 -0
- data/lib/modules/description/style/runts.rb +22 -0
- data/lib/modules/description/style/template.rb +22 -0
- data/lib/modules/description/style/total_output_drops.rb +22 -0
- data/lib/modules/input/style/compare_xml.rb +89 -0
- data/lib/modules/input/style/console.rb +222 -0
- data/lib/modules/input/style/console.rb.bak +114 -0
- data/lib/modules/input/style/xinhua_nat.rb +70 -0
- data/lib/modules/output/style/boc_day.rb +223 -0
- data/lib/modules/output/style/cmds.rb +77 -0
- data/lib/modules/output/style/compare_json.rb +26 -0
- data/lib/modules/output/style/compare_report.rb +31 -0
- data/lib/modules/output/style/compare_xml.rb +86 -0
- data/lib/modules/output/style/excel_table_office.rb +407 -0
- data/lib/modules/output/style/excel_table_wps.rb +400 -0
- data/lib/modules/output/style/summary_report.rb +563 -0
- data/lib/modules/special/style/compare.rb +110 -0
- metadata +176 -0
data/README.md
ADDED
data/config.rb
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# 此配置模块用于过滤多余的警告信息
|
|
2
|
+
|
|
3
|
+
module Aio::Config
|
|
4
|
+
module Warning
|
|
5
|
+
Pass = "pass"
|
|
6
|
+
|
|
7
|
+
Serious = [
|
|
8
|
+
#:crc,
|
|
9
|
+
#:input_errors,
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
Ordinary = [
|
|
13
|
+
#:total_output_drops,
|
|
14
|
+
:iface_resets,
|
|
15
|
+
:giants,
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
# 包括数值 或者 Pass
|
|
19
|
+
Compare = {
|
|
20
|
+
# version
|
|
21
|
+
:uptime => Pass,
|
|
22
|
+
# interface
|
|
23
|
+
:crc => 50,
|
|
24
|
+
:frame => Pass,
|
|
25
|
+
# memory
|
|
26
|
+
:proc_ratio => 50,
|
|
27
|
+
# cpu
|
|
28
|
+
:minute_1 => 10,
|
|
29
|
+
:minutes_5 => 10,
|
|
30
|
+
# clock
|
|
31
|
+
:time => Pass,
|
|
32
|
+
:week => Pass,
|
|
33
|
+
:year => Pass,
|
|
34
|
+
:month => Pass,
|
|
35
|
+
:day => Pass,
|
|
36
|
+
}
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module Aio::Base
|
|
2
|
+
module Debug
|
|
3
|
+
|
|
4
|
+
class << self
|
|
5
|
+
def enable?
|
|
6
|
+
false
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# core/text/context.rb
|
|
10
|
+
# 如果没有找到匹配的行,则输出debug
|
|
11
|
+
def mismatch?
|
|
12
|
+
true
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# core/text/context.rb:56
|
|
17
|
+
# 如果模块中方法有问题,则报错
|
|
18
|
+
def module_debug?
|
|
19
|
+
true
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# ui.rb
|
|
23
|
+
# 查看解析后设备情况
|
|
24
|
+
def ui_enable?
|
|
25
|
+
false
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Aio::Base::Toolkit::Array
|
|
2
|
+
class << self
|
|
3
|
+
|
|
4
|
+
# 按pattern分割数组
|
|
5
|
+
def split(array, pattern)
|
|
6
|
+
res = [[]]
|
|
7
|
+
count = 0
|
|
8
|
+
array.each do |a|
|
|
9
|
+
|
|
10
|
+
a = Aio::Base::Toolkit::String.safe(a)
|
|
11
|
+
unless pattern.match(a)
|
|
12
|
+
res[count] << a
|
|
13
|
+
else
|
|
14
|
+
res << []
|
|
15
|
+
count += 1
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
res
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module Aio::Base::Toolkit::Date
|
|
2
|
+
class << self
|
|
3
|
+
|
|
4
|
+
def month_to_i(str)
|
|
5
|
+
return case str
|
|
6
|
+
when /(?i)Jan/
|
|
7
|
+
"01"
|
|
8
|
+
when /(?i)Feb/
|
|
9
|
+
"02"
|
|
10
|
+
when /(?i)Mar/
|
|
11
|
+
"03"
|
|
12
|
+
when /(?i)Apr/
|
|
13
|
+
"04"
|
|
14
|
+
when /(?i)May/
|
|
15
|
+
"05"
|
|
16
|
+
when /(?i)Jun/
|
|
17
|
+
"06"
|
|
18
|
+
when /(?i)Jul/
|
|
19
|
+
"07"
|
|
20
|
+
when /(?i)Aug/
|
|
21
|
+
"08"
|
|
22
|
+
when /(?i)Sep/
|
|
23
|
+
"09"
|
|
24
|
+
when /(?i)Oct/
|
|
25
|
+
"10"
|
|
26
|
+
when /(?i)Nov/
|
|
27
|
+
"11"
|
|
28
|
+
when /(?i)Dec/
|
|
29
|
+
"12"
|
|
30
|
+
else
|
|
31
|
+
"unknow"
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# arr = [time, zone, week, year, month, day]
|
|
36
|
+
def time_to_s(arr)
|
|
37
|
+
year = arr[3]
|
|
38
|
+
month = arr[4]
|
|
39
|
+
day = arr[5]
|
|
40
|
+
time = arr[0]
|
|
41
|
+
format("%s-%s-%s %s", year, month, day, time)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
end # class self
|
|
45
|
+
end
|
|
46
|
+
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# 此文件是用来比较两个命令文件不同之处,并生产Ruby格式命令
|
|
2
|
+
|
|
3
|
+
#module Aio::Base::Toolkit
|
|
4
|
+
class Diff
|
|
5
|
+
|
|
6
|
+
# 输入文件1
|
|
7
|
+
attr_accessor :input_1
|
|
8
|
+
|
|
9
|
+
# 输入文件2
|
|
10
|
+
attr_accessor :input_2
|
|
11
|
+
|
|
12
|
+
def initialize(input_1, input_2)
|
|
13
|
+
self.input_1 = File.open(input_1)
|
|
14
|
+
self.input_2 = File.open(input_2)
|
|
15
|
+
@context_name = "context"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def diff
|
|
19
|
+
in_1 = @input_1.dup
|
|
20
|
+
in_2 = @input_2.dup.readlines
|
|
21
|
+
# 行计数从1开始
|
|
22
|
+
line_count = 0
|
|
23
|
+
res_text = []
|
|
24
|
+
|
|
25
|
+
in_1.each_line do |line_1|
|
|
26
|
+
# 加入了区间,如果不是在这个区间内,则忽略
|
|
27
|
+
line_count += 1
|
|
28
|
+
unless @range.nil?
|
|
29
|
+
if ! @range.include?(line_count)
|
|
30
|
+
next
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
line_1 = line_1.chomp
|
|
35
|
+
begin
|
|
36
|
+
line_2 = in_2[line_count - 1].chomp
|
|
37
|
+
rescue EOFError
|
|
38
|
+
break
|
|
39
|
+
end
|
|
40
|
+
#new_line = "#{@context_name}[#{line_count}].match_block(/"
|
|
41
|
+
new_line = "#{@context_name}.readline_match_block(/"
|
|
42
|
+
|
|
43
|
+
# 按照单词进行比对
|
|
44
|
+
word_1_arr = line_1.split(' ')
|
|
45
|
+
word_2_arr = line_2.split(' ')
|
|
46
|
+
|
|
47
|
+
word_arr = []
|
|
48
|
+
merge_count = []
|
|
49
|
+
word_1_arr.each_with_index do |word_1, i|
|
|
50
|
+
|
|
51
|
+
word_2 = word_2_arr[i]
|
|
52
|
+
|
|
53
|
+
if word_1 == word_2
|
|
54
|
+
word_arr << inn(word_1)
|
|
55
|
+
else
|
|
56
|
+
word_arr << '(.*)'
|
|
57
|
+
merge_count << i
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
# 合并word_arr中相邻的(.*)
|
|
61
|
+
real_word_arr = []
|
|
62
|
+
word_arr.each_with_index do |word, i|
|
|
63
|
+
if word != '(.*)'
|
|
64
|
+
real_word_arr << word
|
|
65
|
+
next
|
|
66
|
+
end
|
|
67
|
+
if word_arr[i+1] == '(.*)'
|
|
68
|
+
next
|
|
69
|
+
end
|
|
70
|
+
# 加入(.*)
|
|
71
|
+
real_word_arr << word
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
new_line << real_word_arr.join(' ')
|
|
75
|
+
new_line << '/)'
|
|
76
|
+
|
|
77
|
+
res_text << new_line
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
res = res_text.join("\n")
|
|
81
|
+
puts res
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def set_range(first, last)
|
|
85
|
+
@range = Range.new(first, last)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def context_name=(var)
|
|
89
|
+
@context_name = var
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# 无害化处理
|
|
93
|
+
def inn(word)
|
|
94
|
+
word.gsub!('/', '\/')
|
|
95
|
+
word.gsub!('(', '\(')
|
|
96
|
+
word.gsub!(')', '\)')
|
|
97
|
+
word.gsub!('.', '\.')
|
|
98
|
+
word
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
#end
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
|
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
module Aio::Base::Toolkit
|
|
2
|
+
module ExcelOffice
|
|
3
|
+
class WorkBook
|
|
4
|
+
|
|
5
|
+
include Aio::Ui::Verbose
|
|
6
|
+
|
|
7
|
+
@@worksheets_name = []
|
|
8
|
+
def initialize(encoding = "utf-8")
|
|
9
|
+
|
|
10
|
+
if Aio::Base::Toolkit::OS.windows?
|
|
11
|
+
require "win32ole"
|
|
12
|
+
else
|
|
13
|
+
print_error "只有Windows系统才能使用Excel模块"
|
|
14
|
+
exit 0
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
@excel = WIN32OLE.new("excel.Application")
|
|
18
|
+
@excel.visible = false
|
|
19
|
+
@workbook = @excel.workbooks.add
|
|
20
|
+
@encoding = encoding
|
|
21
|
+
create_style
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# 切换到分页预览视图
|
|
25
|
+
def window_pagebreak
|
|
26
|
+
@excel.ActiveWindow.View = 2
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# 切换到普通视图
|
|
30
|
+
def window_normal
|
|
31
|
+
@excel.ActiveWindow.View = 1
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# 警告提示开关
|
|
35
|
+
def display_alerts=(bool)
|
|
36
|
+
@excel.DisplayAlerts = bool
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def add_worksheet(name)
|
|
40
|
+
while @@worksheets_name.include?(name)
|
|
41
|
+
name += "1"
|
|
42
|
+
end
|
|
43
|
+
@@worksheets_name << name
|
|
44
|
+
worksheet = @workbook.worksheets.add
|
|
45
|
+
worksheet.activate
|
|
46
|
+
worksheet.name = name
|
|
47
|
+
return WorkSheet.new(worksheet)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def create_style
|
|
51
|
+
sty = @workbook.styles.add("NormalStyle")
|
|
52
|
+
self.class.normal_style(sty)
|
|
53
|
+
|
|
54
|
+
sty = @workbook.styles.add("BoldStyle")
|
|
55
|
+
self.class.bold_style(sty)
|
|
56
|
+
|
|
57
|
+
sty = @workbook.styles.add("TitleStyle")
|
|
58
|
+
self.class.title_style(sty)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def self.normal_style(sty)
|
|
62
|
+
sty.font.size = 9
|
|
63
|
+
sty.HorizontalAlignment = -4108
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def self.bold_style(sty)
|
|
67
|
+
sty.font.size = 9
|
|
68
|
+
sty.font.bold = true
|
|
69
|
+
sty.HorizontalAlignment = -4108
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def self.title_style(sty)
|
|
73
|
+
sty.font.size = 20
|
|
74
|
+
sty.font.bold = true
|
|
75
|
+
sty.HorizontalAlignment = -4108
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def show
|
|
79
|
+
@excel.visible = true
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def save(path)
|
|
83
|
+
path = Aio::Base::Toolkit::String.safe_path(path)
|
|
84
|
+
@workbook.saveas(path)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def close
|
|
88
|
+
@workbook.close
|
|
89
|
+
@excel.quit
|
|
90
|
+
end
|
|
91
|
+
end # class WorkBook
|
|
92
|
+
|
|
93
|
+
class WorkSheet
|
|
94
|
+
IMAGE_ROW_NUM = 56
|
|
95
|
+
@@worksheets_name = []
|
|
96
|
+
def initialize(worksheet)
|
|
97
|
+
@row_count = 1
|
|
98
|
+
@worksheet = worksheet
|
|
99
|
+
@nil_space = []
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# 增加一个空行
|
|
103
|
+
def add_space_line(n=1)
|
|
104
|
+
return if n < 1
|
|
105
|
+
@row_count += n
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# 对列进行合并
|
|
109
|
+
def merge(range1, range2)
|
|
110
|
+
@worksheet.range("#{range1}:#{range2}").merge
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# 产生 ::Range 类
|
|
114
|
+
def range(str)
|
|
115
|
+
@worksheet.range(str)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# 添加标题行
|
|
119
|
+
def add_title(name)
|
|
120
|
+
add_row.add_cell(name, false, "BoldStyle")
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# 设置列的宽度
|
|
124
|
+
def width(col, width)
|
|
125
|
+
@worksheet.Columns("#{col}:#{col}").ColumnWidth = width
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def height(height)
|
|
129
|
+
@row_height = height
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# 增加Row类
|
|
133
|
+
def add_row(&block)
|
|
134
|
+
@current_row = Row.new(@worksheet, @row_count)
|
|
135
|
+
@current_row.height = @row_height if @row_height
|
|
136
|
+
@row_count += 1
|
|
137
|
+
yield @current_row if block
|
|
138
|
+
@current_row.merge!
|
|
139
|
+
begin
|
|
140
|
+
@current_row.real_row.borders.linestyle = 1
|
|
141
|
+
rescue Exception
|
|
142
|
+
retry
|
|
143
|
+
end
|
|
144
|
+
return @current_row
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# 返回此时的Row类
|
|
148
|
+
def current_row
|
|
149
|
+
return @current_row
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# 返回此时的行索引
|
|
153
|
+
def current_row_id
|
|
154
|
+
return @current_row.row_id
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# 添加图像
|
|
158
|
+
def add_image(image_path)
|
|
159
|
+
return unless File.exist?(image_path)
|
|
160
|
+
add_space_line
|
|
161
|
+
add_row
|
|
162
|
+
cell_name = current_row.first_cell
|
|
163
|
+
@worksheet.Range(cell_name).Select
|
|
164
|
+
@worksheet.Pictures.Insert(image_path)
|
|
165
|
+
add_space_line IMAGE_ROW_NUM
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# 判断是否有垂直分页符存在
|
|
169
|
+
def has_pagebreak?
|
|
170
|
+
@worksheet.VPageBreaks.count > 0
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# 对列修改分页符
|
|
174
|
+
def pagebreak_left(num)
|
|
175
|
+
#@worksheet.VPageBreaks(1).Location = @worksheet.columns(col)
|
|
176
|
+
@worksheet.VPageBreaks(1).DragOff("-4161", num.to_i)
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# 返回::WorkSheet
|
|
180
|
+
def worksheet
|
|
181
|
+
@worksheet
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
# 添加图表
|
|
185
|
+
def add_chart(&block)
|
|
186
|
+
ch = @worksheet.Shapes.AddChart
|
|
187
|
+
active = ch.chart
|
|
188
|
+
|
|
189
|
+
# 占位符
|
|
190
|
+
block.call(Chart.new(active))
|
|
191
|
+
|
|
192
|
+
ch.copy
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
class Row
|
|
197
|
+
FILL_TYPE = 4
|
|
198
|
+
|
|
199
|
+
attr_reader :row_id
|
|
200
|
+
|
|
201
|
+
@@cell_map = ("A".."Z").to_a
|
|
202
|
+
def initialize(worksheet, row_id)
|
|
203
|
+
@row_id = row_id
|
|
204
|
+
@cell_count = 0
|
|
205
|
+
@worksheet = worksheet
|
|
206
|
+
@nil_space = []
|
|
207
|
+
@merge_cell = []
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
# 此时的单元格
|
|
211
|
+
def curent_cell
|
|
212
|
+
return cell_name(@cell_count)
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
# 第一个单元格
|
|
216
|
+
def first_cell
|
|
217
|
+
return cell_name(0)
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
# 设置行高
|
|
221
|
+
def height=(height)
|
|
222
|
+
begin
|
|
223
|
+
@worksheet.rows(@row_id).RowHeight = height
|
|
224
|
+
rescue Exception
|
|
225
|
+
retry
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
# 增加单元格
|
|
230
|
+
def add_cell(value, auto_fit = false, style = "NormalStyle")
|
|
231
|
+
range = @worksheet.Range(cell_name(@cell_count))
|
|
232
|
+
begin
|
|
233
|
+
range.Value = value.to_s
|
|
234
|
+
range.Style = style
|
|
235
|
+
rescue Exception
|
|
236
|
+
retry
|
|
237
|
+
end
|
|
238
|
+
range.Columns.AutoFit if auto_fit
|
|
239
|
+
@cell_count += 1
|
|
240
|
+
while(@nil_space.include?(to_letter(@cell_count))) do
|
|
241
|
+
range = @worksheet.Range(cell_name(@cell_count))
|
|
242
|
+
range.Value = ""
|
|
243
|
+
range.Style = style
|
|
244
|
+
@cell_count += 1
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
# 通过索引变成对应的字母
|
|
250
|
+
def to_letter(index)
|
|
251
|
+
@@cell_map.at(index)
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
# 特别注意,由于Toolkit中加入了Array,String的模块
|
|
255
|
+
# 所以判断的时候特别注意要是
|
|
256
|
+
def << (arr)
|
|
257
|
+
case arr
|
|
258
|
+
when ::Array
|
|
259
|
+
arr.size.times do |t|
|
|
260
|
+
add_cell(arr[t])
|
|
261
|
+
end
|
|
262
|
+
when ::String
|
|
263
|
+
add_cell(arr)
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
# 获得单元格的名字(通过索引)
|
|
268
|
+
def cell_name(index)
|
|
269
|
+
second = index % 26
|
|
270
|
+
first = (index - second) / 26
|
|
271
|
+
if first == 0
|
|
272
|
+
return @@cell_map[second] + @row_id.to_s
|
|
273
|
+
end
|
|
274
|
+
first -= 1
|
|
275
|
+
return @@cell_map[first] + @@cell_map[second] + @row_id.to_s
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
# 获得单元格的名字(通过字母)
|
|
279
|
+
def cell_name!(letter)
|
|
280
|
+
return letter + @row_id.to_s
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
def set_cell(index, value, auto_fit = false, style = "NormalStyle")
|
|
284
|
+
range = @worksheet.Range(cell_name(index))
|
|
285
|
+
range.Value = value.to_s
|
|
286
|
+
range.Style = style
|
|
287
|
+
range.Columns.AutoFit if auto_fit
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
# 设置单元格风格
|
|
291
|
+
def set_style(letter, style = "NormalStyle")
|
|
292
|
+
range = @worksheet.range(cell_name!(letter))
|
|
293
|
+
range.Style = style
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
# 合并一行中的单元格, 这里仅仅是记录
|
|
297
|
+
def merge(idx_begin, idx_end)
|
|
298
|
+
cell_begin = "#{idx_begin}#{@row_id}"
|
|
299
|
+
cell_end = "#{idx_end}#{@row_id}"
|
|
300
|
+
@merge_cell << [cell_begin, cell_end]
|
|
301
|
+
tmp = ((idx_begin.upcase)..(idx_end.upcase)).to_a
|
|
302
|
+
tmp.shift
|
|
303
|
+
@nil_space = (@nil_space | tmp).sort
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
def merge!
|
|
307
|
+
return if @merge_cell.empty?
|
|
308
|
+
@merge_cell.each do |cell_begin, cell_end|
|
|
309
|
+
range = @worksheet.Range("#{cell_begin}:#{cell_end}")
|
|
310
|
+
range.merge
|
|
311
|
+
end
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
# 开启自动换行
|
|
315
|
+
def wraptext(letter)
|
|
316
|
+
range = @worksheet.range(cell_name!(letter))
|
|
317
|
+
range.WrapText = true
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
# 对此时的行的下方下分页符
|
|
321
|
+
def pagebreak
|
|
322
|
+
begin
|
|
323
|
+
@worksheet.rows(@row_id+1).PageBreak = 1
|
|
324
|
+
rescue Exception
|
|
325
|
+
retry
|
|
326
|
+
end
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
# 返回此时的::Row类
|
|
330
|
+
def real_row
|
|
331
|
+
#@worksheet.rows(@row_id)
|
|
332
|
+
@worksheet.range("A#{@row_id}:#{cell_name(@cell_count - 1)}")
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
alias :style :set_style
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
# 图表
|
|
339
|
+
class Chart
|
|
340
|
+
|
|
341
|
+
# 图形类型
|
|
342
|
+
ColumnClustered = 51 # 簇状柱形图
|
|
343
|
+
ColumnStacked = 52 # 堆积柱状图
|
|
344
|
+
Doughnut = -4120 # 圆环图
|
|
345
|
+
Line = 4 # 折线图
|
|
346
|
+
Pie = 5 # 饼图
|
|
347
|
+
BarClustered = 57 # 簇状条形图
|
|
348
|
+
|
|
349
|
+
# 标签数据
|
|
350
|
+
DataLabelsShowLabel = 4 # 数据点所属的分类
|
|
351
|
+
DataLabelsShowLabelAndPercent = 5 # 占比百分比以及所属分类,仅饼图
|
|
352
|
+
DataLabelsShowPercent = 3 # 百分比, 仅饼图
|
|
353
|
+
DataLabelsShowValue = 2 # 默认值
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
def initialize(active)
|
|
357
|
+
@chart = active
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
def chart_work
|
|
361
|
+
@chart
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
# 修改标题
|
|
365
|
+
def title=(name)
|
|
366
|
+
@chart.HasTitle = true
|
|
367
|
+
@chart.ChartTitle.Characters.Text = name
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
# 这是原数据地址, 按列生成数据
|
|
371
|
+
def source=(range)
|
|
372
|
+
@chart.SetSourceData(range, 2)
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
# 更改图形类型
|
|
376
|
+
def type=(c_type)
|
|
377
|
+
@chart.ChartType = c_type
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
# 设置X轴名称, 只用于条形图
|
|
381
|
+
def axes_x=(name)
|
|
382
|
+
@chart.Axes(1,1).HasTitle = true
|
|
383
|
+
@chart.Axes(1,1).AxisTitle.Characters.Text = name
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
# 设置Y轴名称, 只用于条形图
|
|
387
|
+
def axes_y=(name)
|
|
388
|
+
@chart.Axes(2,1).HasTitle = true
|
|
389
|
+
@chart.Axes(2,1).AxisTitle.Characters.Text = name
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
# 修改样式
|
|
393
|
+
# 通过录制宏可以查看样式编号
|
|
394
|
+
# 条形图中203 比较好看
|
|
395
|
+
# 饼图中 251, 254 比较好看
|
|
396
|
+
def style=(int)
|
|
397
|
+
@chart.ChartStyle = int
|
|
398
|
+
data_label
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
# 添加饼图的百分比
|
|
402
|
+
def data_label(type=DataLabelsShowLabelAndPercent)
|
|
403
|
+
|
|
404
|
+
# 应用标签选项
|
|
405
|
+
@chart.ApplyDataLabels(type)
|
|
406
|
+
|
|
407
|
+
# 取消标签选项的系列名称
|
|
408
|
+
now = @chart.SeriesCollection(1).DataLabels
|
|
409
|
+
now.ShowSeriesName = false
|
|
410
|
+
|
|
411
|
+
# 将图例放到右边
|
|
412
|
+
now = @chart.Legend
|
|
413
|
+
now.Position = -4152
|
|
414
|
+
end
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
end
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
|