用python的openpyxl库实现对excel工作表的自动化操作

用python的openpyxl库实现对excel工作表的自动化操作

用python的openpyxl库读取excel工作表,批量建立工作表,批量修改工作表标题,批量设置单元格样式,批量调整打印设置。



一、提出问题

因工作需要需制订公交线路站台的调查方案,现有公交线路站点的具体信息。目标需求是制作一个excel工作簿,工作簿约包含120个工作表,每个工作表包含要调查公交线路站点信息情况,同时,每个工作表以该线路的名称来命名以方便查询。如下图所示。
在这里插入图片描述

该工作簿约包含120个工作表,如果重复性地进行新建、复制、粘贴、查找、复制、粘贴,太无聊,太浪费时间了,如何才能快速方便的完成这项工作,解决机械性的重复操作问题,提高工作效率呢?

二、分析问题

1.公交线路站点信息表

提供的公交线路站点信息如下表所示。
在这里插入图片描述
表 datachengdu_station.xlsx

提供的线路站点信息表如图所示,从中可以看出,表头主要包含线路名称、经度、纬度、站点名称和站序5个字段,线路包含上行和下行两个方向,站序升序排列。

2.调查线路站点信息表

分析调查线路信息表可知,每张调查表都具有相同的头部和尾部结构,只是中间部分不同,需要把具体需要调查的线路站点信息写入中间部分,同时,对工作表的标题进行修改。
在这里插入图片描述

三、解决问题

1.openpyxl库

好在前段时间看了《Python编程快速上手 让繁琐工作自动化》一书,里面讲到了如何用python处理excel表格。本文主要用到openpyxl,一个用于读取和写入Excel 2010 xlsx/xlsm文件的python第三方库。Python本身是不能对excel进行读写的,但是借助于openpyxl就可以非常方便地对excel进行自动化操作。

2.程序的编写思路

程序的思路和代码顺序并没有直接关联,以下主要说明程序的思路。
首先,读取调查方案excel表中的线路名称,调查方案表如下图所示,并保存为一个列表;
其次,新建表格,修改表格标题,写入表头信息;对于调查方案中的每个线路名称,遍历线路站点表,找到对应线路的站点名称和站序,由于线路站点信息表是分上行和下行的,调查方案表格中只需要上行即可,分析线路站点表可知,站序是递增的,但当线路由上下变为下行时,站序会重新从1开始,这时加入一个判断,当站序不再递增时,停止写入,如此重复遍历判断,对新表逐一添加一行,写入一行,直至站点遍历结束;判断新表的最大行长度,在新表末尾写入表尾的内容、合并单元格、添加公式、设置填充颜色、调整行高列宽、设置字号加粗、设置边框、调整对齐方式、设置纸张大小横向打印、设置水平居中打印,重复打印标题,直至调查方案中的每条线路遍历结束。
最后,保存工作簿。
在这里插入图片描述
表 需调查线路汇总新方案.xlsx

3.运行结果

运行程序后,得到如下结果。
在这里插入图片描述表 sample.xlsx

四、完整代码

from openpyxl import Workbook
from openpyxl import load_workbook
from openpyxl.utils import get_column_letter
from openpyxl.styles import PatternFill, Border, Side, Font, Alignment

# 新建工作表
wb1 = Workbook()

# 加载工作表
wb2 = load_workbook(r'C:\Users\Desktop\pythonProject\需调查线路汇总新方案.xlsx')
wb3 = load_workbook(r'C:\Users\Desktop\pythonProject\datachengdu_station.xlsx')
# 获取活动单元表
wb2s = wb2.active
title = []
a0 = wb2s.max_row
for i in range(2, a0 + 1):
    t0 = wb2s.cell(row=i, column=1).value
    t1 = str(t0)
    title.append(t1)

wb3s = wb3.active
a = wb3s.max_row

# 批量创建工作表,并写入模板表格中的数据
for i in title:
    # 创建表格
    ws = wb1.create_sheet(i)

    # 添加表头
    ws.append(['序号', '站台名', '类型', '站牌问题', '', '', '', '', '', '', '站台问题'])
    ws.append(['', '', '', '破损', '有污渍', '有牛皮廯', '信息不清晰', '信息缺失', '无警示标志', '无投诉电话', '乘车秩序混乱', '地面有垃圾', '共享单车乱停放'])

    # 合并单元格
    ws.merge_cells('A1:A2')
    ws.merge_cells('B1:B2')
    ws.merge_cells('C1:C2')
    ws.merge_cells('D1:J1')
    ws.merge_cells('k1:M1')

    # 调整标头样式

    # 写入线路站点信息
    m = 1
    for j in range(1, a + 1):
        b = wb3s.cell(j, 1).value
        if b == i:
            d = wb3s.cell(j, 6).value
            c1 = wb3s.cell(j, 7).value
            c2 = wb3s.cell(j + 1, 7).value
            # print(c1, d)
            ws.insert_rows(j + 3)  # 插入一行
            ws.cell(m + 2, 1).value = c1
            ws.cell(m + 2, 2).value = d

            m = m + 1
            if int(c2) != int(c1) + 1:
                break
    # 计算现表长度
    b = ws.max_row
    # print(b)
    # 添加表底
    ws.append(['标准分值', '', '', 20, 10, 10, 10, 20, 10, 5, 10, 5, '不计入得分'])
    ws.append(['问题笔数'])
    ws.append(['分项得分'])
    ws.append(['折算得分(百分制)'])
    ws.append(['合计得分'])

    # 合并单元格
    # ws.merge_cells('A1:A2')
    ws.merge_cells(start_row=b + 1, start_column=1, end_row=b + 1, end_column=3)
    ws.merge_cells(start_row=b + 2, start_column=1, end_row=b + 2, end_column=3)
    ws.merge_cells(start_row=b + 3, start_column=1, end_row=b + 3, end_column=3)
    ws.merge_cells(start_row=b + 4, start_column=1, end_row=b + 4, end_column=3)
    ws.merge_cells(start_row=b + 5, start_column=1, end_row=b + 5, end_column=3)

    # 添加公式
    for n in range(4, 13):
        le = get_column_letter(n)
        formula1 = "=SUM(" + le + "3:" + le + str(b) + ")"
        formula2 = "=" + le + str(b + 1) + "*(1-" + le + str(b + 2) + "/$A" + str(b) + ")"
        # print(formula2)
        ws.cell(b + 2, n, formula1)
        ws.cell(b + 3, n, formula2)
        le = get_column_letter(n)

    formula3 = "=D" + str(b + 3) + "/D" + str(b + 1) + "*100"
    formula4 = "=SUM(E" + str(b + 3) + ":G" + str(b + 3) + ")/SUM(E" + str(b + 1) + ":G" + str(b + 1) + ")" + "*100"
    formula5 = "=SUM(H" + str(b + 3) + ":I" + str(b + 3) + ")/SUM(H" + str(b + 1) + ":I" + str(b + 1) + ")" + "*100"
    formula6 = "=SUM(D" + str(b + 4) + "*0.02+E" + str(b + 4) + "*0.03+H" + str(b + 4) + "*0.03)/0.08"

    ws.cell(b + 4, 4, formula3)
    ws.cell(b + 4, 5, formula4)
    ws.cell(b + 4, 8, formula5)
    ws.cell(b + 5, 4, formula6)

    # 合并单元格
    ws.merge_cells('E' + str(b + 4) + ':G' + str(b + 4))
    ws.merge_cells('H' + str(b + 4) + ':I' + str(b + 4))
    ws.merge_cells('D' + str(b + 5) + ':M' + str(b + 5))

    # 设置单元格样式
    # 设置填充颜色
    orange_fill = PatternFill(fill_type='solid', fgColor="ffc000")
    green_fill = PatternFill(fill_type='solid', fgColor="92d050")
    blue_fill = PatternFill(fill_type='solid', fgColor="00b0f0")
    yellow_fill = PatternFill(fill_type='solid', fgColor="ffff00")
    for o in range(4, 13):
        ws.cell(row=b + 3, column=o).fill = orange_fill
    ws.cell(row=b + 4, column=4).fill = orange_fill
    ws.cell(row=b + 4, column=5).fill = green_fill
    ws.cell(row=b + 4, column=8).fill = blue_fill
    ws.cell(row=b + 5, column=1).fill = yellow_fill
    ws.cell(row=b + 5, column=4).fill = yellow_fill

    # 设置字号,加粗等
    font = Font(size=11, bold=True)
    for y in range(1, 14):
        for x in range(1, 3):
            ws.cell(x, y).font = font
        for z in range(b + 1, b + 6):
            ws.cell(z, y).font = font

    # 设置边框
    thin = Side(border_style="thin", color="000000")
    border = Border(top=thin, left=thin, right=thin, bottom=thin)
    for x in range(1, b + 6):
        for y in range(1, 14):
            ws.cell(x, y).border = border

    # 设置对其方式
    for x in range(1, b + 6):
        for y in range(1, 14):
            ws.cell(x, y).alignment = Alignment(horizontal='center', vertical='center', wrapText=True)

    for x in range(3, b + 1):
        ws.cell(x, 2).alignment = Alignment(horizontal='right', vertical='center')

    # 设置行高列宽
    ws.row_dimensions[1].height = 15
    ws.row_dimensions[2].height = 30
    ws.column_dimensions['B'].width = 22
    ws.column_dimensions['M'].width = 11

    # 设置A4纸横向
    ws.set_printer_settings(paper_size=9, orientation='landscape')

    # 设置水平居中打印,重复打印标题
    ws.print_options.horizontalCentered = True
    ws.print_titles_cols = 'A:M'
    ws.print_title_rows = '1:2'

# 保存文件
wb1.save("sample.xlsx")

总结

利用python openpyxl库,对excel进行自动化操作,相对于一张表格接着一张表格的进行新建、复制、粘贴、查找、复制、粘贴,行机械性地进行重复操作,工作效率得到了极大地提高,几秒钟工作簿就做好了,成就感满满。

  • 7
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值