【问题标题】:'[Errno 13]' Permission denied: Openpyxl and win32com conflict'[Errno 13]' 权限被拒绝:Openpyxl 和 win32com 冲突
【发布时间】:2019-08-21 16:30:33
【问题描述】:

我正在使用 win32com 在 excel 中运行宏,并使用 openpyxl 来修改单元格值。在调试过程中,我尝试创建现有代码的简化版本,但仍然遇到相同的情况

[Errno 13] Permission denied:'C:\\Users\\NAME\\Desktop\\old\\Book1.xlsx'. 

我认为该错误是由打开同一个文件的两个包(win32com 和 openpyxl)引起的,并且在尝试保存/关闭时,无法关闭在另一个包中打开的实例。 当我在使用 win32com 保存/关闭之前尝试使用 openpyxl 保存/关闭时,我遇到了权限被拒绝错误。这是有道理的; Openpyxl 可能没有权限关闭通过 win32com 打开的 excel 实例。代码如下:

wb.save(r"C:\Users\NAME\Desktop\old\Book1.xlsx")
xel.Workbooks(1).Close(SaveChanges=True)

但是,当我切换顺序时:

xel.Workbooks(1).Close(SaveChanges=True)
wb.save(r"C:\Users\NAME\Desktop\old\Book1.xlsx")

Excel 尝试保存备份文件(随机命名为“522FED10”或“35C0ED10”等),当我按下保存时,Excel 崩溃。

解决方法是什么?我在想您可以使用 win32com 运行宏,以不同的文件名保存,然后使用 openpyxl 访问该文件并编辑值。但是,这是非常低效的(我正在处理具有数十万行数据的 excel 文件)。我可以考虑只使用 win32com,但这需要对系统进行改造。

简单代码:

import openpyxl as xl
import win32com.client

xel=win32com.client.Dispatch("Excel.Application")
xel.Workbooks.Open(Filename=r"C:\Users\NAME\Desktop\old\Book1.xlsx")
wb = xl.load_workbook(r"C:\Users\NAME\Desktop\old\Book1.xlsx")
ws = wb.active
xel.visible = False
xel.Cells(1,1).Value = 'Hello Excel'
ws.cell(row = 1,column = 2).value = "test"
xel.Workbooks(1).Close(SaveChanges=True)
wb.save(r"C:\Users\NAME\Desktop\old\Book1.xlsx")

【问题讨论】:

  • Windows 确实强制执行文件锁定,这就是您看到此内容的原因。另一种方法是简单地使用 xlwings。

标签: python excel permissions openpyxl win32com


【解决方案1】:

当前问题

您绝对应该不混合使用 win32com 和 openpyxl 操作。

win32com 语句xel.Workbooks.Open() 将工作簿内容加载到由 Excel 进程控制的内存空间中。另一方面,openpyxl xl.load_workbook() 语句将工作簿内容加载到由 Python 进程控制的完全独立的内存空间中。

因此,任何后续的 win32com 命令都不会影响位于 python 进程控制的内存中的工作簿,反之亦然,任何 openpxyl 命令都不会影响位于 Excel 进程控制的内存中的工作簿。

解决方案

您提到您必须运行一些 excel 宏。这排除了仅限 openpyxl 的解决方案。我的建议是使用 xlwings,它本质上是一个强大且用户友好的 win32com API 包装器。

以下是一个简单示例,说明如何在单个 Python 脚本中执行 Excel 宏并手动更新单元格值:

import xlwings as xw

# Start Excel app (invisibly in the background)
app = xw.App(visible=False)

# Load excel file into active Excel app
book = app.books.open(r"Book1.xlsm")

# Instruct Excel to execute the pre-existing excel macro named "CleanUpMacro"
book.macro("CleanUpMacro")()

# Instruct Excel to write a cell value in the first sheet
book.sheets["Sheet1"].range('A1').value = 42

# Save workbook and terminate Excel application
book.save()
book.close()
app.kill()

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2017-04-20
  • 2011-06-11
  • 2014-07-15
  • 2015-07-17
  • 2016-07-25
  • 2013-06-12
  • 2016-05-07
  • 2013-05-02
相关资源
最近更新 更多