多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
作者:董帅岭 [TOC] 所有技术和原理都是来源于生活,并且高于生活。咱们所谓的编程什么的,就是按照他们编程涉及的规则、语法。然后按照咱们的思想涉及出来就可以了。 # 一、设计思路 * 按照特定的格式生成log文件。具体什么格式咱们后面慢慢讲,假定咱们已经有了特定格式的log文件。 * 通过Python工具去读取文件,然后按照咱们的想法进行分段,将分段内容放到咱们的word中。当然咱们要提前设计好word文档的格式。 * 所以咱们需要用到的知识就是Python的基本语法,函数,Python操作word。 # 二、函数说明 首先在这里我要感谢一位博主,在博主的指引下学习到了很多东西。同时我也加博主微信了。先把巨人肩膀供上。[https://www.modb.pro/db/31880](https://www.modb.pro/db/31880) ## 自动生成目录 在我们巡检过程中或者自动生成word的过程中,为了方便,可以定义新建一个文件夹里面放我们特定的东西和内容。例如生成的word放在什么位置,自动生成的软件运行log日志放在什么位置等。 函数思路:首先取运行目录,读入目录的最后一个文件夹名字,如果不存在就创建一个,如果存在就跳过。 ``` # 生成目录的 def mkdir(path): import os path = path.strip() print(path) path = path.rstrip("\\") isExists = os.path.exists(path) if not isExists: os.makedirs(path) return True else: return False ``` ## 添加word的首页logo图片函数 此函数就是利用的创建单元格,然后再单元格中添加图片,达到居中的目的,应该还有更好的替代语句,不过目前还没有时间研究,后续再进行优化。 ``` #添加图片居中函数 def add_center_picture(image_path_or_stream, width=None, height=None): # run = self.doc.add_paragraph().add_run() tab = Docx.add_table(rows=1, cols=3) # 添加一个1行3列的空表 cell = tab.cell(0, 1) # 获取某单元格对象(从0开始索引) ph =cell.paragraphs[0] run = ph.add_run() # run.add_break() run.add_picture(image_path_or_stream, width=width, height=height) ``` ## 遍历文件下的所有log文件 此函数从大佬学习的[red\_hope](https://www.modb.pro/u/372611)。大家也可以学习一下。 函数说明:首先获取给定路径,然后通过巡检和判断获取你想要的所有文件路径下的文件名称,方便下一步读取操作。 ``` # #目录遍历函数,用于读取目录下所有文件 def list_dir(file_dir): dir_list = os.listdir(file_dir) file_r = [] for cur_file in dir_list: # 准确获取一个txt的位置,利用字符串的拼接 path = os.path.join(file_dir, cur_file) if cur_file.startswith("Py") & path.endswith(".log"): file_r.append(path) return file_r ``` # 三、源码说明 ``` import re from docx import Document import os from docx.oxml.ns import nsdecls from docx.oxml import parse_xml from docx.oxml.ns import qn from docx.shared import RGBColor from docx.shared import Pt from docx.shared import Inches from docx.enum.text import WD_LINE_SPACING from docx.enum.text import WD_PARAGRAPH_ALIGNMENT import datetime from docx.shared import Inches from docx.enum.table import WD_CELL_VERTICAL_ALIGNMENT from docx.shared import Cm from docx.enum.text import WD_ALIGN_PARAGRAPH # 定义时间 year = datetime.datetime.now().year month = datetime.datetime.now().month day = datetime.datetime.now().day ymd_time = str(year)+'-'+str(month)+'-'+str(day) # 生成目录的 def mkdir(path): import os path = path.strip() print(path) path = path.rstrip("\\") isExists = os.path.exists(path) if not isExists: os.makedirs(path) return True else: return False # 标题用大写数字函数,正规 def num_to_char(num): """数字转中文""" num = str(num) new_str = "" num_dict = {"10":u"十","11":u"十一","12":u"十二","13":u"十三","14":u"十四","15":u"十五","16":u"十六","17":u"十七","18":u"十八","19":u"十九","20":u"二十","21":u"二十一","22":u"二十二","23":u"二十三","24":u"二十四","25":u"二十五","26":u"二十六","27":u"二十七","28":u"二十八","29":u"二十九","30":u"十","0": u"零", "1": u"一", "2": u"二", "3": u"三", "4": u"四", "5": u"五", "6": u"六", "7": u"七", "8": u"八","9": u"九"} listnum = list(num) # print(listnum) shu = [] for i in listnum: # print(num_dict[i]) shu.append(num_dict[i]) new_str = "".join(shu) # print(new_str) return new_str # ####返回标题,巡检日志中我们一般用英文,但是文档必须是中文的 #def get_title(flag_fg):# flag_fg是传入的分隔段,其实也是英文标题 if 'Check file system' in flag_fg: xj_title_hs = '交换机巡检' elif 'display fan' in flag_fg: xj_title_hs = '设备风扇' elif 'display device power' in flag_fg: xj_title_hs = '设备电源' elif 'display environment' in flag_fg: xj_title_hs = '设备温度' elif 'display cpu' in flag_fg: xj_title_hs = '设备CPU' elif 'display memory' in flag_fg: xj_title_hs = '设备内存' elif 'display trapbuffer' in flag_fg: xj_title_hs = '设备告警缓冲区信息' elif 'display device' in flag_fg: xj_title_hs = '设备信息' elif 'display clock' in flag_fg: xj_title_hs = '设备时间' elif 'display current-configuration' in flag_fg: xj_title_hs = '设备当前配置' elif 'display users' in flag_fg: xj_title_hs = '设备用户信息' elif 'display version' in flag_fg: xj_title_hs = '设备版本信息' elif 'display acl all' in flag_fg: xj_title_hs = '设备ACL信息' elif 'display interface counters' in flag_fg: xj_title_hs = '设备接口会话数' elif 'display stack topology' in flag_fg: xj_title_hs = '堆叠拓扑' elif 'display stack configuration' in flag_fg: xj_title_hs = '设备堆叠配置' elif 'display stack' in flag_fg: xj_title_hs = '设备堆叠信息' elif 'display mac-address total-number' in flag_fg: xj_title_hs = '设备MAC表总数' elif 'display arp' in flag_fg: xj_title_hs = '设备ARP信息' elif 'display ip routing-table statistics' in flag_fg: xj_title_hs = '设备路由表总数' elif 'display ip routing-table' in flag_fg: xj_title_hs = '设备路由表' elif 'display logbuffer' in flag_fg: xj_title_hs = '设备日志' elif 'display mac' in flag_fg: xj_title_hs = 'MAC地址信息' elif 'display interface brief' in flag_fg: xj_title_hs = '接口摘要' elif 'display ip interface brief' in flag_fg: xj_title_hs = '接口IP摘要' else: xj_title_hs = flag_fg #很关键,防止穷尽不了英文标题 return xj_title_hs # #目录遍历函数,用于读取目录下所有文件 def list_dir(file_dir): dir_list = os.listdir(file_dir) file_r = [] for cur_file in dir_list: # 准确获取一个txt的位置,利用字符串的拼接 path = os.path.join(file_dir, cur_file) if cur_file.startswith("Py") & path.endswith(".log"): file_r.append(path) return file_r # 知识库函数-简例子 #def get_knowledge(str_input): str_output = [] # 没发现什么,就先输出巡检正常。 str_output_text='巡检正常' if '[always] madvise never' in str_input: str_output = ['Linux未关闭透明大页,根据ORACLE安装要求,应关闭透明大页,提升ORACLE 内存及IO读写性能','1111111'] elif 'always madvise [never]' in str_input: str_output = ['巡检正常:Linux已关闭透明大页','000000'] else: str_output = ['巡检正常','000000'] return str_output #添加图片居中函数 def add_center_picture(image_path_or_stream, width=None, height=None): # run = self.doc.add_paragraph().add_run() tab = Docx.add_table(rows=1, cols=3) # 添加一个1行3列的空表 cell = tab.cell(0, 1) # 获取某单元格对象(从0开始索引) ph =cell.paragraphs[0] run = ph.add_run() # run.add_break() run.add_picture(image_path_or_stream, width=width, height=height) # Press the green button in the gutter to run the script. if __name__ == '__main__': # 打开文件 file_dir= os.getcwd()+'\\log\\' file_all = list_dir(file_dir) for i in range(len(file_all)): file = file_all[i] file_full = file.split('\\') file_str = '' ##截取文件名称,用于报告输出 for value in file_full: file_name = value new_filename = file_name.split('.') for new_value in new_filename: if 'Py' in new_value: # print(new_value) file_str = new_value f = open(file, 'r',encoding='UTF-8') lines = f.readlines() name_line = lines[0] name_line = name_line.strip() ip_line = lines[1] ip_line = ip_line.strip() #print(name_line) #print(ip_line) f.close() with open(os.getcwd() + '\\config\\Word_conf.ini') as file_conf: file_conf = file_conf.readlines() format_file = [] for line in file_conf: imgfile = line.strip() format_file.append(imgfile) #print(format_file) word_xmmc = format_file[0].rpartition(":")[2] word_wjmc = format_file[1].rpartition(":")[2] word_wdbh = format_file[2].rpartition(":")[2] word_dqbb = format_file[3].rpartition(":")[2] word_sj = format_file[4].rpartition(":")[2] word_sp = format_file[5].rpartition(":")[2] word_cjr = format_file[6].rpartition(":")[2] word_wdbt = format_file[7].rpartition(":")[2] #print(word_sp) f = open(file, 'r', encoding='UTF-8') # 读取分隔符,写入到list类型的number变量中,关键字就是#### lines = f.readlines() number = [] for lss in lines: m = re.findall(r"####", lss) if m: number.append(lss) f.close() ##用完文件关闭是个好习惯 # 创建一个world实例 Docx = Document() # # 设置正文格式 Docx.styles['Normal'].font.name = '宋体' # 设置文档的基础字体 Docx.styles['Normal'].element.rPr.rFonts.set(qn('w:eastAsia'), '宋体') # 添加word标题 并居中 Docx.add_paragraph('') Docx.add_paragraph('') Docx.add_paragraph('') timu = Docx.add_paragraph('') run=timu.add_run(word_xmmc) Docx.paragraphs[3].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER run.bold = True run.font.size = Pt(20) # 首页添加那个月份的巡检报告 xj = str(month)+'月'+'-'+name_line+'-巡检报告' ydxj = Docx.add_paragraph('') run = ydxj.add_run(xj) Docx.paragraphs[4].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER run.bold = True run.font.size = Pt(20) Docx.add_paragraph('') Docx.add_paragraph('') # 添加logo并居中 Docx.paragraphs[6].add_run().add_picture(os.getcwd()+'\\config\\北佳logo.png') Docx.paragraphs[6].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER Docx.add_paragraph('') Docx.add_paragraph('') Docx.add_paragraph('') Docx.add_paragraph('') # 填写表格内容 table=Docx.add_table(rows=6,cols=3,style = 'Table Grid') table.cell(0, 0).text = '文件状态:' table.cell(1, 0).text = '[ ] 草稿' table.cell(2, 0).text = '[√] 正式发布' table.cell(3, 0).text = '[ ] 正在修改' hb=table.cell(0, 0).merge(table.cell(5, 0)) hb.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER table.cell(0, 1).text = '文件名称:' table.cell(1, 1).text = '文档编号:' table.cell(2, 1).text = '当前版本:' table.cell(3, 1).text = '设 计:' table.cell(4, 1).text = '审 批:' table.cell(5, 1).text = '审批日期:' table.cell(0, 2).text = word_xmmc+xj table.cell(1, 2).text = word_wdbh table.cell(2, 2).text = word_dqbb table.cell(3, 2).text = word_sj table.cell(4, 2).text = word_sp table.cell(5, 2).text = str(year)+'年'+str(month)+'月'+str(day)+'日' wt0 = 3.5 wt1 = 2.5 wt2 = 9.37 table.cell(0, 0).width = Cm(wt0) table.cell(0, 1).width = Cm(wt1) table.cell(1, 1).width = Cm(wt1) table.cell(2, 1).width = Cm(wt1) table.cell(3, 1).width = Cm(wt1) table.cell(4, 1).width = Cm(wt1) table.cell(5, 1).width = Cm(wt1) table.cell(0, 2).width = Cm(wt2) table.cell(1, 2).width = Cm(wt2) table.cell(2, 2).width = Cm(wt2) table.cell(3, 2).width = Cm(wt2) table.cell(4, 2).width = Cm(wt2) table.cell(5, 2).width = Cm(wt2) Docx.add_paragraph('') Docx.add_paragraph('') # 添加首页公司信息 sygs = Docx.add_paragraph('') run=sygs.add_run('陕西北佳信息技术有限责任公司') Docx.paragraphs[13].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER run.bold = True run.font.size = Pt(14) #首页 添加下面的日期 sysj = Docx.add_paragraph('') run = sysj.add_run(str(year)+'年'+str(month)+'月') Docx.paragraphs[14].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER run.bold = True run.font.size = Pt(14) Docx.add_page_break() run = Docx.add_paragraph('') run = run.add_run('版本说明:') run.bold = True run.font.size = Pt(14) table = Docx.add_table(rows=6, cols=4, style='Table Grid') table.cell(0, 0).text = '创建/修改人' table.cell(0, 1).text = '修改时间' table.cell(0, 2).text = '修改内容' table.cell(0, 3).text = '备注' # 首行设置背景色 rows = table.rows[0] for cell in rows.cells: shading_elm = parse_xml(r'<w:shd {} w:fill="D9D9D9"/>'.format(nsdecls('w'))) cell._tc.get_or_add_tcPr().append(shading_elm) table.cell(1, 0).text = word_cjr table.cell(1, 1).text = str(year)+'年'+str(month)+'月'+str(day)+'日' table.cell(1, 2).text = '建立' table.cell(1, 3).text = '' Docx.add_page_break() # 再打开文件,开始正式读取巡检内容 f = open(file, 'r', encoding='UTF-8') buff = f.read() # 将多余的SQL>格式去掉 # for a in buff: buff = buff.replace('SQL>', '') buff = buff.replace('\r', '') # 现在表格中输出巡检数据库基本信息: run = Docx.add_heading('', level=1).add_run(word_wdbt) run.font.name = u'宋体' run._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体') # 做个表格,放入巡检机器的基本信息 table_1 = Docx.add_table(rows=3, cols=2, style='Table Grid') table_1.cell(0,0).text = '设备名称' table_1.cell(0,1).text = name_line table_1.cell(1, 0).text = '设备IP' table_1.cell(1,1).text = ip_line table_1.cell(2, 0).text = '备注' xj_title = "" #world的各级标题变量 #wt_all = [] # 记录巡检发现问题的列表 # 开始循环读取巡检结果 for j in range(len(number)): k = j + 1 # 只所以要设置K,是为了防止和j溢出,因为最后一行是没有j+1的 if k < len(number): #print(len(number)) fenge1 = number[j] fenge2 = number[j + 1] fenge1 = fenge1.replace('\n', '') print(f'{k}:开始查找{fenge1}相关的内容') xj_title = fenge1.replace('####','') #if xj_title == 'PLNOCHECK': # 遇到不检查项目,跳出本次循环 #continue daxie = num_to_char(k) title = f'{k}、{xj_title}' run1 = Docx.add_heading('',level=1).add_run(title) run1.font.name = u'宋体' run1._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体') #Docx.add_heading("1、巡检信息:", level=2) pat = re.compile(fenge1 + '(.*)' + fenge2, re.S) result = pat.findall(buff) match_list = [] for match1 in result: #print(match1) match_list=match1.split('\n###') #print(match_list) match_ml = match_list[1] match_ml = match_ml.rstrip() match_ml = match_ml.lstrip() #print(match_ml) match_jg = match_list[2] match_jg = match_jg.rstrip() match_jg = match_jg.lstrip() #print(match_jg) #match1 = match1.replace('\n\n', '') ##中间多余的信息删除 #match1 = match1[:match1.rfind('CHECKJCSQL')] #match1 = match1.rstrip() #match1 = match1.lstrip() ##中间多余的信息删除完成 table = Docx.add_table(rows=3, cols=2, style='Table Grid') table.cell(0, 0).width = Cm(2.2) table.cell(1, 0).width = Cm(2.2) table.cell(2, 0).width = Cm(2.2) table.rows[0].height = Cm(2) table.rows[2].height = Cm(4) cell = table.cell(0, 0) p = cell.paragraphs[0] run = p.add_run('巡检命令') cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER cell = table.cell(0, 1) p = cell.paragraphs[0] fen = match_ml run = p.add_run(fen) cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER cell = table.cell(1, 0) p = cell.paragraphs[0] run = p.add_run('巡检内容') cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER cell = table.cell(1, 1) p = cell.paragraphs[0] run = p.add_run(match_jg) run.font.size = Pt(9) cell = table.cell(2, 0) p = cell.paragraphs[0] run = p.add_run('结果分析') cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER cell = table.cell(2, 1) p = cell.paragraphs[0] run = p.add_run(' □正常 □异常') cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.TOP table.cell(0, 0).width = Cm(2.2) table.cell(1, 0).width = Cm(2.2) table.cell(2, 0).width = Cm(2.2) table.cell(0, 1).width = Cm(13.4) table.cell(1, 1).width = Cm(13.4) table.cell(2, 1).width = Cm(13.4) table.rows[0].height = Cm(2) table.rows[2].height = Cm(2) #Docx.add_heading("问题汇总:", level=1) #for k in range(len(wt_all)): #Docx.add_heading(f'{k+1}.{wt_all[k]}',level=3) yemei = Docx.sections[0].header par = yemei.paragraphs[0] par.add_run(word_xmmc) par.alignment = WD_ALIGN_PARAGRAPH.CENTER sec1 = Docx.sections[0] sec1.different_first_page_header_footer = True yejiao = Docx.sections[0].footer par0 = yejiao.paragraphs[0] run0=par0.add_run('陕西北佳信息技术有限责任公司 地址:西安市雁塔路67号红锋商务大厦8层') run0.font.size = Pt(9) par0.paragraph_format.space_after = Pt(0) par1 = yejiao.add_paragraph('') run1 = par1.add_run('联系电话:(029) 85511000 4000184818 传真:(029)85510292') run1.font.size = Pt(9) par1.paragraph_format.space_after = Pt(0) par2 = yejiao.add_paragraph('') run2 = par2.add_run('网址:http://www.beijiait.com') run2.font.size = Pt(9) par2.paragraph_format.space_after = Pt(0) # 设置工程师签字的地方 Docx.add_paragraph('') Docx.add_paragraph('') table_qz = Docx.add_table(rows=2, cols=1) table_qz.cell(0,0).text = '工程师签字:' table_qz.cell(1, 0).text = '日 期:' table_qz.rows[0].height = Cm(0.5) table_qz.rows[1].height = Cm(0.5) # print(file_str) mkdir(os.getcwd()+"\\word") Docx.save(os.getcwd()+'\\word\\'+name_line+'_巡检报告'+ymd_time+'.docx') f.close() ```