web技术

Python Excel 删除行示例:按条件删除、删除空行等

2023-10-19 18:33 作者:Admin原创

如何使用 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。

标签: #openpyxl
推荐文章
如何批量修改文件名?你可能在网上搜到了许多方法,但操作起来并不简单,有...
同事找我帮忙,让我帮他写一个Python程序,用来删除Excel中的重复行。于是我...
同事找我帮忙,希望能帮她写一个文件检测程序,运行程序就能快速找出被修改...
如何使用 Python 在 Excel 查找数据?如何实现模糊查找和精确查找?如何在一...
本文讲解如何使用Python在Excel工作表中添加列(追加一列)和插入列(在指定...
推荐专题
如何自己建网站?建网站难不难?其实建网站说难不难,说容易也并不容易,难...
本专题精心收集整理了多种HTML+CSS+JS轮播图实现方案,带详细代码和讲解,正...