如何强制python(使用win32com)创建新的Excel实例?

14 投票
2 回答
8519 浏览
提问于 2025-04-16 13:43

我正在自动化一些与Excel相关的任务,这些任务花费的时间很长。

我使用以下代码创建一个Excel实例:

excel = win32.gencache.EnsureDispatch('Excel.Application')
wb = excel.Workbooks.Add()

但是,当脚本开始运行后,如果我选择一个打开的Excel工作簿(不是Python正在处理的那个),Python脚本就会崩溃。不过,如果我打开一个新的Excel工作簿并在里面输入内容,Python脚本就不会受到影响。

有没有什么特别的方法可以调用Excel,以防止这种情况发生?或者有什么其他解决方案吗?

补充:这个方法似乎有效。

excel = win32.DispatchEx('Excel.Application')

2 个回答

0

你为什么不这样做呢?

from win32com import client
excel=client.Dispatch("Excel.Application")
9

这里有一种方法可以创建一个新的实例,并且使用静态缓存(这样会更快,并且可以使用关键字参数):

import sys
import shutil
import pythoncom
from win32com.client import gencache

def EnsureDispatchEx(clsid, new_instance=True):
    """Create a new COM instance and ensure cache is built,
       unset read-only gencache flag"""
    if new_instance:
        clsid = pythoncom.CoCreateInstanceEx(clsid, None, pythoncom.CLSCTX_SERVER,
                                             None, (pythoncom.IID_IDispatch,))[0]
    if gencache.is_readonly:
        #fix for "freezed" app: py2exe.org/index.cgi/UsingEnsureDispatch
        gencache.is_readonly = False
        gencache.Rebuild()
    try:
        return gencache.EnsureDispatch(clsid)
    except (KeyError, AttributeError):  # no attribute 'CLSIDToClassMap'
        # something went wrong, reset cache
        shutil.rmtree(gencache.GetGeneratePath())
        for i in [i for i in sys.modules if i.startswith("win32com.gen_py.")]:
            del sys.modules[i]
        return gencache.EnsureDispatch(clsid)

wdApp = EnsureDispatchEx("Word.Application")

更新:改进后的版本在出错时会重置缓存

撰写回答