Openpyxl 不会以只读模式关闭 Excel 工作簿

Openpyxl does not close Excel workbook in read only mode

我希望能够读取 Python 中的 Excel 文件,在读取完成后让 Python 脚本 运行ning 执行其他操作,并且能够同时在另一个进程中编辑 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() 但它给出了错误“'Workbook' 对象没有属性 'close'”。我找到了 this post,但似乎没有用。

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

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

OESwb.save('filename.xlsx')

希望这对您有所帮助。

我也发现了这个问题,觉得workbooks没有close方法很奇怪

我想出的解决方案是一个上下文管理器,它 "closes" 我的文件,这样我就不会在每次阅读电子表格时都在我的代码中进行无意义的保存。

@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
wb._archive.close()

与 use_iterator 合作。

你可以试试:

wb = None

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

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

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

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

wb = load_workbook(in_mem_file, read_only=True)

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

出于某些严酷的原因,Whosebug 将允许我 post 一个答案,但我没有足够的 'rep' 来评论或投票 - 所以我们在这里。

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

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)

为了您的最新信息,openpyxl 2.4.4+ 提供了Workbook.close() 方法。以下是参考资料。

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