用Python玩转Excel办公自动化

938 阅读5分钟

本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。

image.png

摘要

Python 操作 Excel 可能是当下自动化办公最火热的需求了,

今天就来分享如何使用 Python 玩转 Excel

环境配置

  • Python 3.10.0
  • Openpyxl 3.0.9
  • xlrd 1.3.0

谈到用Python操作excel,不得不向大家介绍一下这两个Python库,

  • Openpyxl 3.0.9
  • xlrd 1.3.0

Openpyxl

Openpyxl 是一个用于处理 xlsx 格式Excel表格文件的第三方python库,其支持Excel表格绝大多数基本操作。

image.png

Xlrd

xlrd和与之配套的xlwt库用于python批量读写excel文件

xlrd是读excelxlwt是写excel的库。

  image.png

现在最新版本的xlrd2.0.1不支持打开.xlsx文件,  

官方解释:

xlrd is a library for reading data and formatting information from Excel files in the historical .xls format. #只能够操作xls老版本文件,如何操作xlsx需要调用其他的库

因此该库,需要降维安装:

pip unistall xlrd

image.png

再使用国内镜像源安装

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple xlrd==1.2.0

image.png

玩转自动化

获取Excel表格文件中的表格名称

from openpyxl import load_workbook
# 获取Excel文件中的表格名称
workbook = load_workbook(filename = "test.xlsx")
print(workbook.sheetnames)

image.png

输出为:

image.png

通过sheet名称获取表格

# 通过sheet名称获取表格
sheet=workbook["汇总表"]
print(sheet)

输出为:

image.png

获取表格的尺寸大小

# 输出sheet(汇总表)的大小
print(sheet.dimensions)

image.png

输出为:

image.png

获取表格内某个格子的数据

cell1 = sheet["A1"]
cell2 = sheet["C4"]
print(cell1.value)
print(cell2.value)
print(cell1.value, cell2.value)

image.png

输出为

image.png

获取某个格子的行数、列数、坐标

# row 获取某个格子的行数;
# columns 获取某个格子的列数;
# corordinate 获取某个格子的坐标;
print(cell1.value, cell1.row, cell1.column, cell1.coordinate)
print(cell2.value, cell2.row, cell2.column, cell2.coordinate)

输出为:

image.png

获取一系列格子的值

# 获取A1:C4区域的值
cell = sheet["A1:C4"]
print(cell)
for i in cell:
    for j in i:
        print(j.value)

输出为:

image.png

向某个格子中写入内容并保存

# 向某个格子写入内容
sheet["A5"] = "张小三"
workbook.save(filename = "test.xlsx")

执行该步骤时,需要先关闭excel文件

输出为:

image.png

注:应该在Excel文件关闭的情况下进行代码操作。

使用Excel函数

其实在Python中操作Excel文件时还可以使用Excel函数

例如:计算C列最大的数字

# 计算C列最大的数字
sheet["C5"]='=Max(C2:C4)'
workbook.save(filename = "test.xlsx")

输出为:

image.png

利用以下命令可以查看Python支持哪些Excel函数公式

from openpyxl.utils import FORMULAE
print(FORMULAE)

输出为:

image.png

删除操作

# 删除第1列,第1行
sheet.delete_cols(idx=1)
sheet.delete_rows(idx=1)

创建新的表格

workbook.create_sheet("新表00")
workbook.save(filename = "test.xlsx")

删除某个表格

sheet=workbook['新表']
workbook.remove(sheet)
workbook.save(filename = "test.xlsx")

修改某个表格名字

sheet=workbook['新表00']
sheet.title="新表001"
workbook.save(filename = "test.xlsx")

完成度10%的Excel便携处理系统

最后献上一个结合Tkinter,完成度10%Excel便携处理系统:

image.png

main函数:

import tkinter as tk
from excelFunc import ManageSystem
from excelGui import windows
if __name__ == '__main__':
    root = tk.Tk()
    root.title("Excel便携处理系统")
    screenwidth = root.winfo_screenwidth()
    screenheight = root.winfo_screenheight()
    root.geometry('%dx%d+%d+%d' % (800, 600, (screenwidth - 800) / 2, (screenheight - 600) / 2))
    manage = ManageSystem()
    windows(root,manage)
    root.mainloop()

GUI函数

import tkinter as tk
from tkinter import ttk

class windows:
    def __init__(self, master,manage):
        self.master=master
        self.manage = manage

        self.lbl = tk.Label(self.master, text='Excel便携处理系统', font=('HGBTS_CNKI', 15), fg='Black')
        self.lbl.place(x=330, y=0)

        self.lbl1 = tk.Label(self.master, text='作者:', font=('HGBTS_CNKI', 15), fg='Black')
        self.lbl1.place(x=600, y=30)

        self.lbl1 = tk.Label(self.master, text='看那个码农', font=('HGBTS_CNKI', 15), fg='Black')
        self.lbl1.place(x=660, y=30)

        self.f1 = None

        self.createWidgest()

    def createWidgest(self):

        if self.f1:
            self.f1.destroy()

        self.f1 = tk.Frame(self.master)
        self.f1['width'] = 800
        self.f1['height'] = 800

        self.lab01 = tk.Label(self.f1, text='请输入文件所在路径:', font=('黑体', 15), width=23, fg='black')
        self.lab01.place(x=70, y=0)

        self.lab01_entry = tk.Entry(self.f1,width=50)
        self.lab01_entry.place(x=300, y=3)

        self.lab02 = tk.Label(self.f1, text='请输入Excel文件名:', font=('黑体', 15), width=23, fg='black')
        self.lab02.place(x=66, y=30)

        str1 = tk.StringVar()

        self.lab02_entry = tk.Entry(self.f1, width=50)
        self.lab02_entry.place(x=300, y=35)

        def cmd1():
            str1=self.manage.select_file_message(self.lab01_entry.get(),self.lab02_entry.get())
            self.text.delete(0.0, 'end')
            self.text.insert(0.0, str1)

        self.btn1 = tk.Button(self.f1, text='查询', width=6, height=2,command=cmd1)
        self.btn1.place(x=670, y=3)

        self.lab03 = tk.Label(self.f1, text='该Excel中所存在的表:', font=('黑体', 15), width=23, fg='black')
        self.lab03.place(x=75, y=60)

        self.text = tk.Text(self.f1, width=50, height=3)
        self.text.place(x=300, y=65)

        self.lab04 = tk.Label(self.f1, text='请输入你想打开的表:', font=('黑体', 15), width=23, fg='black')
        self.lab04.place(x=72, y=111)

        self.lab04_entry = tk.Entry(self.f1, width=50)
        self.lab04_entry.place(x=300, y=115)

        def showdata(self, data):
            # 定义树状图表格函数
            '''
            frame:容器
            data:数据,数据类型为列表

            '''

            nrows = len(data)

            ncols = len(data[0])
            columns = [""]
            for i in range(ncols):
                columns.append(str(i))
            heading = columns

            """
                定义Treeview
                self.Frame2为父容器
                columns为列名集合
                show="headings"表示显示表头
            """
            tree = ttk.Treeview(self, columns=columns, show="headings")

            # 定义各列列宽及对齐方式
            for item in columns:
                tree.column(item, width=50, anchor="center")

            tree.heading(heading[0], text=heading[0])  # 第一列的表头为空

            # 定义表头
            for i in range(1, len(columns)):
                tree.heading(heading[i], text=str(i))

            # 设置表格内容
            i = 0
            for v in data:
                v.insert(0, i + 1)  # 第一列的显示内容(序号)
                tree.insert('', i, values=(v))
                i += 1

            # 放置控件,rel*表示使用相对定位,相对于父容器的定位
            # tree.place(relx=0, rely=0, relwidth=1, relheight=1)

            return tree

        def cmd2(sel):
            data=self.manage.select_excel_message(self.lab01_entry.get(),
                                             self.lab02_entry.get(),
                                             self.lab04_entry.get())
            tree = showdata(sel, data)
            tree.place(relx=0.05, rely=0.2, relheight=0.3, relwidth=0.9)


        self.btn2 = tk.Button(self.f1, text='查询', width=6, height=1,command=lambda:cmd2(self.f1))
        self.btn2.place(x=670, y=110)

        self.f1.place(x=0, y=80)

功能函数:

from openpyxl import load_workbook
from openpyxl.styles import Font
import xlrd
import tkinter.messagebox

class ManageSystem(object):
    def __init__(self):
        self.font = Font(name="Courier New", size=9, italic=True, bold=False)

    def select_file_message(self,lab01_entry,lab02_entry):
        if lab01_entry == '' or lab02_entry == '':
            tkinter.messagebox.showinfo("提示", "请输入完整信息1")

        workbook = load_workbook(filename = lab01_entry+"\"+lab02_entry+".xlsx")
        str=','.join(workbook.sheetnames)
        return str

    def select_excel_message(self,lab01_entry,lab02_entry,lab04_entry):
        if lab04_entry == '':
            tkinter.messagebox.showinfo("提示", "请输入完整信息2")
        filename = lab01_entry + "\" + lab02_entry + ".xlsx"

        book = xlrd.open_workbook(filename)
        sheet = book.sheet_by_name(lab04_entry)
        nrows = sheet.nrows

        values = []
        for i in range(nrows):
            row_values = sheet.row_values(i)
            values.append(row_values)
        return values

运行输出

image.png

目前软件界面的功能是首先输入文件所在路径,再输入文件夹,按查询后会出现该Excel中所存在的表,再输入想打开的表即可打开表在下方。以及后续陆续完善一些功能。

该系统整个完成度10%,有待继续进行优化,待成品完成后会发布于Github中。

篇篇精彩,尽请关注。