Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用Openpyxl迭代时的MemoryLoadError_Python_Error Handling_Out Of Memory_Openpyxl - Fatal编程技术网

Python 使用Openpyxl迭代时的MemoryLoadError

Python 使用Openpyxl迭代时的MemoryLoadError,python,error-handling,out-of-memory,openpyxl,Python,Error Handling,Out Of Memory,Openpyxl,当我遍历一系列.xlsm和.xlsx文件时,我试图将第一张工作表复制到存储工作簿中。然而,在大约30-40个文件之后,我开始专门从一些非常小的.xlsx文件中获取内存错误。我觉得单独打开excel文件应该不会太费力 我相信我正在保存和关闭必要的文件。但很明显我在某处的记忆超载了。有什么想法吗 import logging import os import openpyxl as xl from copy import copy from zipfile import BadZipFile #

当我遍历一系列
.xlsm
.xlsx
文件时,我试图将第一张工作表复制到存储工作簿中。然而,在大约30-40个文件之后,我开始专门从一些非常小的
.xlsx
文件中获取
内存错误。我觉得单独打开excel文件应该不会太费力

我相信我正在保存和关闭必要的文件。但很明显我在某处的记忆超载了。有什么想法吗

import logging
import os
import openpyxl as xl

from copy import copy
from zipfile import BadZipFile

# Create and configure logger
LOG_FORMAT = "%(levelname)s - %(message)s"
logging.basicConfig(filename="errors.log",
                    level=logging.INFO,
                    format = LOG_FORMAT,
                    filemode ='w')
logger = logging.getLogger()


def copy_paste_sheets(sheet_giv, sheet_rec, filename_giv='', filename_rec='', start_row=1, start_col=1, end_row=None, end_col=None, offset_row=0, offset_col=0):

    if end_row == None:
        end_row = sheet_giv.max_row
    if end_col == None:
        end_col = sheet_giv.max_column


    print(f"Copying and Pasting {filename_giv} {sheet_giv} to {filename_rec}{sheet_rec}...")
    for i in range(start_row, end_row + 1):
        for j in range(start_col, end_col + 1):

            giv_cell = sheet_giv.cell(row=i, column=j)            
            rec_cell = sheet_rec.cell(row=i+offset_row, column=j+offset_col, value=giv_cell.value)

            if giv_cell.has_style:
                rec_cell.font = copy(giv_cell.font)
                rec_cell.border = copy(giv_cell.border)
                rec_cell.fill = copy(giv_cell.fill)
                rec_cell.number_format = copy(giv_cell.number_format)
                rec_cell.protection = copy(giv_cell.protection)
                rec_cell.alignment = copy(giv_cell.alignment)


def main():
    directory = r'C:\path'

rec_wb = xl.Workbook()

    for n, filename in enumerate(os.listdir(directory)):
        if filename.endswith(".xlsx") or filename.endswith(".xlsm"):
            try:
                giv_wb = xl.load_workbook(filename=os.path.join(directory, filename))
                giv_ws = giv_wb.worksheets[0]

                rec_ws = rec_wb.create_sheet(str(n), -1)
                title_cell = rec_ws.cell(row=1, column=1)
                title_cell.value = filename
                copy_paste_sheets(giv_ws, rec_ws, filename_giv=filename, end_row=50, end_col=15, offset_row=1)


            except (BadZipFile, MemoryError) as e:
                if type(e) == MemoryError:
                    e = 'MemoryError'

                print(f'No: {n} - {filename} = {e}')
                logger.error(f'No: {n} - {filename} = {e}')
    
        giv_wb.close()

        elif not filename.endswith(".xlsx") or not filename.endswith(".xlsm"):
            logger.info(f'No: {n} - {filename} = Not xlsx or xlsm file')

        rec_wb.save("output.xlsx")
        rec_wb.close()
        rec_wb =  xl.load_workbook(filename="output.xlsx")

if __name__ == "__main__":
    main()

我可以通过将
gc.collect()
添加到循环的末尾来解决这个问题

giv\u wb.close()
应该位于
try
块的底部,在
copy\u paste\u sheets
下,不幸的是我最初是这样设置的。恐怕不行。我将它移出了条件,以确保它在每个循环中都被关闭,但这仍然并没有修复它,我也不知道为什么。我在循环的末尾添加了gc.collect(),这似乎基本上修复了它。但是它进入了第80个文件(n/79),它似乎暂停了很长时间,直到崩溃。最初是一个XMLSyntax错误造成的。但当我将该错误添加到异常中时,它仍然会崩溃。如果内存有问题,请使用只读模式,尽管您需要调整代码以处理样式。同时将用于处理的代码移出try/except块。在只读模式下是否可以合并样式?我现在将尝试将处理移出try/except块。这应该不是必需的。它也不能很好地工作。它更进一步了,但它仍然会因特别大的excel文件而崩溃。