Python win32com.client.Dispatch 循环遍历 Word 文档并导出为 PDF;下一个循环发生时失败

标签 python pdf docx win32com comtypes

基于此处的脚本:.doc to pdf using python我有一个半工作脚本,用于将 .docx 文件从 C:\Export_to_pdf 导出到新文件夹中。

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

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

这显然是一条无用的一般错误消息。如果我使用 pdb 慢慢调试它,我可以遍历所有文件并成功导出。如果我还关注 Windows 任务管理器中的进程,我可以看到 WINWORD 启动然后结束,但在较大的文件上,内存使用量需要更长的时间才能稳定下来。这让我认为,当 WINWORD 在 client.Dispatch 对象上调用下一个方法之前没有时间初始化或退出时,脚本会出错。

有没有办法用 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 block 。注意将 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()

最佳答案

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

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,就好像你打开它们并且错误发生在你关闭它之前它不会关闭(因为它还没有到达那个命令)。

您可能还想考虑使用 DispatchEx 而不仅仅是 Dispatch。 DispatchEx 打开一个新实例(一个全新的 .exe),而我相信只使用 Dispatch 会尝试寻找一个打开的实例来锁定,但它的文档是模糊的。如果您实际上需要多个实例(即在一个文件中打开一个文件,在另一个文件中打开一个文件),请使用 DispatchEx。

至于等待,程序应该只在需要更多时间时在那条线上等待,但我不知道。

哦!如果你想看到实际打开的实例和文件,你也可以使用 word.Visible = True事情下来 ;-)).

关于Python win32com.client.Dispatch 循环遍历 Word 文档并导出为 PDF;下一个循环发生时失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16056793/

相关文章:

python - 将呈现的 pdf 文件保存到模型字段 Django

python - 声明 Pydantic 模型 "TypeError: ' 类型的对象不可迭代”

python - 排序和过滤列表

python - 在 Selenium 中关闭并打开新浏览器

html - 文本对齐 : justify; not working with wkhtmltopdf

pdf - OCSP 响应解析错误。 BER解码出错

python - 在raspberrypi中安装MySql并使用python3将数据放入表中

PDF 和 DOCX 魔数(Magic Number)

linux - 将 PDF/DOCX 转换为 mac iwork Pages(5.5.3) 格式

xpath - 如何从 C# 中的 word (docx) 文档中获取文本?