openpyxl在修改.xlsx文件后发现修改无效的问题

这篇博客记录了在使用openpyxl库处理.xlsx文件时遇到的问题及解决方案。作者在尝试修改文件后发现修改无效,原因是忘记调用save()函数保存更改。文中详细介绍了如何加载工作簿、获取工作表、修改内容以及保存文件的步骤,并提供了一个删除含有过多特定数据行的示例代码。最后,强调了保存修改的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

openpyxl在修改.xlsx文件后发现修改无效的问题

临时要处理大量数据,用的是.xlsx的格式保存,因为xlrd、xlwt和xlutils对xlsx文件太不友好了,所以.xlsx格式的文件我一般都用openpyxl进行修改。

在修改后结束程序的过程中,我发现文件并没有被修改,后来发现是还要再使用save函数。在网上查找也没人有这个问题(可能是因为我太菜),就在此记录一下。

关于相关函数的具体操作,在其他的文章中有很详细的描写,故我在此不多作赘述。

  1. 在一开始要:
# 可能需要先安装
import openpyxl
  1. 然后创建一个workbook类型的对象:
# 这里是默认可读可写的,可手动调整为只读或者只写
wt_book=openpyxl.load_workbook("Origin_File.xlsx") # 相对路径或绝对路径
  1. 接着获取工作表:
# 这里的active是获取打开文件时所显示的那一张表格,一般是第一张表
sheet=wt_book.active
  1. 在获取了工作表之后,就可以对该表的内容进行修改,修改完成之后需要保存:
# 在这里填写的文件,若存在则覆盖,若不存在则创建
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")

import os import pandas as pd from openpyxl import load_workbook from openpyxl.utils.dataframe import dataframe_to_rows # 指定要合并的文件夹路径 folder_path = r"E:\aaaa\aaaa" fields_to_write = ['aaaa', 'aaaa'] # 获取文件夹中所有的 xlsx 文件路径 xlsx_files = [os.path.join(folder_path, f) for f in os.listdir(folder_path) if f.endswith('.xlsx')] # 创建一个空的 DataFrame 用于存储合并后的数据 merged_data = pd.DataFrame() # 循环读取每个 xlsx 文件,将它们合并到 merged_data 中 for xlsx_file in xlsx_files: # 使用 pandas 读取 xlsx 文件,并清理无效字符引用 wb = load_workbook(filename=xlsx_file, read_only=False, data_only=True, keep_vba=False, keep_links=False, keep_protection=False) for sheet_name in wb.sheetnames: ws = wb[sheet_name] for row in ws.rows: for cell in row: cell.value = cell.value if cell.value is None else str(cell.value).strip() df = pd.read_excel(wb) # 将读取到的数据追加到 merged_data 中 merged_data = merged_data.append(df, ignore_index=True) # 在 merged_data 中添加新的一列数据 merged_data['new_column'] = 'new_value' # 创建一个新的工作簿 wb_new = load_workbook(write_only=True) ws_new = wb_new.create_sheet('merged_data') # 将 DataFrame 中的数据逐行写入到新的工作簿中 rows = dataframe_to_rows(merged_data[fields_to_write + ['new_column']], index=False) for row in rows: ws_new.append(row) # 保存合并后的数据到新的 xlsx 文件中 wb_new.save(r"E:\aaaa\aaaa\merged_file.xlsx")使用此代码会出现ValueError: Invalid file path or buffer object type: <class 'openpyxl.workbook.workbook.Workbook'>的报错,请优化下
06-09
import os from PIL import Image from openpyxl import Workbook from openpyxl.drawing.image import Image as ExcelImage # 创建Excel文件 wb = Workbook() ws = wb.active # 设置单元格宽度和高度 ws.column_dimensions['A'].width = 10 ws.row_dimensions[1].height = 100 # 图片文件夹路径 folder_path = r"D:\迅雷下载\新建文件夹\01-柱状图\新建文件夹\新建文件夹\music" # 逐个处理文件夹下的图片文件 for i, filename in enumerate(os.listdir(folder_path)): if filename.endswith(".jpg") or filename.endswith(".png"): # 可以根据需要修改图片格式 image_path = os.path.join(folder_path, filename) # 调整图片大小为单元格大小 img = Image.open(image_path) img.thumbnail((100, 100)) # 修改为单元格大小,这里假设单元格大小为100x100 # 将图片保存到Excel文件中 excel_img = ExcelImage(img) ws.add_image(excel_img, f"A{i + 1}") # 每处理100张图片保存一次Excel文件 if (i + 1) % 100 == 0: wb.save("aaa.xlsx") # 保存最终的Excel文件 wb.save("aaa.xlsx")显示Traceback (most recent call last): File "D:\python+pycharm\venv\rrr.py", line 35, in <module> wb.save("aaa.xlsx") File "C:\Users\78776\AppData\Roaming\Python\Python39\site-packages\openpyxl\workbook\workbook.py", line 386, in save save_workbook(self, filename) File "C:\Users\78776\AppData\Roaming\Python\Python39\site-packages\openpyxl\writer\excel.py", line 294, in save_workbook writer.save() File "C:\Users\78776\AppData\Roaming\Python\Python39\site-packages\openpyxl\writer\excel.py", line 275, in save self.write_data() File "C:\Users\78776\AppData\Roaming\Python\Python39\site-packages\openpyxl\writer\excel.py", line 79, in write_data self._write_images() File "C:\Users\78776\AppData\Roaming\Python\Python39\site-packages\openpyxl\writer\excel.py", line 116, in _write_images self._archive.writestr(img.path[1:], img._data()) File "C:\Users\78776\AppData\Roaming\Python\Python39\site-packages\openpyxl\drawing\image.py", line 51, in _data img.fp.seek(0) AttributeError: 'NoneType' object has no attribute 'seek' Process finished with exit code 1
07-16
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值