e676f361c2e1ea951100f6c04f405ca8.gif

在后台回复【阅读书籍】

即可获取python相关电子书~

Hi,我是山月。

前面给大家介绍了xlrd、xlwt的教程👇

今天来给大家介绍山月最常用的:openpyxl。它不仅能直接读写,功能相对于xlrd、xlwt来说也较完整。

由于篇幅较长,文章分为基础和进阶两个部分,现在先来看看基础教程。

01

openpyxl的介绍

1、安装

pip install openpyxl

注意:openpyxl模块只支持xlsx/xlsm/xltx/xltm格式,不支持xls格式。


2、官方文档:https://openpyxl.readthedocs.io/en/stable/

02

新建

1、新建工作薄

# 导入openpyxl模块的Workbook类
from openpyxl import Workbook

# 创建一个workbook对象,同时也会创建一个工作表
wb = Workbook()

# 调用得到正在运行的工作表。注意:调用工作表的索引默认是0,即默认对第一张工作表进行操作。
ws = wb.active

#保存
wb.save("实例.xlsx")

效果:

931a4d587d0fe6ce259054408651c623.png

2、新建工作表

可以使用create_sheet()函数新建一张工作表。

#新建工作表,名称以Sheet1,Sheet2,....自动填充
ws_1 = wb.create_sheet()    # 默认在结尾处新建一个新的工作表
ws_2 = wb.create_sheet(0)   # 在当前工作表的指定索引处新建一个工作表

# 用title指定工作表名称
ws_1.title = "新建工作表" 

# 新建工作表,并指定名称
ws_3 = wb.create_sheet(title="新建工作表-2",index=0)
ws_4 = wb.create_sheet("新建工作表-1", 0) 

# 改变工作表标签颜色,默认为无颜色
ws.sheet_properties.tabColor = "F22F27"

实例:

from openpyxl import Workbook
wb = Workbook()
ws = wb.active

# 改变当前正在运行工作表的标签颜色
ws.sheet_properties.tabColor = "F22F27" 

# 在开始位置处新建一张名称为【新建工作表-1】的工作表
ws_1 = wb.create_sheet("新建工作表-1", 0) 

# 在结尾处新建一张名称为【新建工作表-2】的工作表
ws_2 = wb.create_sheet()
ws_2.title = "新建工作表-2"

#保存
wb.save("实例.xlsx")

效果:

6ac80aaa5bb1eb861ebea678deb3fa0d.png

03

操作

1、设置工作薄只读

假设有一个名称为【数据.xlsx】的excel文件,它的内容如下:

63b3e15688d977ee9040b273542e2ce7.png

如果我们把它设置成只读后,尝试在单元格写入数据的话:

# 导入openpyxl模块的 load_workbook类
from openpyxl import load_workbook

wb = load_workbook(filename='数据.xlsx', read_only=True) #设置只读
ws = wb.active

#读取表格数据
for row in ws.rows:
    for cell in row:
        print(cell.value)

ws['A9']=88 #尝试写入单元格,会报错

# 关闭文件
wb.close()

结果:

eb19d85d77a7c17889540ccf95d54bed.png

2、工作表操作

#获取工作簿所有工作表名称
print(wb.sheetnames)

# 遍历工作簿所有工作表名称
for sheet in wb:
 print(sheet.title)
 
#获取指定工作表名称
ws = wb["新建工作表-1"]
print(ws.title)  

#复制工作表
ws = wb["新建工作表-1"]
ws_copy = wb.copy_worksheet(ws) 

#删除工作表
# 方式一
ws = wb["新建工作表-1"]
wb.remove(ws)
# 方式二
del wb["新建工作表-1"]

以我们刚刚新建的表格【实例.xlsx】来示例:

b9d412ef400ebcad628d4dbf8027784d.png

# 导入openpyxl模块的load_workbook类
from openpyxl  import load_workbook

#打开【例子.xlsx】工作薄
wb = load_workbook('实例.xlsx')

# 遍历工作簿所有工作表名称
for sheet in wb:
 print(sheet.title)

#复制工作表
ws = wb["新建工作表-2"]
target = wb.copy_worksheet(ws) 

# 删除工作表
del wb["新建工作表-1"]

#获取工作簿所有工作表
print(wb.sheetnames)

结果:

新建工作表-1
Sheet
新建工作表-2
['Sheet', '新建工作表-2', '新建工作表-2 Copy']

3、行列操作

# 获得工作表最大列和最大行
print(ws.max_row)     # 获取工作表最大行
print(ws.max_column)  # 获取工作表最大列
print(ws.calculate_dimension())  # 获取工作表全部数据的单元格区域


# 插入空行/空列
ws.insert_rows(1)     # 在第1行插入空行
ws.insert_cols(1)     # 在第1列插入空列
ws.insert_rows(2,2)   # 从第2行开始插入2行空行,即在2、3行插入空行
ws.insert_cols(2,2)   # 从第2列开始插入2列空列,即在B、C列插入空列

# 删除行/列
ws.delete_rows(2)    # 删除第2行
ws.delete_rows(2,2)  # 从第2行开始删除2行
ws.delete_cols(2)    # 删除第2列
ws.delete_cols(2,2)  # 从第2列开始删除2列

以【数据.xlsx】为例:

be3bb105a25e4b29a437a5cf27e60c1c.png

from openpyxl  import load_workbook
wb = load_workbook('数据.xlsx')
ws = wb.active

print(ws.max_row)     # 获取工作表最大行
print(ws.max_column)  # 获取工作表最大列
print(ws.calculate_dimension())  # 获取工作表全部数据的单元格区域

ws.insert_cols(2,2)   # 从第2列开始插入2列空列,即在B、C列插入空列
ws.delete_rows(2,2)  # 从第2行开始删除2行

wb.save("实例.xlsx")

结果:

8
3    
A1:C8

3b8dd027eacacac373efe29079d4efba.png

4、访问单元格

注意:当一个工作表被创建时,其中不包含单元格,只有当单元格被获取时才被创建。

这种方式我们不会创建我们从不会使用的单元格,从而减少了内存消耗。

'''
1)单个单元格访问
''' 

# 方法一
cell_A2 = ws['A2']

# 方法二:row 行;column 列
cell_B2 = ws.cell(row=2, column=2)

'''
2)多个单元格访问
结果都可以用 tuple()、list()、循环进行处理
'''    

# 通过切片
cell_area = ws['A1':'B4']
cell_exact = ws.iter_rows(min_row=1, max_row=3, min_col=1, max_col=2)     #即A1:B3

# 通过行/列
col_A = ws['A']           #A列
col_area = ws['A:B']      #A、B列
row_2 = ws[2]             #第2行
row_area = ws[2:5]        #2-5行

# 迭代所有行
all_by_row = ws.rows 

# 迭代所有列
all_by_col =ws.columns

还是以【数据.xlsx】为例:

from openpyxl  import load_workbook
wb = load_workbook('数据.xlsx')
ws = wb.active

#获取单个单元格值
cell_A2 = ws['A2']
cell_B2 = ws.cell(row=2, column=2)
print(cell_A2.value, cell_B2.value)

print('---')

#获取多个单元格值
cell_area = ws['A1':'B3']
for rows in cell_area:
    for cells in rows:
        print(cells.value)

结果:

红儿 99
---    
姓名   
年龄   
红儿   
99     
橙儿
98

5、设置行高和列宽

from openpyxl import Workbook

wb = Workbook()
ws = wb.active

# 写入单元格
ws['A1'] = '默认'
ws['B2'] = '设置行高'
ws['C3'] = '设置列宽'

# 设置第2行行高
ws.row_dimensions[2].height = 40

# 设置C列列宽
ws.column_dimensions['C'].width = 30

wb.save('实例.xlsx')

效果:

bfe3b7f5b7a44cd09659ff4f3b380e4c.png

6、合并单元格

1)合并

注意:要想在合并单元格写入数据,只需要在合并区域左上角的单元格写入数据即可。

如果合并区域内的单元格都有数据,也只会保留左上角的数据。

from openpyxl.workbook import Workbook

wb = Workbook()
ws = wb.active

#合并单元格
ws.merge_cells('A2:D4')
# 等同于:ws.merge_cells(start_row=2, start_column=1, end_row=4, end_column=4)

ws['A2'] = '合并单元格' #在合并区域的左上角单元格A2写入

wb.save('实例.xlsx')

效果:

9665bb243e56ddca5788cf57c959b908.png

2)取消合并

取消合并后合并单元格的值将返回到合并区域左上角的单元格。比如我们打开刚刚合并后的表格:

from openpyxl  import load_workbook

#打开【实例.xlsx】工作薄
wb = load_workbook('实例.xlsx')
ws = wb.active

# 取消合并
ws.unmerge_cells('A2:D4')
# 等同于:ws.unmerge_cells(start_row=2, start_column=1, end_row=4, end_column=4)

wb.save('实例-1.xlsx')

效果:

2dfa60ade4561e3b58122d9c93dc96bb.png

04

写入

1、写入数据

# 在单元格写入数据
ws['A1'] = 42    #A1单元格写入
ws.cell(row=1, column=2, value=42)   #B1单元格写入
ws.cell(1,3).value= 42   #C1单元格写入

# 新增一行数据
ws.append([1, 2, 3, 4])

2、写入公式

#写入公式
ws['B2'] = "=SUM(A2:A4)"
ws.cell(row=2, column=2, value = "=SUM(A2:A4)")
ws.cell(2,2).value = "=SUM(A2:A4)"

3、插入图片

img = Image('image') # image:要插入的图片
ws.add_image(img, 'B1') #在B1单元格插入图片

4、实例

from openpyxl import Workbook
from openpyxl.drawing.image import Image

wb = Workbook()
ws = wb.active

ws['A1'] = '图片' # 在A1单元格写入【图片】
ws.cell(row=2, column=2, value = "=1+2+3") #在B2单元格写入公式

img = Image('圣诞帽(1).png') # 要插入的图片名称
ws.add_image(img, 'B1')  #在B1单元格插入图片

#设置行宽列高以更好显示图片
ws.row_dimensions[1].height = 40
ws.column_dimensions['B'].width = 10

wb.save('实例.xlsx')

效果:

ccb7ce8357749bf9ab338029362a5bfb.png

05

设置单元格样式

单元格样式有:number_format(数据格式)、Font(字体)、Fill(填充)、Border(边框)、Alignment(对齐方式)、Protection(保护)。

1、数字格式

默认General,可设置的选项:

f8a47b13c7346585289e081c8be0636b.png

实例:

from openpyxl import Workbook
import datetime

wb = Workbook()
ws = wb.active

ws['A1'] = '文字'
print(ws['A1'].number_format)    #-->>> General

ws['A2'] = 5
print(ws['A2'].number_format)   #-->>> General

ws['A3'] = 0.05
ws['A3'].number_format='0.00%' # 自定义格式
print(ws['A3'].number_format)  # -->>> 0.00%

ws['B1'] = datetime.datetime.now()
print(ws['B1'].number_format)   # -->>> yyyy-mm-dd h:mm:ss

ws['B2'] = datetime.datetime.now()
ws['B2'].number_format='yyyy-mm-dd' # 自定义格式
print(ws['B2'].number_format)  #-->>>  yyyy-mm-dd 

wb.save("实例.xlsx")

效果:

3c3477ebda8b3b2c85a27d2af63e6b3e.png

2、字体

1)导入

# 导入Font
from openpyxl.styles import Font

2)参数说明

name           #字体
size           #字号,默认11。
bold           #是否加粗,默认False。加粗:True
italic         #是否斜体,默认False。斜体:True
vertAlign      #上下标,默认None。正常:baseline,上标:superscript,下标:subscript
color          #字体颜色,默认黑色(FF000000)。
strikethrough  #删除线,默认不设置。设置:True
underline      #下划线,默认不带下划线。单下划线:single,双下划线:double,会计用单下划线:singleAccounting,会计用双下划线:doubleAccounting

3)实例

from openpyxl import Workbook
from openpyxl.styles import Font

wb = Workbook()
ws = wb.active

ws['A1'] = '默认'      #A1单元格写入
ws['B2'] = '设置格式'  #B2单元格写入
ws['C3'] = '设置上标'  #C3单元格写入

#设置B2单元格字体格式
ws['B2'].font = Font(name='Calibri', size=12, color="00FF9900", italic=True, underline='double', strikethrough=True)

#设置C3单元格字体格式
ws['C3'].font = Font(vertAlign='superscript',  bold=True)

#保存
wb.save("实例.xlsx")

效果:

b01bc5f587054a185fb32514f86dbe4c.png

3、填充

1、纯色填充(PatternFill)

1)导入

#导入
from openpyxl.styles import PatternFill

2)参数说明

fill_type    #设置图案样式,如果不设置则不会显示颜色。
'''
fill_type可设置的值:solid(实心),lightHorizontal, 
darkTrellis, darkUp, darkGray, darkVertical, lightDown,
lightTrellis, lightUp, darkDown, darkHorizontal, mediumGray, 
lightVertical, gray0625, gray125, lightGrid, darkGrid, lightGray
'''
fgColor/start_color     #前景色 ,即填充色
bgColor/end_color      #背景色,即图案颜色

93ebfe0aef6db5633c51b5bff13c3578.png

3)实例

from openpyxl import Workbook
from openpyxl.styles import PatternFill

wb = Workbook()
ws = wb.active

ws['A1'] = '默认'    #A1单元格写入
ws['B2'] = '前景色'  #B2单元格写入
ws['C3'] = '背景色'  #C3单元格写入

#前景色,即填充色。也是我们一般设置的填充色
ws['B2'].fill = PatternFill(fill_type='solid', fgColor='00FF9900') 

#背景色,即图案颜色。
ws['C3'].fill = PatternFill(fill_type='solid', bgColor='00FF9900')  

wb.save("实例.xlsx")

效果:

c7a4ad01911183de6911ce0131f8586e.png

2、渐变填充(GradientFill)

1)导入

#导入
from openpyxl.styles import GradientFill

2)参数说明

type/fill_type  # 渐变填充类型:linear,path

'''
linear :
渐变在一组指定的 Stops 之间插入颜色,跨越一个区域的长度。默认情况下渐变是从左到右的,但可以使用 degree 属性修改此方向。可以改为提供颜色列表,它们之间的距离将相等。

path: 
渐变从区域的每个边缘应用线性渐变。属性 top、right、bottom、left 指定从各个边界填充的范围。比如top=”0.2” 将填充单元格的前 20%。
'''

3)实例

from openpyxl.styles import GradientFill
from openpyxl import Workbook

wb = Workbook()
ws = wb.active

# 合并单元格
ws.merge_cells('B2:F4')

#对合并单元格左上角单元格设置渐变填充
top_left_cell = ws['B2']
top_left_cell.fill = GradientFill(type='linear', degree=0, stop=('FFFFFF', '99ccff', '000000'))   #渐变填充

wb.save("实例.xlsx")

效果:

d71d5ca4f00d8dc74250e806fb8c6d9c.png

4、边框

设置边框样式时还需要通过Side。

1)导入

#导入
from openpyxl.styles import Border, Side

2)参数说明

# Border参数说明
left = Side(style , color)  #左边框设置
right = Side(style , color)  #右边框设置
top = Side(style , color)  #上边框设置
bottom = Side(style , color) #下边框设置

diagonalDown  #是否显示左上-右下对角线,显示:True
diagonalUp   #是否显示左下-右上对角线,显示:True
diagonal = Side(style , color)    #对角线边框设置,注意首先要设置显示对角线

#Side参数说明
style/border_style   #边框样式
'''
边框样式可设置的有:
thick, mediumDashDot, dashed, mediumDashDotDot, 
dashDot, slantDashDot, dotted, double, thin, 
hair, dashDotDot, mediumDashed, medium
'''
color  #边框颜色

1e24a8eb3c8db1e309c35f62fabd3e3d.png

3)实例

from openpyxl import Workbook
from openpyxl.styles import Border, Side

wb = Workbook()
ws = wb.active


ws['A1'] = '默认'   #A1单元格写入
ws['B2'] = '边框'   #B2单元格写入
ws['C3'] = '对角线'      #C3单元格写入

#边框线格式设置
line_format = Side(style='medium',color='00FF9900')

#B2单元格设置上下左右边框
ws['B2'].border = Border(left=line_format, right=line_format, top=line_format, bottom=line_format)

#C3单元格设置对角线
ws['C3'].border = Border(diagonalDown=True, diagonalUp=True, diagonal=line_format)

#保存
wb.save("实例.xlsx")

效果:

0de00f2cfc8b9d6177f0bda338468ce4.png

5、 对齐方式

1)导入

#导入
from openpyxl.styles import Alignment

2)参数说明

horizontal   # 水平对齐方式,默认常规general。还可设置:center, fill,left,distributed,right,centerContinuous,justify
vertical   # 垂直对齐方式,默认靠下bottom。还可设置:center,top,justify,distributed
text_rotation/textRotation    # 文字旋转,默认0°。可设置:-90-90°
wrap_text/wrapText  # 设置自动换行,默认不设置(False)。设置:True
shrinkToFit/shrink_to_fit  # 设置缩小字体填充,默认不设置(False)。设置:True
indent   # 缩进,默认0。
readingOrder  # 文字方向,默认为0。0:根据内容,1:总是从左向右,2:总是从右向左

3)实例

from openpyxl import Workbook
from openpyxl.styles import Alignment

wb = Workbook()
ws = wb.active

ws['A1'] = '默认'  #A1单元格写入
ws['B2'] = '居中并且换行'  #B2单元格写入
ws['C2'] = '靠上不换行'  #C3单元格写入

ws['B2'].alignment = Alignment(horizontal='center',vertical='center',wrap_text=True)
ws['C2'].alignment = Alignment(horizontal='center',vertical='top')

wb.save("实例.xlsx")

效果:

edad3fab457f232b50f580b7cd73dde9.png

6、保护

1、保护工作薄

防止其他用户查看隐藏的工作表,添加、移动或隐藏工作表以及重命名工作表,可以使用密码保护 Excel 工作簿的结构。

wb.security.lockStructure = True  #设置保护
wb.security.workbookPassword = '123' # 设置密码

2、保护工作表

可以不指定密码就启动工作表保护。

#启动工作表保护
ws.protection.sheet = True  
ws.protection.enable()

# 不启动工作表保护
ws.protection.sheet = False  
ws.protection.disable()

也可以指定密码:

ws.protection.password = '123'

3、设置保护格式

1)导入

#导入
from openpyxl.styles import Protection

2)参数说明

locked    # 是否设置锁定,默认True。其他项:False
hidden   # 是否设置隐藏,默认False。其他项:True

3)实例

注意:只有保护工作表后,锁定单元格或隐藏公式才有效。

5e32a15150f733f85fa821c2fc9ec88a.png

from openpyxl import Workbook
from openpyxl.styles import Protection

wb = Workbook()
ws = wb.active

ws.protection.sheet = True   # 启动工作表保护
ws.protection.password = '123' # 设置保护密码

ws['A1'] = '已保护'  # A1单元格写入
ws['C3'] = "=1+2+3"  # C3单元格写入

# 设置保护格式
protection = Protection(locked=True, hidden=True)
ws['C3'].protection = protection

wb.save("实例.xlsx")

效果:

114a007951813a4b03b4b1b4bf58c5ee.png

7、单元格样式

注意:单元格样式一旦指定,就无法更改。如果想要改变样式,需要重新指定。

1)设置合并单元格的样式

要想改变合并单元格的样式,也只需要改变合并区域左上角的单元格样式即可。

注意:如果先合并单元格,再设置样式,合并单元格的边框设置不完整。而如果是先设置样式再合并单元格,则没有问题。

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

wb = Workbook()
ws = wb.active

top_left_cell = ws['B2']  #选定单元格B2
top_left_cell.value = "设置样式"    #写入内容

# 设置格式
thin = Side(border_style="thin", color="000000")
double = Side(border_style="double", color="ff0000")
top_left_cell.border = Border(top=double, left=thin, right=thin, bottom=double)
top_left_cell.fill = PatternFill("solid", fgColor="DDDDDD")
top_left_cell.font = Font(b=True, color="FF0000")
top_left_cell.alignment = Alignment(horizontal="center", vertical="center")

ws.merge_cells('B2:F4') # 合并单元格

wb.save("实例.xlsx")

效果:

e02dc0ad85b2d0abeed56eeaa98d1d99.png

2)复制样式

from openpyxl.styles import Font
from copy import copy

ft1 = Font(name='Arial', size=14)
ft2 = copy(ft1)
ft2.name = "Tahoma"

print(ft1.name) #Arial
print(ft2.name) #Tahoma
print(ft2.size) #14.0

3)应用样式

我们上面的样式都是直接应用于单元格,比如:

ws['A1'].font = Font(size=12)

其实样式也可以应用于整行和整列,但整行整列应用后对已有的单元格数据并不会发生改变,只有在手动打开表格新增内容时才会改变。

from openpyxl import Workbook
from openpyxl.styles import Font

wb = Workbook()
ws = wb.active

ws['A1']= 12
ws['A2']= 12

col = ws.column_dimensions['A']
col.font = Font(bold=True)

row = ws.row_dimensions[1]
row.font = Font(underline="single")

wb.save("实例.xlsx")

我们可以发现写入的单元格并没有带格式。但是如果我们在A列新增数据,会加粗;在第1行新增的数据,会带下划线。

299b3d391a41d3156be2faed82f4ebf0.gif

4)命名样式

from openpyxl.styles import NamedStyle, Font, Border, Side
from openpyxl import Workbook

wb = Workbook()
ws = wb.active

# 创建命名样式
highlight = NamedStyle(name="highlight")
highlight.font = Font(bold=True, size=20)
bk = Side(style='thick', color="000000")
highlight.border = Border(left=bk, top=bk, right=bk, bottom=bk)

# 使用
wb.add_named_style(highlight)
ws['B2'] = 2
ws['D5'] = 5

ws['B2'].style = highlight
ws['D5'].style = 'highlight'

wb.save("实例.xlsx")

效果:

cc1143521d0610e61f0e7037bd90460a.png

06

其它

1、颜色设置

字体/填充/边框的颜色可以通过三种方式来设置: indexed, aRGB or theme。

一般建议用aRGB ,因为其他两种受excel限制。

1)aRGB颜色

from openpyxl.styles import Font
font = Font(color="00FF9900")

2)索引颜色、主题颜色

from openpyxl.styles.colors import Color
font = Font( color=Color(indexed=32))
font = Font(color= Color(theme=6, tint=0.5))

索引颜色:

caebdeae27d370dd6adc3e123d047028.png

2、列号的字母数字转换

from openpyxl.utils import get_column_letter, column_index_from_string

# 根据列的数字返回字母
print(get_column_letter(2))  # B

# 根据字母返回列的数字
print(column_index_from_string('D'))  # 4

好啦,基础的使用就讲解的差不多啦。进阶使用我们下期再见!

已经到底啦~(≧▽≦*)/~

bdba6b56e3f2250300a5a687cbb48688.png 往 期 推 荐 11651f2f3df1692db9f7f2d451c51328.png

年会将近?赶紧学学如何用Python做个抽奖界面

2022-01-02

929f0386059bbf090d7ee9ddd9818f4d.png

年会将近,如何用Excel做个抽奖界面?

2022-01-04

69055f3a41d5326a7d1f8b925b5af452.png

Python自动化办公:xlrd万字教程

2021-12-12

af2a2085abd96796ee89dc7a65a1d77c.png

Python自动化办公:xlwt教程(二)

2021-12-23

7190ccb4b2f01f641af87f27590a9721.png

d02174beff4d2e45d85ab8a1ca3edce4.gif

您的“点赞”、“在看”和 “分享”是我们产出的动力。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐