Python Excel 删除行示例:按条件删除、删除空行等
如何使用 Python 在 Excel 中删除行?简单地说就是使用 openpyxl 库的 delete_rows() 函数一行代码搞定,但实际应用远没这么简单,实际情景中往往是要求按条件删除、批量删除空行等,找出要删除的行比删除这个动作要复杂得多。本文通过几个的示例,讲解几种使用 Python 删除 Excel 行的实用方法。
首先安装 openpyxl 库:
pip install openpyxl
一、删除指定行号的行(删除行基本操作)
Python 程序:
from openpyxl import load_workbook
# 设置文件名和工作表名,大小写敏感
file_path = '测试的文件.xlsx'
sheet_name = 'Sheet1'
# 要删除的行号
row_n = 5
# 加载 Excel 文件
workbook = load_workbook(file_path)
# 选择工作表
sheet = workbook[sheet_name]
# 删除行
sheet.delete_rows(row_n)
# 保存工作簿
workbook.save(file_path)
这段程序演示了如何删除指定行号的行,焦点在于 delete_rows() 函数,它的使用非常简单,只需把行号传给它即可。这段程序没有太多实用价值,因为我们一般不会只删除一行,事先一般也并不知道要删除的行号,否则我们自己手动去删除就行了,但这段程序是后面其它程序的基础,所以有必要拿出来说一下。
二、删除符合条件的行
Python 程序:
from openpyxl import load_workbook
# 在一列中查找并删除满足条件的行
# col_letter 为列号,wd 为搜索词,mode = 0 为模糊查找,mode = 1 为精确查找,start 为起始行
def delete_rows(file_path,sheet_name,col_letter,wd,mode=1,start=1):
# 加载 Excel 文件
workbook = load_workbook(file_path)
# 选择工作表
sheet = workbook[sheet_name]
i = sheet.max_row
while i >= start:
index = col_letter + str(i)
value = sheet[index].value
if (mode == 0 and str(wd) in str(value)) or (mode == 1 and wd == value):
print({index : value})
sheet.delete_rows(i)
workbook.save(file_path)
i -= 1
# 设置文件名和工作表名,大小写敏感
file_path = '测试的文件.xlsx'
sheet_name = 'Sheet1'
# 要查找的列的字母序号
col_letter = 'E'
# 要查找的内容
wd = '00'
# 起始行
start = 5
delete_rows(file_path,sheet_name,col_letter,wd,0,start)
在这段程序中,自定义了一个函数 delete_rows() (注意:这个函数和 sheet.delete_rows() 同名,但它们是两个不同函数),这个函数用于找出某一列中存在某个值的所有行,并将其全部删除。这个函数有5个参数,其中 col_letter 是要查找的列的字母序号,本例设置为“E”,表示将要在 E 列中查找;参数 wd 是要查找的内容,即搜索词、关键词;mode 表示搜索模式,mode = 0 表示模糊查找,即只要单元格的值包含搜索词就满足条件; mode = 1 表示精确查找,即单元格的值必须完全等于搜索词才算满足条件。
这个函数的重点在于 while 循环,我们将表格总行数 sheet.max_row 赋给循环变量 i,然后递减执行循环。为什么要用 while 循环而不是 for 循环?为什么要递减循环而不是递增循环?这是涉及到 Python 对 Excel 删除行的一个关键问题:每删除一行,后面的行号都会发生变化。由于 Python 语言的 for 循环是一种枚举循环,难以处理遍历对象数量动态变化的情况,所以用 while 更加简便。递增循环也不是不行,但会令程序变得复杂,后面有一个示例就用了递增循环,不过我建议还是使用递减循环。
col_letter + str(i) 将字母序号和行号组合成单元格坐标,形如“A5”。sheet[index].value 获得一个单元格的值,然后在 if 中判断是否符合条件,符合条件则删除之。
三、删除不符合条件的行
Python 程序:
from openpyxl import load_workbook
# 在一列中查找并删除不满足条件的行
# col_letter 为列号,wd 为搜索词,mode = 0 为模糊查找,mode = 1 为精确查找,start 为起始行
def delete_rows(file_path,sheet_name,col_letter,wd,mode=1,start=1):
# 加载 Excel 文件
workbook = load_workbook(file_path)
# 选择工作表
sheet = workbook[sheet_name]
i = sheet.max_row
while i >= start:
index = col_letter + str(i)
value = sheet[index].value
if (mode == 0 and str(wd) not in str(value)) or (mode == 1 and wd != value):
print({index : value})
sheet.delete_rows(i)
workbook.save(file_path)
i -= 1
# 设置文件名和工作表名,大小写敏感
file_path = '测试的文件.xlsx'
sheet_name = 'Sheet1'
# 要查找的列的字母序号
col_letter = 'E'
# 要查找的内容
wd = '00'
# 起始行
start = 5
delete_rows(file_path,sheet_name,col_letter,wd,0,start)
这段程序和前面那段程序很相似,主要区别在于 while 循环的 if 语句,in 改成 not in ,== 号改成 != 号。
如果这段程序不采用递减循环,而是采用递增循环,则第11至20行可改为:
i = start
count = sheet.max_row
while i <= count:
index = col_letter + str(i)
value = sheet[index].value
if (mode == 0 and str(wd) not in str(value)) or (mode == 1 and wd != value):
print({index : value})
sheet.delete_rows(i)
workbook.save(file_path)
count -= 1
else:
i += 1
这明显要复杂一些。
四、删除空行
Python 程序:
from openpyxl import load_workbook
# 删除空行,start 为起始行
def delete_empty_rows(file_path,sheet_name,start=1):
# 加载 Excel 文件
workbook = load_workbook(file_path)
# 选择工作表
sheet = workbook[sheet_name]
i = sheet.max_row
while i >= start:
flag = True
rows = sheet.iter_rows(min_row=i, max_row=i, min_col=1, max_col=sheet.max_column, values_only=True)
for row in rows:
for value in row:
if value != None:
flag = False
if flag:
print(i)
sheet.delete_rows(i)
workbook.save(file_path)
i -= 1
# 设置文件名和工作表名,大小写敏感
file_path = '测试的文件.xlsx'
sheet_name = 'Sheet1'
# 起始行
start = 5
delete_empty_rows(file_path,sheet_name,start)
在这段程序中,使用 sheet.iter_rows() 函数获取一行数据,其实这个函数是获取一个包含多行数据的对象,但我们用参数限定了它只包含一行,所以我们仍需要使用 for row in rows 将这行数据 row 从对象 rows 中读出来,理论上这个循环只会执行一次。如果某一行中存在一个单元格的 value 不为 None,则不是空行,否则将其删除。
五、要注意的问题
1、每删除一行数据,后面的数据的行号都会发生变化,所以最好使用倒序遍历(递减循环)。
2、对于“合并行”、“合并列”的情况会复杂得多,本文的程序没有考虑合并的情况。在实际应用中,建议使用行号限制避开存在合并格式的行和列,以免出现难以处理的BUG。