openpyxl在修改.xlsx文件后发现修改无效的问题
临时要处理大量数据,用的是.xlsx的格式保存,因为xlrd、xlwt和xlutils对xlsx文件太不友好了,所以.xlsx格式的文件我一般都用openpyxl进行修改。
在修改后结束程序的过程中,我发现文件并没有被修改,后来发现是还要再使用save函数。在网上查找也没人有这个问题(可能是因为我太菜),就在此记录一下。
关于相关函数的具体操作,在其他的文章中有很详细的描写,故我在此不多作赘述。
- 在一开始要:
# 可能需要先安装
import openpyxl
- 然后创建一个workbook类型的对象:
# 这里是默认可读可写的,可手动调整为只读或者只写
wt_book=openpyxl.load_workbook("Origin_File.xlsx") # 相对路径或绝对路径
- 接着获取工作表:
# 这里的active是获取打开文件时所显示的那一张表格,一般是第一张表
sheet=wt_book.active
- 在获取了工作表之后,就可以对该表的内容进行修改,修改完成之后需要保存:
# 在这里填写的文件,若存在则覆盖,若不存在则创建
wt_book.save("Final_File.xlsx") # 相对路径或绝对路径
这样应该就能够得到修改之后的文件:Final_File.xlsx
下面是我在对一个几千行的Excel文件进行数据处理时,用来删除.xlsx文件中无用数据过多的行时(即". ."过多)的代码:
在这个Origin_File.xlsx文件中,每相邻的两行为一项数据,故删除时要一起删,在记录要删除的行数时,只需要记录其中一行的行数即可.
# 要把xlrd返回到1.2.0版本才行,最新版本不支持xlsx文件,只支持xls文件
# 现在发现xlrd、xlwt和xlutils对xlsx文件太不友好了,所以换成openpyxl
# 之前删除操作之后发现没反应,后来发现是还要用save函数来保存
# 在遍历的时候,如果删除某一行,遍历还是会往下一位,则会跳过本来应该读取的下一行而去读取下下行
import openpyxl
# 用来筛选出不符合要求的行
def rewrite(wt_book):
# 记录要删除的行数
keep_rows=list()
# 用来验证是否删除成功
delete_num = 0
# 获取打开时显示的工作表的表名
sheet=wt_book.active
# 获取原表的行数
origin_rows=sheet.max_row
print(sheet,'\n')
# 记录现在遍历到了第几行
row_count=0
# 对每一行进行遍历,注意在删除操作时,row还是会往下走,即会跳过一次
# 每一行都生成了一个元组,每个元组的元素为每个单元格的元素
for row in sheet.rows:
# 删除是从第1行开始,没有第0行
row_count+=1
# 计算空值的数目
count=0
for val in row:
# 删掉数据有缺的那一行,并不检查BM列
if val.value==".." and val.column_letter!="BM":
count+=1
break
# 改变这个判断条件即可删除不同要求的行数
if count>0:
# 保存要删除的行数
# 避免同时保存要删除的同一组的两行
if len(keep_rows)!=0 and keep_rows[-1]+1==row_count and row_count%2==1:
continue
keep_rows.append(row_count)
# 进行删除操作
for num in keep_rows:
# 奇数
if num%2==1:
sheet.delete_rows(num-1-delete_num)
print("Delete ", num-1, "......")
sheet.delete_rows(num-1-delete_num)
print("Delete ", num, "......")
delete_num += 2
# 偶数
else:
sheet.delete_rows(num-delete_num)
print("Delete ", num, "......")
sheet.delete_rows(num - delete_num)
print("Delete ", num+1, "......")
delete_num += 2
# 创建一个新文件来保存修改之后的文件
# 这里可以填写相对路径
wt_book.save("Final_File.xlsx")
# 打开修改之后的文件并查询行数
# 可填写相对路径
final_book=openpyxl.load_workbook("Final_File.xlsx")
final_sheet=final_book.active
# 修改后的行数
final_sheet_rows=final_sheet.max_row
# 验证是否修改成功
if origin_rows==final_sheet_rows+delete_num:
print("Success to delete",'\n',"Delete ",delete_num," rows in total")
else:
print("Fail to delete")
if __name__=="__main__":
# 获取一个Workbook对象,这里文件默认装备为可读可写
# 填写文件名,带上文件格式
# 可填写相对路径
wt_book = openpyxl.load_workbook("Origin_File.xlsx")
rewrite(wt_book)
print("Complete")