在进行word文档转pdf,想要连续批量转换多个文件时,run第一次报错如下:
pywintypes.com_error: (-2147417848, ‘被调用的对象已与其客户端断开连接。’, None, None)
接着run的报错为:
AttributeError: <unknown>.Open
代码如下:
from win32com.client import Dispatch
from os import walk
import win32com
def doc2pdf(input_file):
word = win32com.client.Dispatch('Word.Application')
doc = word.Documents.Open(input_file)
if file.endswith(".doc"): # word文件后缀名有.doc和.docx
doc.SaveAs(input_file.replace(".doc", ".pdf"), FileFormat=17)
elif file.endswith(".docx"):
doc.SaveAs(input_file.replace(".docx", ".pdf"), FileFormat=17)
doc.Close()
word.Quit()
if __name__ == "__main__":
directory = "C:\\Users\\86151\\Documents\\0_work document\\test" # 绝对路径
for root, dirs, filenames in walk(directory):
for file in filenames:
if file.endswith(".doc") or file.endswith(".docx"):
doc2pdf(str(root + "\\" + file))
报错原因:for循环中,上一个进程刚想执行word.Quit()时,下一个进程就已经开始执行到win32com.client.Dispatch(‘Word.Application’),前后矛盾,导致打开不了。
<unknown>说明程序不知道用什么打开,说明word软件这个资源仍然是处于占有状态。
解决办法1:让打开和关闭软件的命令只执行一次,即将Dispatch()和Quit()调到程序开始与结束处。
代码如下:
from win32com.client import Dispatch
from os import walk
import win32com
word = win32com.client.Dispatch('Word.Application')
def doc2pdf(input_file):
doc = word.Documents.Open(input_file)
if file.endswith(".doc"): # word文件后缀名有.doc和.docx
doc.SaveAs(input_file.replace(".doc", ".pdf"), FileFormat=17)
elif file.endswith(".docx"):
doc.SaveAs(input_file.replace(".docx", ".pdf"), FileFormat=17)
doc.Close()
if __name__ == "__main__":
directory = "C:\\Users\\86151\\Documents\\0_work document\\入党" # 绝对路径
for root, dirs, filenames in walk(directory):
for file in filenames:
if file.endswith(".doc") or file.endswith(".docx"):
doc2pdf(str(root + "\\" + file))
word.Quit()
解决方法2:使用time.sleep(),使得程序每执行完一次doc2pdf(),都强制等待几秒再执行下一次。
代码如下:
from win32com.client import Dispatch
from os import walk
import win32com
import time
def doc2pdf(input_file):
word = win32com.client.Dispatch('Word.Application')
doc = word.Documents.Open(input_file)
if file.endswith(".doc"): # word文件后缀名有.doc和.docx
doc.SaveAs(input_file.replace(".doc", ".pdf"), FileFormat=17)
elif file.endswith(".docx"):
doc.SaveAs(input_file.replace(".docx", ".pdf"), FileFormat=17)
doc.Close()
word.Quit()
time.sleep(5)
if __name__ == "__main__":
directory = "C:\\Users\\86151\\Documents\\0_work document\\test" # 绝对路径
for root, dirs, filenames in walk(directory):
for file in filenames:
if file.endswith(".doc") or file.endswith(".docx"):
doc2pdf(str(root + "\\" + file))
解决方法3:win32com.client.Dispatch() 改成 win32com.client.DispatchEx()
解释:Dispatch()是多线程,在执行时,会先检查有没有已经开了的word软件资源,如果有,就会直接用那个word软件资源,这样就导致了资源抢夺最终进程堵塞; 而DispatchEx()是独立线程,在执行时,无论当前有没有已经开了的word软件资源,它都会自己根据文档再开一次word软件,也就是说,上一个进程进行到哪里与它无关,所以不会出现资源抢夺的问题。