Python 自动化教程 概述,第一篇 Excel自动化首篇
Posted JoStudio
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python 自动化教程 概述,第一篇 Excel自动化首篇相关的知识,希望对你有一定的参考价值。
人生苦短, 我用Python! Python语法简炼、易上手,且有丰富的库可用,实现一个应用很简洁。
Python常用于自动化。自动化的基本含义,是把人的动作写成程序,让计算机代替人工作。主要分为几类:
1、自动化办公:对excel、word、ppt等office文档或pdf进行批量化、自动化等处理。
2、自动化媒体处理:对图片、视频等媒体文件进行批量化、自动化等处理。
3、自动化机器人:比如微信客服/聊天机器人、网站操作/录入、网络爬虫/网页信息抓取、自动化数据服务等
由于python开发社区的广泛性,各类自动化python都有对应的库,可以很方便的调用。
本系列教程旨在示范各类典型的自动化、理解相关库及其编程使用方法。
学习者需要有Python基础编程知识。
开发环境是:Python3, PyCharm IDE, 操作系统:Win10
系列教程:
Python 自动化教程(1) 概述,第一篇 Excel自动化
Python 自动化教程(2) : Excel自动化:使用pandas库
Python 自动化教程(3) : 自动生成PPT文件 Part 1
Python 自动化教程(4) : 自动生成PPT文件 Part 2
Python 自动化教程(6) : PDF文件处理
第一篇 Excel自动化
Excel自动化,是用Python程序创建、编辑、修改Excel文件,处理其中的数据,从而无人化、大批量处理excel文件数据。
处理excel常用的库有:openpyxl、xlwings、xlrd、xlwt等。数据处理的库常用 pandas
这里主要讲 openpyxl、xlwings、pandas 三个库。
一、首先用 PIP 安装 openpyxl、xlwings、pandas 库
打开命令行窗口,分别输入三行命令
pip install openpyxl
pip install xlwings
pip install pandas
为快速下载,可以使用 阿里云 镜像 (pandas 库比较大)
pip install openpyxl -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com
pip install xlwings -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com
pip install pandas -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com
二、Excel的基本概念
WorkBook (工作簿) 一个Excel文件就是一个WorkBook(工作簿)
WorkSheet(工作表) 一个WorkBook(工作簿)中包含多张WorkSheet工作表。每个WorkSheet有一个标题(title), 如:Sheet1
Cell (单元格), 一个WorkSheet工作表包含多个单元格。一个单元格有行号、列号。例如:B3
Reference Address (引用地址): B3 表示一个单元格, B3:D6 表示一个区域(Range),包含多个单元格。 Sheet2!B3:D6 表示 工作表Sheet2中的 B3:D6 这个区域
三、openpyxl 库的基本使用方法
用PyCharm创建一个新项目,创建一个新的.py文件,在程序开头引用 openpyxl
import openpyxl
或
import openpyxl as xl
import openpyxl as xl 是将openpyxl库起一个别名xl, 以便后续程序简化书写
1, 打开Excel文件, 打印所有的工作表标题
import openpyxl as xl
filename = "202201报表.xlsx"
# 打开excel文件,取得workbook对象
workbook = xl.load_workbook(filename)
# 列出所有worksheet
for worksheet in workbook:
print(type(worksheet), worksheet.title) # 打印worksheet的类型, 标题
其中:excel文件 202201报表.xlsx 是这样的。 py程序和excel文件可以在此下载
注意:
1、由于程序中未指明文件路径,因此要将 202201报表.xlsx 文件放在 .py程序文件同一目录下。
2、openpyxl 库只支持 .xlsx 文件, 不支持 后缀为 .xls 的老格式excel文件(Excel 2003之前的)。
3、如果执行程序时, excel文件正在被 Excel程序打开,会因为共享冲突而出错。
PermissionError: [Errno 13] Permission denied: '202201报表.xlsx'
运行程序,结果如下
<class 'openpyxl.worksheet.worksheet.Worksheet'> 商品销售
<class 'openpyxl.worksheet.worksheet.Worksheet'> 客户
<class 'openpyxl.worksheet.worksheet.Worksheet'> 库存
<class 'openpyxl.worksheet.worksheet.Worksheet'> 汇总
说明:
1、workbook = xl.load_workbook(filename) 打开文件。
如果要创建新的excel文件。一般情况下,是复制一个模板文件到新的文件。
例如:
import shutil
template_file = "报表模板.xlsx"
new_file = "新报表.xlsx"
# 使用shutil库的copyfile()函数复制文件,如new_file文件不存在则创建新文件
shutil.copyfile(template_file, new_file)
2、xl.load_workbook(filename)的返回值 workbook 是一个Workbook对象
3、通过 for worksheet in workbook: 循环可以获得每一张工作表 Worksheet对象
2, 通过标题,取得WorkSheet
# 如果 workbook 中有名为 '商品销售' 的 worksheet
if '商品销售' in workbook:
# 取得 worksheet
worksheet = workbook['商品销售']
3、通过地址取得单元格Cell对象, 读取单元格的值、修改值
# 取得一个单元格
cell = worksheet["B3"]
print(type(cell))
# 取得单元格的值
print(cell.value)
# 取得单元格的行号(数字, 第一行列为1), 列号(数字, A列为1)
print('row, col=', cell.row, cell.column)
# 取得单元格的另一个方法:使用row, col 数字
row = 3
col = 2
cell2 = worksheet.cell(row, col) # 相当于 B3
# 写入单元格的值
cell2.value = "北京"
运行程序,结果如下
<class 'openpyxl.cell.cell.Cell'>
深圳
row, col= 3 2
说明:
1、worksheet[address] 返回一个 Cell对象。 cell.value 可以读取或写入值
如果cell中有公式,则 cell.value 返回公式字符串,如: '= B2 + D2', 如果要修改公式,直接将公式字符串赋值给 cell.value即可。例如: cell.value = '=B3+D2'
2、cell.row 取得单元格的行(整数,第一行是1)
cell.column 取得单元格的列(整数,A列 是1,依次类推)
3、取得单元格B3有两个写法: 第一种是使用引用地址字符串: worksheet['B3']
第二种是使用 行、列数值, 如: worksheet(row=3, column=2) , 第二种便于书写循环程序,批量读取数值, 例如:
for row in range(1, 11):
for col in range(1, 5):
print(worksheet.cell(row, col).value)
4、通过地址取得一个区域(多个单元格), 读取区域的值
# 取得一个区域
range1 = worksheet['A1:B5']
print(range1)
# 取得区域内所有单元格的值
data = []
for row in range1:
row_values = []
for cell in row:
row_values.append(cell.value)
data.append(row_values)
print(data)
运行程序,结果如下
((<Cell '商品销售'.A1>, <Cell '商品销售'.B1>), (<Cell '商品销售'.A2>, <Cell '商品销售'.B2>), (<Cell '商品销售'.A3>, <Cell '商品销售'.B3>))
[['地区分类', '城市'], ['二类', '广州'], ['一类', '北京']]
说明:
range1 = worksheet['A1:B3'] # 取A1: B3区域
print(range1) 显示 range1 是一个tuple, 其中每一个子元素是一行(多个cell对象的 tuple),共3行,即range tuple包含了多个行、多个列的cell
for row in range1 这个循环列出每一行
for cell in row 这个循环列出一行内的每一个cell
row_values 是一行的数值列表
data 是所有数据的列表, print(data) 显示出所有cell的值
5、Worksheet 的最大行数、最大列数
# 工作表的最大行数
print(worksheet.max_row)
# 工作表的最大行数
print(worksheet.max_column)
工作表实际使用的最大行数、最大列数
6、保存文件(保存WorkBook),关闭文件(关闭WorkBook)
# 保存文件
workbook.save(filename)
# 关闭文件
workbook.close()
保存WorkBook,则将数据修改存入文件了。不保存直接关闭,修改就丢了。
7、openpyxl 库小结
以上是 openpyxl 库的基本操作,常规工作中基本够用了。比如:
(1) 合并报表:每个月有一个报表,通过python读取多个文件,写入另一个汇总文件。
(2)拆分报表:将一个汇总表,生成多个子表。
(3)读取或写入数据
(4)修改图表: 在excel文件中预先手工生成图表,修改数据即可更新图表。
openpyxl库还可以处理单元格的颜色、字体、边框,创建图表等复杂操作。但平时用的很少。一般情况,我们手工创建 excel文件模板、编写好公式、画好图表,python程序读写数值即可。
三、xlwings 库的基本使用方法
与openpyxl库一样, xlwings库可以读写excel文件。不同的是, xlwings库是调用本机安装的Microsoft Excel程序打开并读写excel文件,因此运行 python程序的本机必须安装Excel程序。相反,openpyxl库不依赖Excel程序,因此openpyxl可以在linux服务器上使用。 同时,由于xlwings使用Microsoft Excel, 因此能打开老式的 .xls文件, 具有Microsoft Excel所具备的一切能力。
1, 使用xlwings打开Excel文件, 打印所有的工作表标题
import xlwings as xw
# 创建 App对象
app = xw.App(visible=True, add_book=False)
print(type(app))
# 使用App对象, 打开excel文件
filename = "202201报表.xlsx"
workbook = app.books.open(filename)
print(type(workbook))
# 列出所有 worksheet
for sheet in workbook.sheets:
print(type(sheet), sheet.name) # 注意:要使用 sheet.name 取得工作表标题
workbook.close()
app.quit() # 退出Excel程序
运行结果:
<class 'xlwings.main.App'>
<class 'xlwings.main.Book'>
<class 'xlwings.main.Sheet'> 商品销售
<class 'xlwings.main.Sheet'> 客户
<class 'xlwings.main.Sheet'> 库存
<class 'xlwings.main.Sheet'> 汇总
说明:
1, 与openpyxl库不同, 使用xlwings库时,首先要创建 App对象,再用App对象打开excel文件
app = xw.App(visible=True, add_book=False)。 一个App对象就是 一个Excel程序实例。
visible=True 表示显示Microsoft Excel界面。运行时可以看到Excel界面出现了。
add_book=False 表示打开Excel 程序时,不添加空白工作表
2, 通过 for worksheet in workbook: 循环可以获得每一张工作表 (与openpyxl库一样)
3,使用 worksheet.name 取得工作表标题。 (与openpyxl库使用 worksheet.title 不同)
4,由于是使用Excel程序打开文件,打开后文件被锁定,其他程序将无法同时读写该excel文件。
5,结束前,要调用 app.quit() 退出Excel程序 (否则Excel程序将不会关闭)
2, 通过标题,取得WorkSheet
# 取得 标题是 '商品销售' 的 worksheet
worksheet = workbook.sheets('商品销售')
print(type(worksheet))
说明: xlwings库不支持 in 写法: if '标题' in workbook
3、通过地址取得单元格, 读取单元格的值、修改值
# 取得一个单元格 B3
cell = worksheet['B3']
print(type(cell), cell.value) # 打印cell的类型, 读取cell的值
# 设置单元格的值
cell.value = "新城"
# 取得单元格的行号(数字, 第一行列为1), 列号(数字, A列为1)
print('row, col=', cell.row, cell.column)
# 取得 E2 格中的公式、 值
print(worksheet['E2'].formula, worksheet['E2'].value)
说明:
(1)、worksheet[address] 返回一个 Range 对象。 cell.value 可以读取或写入值
(2)、cell.row 取得单元格的行(整数,第一行是1)
cell.column 取得单元格的列(整数,A列 是1,依次类推)
(3)、使用 cell.formula 读取或设置单元格的公式, 使用 cell.value读取或设置单元格的值
# 另一种方式:使用row, col 数字取得 B3 单元格
row = 3
col = 2
cell2 = worksheet.cells(row, col)
print(type(cell2), cell2.value)
(4)、取得单元格B3的第二种写法是使用 行、列数值, 如: worksheet(row, column)
4、通过地址取得一个区域(多个单元格), 读取区域的值
# 取得一个区域
range1 = worksheet['A1:B3']
# 取得区域内所有单元格胡值
print(range1.value)
运行结果:
<class 'xlwings.main.Range'> 新城
[['地区分类', '城市'], ['二类', '广州'], ['一类', '新城']]
可以看到: range1.value 直接返回一个 list, 每个元素表示一行,直接是各单元格的值。(这个比openpyxl 方便一点)
5、保存文件(保存WorkBook),关闭文件(关闭WorkBook)、退出App
# workbook 保存
workbook.save(filename)
# workbook 关闭
workbook.close()
# 注意:要退出 app(即关闭Microsoft Excel程序)
app.quit()
6、xlwings 库基本用法小结
xlwings 库用法与 openpyxl库 大同小异。
7、xlwings库的特殊用法:在Microsoft Excel程序中调用 python程序
xlwings 库有一个很好用的功能:将python程序作为Microsoft Excel的插件/扩展程序运行,就是说,无需打开Python 或 PyCharm, 在Excel程序中直接运行python。另外,也可以用python语言为Exce编写用户自定义函数(User Defined Function, 简称UDF), 扩展Excel的功能。
众所周知, Microsoft Office程序(包括Excel) 支持 以Visual Basic for Application 或 CSharp 语言编写扩展程序,允许用户增强Excel的功能。 xlwings作为python与Excel的桥梁,支持将python程序作为Microsoft Excel的插件/扩展程序运行。
使用方法如下。
首先,关闭Excel程序, 打开命令行窗口,输入以下命令,安装 xlwings for Excel 的插件 (addin).
xlwings addin install
运行结果:表明xlwings for Excel 的插件(addin) 安装成功。
xlwings version: 0.27.11
Successfully installed the xlwings add-in! Please restart Excel.
There is already an existing ~/.xlwings/xlwings.conf file. Run 'xlwings config create --force' if you want to reset your configuration.
然后, 重新启动Microsoft Excel程序, 则可以看到 Excel 多了一个名为 xlwings 的菜单页
菜单页上有多个选项和文本框,不用管它们。我们只使用上图最左边红色方框指示的 "Run Main"这个按钮就够了。
按下 "Run Main" 按钮会发生什么呢?
比如:当前打开的文件名是 abcd.xlsx, 当按下 "Run Main" 按钮,Excel会调用xlwings库,xlwings库将寻找 与 abcd.xlsx 文件同一个目录下的同名.py文件 (即:abcd.py), 运行这个python文件中的 main() 函数。 main() 函数以python编写,写什么内容都行,比如:可以从网络、或数据库读取数据,再写入工作表中。
注意:
1、xlwings库不支持中文名的.py文件。因此,使用该功能的excel文件名不能包含中文(否则出错)。
2、xlwings库将以import 模块的方式加载 .py文件。 因此,使用该功能的excel文件名必须以英文字母开头、且不能包含空格、特殊字符等,excel文件名必须是一个合法的python变量名,且不能与已有的python库重名。否则出错。
3、本人认为,上述两点是xlwings库的bug。 没办法只能遵守。 (PS: 本人将xlwings addin 改了一下,可不受此限制)
实战:
将 “202201报表.xlsx” 文件复制一份,改名为 abcd.xlsx, 在同目录下编写一个名为 abcd.py 程序文件。程序如下:
import xlwings as xw
def main():
# 获得调用本程序的 workbook
workbook = xw.Book.caller()
# 获得当前激活的 worksheet
worksheet = xw.sheets.active
# 在 B9 单元格中写入一个数值
worksheet['B9'].value = "你好,我来了"
abcd.py 中只定义了一个 main() 函数, 该函数无输入参数。
代码注释写得很清楚: 首先用 xw.Book.caller() 获得调用本程序的 workbook对象,然后,取得当前工作表,在单元格B12中写入一串文字。
用Excel程序打开abcd.xlsx, 点击 xlwings菜单的 "run main"按钮, 运行效果如下:
如图: 在Excel程序中,点击 xlwings 菜单中的 Run main 按钮(左上红框), B9单元格(蓝框) 将自动写入python程序运行的结果。
实际上, .py程序可以是任意合法的python程序,可以调用各种库、写多个函数。
xlwings为扩展Excel功能提供了无限的潜力和想象力.
比如: 读取Excel单元格中的股票名称,到网络上查出该股票当前价格。
读取Excel单元格中的人员名称,在数据库中查出该人员上班有否迟到。
总之,运行python, 一切都可行。
xlwings for Excel 插件功能是否很棒呢!
本篇小结:
本篇讲解了 openpyxl, xlwings库的基本用法。py程序和excel文件可以在此下载
事实上,在处理excel 大数据量的时候,我们直接使用 pandas 库就可以了,pandas 将调用openpyxl 或 xlwings库读写excel文件。往往我们将不需要直接使用openpyxl, xlwings库,但了解这两个库对深入理解pandas是有必要的。
下一篇,我们将讲解 pandas 库,操作excel数据。
练习作业及其答案:
1,写一个python程序,在excel文件 ”202201报表.xlsx“ 的 "商品销售" Worksheet 上 自动找到 值为 "广州" 的单元格
答案:
import openpyxl
def find(sheet1, value):
""" 在sheet1中查找值为value的单元格, 找到到返回Cell对象,找不到则返回None"""
for row in range(1, sheet1.max_row + 1):
for col in range(1, sheet1.max_column + 1):
cell = sheet1.cell(row, col)
if cell.value == value:
return cell
filename = "202201报表.xlsx"
workbook = openpyxl.load_workbook(filename)
cell = find(workbook['商品销售'], '广州')
print(cell)
运行结果: <Cell '商品销售'.B2>
2, 写一个python程序,在excel文件 ”202201报表.xlsx“ 的 "商品销售" Worksheet 上 自动找到两个值 "广州", "金额" 的两个单元格交叉的单元格的值, 就是说:找到广州的金额
import openpyxl
def find(sheet1, value):
""" 在sheet1中查找值为value的单元格, 找到返回Cell对象,找不到则返回None"""
for row in range(1, sheet1.max_row + 1):
for col in range(1, sheet1.max_column + 1):
cell = sheet1.cell(row, col)
if cell.value == value:
return cell
def find2(sheet1, value1, value2):
""" 在sheet1中查找值为value1, value2的两个单元格, 返回其交叉的Cell,找不到则返回None"""
cell1 = find(sheet1, value1)
cell2 = find(sheet1, value2)
if cell1 and cell2:
return sheet1.cell(cell1.row, cell2.column)
def find_file(filename, sheetname, value1, value2):
""" 在文件中,指定工作表名, 查找值为value1, value2的两个单元格, 返回其交叉的Cell,找不到则返回None"""
workbook = openpyxl.load_workbook(filename)
if sheetname in workbook:
return find2(workbook[sheetname], value1, value2)
# 使用范例: 查找 商品销售表中 广州的金额
cell = find_file("202201报表.xlsx", '商品销售', '广州', '金额')
if cell:
print(cell.value)
else:
print('not found')
运行结果: 1003
找到广州的金额是1003
这个是有用的,比如说:每月有一个报表文件,我们要找到某个月,某业务,某地区的金额。
使用场景可以是: 你对微信机器人讲,请找2022年1月广州商品销售金额。机器人分析后,定位为202201报表.xlsx文件,把数据找出来,回答你。这个故事我们将在随后的章节中实现它。
3, 在excel文件 ”202201报表.xlsx“ 的 "库存" Worksheet 上, 表格的位置不是从 A1开始的。
请编写一个python程序, 自动找到 "库存" Worksheet中的表格。
import openpyxl
def find_first_cell(sheet1):
""" 在sheet1中查找值不为空的第一个单元格, 找到返回Cell对象,找不到则返回None"""
for row in range(1, sheet1.max_row + 1):
for col in range(1, sheet1.max_column + 1):
cell = sheet1.cell(row, col)
if cell.value is not None:
return cell
def expand_column(cell):
""" 从单元格cell出发,水平向右查找,找到最后一个不为空值的Cell对象 """
for col in range(cell.column + 1, cell.parent.max_column + 2):
c = cell.parent.cell(cell.row, col)
if c.value is None:
return cell.parent.cell(cell.row, col - 1)
def expand_row(cell):
""" 从单元格cell出发,垂直向下查找,找到最后一个不为空值的Cell对象 """
for row in range(cell.row + 1, cell.parent.max_row + 2):
c = cell.parent.cell(row, cell.column)
if c.value is None:
return cell.parent.cell(row - 1, cell.column)
def find_table(sheet1):
""" 查找sheet1中的首个表格。 返回 tuple, 每一个元素是一行Cell. 找不到则返回空的tuple """
result = []
cell = find_first_cell(sheet1) # 查找值不为空的第一个单元格
if cell:
cell1 = expand_column(cell) # 向右扩展
cell2 = expand_row(cell) # 向下扩展
if cell1 and cell2:
# 构造返回值
for row in range(cell.row, cell2.row + 1):
r = []
for col in range(cell.column, cell1.column + 1):
r.append(cell.parent.cell(row, col))
result.append(tuple(r))
return tuple(result)
# 使用范例
filename = "202201报表.xlsx"
workbook = openpyxl.load_workbook(filename)
sheet1 = workbook['库存']
area = find_table(sheet1)
if len(area) > 0:
print(area)
else:
print("not found")
运行结果:
((<Cell '库存'.B6>, <Cell '库存'.C6>, <Cell '库存'.D6>), (<Cell '库存'.B7>, <Cell '库存'.C7>,...
这个结果与使用 sheet['B6:D10'] 返回值是一样的。
使用场景可以是: 你对微信机器人讲,请查一下库存情况。机器人分析后,定位为当前 月份是202201, 查找202201报表.xlsx文件的库存工作表,把表格找出来,列个表回答你。
以上是关于Python 自动化教程 概述,第一篇 Excel自动化首篇的主要内容,如果未能解决你的问题,请参考以下文章
Python 自动化教程 概述,第一篇 Excel自动化首篇
Python 自动化教程 : Excel自动化:使用pandas库