2017-07-27 70 views
1

我在使用Dispatch後遇到了關閉excel的問題。python3和pywin32關閉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示例

一些建議將不勝感激。

+0

哦,我都試過了,但它似乎並沒有工作... –

+1

我看沒有試用或嘗試這裏關閉任何對象。另外,你給出了一個更大的班級片段。如果沒有足夠的,可編譯的[可重現的示例](https://stackoverflow.com/help/mcve),很難提供幫助。 – Parfait

+0

添加完整的類 - 運行這將導致無限循環 –

回答

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() 
+0

感謝您的幫助,我將文件保存在「TestFiles」文件夾中做了輕微的修改,並且我假定它發生是因爲文件傳遞的是完整路徑,所以我刪除了完整路徑併爲「 xlbook「,所以導出只有文件名沒有完整的路徑。 –

+0

太棒了!樂意效勞。我在這裏學到了一些東西。啊!你是對的路徑。是傳遞文件名到方法中,並用'os.path.join()'連接路徑。請參閱編輯。 – Parfait

+1

是的,這正是我所做的,太棒了! –