如何使用openpyxl只加载和保存一次?我的程序多次加载和保存当前的excel文件,这导致它非常慢



我有一个程序,可以导入原始数据,对其进行解释,生成excel文件,并根据所解释的内容将信息写入多个工作表。

我从别人那里继承了这个程序。他们使用openpyxl编写程序,并且有几个函数可以加载和保存excel文件。这些函数在整个程序中被调用多次。原始数据文件越大,调用函数的次数就越多。这需要花费大量时间来运行程序。260kb的原始数据文件需要我的笔记本电脑处理2个多小时我很难让excel文件只保存一次,但这正是我希望实现的

以下是它最初是如何在先前开发人员编写的createExcel.py文件中编写的。所有这些函数都被main.py和其他.py文件多次调用。

(in createExcel.py)
def create_excel(file_name):
# create the shell/format of the sheets in the excel file 
# but does not write anything other than headers
wb = Workbook()
...# lots of code
wb.save(f'{file_name}.xlsx')

def insert_sheet_1_data(array):
# take data that was interpreted in another .py file and add
# the information to the relevant sheet in the excelfile
wb = load_workbook(f"{fileName}.xlsx")
...
wb.save(f'{file_name}.xlsx')
...
...
def insert_sheet_5_data(array):
# take data that was interpreted in another .py file and add
# the information to the relevant sheet in the excelfile
wb = load_workbook(f"{fileName}.xlsx")
...
wb.save(f'{file_name}.xlsx')

我尝试在createExcel.py中的函数之外声明wb=Workbook。然后删除了上面函数中的所有load_Workbook调用和wb.save调用。然后,我将createExcel导入到main.py文件中,并写了一行将wb文件保存为main.py中的最后一行代码:

(in createExcel.py)
wb = Workbook()
def create_excel(file_name):
# create the shell/format of the sheets in the excel file 
# but does not write anything other than headers

def insert_sheet_1_data(array):
# take data that was interpreted in another .py file and add
# the information to the relevant sheet in the excelfile
...
def insert_sheet_5_data(array):
# take data that was interpreted in another .py file and add
# the information to the relevant sheet in the excelfile
(in main.py)
import createExcel
...
#rest of the code
wb = createExcel.wb
wb.save(f'{file_name}'
# end

原始代码是有效的,但执行起来需要非常长的时间。新代码要快得多,通过调试模式,我看到它仍然可以执行所有与openpyxl相关的调用,但它从未在我的计算机上创建excel文件(我可以找到(,而且它在尝试保存不存在的文件时也不会出现任何错误,所以我不知道该怎么处理它。

如果能了解我在这里做错了什么,我们将不胜感激!非常感谢。

您提到每个KiB处理一个电子表格大约需要一分钟。这似乎非常非常高。肯定有一些相关的细节,原来的帖子没有提到。


你写了

# (in createExcel.py)
wb = Workbook()

这不是最佳实践;请不要那样做。一般来说,避免在import时间做耗时的工作尤其要避免";。save(("当时的副作用。最好将此类操作推迟到运行时,当函数已显式调用。


def create_excel(...)结束时,考虑附加

return wb

这样您就可以通过调用堆栈来传递结果而不是通过文件系统。


你也写过

# (in main.py)
import createExcel
...
# other things
wb = createExcel.wb
wb.save(f'{file_name}'

import很好,但获取了对createExcel.wb的引用不是——您不希望import花时间创建该对象。最好指定wb = createExcel.create_excel(...)。也就是说,推迟执行工作,直到调用方实际需要该对象。

考虑定义

def other_things(...):
...

因此,您可以在适当的时候调用它,而不是在import时间调用它。


此代码的总体主题是您希望避免做无用的重复工作。考虑以这种方式构建代码:

class MyWorkbook:
def __init__():
self.wb = Workbook()  # or even: self.wb = self.create_excel(...)

现在,所有各种方法都可以廉价地访问现有的self.wb属性根据需要添加纸张。最后,您可以.save()一次

最新更新