我们如何使用不同的win32com实例创建多个PDF文件?

问题描述 投票:1回答:1

我一直在尝试使用DispatchEx创建多个pdf文件,但是当我尝试测试我的代码时,它仅创建第一个pdf文件,而所有其他请求均因奇怪的错误而失败。我在做什么错,和/或如何有效地同时处理多个客户端调用,以生成他们请求的各自的pdf文件?

这是我的代码的一部分:

            rundate = "Quote_{:%d%m%Y_%H%M%S%f}".format(datetime.now())
            pythoncom.CoInitialize()
            FILENAME = "D:/packages/abc.pptx"
            APPLICATION = win32com.client.DispatchEx("PowerPoint.Application")
            APPLICATION.Visible = True
            path_ppt = shutil.copy(FILENAME, "D:/{0}.pptx".format(rundate))
            PRESENTATION = APPLICATION.Presentations.Open(path_ppt)
            Slide1 = PRESENTATION.Slides(1)
            Shape1 = Slide1.Shapes(1)
            print(Shape1.AlternativeText)
            for shape in Slide1.Shapes:
                if shape.AlternativeText:
                    print(shape.AlternativeText)
                if shape.HasTextFrame:
                    shape.TextFrame.TextRange.Replace(FindWhat="#abc",ReplaceWhat="THAILAND", WholeWords=False)
                if shape.AlternativeText == "1":
                    shape.Fill.UserPicture("D:/1.jpg")
                if shape.AlternativeText == "2":
                    shape.Fill.UserPicture("D:/2.jpg")
                if shape.AlternativeText == "3":
                    shape.Fill.UserPicture("D:/3.jpg")
            PATH_TO_PDF = "{0}{1}{2}".format(r'd:/',rundate,'.pdf')
            PRESENTATION.SaveAs(PATH_TO_PDF, 32)
            APPLICATION.Quit()
            PRESENTATION.Close()
            PRESENTATION =  None
            APPLICATION = None
            os.remove(path_ppt)

PS-代码成功创建了与发送给它的请求一样多的ppt副本(使用shutil),但是当在短时间间隔内发出多个请求(例如shape.AlternativeText找不到,对象不存在等)时,win32com会出错。 。

python win32com pythoncom
1个回答
0
投票

您可以通过在单独的过程中运行此代码来解决APPLICATION退出问题。 (忽略同时调用时使用硬编码文件名的风险)。

在项目包中创建另一个模块

powerpointer.py

import shutil
import sys
import subprocess as subp

def do_powerpoint(filename):
   """run external copy of self to do powerpoint stuff"""
   # sys.executable is the python.exe you are using, __file__ is the
   # path to this module's source and filename you pass in
   return subp.call([sys.executable, __file__, filename])

def _do_powerpoint(filename):
    rundate = "Quote_{:%d%m%Y_%H%M%S%f}".format(datetime.now())
    pythoncom.CoInitialize()
    APPLICATION = win32com.client.DispatchEx("PowerPoint.Application")
    APPLICATION.Visible = True # I think False is better so you dont see it pop up
    path_ppt = shutil.copy(filename, "D:/{0}.pptx".format(rundate))
    PRESENTATION = APPLICATION.Presentations.Open(path_ppt)
    Slide1 = PRESENTATION.Slides(1)
    Shape1 = Slide1.Shapes(1)
    print(Shape1.AlternativeText)
    for shape in Slide1.Shapes:
        if shape.AlternativeText:
            print(shape.AlternativeText)
        if shape.HasTextFrame:
            shape.TextFrame.TextRange.Replace(FindWhat="#abc",ReplaceWhat="THAILAND", WholeWords=False)
        if shape.AlternativeText == "1":
            shape.Fill.UserPicture("D:/1.jpg")
        if shape.AlternativeText == "2":
            shape.Fill.UserPicture("D:/2.jpg")
        if shape.AlternativeText == "3":
            shape.Fill.UserPicture("D:/3.jpg")
    PATH_TO_PDF = "{0}{1}{2}".format(r'd:/',rundate,'.pdf')
    PRESENTATION.SaveAs(PATH_TO_PDF, 32)
    PRESENTATION.Close()
    APPLICATION.Quit()
    os.remove(path_ppt)

if __name__ == "__main__":
    _do_powerpoint(sys.argv[1]) # will raise error if no parameters

现在,在主代码中,输入import powerpointer并根据需要调用powerpointer.do_powerpoint(filename)。它将作为脚本运行其自己的模块,并且在该实例中您将只有1个应用程序对象。

© www.soinside.com 2019 - 2024. All rights reserved.