2017-07-27 15 views
1

Dispatchを使用した後、問題を閉じることができません。python3とpywin32 closing 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の方法が正しくありませんでした。

最後に、aviodの前後のスラッシュに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

はい、まさに私がやったことですね。 –