经验分享:使用Python3处理excel-案例1

简介

    本博文案例场景为使用python3通过调用xlrd、xlwt模块编写脚本,实现对excel进行处理,其中涉及行列转换、合并单元格。

背景

  1. 导出后的格式
  2. 期待的格式

思路

    那么该如何将导出后源文件的格式调整为期待的格式呢?我的思路是:

  1. 将源文件中的数据逐行写入到列表Ret中,如下
[[系统名称, 日志路径, IP],
[ZBX, /home/zbx/logs/*.log, 192.168.1.10],
[ZBX, /home/zbx/logs/*.log, 192.168.1.11],
[ELK, /home/elk/logs/*.log, 192.168.1.20],
[ELK, /home/elk/logs/*.log, 192.168.1.21],
[ELK, /home/elk/logs/*.log, 192.168.1.22],
[ELK, /home/elk/logs/*.log, 192.168.1.23],
[ELK, /home/elk/logs/*.log, 192.168.1.24],
[ELK, /home/elk/logs/*.log, 192.168.1.25],
[Nginx, /home/nginx/logs/*.log, 192.168.1.30],
[Nginx, /home/nginx/logs/*.log, 192.168.1.31],
[Nginx, /home/nginx/logs/*.log, 192.168.1.32],
[Nginx, /home/nginx/logs/*.log, 192.168.1.33],
[Tomcat, /home/tomcat/logs/*.log, 192.168.1.40],
[Tomcat, /home/tomcat/logs/*.log, 192.168.1.41],
[Tomcat, /home/tomcat/logs/*.log, 192.168.1.42],
[Tomcat, /home/tomcat/logs/*.log, 192.168.1.43],
[Tomcat, /home/tomcat/logs/*.log, 192.168.1.44],
[Tomcat, /home/tomcat/logs/*.log, 192.168.1.45],
[Tomcat, /home/tomcat/logs/*.log, 192.168.1.46],
[Tomcat, /home/tomcat/logs/*.log, 192.168.1.47]]
  1. 将列表中Ret相同系统名称的首行元素的索引追加到列表Idx,Idx初始化时为[0],追加后如下
[0, 1, 3, 9, 13, 21]
  1. 通过列表Idx中的值,可以推断每列需要合并单元格的起始位置和结束为止,然后合并
  2. 将IP以此写在新文件的第四列中

代码

# -*- coding:utf-8 -*-
import os
import sys
import xlrd,xlwt

work_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
r_xls = os.path.join(work_dir,sys.argv[1])
d_xls = os.path.join(work_dir,result.xls)

def DataByLine(Line,ret,idx):
# 读取xls数据,按照需求生成列表
# idx是列表,通过源文件中系统的IP个数推断出在新文件中这个系统的末行数据的行索引
# ret是列表,用于存放xls中的数据
    t = idx[-1]
    while  in Line:
        Line.remove()
        # 从源文件中逐行读取的数据是列表格式,其中会存在空值,需要将空值删除
    for i in range(2,len(Line)):
        # 遍历IP,组成有系统、路径、ip元素的列表
        ret.append([Line[0],Line[1],Line[i]])
        t += 1
    idx.append(t)
    return ret,idx

# 将列表中的数据,依次写入新的xls
def WtData(workbook,table,ret,idx,xls):
    for i,j in enumerate(idx):
        if (i+1) < (len(idx)):
        # 避免idx中最后一个元素参与下面的,最后一个元素代表的是整个表格数据的末行索引
            table.write_merge(j,idx[i+1]-1,0,0,ret[j][0])
            # 对第一列(相同系统)同样的系统进行合并单元格
            table.write_merge(j,idx[i+1]-1,1,1,ret[j][1])
            # 对第二列(相同路径)同样的系统进行合并单元格
            for k in range(idx[i+1]-idx[i]):
                table.write(idx[i]+k,2,ret[j+k][2])
                # 将按行显示的IP,在第三列转置后,按列存储
    workbook.save(xls)

def main():
    workbook_r = xlrd.open_workbook(r_xls)
    table_r = workbook_r.sheet_by_index(0)    
    workbook_d = xlwt.Workbook(encoding = utf-8)
    table_d = workbook_d.add_sheet(result)
    Nrow = table_r.nrows
    Ret = []
    Idx = [0]
    for ln in range(Nrow):
        Ret,Idx = DataByLine(table_r.row_values(ln),Ret,Idx)

    WtData(workbook_d,table_d,Ret,Idx,d_xls)

if __name__ == __main__:
    main()

验证

[root@pyenv xls_format]# /opt/soft/python374/bin/python3 xls_format.py logs.xls

输出文件内容如下:

经验分享 程序员 微信小程序 职场和发展