3

ここのスクリプトに基づいて: Python を使用した .doc to pdf .docx ファイルを C:\Export_to_pdf から新しいフォルダーにエクスポートするための半作業スクリプトがあります。

問題は、最初の 2 つのドキュメントを通過した後、次のエラーで失敗することです。

(-2147352567, 'Exception occurred.', (0, u'Microsoft Word', u'Command failed', u'wdmain11.chm', 36966, -2146824090), None)

これは明らかに役に立たない一般的なエラー メッセージです。pdb を使用してゆっくりとデバッグすると、すべてのファイルをループして正常にエクスポートできます。また、Windows タスク マネージャーでプロセスを監視すると、WINWORD が開始され、想定どおりに終了することがわかりますが、ファイルが大きいほど、メモリ使用量が安定するまでに時間がかかります。これは、client.Dispatch オブジェクトで次のメソッドが呼び出される前に WINWORD が初期化または終了する時間がない場合に、スクリプトがトリップしていると思わせます。

win32com または comtypes を使用して、プロセスの開始または終了を識別して待機する方法はありますか?

私のスクリプト:

import os
from win32com import client

folder = "C:\\Export_to_pdf"
file_type = 'docx'
out_folder = folder + "\\PDF"

os.chdir(folder)

if not os.path.exists(out_folder):
    print 'Creating output folder...'
    os.makedirs(out_folder)
    print out_folder, 'created.'
else:
    print out_folder, 'already exists.\n'

for files in os.listdir("."):
    if files.endswith(".docx"):
        print files

print '\n\n'

try:
    for files in os.listdir("."):
        if files.endswith(".docx"):
            out_name = files.replace(file_type, r"pdf")
            in_file = os.path.abspath(folder + "\\" + files)
            out_file = os.path.abspath(out_folder + "\\" + out_name)
            word = client.Dispatch("Word.Application")
            doc = word.Documents.Open(in_file)
            print 'Exporting', out_file
            doc.SaveAs(out_file, FileFormat=17)
            doc.Close()
            word.Quit()
except Exception, e:
    print e

作業コード - try ブロックをこれに置き換えただけです。DispatchEx ステートメントを for ループの外に移動し、word.Quit() を finally ステートメントに移動して、確実に閉じるようにしました。

try:
    word = client.DispatchEx("Word.Application")
    for files in os.listdir("."):
        if files.endswith(".docx") or files.endswith('doc'):
            out_name = files.replace(file_type, r"pdf")
            in_file = os.path.abspath(folder + "\\" + files)
            out_file = os.path.abspath(out_folder + "\\" + out_name)
            doc = word.Documents.Open(in_file)
            print 'Exporting', out_file
            doc.SaveAs(out_file, FileFormat=17)
            doc.Close()
except Exception, e:
    print e
finally:
    word.Quit()
4

1 に答える 1

7

これは問題ではないかもしれませんが、個別の単語インスタンスをディスパッチし、各反復内でそれを閉じる必要はなく、これがストランド メモリの問題の原因である可能性があります。インスタンスを 1 回開くだけで、そのインスタンス内で必要なすべてのドキュメントを開いたり閉じたりできます。次のように:

try:
    word = client.DispatchEx("Word.Application") # Using DispatchEx for an entirely new Word instance
    word.Visible = True # Added this in here so you can see what I'm talking about with the movement of the dispatch and Quit lines. 
    for files in os.listdir("."):
        if files.endswith(".docx"):
            out_name = files.replace(file_type, r"pdf")
            in_file = os.path.abspath(folder + "\\" + files)
            out_file = os.path.abspath(out_folder + "\\" + out_name)
            doc = word.Documents.Open(in_file)
            print 'Exporting', out_file
            doc.SaveAs(out_file, FileFormat=17)
            doc.Close()

    word.Quit()

except Exception, e:

注: win32com インスタンスとファイルを開くときは、try/except の使用に注意してください。それらを開くと、閉じる前にエラーが発生し、閉じることができません (そのコマンドにまだ達していないため)。

また、Dispatch だけでなく、DispatchEx の使用を検討することもできます。DispatchEx は新しいインスタンス (まったく新しい .exe) を開きますが、Dispatch を使用するだけでラッチする開いているインスタンスを探してみると思いますが、これに関するドキュメントはあいまいです。実際に複数のインスタンスが必要な場合は DispatchEx を使用します (つまり、1 つのファイルを 1 つのファイルで開き、別のファイルで 1 つのファイルを開きます)。

待機に関しては、プログラムはさらに時間が必要なときにその行で待機する必要がありますが、わかりません。

おー!また、インスタンスとファイルが実際に開いていることを確認したい場合にも使用word.Visible = Trueできます (問題を視覚的に確認するのに役立つ場合がありますが、問題が確実に遅くなるため、修正されたらオフにします ;-) )。

于 2013-05-14T19:53:10.530 に答える