【问题标题】:Get name of active Excel workbook from Python从 Python 获取活动 Excel 工作簿的名称
【发布时间】:2011-02-22 00:50:58
【问题描述】:

我正在尝试编写一个 Python 脚本,该脚本将使用 Excel COM 接口访问和修改活动的 Excel 工作簿。但是,当有多个 Excel 实例正在运行时,我很难让它工作。比如代码

import win32com.client

xl = win32com.client.Dispatch("Excel.Application")
print(xl.ActiveWorkbook.FullName)

仅从第一个运行的 Excel 实例中打印出活动工作簿的名称。我真正想要的是我上次单击的工作簿,无论它位于哪个 Excel 实例中。

谢谢。

【问题讨论】:

  • 不是答案。您是否考虑过使用 xlrd、xlwt?在我看来,它比 win32com 更透明
  • 运行时您想要的 Excel 实例是否会成为当前活动窗口?
  • jaoquin - 这些模块不用于进程间通信,这正是我需要的。目标工作簿将打开,它需要实时响应 Python 程序发出的命令。 tgray - 对不起,我不确定我是否理解你的问题。基本上,我希望活动书成为我关注的最后一本工作簿。当我运行我的程序时,工作簿自然仍然是打开的。

标签: python com


【解决方案1】:

使用 xlwings,您可以轻松做到:

import xlwings as xw
print(xw.books.active.name)

即使您打开了多个 Excel 实例,这也能正常工作。

【讨论】:

    【解决方案2】:

    编辑评论

    可能有更好的方法来做到这一点。

    安装优秀的psutil

    import psutil
    excelPids = []
    for proc in psutil.process_iter():
      if proc.name == "EXCEL.EXE": excelPids.append(proc.pid)
    

    现在枚举窗口,但获取窗口标题和 pid。

    windowPidsAndTitle = []
    win32gui.EnumWindows(lambda hwnd, resultList: resultList.append((win32gui.GetWindowThreadProcessId(hwnd),win32gui.GetWindowText(hwnd))), windowPidsAndTitle)
    

    现在只需找到我们 excelPids 中的第一个 pid

      for pid,title in windowPidsAndTitle:
        if pid in excelPids:
          return title 
    

    结束编辑

    这里有很多事情需要考虑:

    一个实例是否打开了多个工作簿?在这种情况下

    xl = win32com.client.Dispatch("Excel.Application")
    xl.ActiveWorkbook.FullName
    

    确实会给你最后一个活动的工作簿。

    或者是否有单独的 EXCEL.EXE 实例正在运行? You can get each instance with:

    xl = win32com.client.GetObjec(None, "Excel.Application") #instance one
    xl = win32com.client.GetObject("Name_Of_Workbook") #instance two
    

    但这违背了目的,因为您需要知道名称,并且这不会告诉您最后一个焦点。

    对于上面的@tgrays 评论,如果您的 excel 实例保证是前台窗口,那么:

    import win32gui
    win32gui.GetWindowText(win32gui.GetForegroundWindow()) 
    #parse this and use GetObject to get your excel instance
    

    但最坏的情况,多个实例,你必须找到最后一个焦点,你必须枚举所有窗口并找到你关心的那个:

    windows = []
    win32gui.EnumWindows(lambda hwnd, resultList: resultList.append(win32gui.GetWindowText(hwnd)),windows)
    #enumerates all the windows open from the top down
    [i for i in windows if "Microsoft Excel" in i].pop(0)
    #this one is closest to the top
    

    祝你好运!

    【讨论】:

    • 非常感谢马克,这很有效。我只有一个问题。可能会返回标题中包含文本“Microsoft Excel”但不是 Excel 窗口的窗口。事实上,我之所以想到这一点,是因为我实际上打开了一个 PDF,其标题中有这些词。有没有办法检查我们返回的窗口实际上是对 Excel 应用程序的引用?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 2011-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-30
    相关资源
    最近更新 更多