#coding=utf-8 require "aio/core" class Aio::Module::OutputStyle::SummaryReport < Aio::Module::OutputStyle include Aio::Module include Aio::Device include Aio::Base::Toolkit::WordWps include Aio::Base::Toolkit::ExcelWps include Aio::Ui::Verbose PlaceHolder = "###" def initialize super({ :author => "Elin", :description => "输出巡检简要报告, 以WPS运行", :file_suffix => "doc", :platform => ['windows'] }) end def generate word = Word.new #word.show word.display_alerts = false @doc = word.init_document @text = @doc.add_text # 创建风格 create_style device_manager.devices.each_pair do |device_name, klass| #puts "summary_report" #pp device_name #pp klass.warning_klass end # 附带信息 info = { :resource_file => File.join(::BaseFile, "aio", "resource"), :client => "中国银行湖北省分行", :time => ::Time.now.to_s.split(' ')[0], } # 标号 @mark = [0, 0, 0] # 按流程算法运行 process(info) # 保存 word.display_alerts = true begin word.save(output_file.to_s) rescue Exception => e e.message ensure #word.close end end # 创建风格 def create_style # 用于目录的标题 @doc.create_style_self("Contents") do |sty| sty.font.size = 20 sty.font.NameFarEast = "黑体" sty.font.NameAscii = "Book Antiqua" sty.font.NameOther = "Book Antiqua" sty.font.bold = true # 段落间距 sty.ParagraphFormat.Alignment = 2 # 文本右对齐 sty.ParagraphFormat.LineUnitBefore = 3 # sty.ParagraphFormat.LineUnitAfter = 2 sty.NextParagraphStyle = "正文" # 段落控制 sty.ParagraphFormat.WidowControl = true sty.ParagraphFormat.KeepWithNext = true sty.ParagraphFormat.PageBreakBefore = true # 边框 sty.ParagraphFormat.Borders(-1).LineStyle = 0 sty.ParagraphFormat.Borders(-2).LineStyle = 0 sty.ParagraphFormat.Borders(-4).LineStyle = 0 bottom = sty.ParagraphFormat.Borders(-3) bottom.LineStyle = 1 bottom.LineWidth = 12 bottom.Color = 0 end # 一级标题 @doc.create_style_self("font_chapter_name1") do |sty| sty.BaseStyle = "Contents" sty.ParagraphFormat.OutlineLevel = 1 sty.NextParagraphStyle = "正文" end # 一级标题标号 @doc.create_style_self("font_chapter_num1") do |sty| sty.BaseStyle = "Contents" sty.font.size = 72 sty.ParagraphFormat.LineUnitBefore = 0.5 sty.ParagraphFormat.LineUnitAfter = 0.5 sty.ParagraphFormat.OutlineLevel = 1 sty.NextParagraphStyle = "font_chapter_name1" end # 二级标题 @doc.create_style_self("font_section_name1") do |sty| sty.BaseStyle = "正文" sty.font.bold = true sty.font.size = 18 sty.ParagraphFormat.LineUnitBefore = 1 sty.ParagraphFormat.LineUnitAfter = 1 sty.ParagraphFormat.OutlineLevel = 2 sty.NextParagraphStyle = "正文" end # 二级标题标号 @doc.create_style_self("font_section_num1") do |sty| sty.BaseStyle = "font_section_name1" sty.NextParagraphStyle = "font_section_name1" end @doc.create_style_self("font_level3_name1") do |sty| sty.BaseStyle = "正文" sty.font.bold = true sty.font.size = 18 sty.ParagraphFormat.LineUnitBefore = 1 sty.ParagraphFormat.LineUnitAfter = 1 sty.ParagraphFormat.OutlineLevel = 3 sty.NextParagraphStyle = "正文" end @doc.create_style_self("font_level3_num1") do |sty| sty.BaseStyle = "font_level3_name1" sty.NextParagraphStyle = "font_level3_name1" end # 要点 @doc.create_style_self("importance") do |sty| sty.BaseStyle = "正文" sty.font.bold = true sty.font.size = 18 sty.ParagraphFormat.LineUnitBefore = 1 sty.ParagraphFormat.LineUnitAfter = 1 sty.NextParagraphStyle = "正文" end end # 主体流程控制 def process(info) generate_cover(info) generate_catalog(info) generate_introduction(info) generate_summary(info) generate_summarize(info) update_catalog end # 创建封面 def generate_cover(info) @text.add_head_image(File.join(info[:resource_file], "cover_picture.png")) @text.style = "正文" @text.entry @text.entry @text.entry @text.font.size = 16 @text.center @text.section { "数据通信网络高级巡检报告" } @text.entry @text.entry client = info[:client] time = info[:time] @text.font.Size = 15 @text.section { "客户名称:#{client}" } @text.section { "巡检时间:#{time}" } @text.add_table(1,1) { |tbl| } =begin @text.entry @text.entry @text.entry @text.left @text.font.bold = true @text.add_image(File.join(info[:resource_file], "logo.png")) =end end # 生成目录 def generate_catalog(info) @text.section("Contents") { "目 录" } @doc.create_catalog @text.page_break end # 生成前言 def generate_introduction(info) @text.section("font_chapter_name1") { "前言" } @text.section("font_section_name1") { "概述" } @text.puts "根据#{info[:client]}的运行维护需要,公司对其网络设备进行了巡检。本文档提供了本次巡检所有设备的检查明细信息及汇总信息,针对检查中发现的设备在运行过程中存在的故障隐患和风险提出了相关建议,并对网络整体的健康程度进行了评估。" @text.entry @text.puts "通过本文档,您可以及时了解网络设备的健康状况,清除设备故障隐患,指导技术人员完成对网络的改造优化,提高网络的可用性,保障业务可靠运行。" @text.section("font_section_name1") { "读者对象" } @text.puts "本项目相关的网络运行维护主管、技术工程师、系统集成商工程师等。" @text.page_break @text.entry @text.section("importance") { "尊敬的_______________________ :" } @text.puts "感谢您选择我们的产品和服务!为了提高网络的可用性,保障网络的稳定运行,我们于#{info[:time]}对贵单位网络设备进行了巡检服务。现将本次服务的情况向您汇报如下,并请您对我们的工作给予评价。" @text.entry @text.puts "感谢您和您的团队在本次服务过程中给我们的配合和支持!" @text.entry @text.entry @text.entry @text.entry @text.entry @text.entry @text.entry @text.puts "本次巡检负责人:" @text.puts "联系电话:" @text.puts "联系邮箱:" end ### # # 巡检概要报告 # ### # 流程控制 def generate_summary(info) add_title_1("巡检概要报告") generate_summary_overview(info) generate_summary_device_type(info) generate_summary_warning_device_top10(info) generate_summary_level(info) generate_summary_problem(info) generate_summary_major_problem(info) end # 概述 def generate_summary_overview(info) add_title_2("概述") tmp = "本次巡检共巡检设备#{device_manager.devices_number}台," + "发现问题#{warning_summarize.total_number}个。" + "其中严重问题#{warning_summarize.serious_number}个," + "一般问题#{warning_summarize.ordinary_number}个。" @text.puts tmp end # 巡检设备类型 def generate_summary_device_type(info) add_title_2("巡检设备类型") @text.puts "下图表示本次巡检各类型设备所占的比例: " # 生成table数据目录 type_info = device_manager.device_type_classify.to_a tbl = [] type_info.size.times do |i| # 将Hash 变成数组后,按照indent输出 tbl << [ type_info[i][0], type_info[i][1].size.to_s ] end # 生成图表 @text.chart(tbl) do |chart| chart.type = chart.class::Pie chart.style = 251 end end # 发现问题数TOP20的设备 def generate_summary_warning_device_top10(info) add_title_2("发现问题数TOP10的设备") @text.puts "本次巡检发现问题数排名前10的设备,如下图所示: " tbl = [["", "serious", "ordinary", "compare"]] type_warning_info = warning_summarize.device_warning_sort n = 0 type_warning_info.each do |dev| n += 1 next unless dev[1].total_number > 0 break if n > 10 tbl << [ dev[0], dev[1].serious_number, dev[1].ordinary_number, dev[1].compare_number ] end @text.chart(tbl) do |chart| chart.type = chart.class::ColumnStacked chart.style = 251 chart.series_name = false chart.category_name = false chart.value = false chart.axes_unit(1) end end # 按问题级别展现 def generate_summary_level(info) add_title_2("按问题级别展现") @text.puts "本次巡检发现的问题级别分布情况,如下图所示: " tbl = [] if warning_summarize.has_serious? tbl << ["serious", warning_summarize.serious_number] end if warning_summarize.has_ordinary? tbl << ["ordinary", warning_summarize.ordinary_number] end if warning_summarize.has_compare? tbl << ["compare", warning_summarize.compare_number] end @text.chart(tbl) do |chart| chart.type = chart.class::Pie chart.style = 251 end #------ @text.entry @text.puts "1、本次巡检发现的严重问题数最多的5台设备,如下图所示:" tbl = warning_summarize.device_serious_sort # 只保留5个 n = 0 tbl.delete_if { |x| n += 1 ;n > 5 } tbl.insert(0, ["", "数量"]) @text.chart(tbl) do |chart| chart.type = chart.class::ColumnClustered chart.style = 251 chart.series_name = false chart.category_name = false chart.value = false chart.axes_unit(1) end #------ @text.entry @text.puts "2、本次巡检发现的一般问题数最多的5台设备,如下图所示:" tbl = warning_summarize.device_ordinary_sort # 只保留5个 n = 0 tbl.delete_if { |x| n += 1 ;n > 5 } tbl.insert(0, ["", "数量"]) @text.chart(tbl) do |chart| chart.type = chart.class::ColumnClustered chart.style = 251 chart.series_name = false chart.category_name = false chart.value = false chart.axes_unit(1) end end # 按问题发生频率展现 def generate_summary_problem(info) add_title_2("按问题发生频率展现") @text.puts "本次巡检发现的发生频率最多的5类问题,如下图所示:" tbl = warning_summarize.problem_frequency n = 0 tbl.delete_if { |x| n += 1 ;n > 5 } tbl.insert(0, ["", "数量"]) @text.chart(tbl) do |chart| chart.type = chart.class::BarClustered chart.style = 251 chart.series_name = false chart.category_name = false chart.value = false chart.axes_unit(1) end end # 主要问题分析及说明 def generate_summary_major_problem(info) add_title_2("主要问题分析及说明") @text.puts "本章节将详细介绍巡检过程中发生的所有严重问题,及发生频率最高的3类一般和提示问题。" #------ warning_summarize.summary[:serious].each_pair do |cs, dev_info| desc_klass = warning_summarize.get_desc(cs) add_title_3(desc_klass.title) level(:serious) @text.puts desc_klass.to_s + "不符合该规则的设备共#{dev_info.size}台,明细如下:" add_device_table(dev_info) end #------ warning_summarize.summary[:ordinary].each_pair do |cs, dev_info| desc_klass = warning_summarize.get_desc(cs) add_title_3(desc_klass.title) level(:ordinary) @text.puts desc_klass.to_s + "不符合该规则的设备共#{dev_info.size}台,明细如下:" add_device_table(dev_info) end end # 打印级别 def level(sym) res = "" case sym when :serious res = "级别: 严重" when :ordinary res = "级别: 一般" end @text.style = "importance" @text.size = 12 @text.puts res end # 添加按照设备标明的表格 def add_device_table(dev_info) tbl = [ ["序号", "名称", "型号", "IP"] ] n = 1 dev_info.each_pair do |name, klass_info| klass = klass_info[:klass] tbl << [n, name, klass.device_info[:device_model], klass.get_manager_ip ] n += 1 end @text.size = 10 @text.add_table_by_value(tbl) do |table| table.center table.border_line table.set_columns_width(1, 44) table.set_columns_width(2, 143) table.set_columns_width(3, 143) end end # 总结流程控制 def generate_summarize(info) @text.page_break generate_machine_room(info) generate_inspection(info) generate_offer(info) generate_appraise(info) end # 机房环境检查结果 def generate_machine_room(info) add_title_2("机房环境检查结果") @text.add_table(1,1) do |tbl| tbl.height = 100 tbl.border_line end end # 巡检结论 def generate_inspection(info) add_title_2("巡检结论") @text.add_table(1,1) do |tbl| tbl.height = 100 tbl.border_line end end # 运行维护建议 def generate_offer(info) add_title_2("运行维护建议") @text.add_table(1,1) do |tbl| tbl.height = 100 tbl.border_line end end # 您对本次巡检情况的评价 def generate_appraise(info) add_title_2("您对本次巡检情况的评价") @text.add_table(1,1) do |tbl| tbl.height = 100 tbl.border_line end end private ### # # 本地方法 # ### # 更新目录 def update_catalog @doc.update_catalog end # 1级标题 def add_title_1(str) @mark[0] += 1 @mark[1] = 0 @mark[2] = 0 mk = @mark[0].to_s @text.style = "font_chapter_name1" @text.print join(mk, str) modify_num(mk, "font_chapter_num1") @text.entry end # 2级标题 def add_title_2(str) @mark[1] += 1 @mark[2] = 0 mk = [@mark[0], @mark[1]].join(".") @text.style = "font_section_name1" @text.print join(mk, str) modify_num(mk, "font_section_num1") @text.entry end # 3级标题 def add_title_3(str) @mark[2] += 1 mk = [@mark[0], @mark[1], @mark[2]].join(".") @text.style = "font_level3_name1" @text.print join(mk, str) modify_num(mk, "font_level3_num1") @text.entry end # 合并,以空格分开 def join(*arg) arg.join(" ") end # 修改标题数字 def modify_num(num, sty) @doc.home_key @doc.move_right(num.size, 1) @text.now.Style = @doc.doc_work.Styles(sty) #@text.now.ParagraphFormat.LineUnitBefore = 0.1 @doc.end_key end # 添加占位符 def add_holder(str) PlaceHolder + " " + str end def replace_holder(str, style) @text.replace(PlaceHolder, str.to_s, style) end # 警告信息汇总类 def warning_summarize device_manager.warning_summarize end end