【问题标题】:python3 and pywin32 closing excelpython3和pywin32关闭excel
【发布时间】:2017-07-27 02:57:34
【问题描述】:

我在使用 Dispatch 后关闭 excel 时遇到问题。

import openpyxl
import os 
from win32com import client



class CTAutomation:

    def __init__(self, file):
        self.invoice = xl.load_workbook(os.getcwd() + "\Templates\ctrates.xlsx")
        self.xlTemplate = xl.load_workbook(os.getcwd() + "\Templates\invoiceTemplate.xlsx")
        self.vpc = xl.load_workbook(os.getcwd() + "\Templates\Vpc.xlsx")
        self.file = file

    def invoice_make(self):
        self.xlApp = client.Dispatch("Excel.Application")
        self.xlbook = self.xlApp.Workbooks.Open(os.getcwd() + '\TestFiles\\' + self.file)
        self.ws = self.xlbook.Worksheets[0]
        self.ws.Visible = 1
        self.ws.ExportAsFixedFormat(0, os.getcwd() + "\complitedpdf\\" + self.file + ".pdf")
        self.quit()

    def quit(self):
        self.xlbook.Close()
        self.xlApp.Quit()

    def xlformater(self):
        return None

def main():
    pwd = os.listdir(os.getcwd() + "\TestFiles")
    for file in pwd:
        CTAutomation(file.strip(".xlsx")).invoice_make()

if __name__ == "__main__":
    main()

在这部分之前一切正常。我在论坛中找到了一些关于这个主题的帖子,但我觉得我仍然缺少一些东西来关闭应用程序, .xlsx and xls(Latest Versions) to pdf using python 在示例中

我们将不胜感激。

【问题讨论】:

  • 哦,我试过了,但它似乎不起作用......
  • 我没有看到任何尝试或尝试关闭任何对象。另外,您还提供了更大级别的 sn-p。如果没有足够的、可编译的reproducible example,很难提供帮助。
  • 添加了完整的类 - 运行这将导致无限循环
  • 我认为应该这样做。
  • 请包含所有import 行。目前尚不清楚load_workbook() 方法的来源或xl 引用的别名。发布的代码必须作为完全可编译的脚本独立存在。不要假设任何事情。设身处地为我们着想,确保示例可以自行运行。

标签: python python-3.x pywin32 win32com


【解决方案1】:

本质上是你的类对象在内存中持久存在。考虑使用with() 将进程包装在上下文管理器中。并在上下文中调用invoice_make()

此外,您的 Excel 方法不正确,使用方括号将工作簿索引为零。

最后,考虑使用os.path.join() 来避免反斜杠或正斜杠,并使用try/except 块来捕获COM 异常并从内存中正确释放对象。

import openpyxl as xl
import os 
from win32com import client

cwd = os.getcwd()

class CTAutomation:

    def __init__(self):
        self.invoice = xl.load_workbook(os.path.join(cwd, "Templates", "ctrates.xlsx"))
        self.xlTemplate = xl.load_workbook(os.path.join(cwd, "Templates", "invoiceTemplate.xlsx"))
        self.vpc = xl.load_workbook(os.path.join(cwd, "Templates", "Vpc.xlsx"))

    def invoice_make(self, file):
        try:
            self.xlApp = client.Dispatch("Excel.Application")
            self.xlbook = self.xlApp.Workbooks.Open(os.path.join(cwd, "TestFiles", file))
            self.ws = self.xlbook.Worksheets(1)       # USE PARENTHESES (NOT BRACKETS AND NON-ZERO INDEX)
            #self.ws.Visible = 1                      # KEEP PROCESS IN BACKGROUND
            self.ws.ExportAsFixedFormat(0, os.path.join(cwd, "complitedpdf", file.replace(".xlsx",".pdf")))
            self.xlbook.Close(False)
            self.xlApp.Quit()

        except Exception as e:
            print(e)

        finally:
            self.ws = None                            # RELEASE EXCEL OBJS FROM MEMORY
            self.xlbook = None
            self.xlApp = None

    def xlformater(self):
        return None

    def __enter__(self):
        return self                                   # BOUND TO as IN with()

    def __exit__(self, *err):
        return None

def main():
    pwd = os.listdir(os.path.join(cwd, "TestFiles"))   

    with CTAutomation() as obj:                       # CONTEXT MANAGER
        for file in pwd:
            print(file)
            obj.invoice_make(file)

if __name__ == "__main__":
    main()

【讨论】:

  • 感谢您的帮助,由于文件保存在“TestFiles”文件夹中,我做了一些细微的更改,我认为这是因为文件连同其完整路径一起传递,所以我剪切了完整的路径并为“xlbook”创建了一个显式路径,因此导出将只有文件名而没有完整路径。
  • 太棒了!乐意效劳。我在这里也学到了一些东西。啊!你是对的路径。是的,仅将文件名传递到方法中,并在内部使用 os.path.join() 连接路径。见编辑。
猜你喜欢
  • 2019-03-19
  • 1970-01-01
  • 2013-09-02
  • 2017-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多