Python win32com.client.调度循环通过Word文档和导出到PDF;发生下一个循环时失败



基于这里的脚本:使用python。doc到pdf,我有一个半工作脚本,将。docx文件从C:Export_to_pdf导出到pdf到一个新文件夹。

问题是它通过了前两个文档,然后失败了:

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

这显然是一个无用的通用错误消息。如果我使用pdb缓慢地调试它,我可以遍历所有文件并成功导出。如果我还密切关注Windows任务管理器中的进程,我可以看到WINWORD在应该启动的时候启动,然后结束,但是对于较大的文件,它需要更长的时间来稳定内存使用。这让我认为,脚本绊倒时,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 'nn'
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块。Note将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()

这可能不是问题,但分派一个单独的word实例,然后在每次迭代中关闭它是不必要的,这可能是您所看到的链内存问题的原因。您只需要打开实例一次,并且在该实例中可以打开和关闭所需的所有文档。例如:

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:

注意:要小心使用try/,除非打开win32com实例和文件,如果你打开它们,错误发生在你关闭它之前,它不会关闭(因为它还没有到达那个命令)。

你也可以考虑使用DispatchEx而不是仅仅使用Dispatch。DispatchEx打开一个新实例(一个全新的。exe),而我相信仅仅使用Dispatch就会尝试寻找一个开放的实例来锁定,但这方面的文档是模糊的。如果你想要多个实例(即在一个实例中打开一个文件,在另一个实例中打开一个文件),请使用DispatchEx。

至于等待,当需要更多时间时,程序应该在那一行等待,但我不知道。

哦!你也可以使用word.Visible = True,如果你想能够看到实例和文件实际打开(可能是有用的,直观地看到问题,但把它修复后,因为它会减慢事情;-))。

最新更新