python word.documents.open报错,Python win32com.client.Dispatch在Word文档中循环并导出为PDF;下一个循环发生时失败...

Based on the script here: .doc to pdf using python I've got a semi-working script to export .docx files to pdf from C:\Export_to_pdf into a new folder.

The problem is that it gets through the first couple of documents and then fails with:

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

This, apparently is an unhelpful general error message. If I debug slowly it using pdb, I can loop through all files and export successfully. If I also keep an eye on the processes in Windows Task Manager I can see that WINWORD starts then ends when it is supposed to, but on the larger files it takes longer for the memory usage to stablise. This makes me think that the script is tripping up when WINWORD doesn't have time to initialize or quit before the next method is called on the client.Dispatch object.

Is there a way with win32com or comtypes to identify and wait for a process to start or finish?

My script:

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

The working code - just replaced the try block with this. Note moved the DispatchEx statement outside the for loop and the word.Quit() to a finally statement to ensure it closes.

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

解决方案

The might not be the problem but dispatching a separate word instance and then closing it within each iteration is not necessary and may be the cause of the strand memory problem you are seeing. You only need to open the instance once and within that instance you can open and close all the documents you need. Like the following:

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:

Note: Be careful using try/except when opening win32com instances and files as if you open them and the error occurs before you close it it won't close (as it has not reached that command yet).

Also you may want to consider using DispatchEx instead of just Dispatch. DispatchEx opens a new instance (an entirely new .exe) whereas I believe just using Dispatch will try and look for an open instance to latch onto but the documentation of this is foggy. Use DispatchEx if in fact you want more than one instance (i.e open one file in one and one file in another).

As for waiting, the program should just wait on that line when more time is needed but I dunno.

Oh! also you can use word.Visible = True if you want to be able to see the instance and files actually open (might be useful to visually see the problem but turn it of when fixed because it will def slow things down ;-) ).

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值