Openpyxl不会以只读模式

时间:2015-07-14 20:38:42

标签: python excel python-2.7 openpyxl

我希望能够在Python中读取Excel文件,在读取完成后保持Python脚本正在运行其他内容,并且能够在此期间在另一个进程中编辑Excel文件。我使用的是python 2.7和openpyxl。

目前它看起来像:

from openpyxl import load_workbook

def get_excel_data():
    OESwb = load_workbook(filename = OESconfigFile, data_only=True, 
                          read_only=True)
    ws = OESwb.get_sheet_by_name('MC01')
    aValue = ws['A1'].value
    return aValue

val = get_excel_data()

运行该功能后,Excel文件仍然被锁定以便从其他进程进行访问(它会显示错误"' filename'当前正在使用。稍后再试一次")甚至当我不想再用Python阅读它时。

如何从脚本中关闭文件?我已经尝试过OESwb.close(),但它会出现错误"'工作簿'对象没有属性' close'"。我发现this post但它似乎没有帮助。

编辑: 看起来OESwb.save(' filename.xlsx')有效,但只有在read_only = False时才有效。但是,能够关闭文件并仍然处于只读模式是理想的。看来这是openpyxl的一个错误,因为它应该在load_workbook完成后关闭文件。

8 个答案:

答案 0 :(得分:11)

wb._archive.close()

也可以使用use_iterator。

答案 1 :(得分:7)

出于一些严苛的原因,stackoverflow将允许我发布答案,但我没有足够的'代表'来评论或投票 - 所以我们在这里。

wb._archive.close()的接受答案对我不起作用。可能这是因为我使用的是只读模式。在“正常”模式下它可能正常工作。

bmiller的回答是唯一对我有用的答案:

with open(xlsx_filename, "rb") as f:
    in_mem_file = io.BytesIO(f.read())

wb = load_workbook(in_mem_file, read_only=True)

正如他所说,使用open()加载时, 更快,而只使用只读。

我的工作代码基于bmiller的回答:

import openpyxl
import io

xlsx_filename=r'C:/location/of/file.xlsx')
with open(xlsx_filename, "rb") as f:
    in_mem_file = io.BytesIO(f.read())

wb = openpyxl.load_workbook(in_mem_file, read_only=True)

答案 2 :(得分:6)

我已经尝试了所有这些解决方案,以只读模式关闭xlsx文件,似乎没有人完成这项工作。 我终于最终使用了一个内存文件:

with open(xlsx_filename, "rb") as f:
    in_mem_file = io.BytesIO(f.read())

wb = load_workbook(in_mem_file, read_only=True)

可能加载更快,无需担心关闭任何东西。

答案 3 :(得分:4)

有关最新信息,openpyxl 2.4.4+提供了Workbook.close()方法。以下是参考文献。

http://openpyxl.readthedocs.io/en/stable/changes.html?highlight=close#id86
https://bitbucket.org/openpyxl/openpyxl/issues/673

答案 4 :(得分:2)

我也发现这是一个问题,并且认为工作簿没有密切的方法很奇怪。

我提出的解决方案是一个上下文管理器,它为我“关闭”文件,这样每次我阅读电子表格时都没有在我的代码中放置无意义的保存。

@contextlib.contextmanager
def load_worksheet_with_close(filename, *args, **kwargs):
    '''
    Open an openpyxl worksheet and automatically close it when finished.
    '''
    wb = openpyxl.load_workbook(filename, *args, **kwargs)
    yield wb
    # Create path in temporary directory and write workbook there to force
    # it to close
    path = os.path.join(tempfile.gettempdir(), os.path.basename(filename))
    wb.save(path)
    os.remove(path)

使用它:

with load_worksheet_with_close('myworkbook.xlsx') as wb:
    # Do things with workbook

答案 5 :(得分:1)

要关闭,我相信你需要保存文件:

OESwb.save('filename.xlsx')

希望这会有所帮助。

答案 6 :(得分:1)

使用OESwb._archive.close() 这将关闭在'read_only=True'模式下保持打开的附加ZipFile文件句柄。 请注意,关闭后您无法从OESwb中读取更多数据。 请注意,这是一种解决方法,在将来的版本中可以删除_archive

答案 7 :(得分:0)

您可以尝试:

wb = None

释放资源,并在需要时再次加载,在相同或其他变量中。