用python-pptx创建ppt

  • Posted on
  • by

几年前,我曾经整理过一篇文章,用宏实现从Excel中复制图片自动生成PPT 。这个方法有点麻烦,几年过去,由于没有持续维护,现在这个工具基本用不了了。

最近,我又遇到了类似的问题,需要做一个有大量图片的PPT。考虑到我最近在温习python语言,就尝试查找python的解决方案。稍作查找,果然找到了现成的模块:python-pptx。

我需要做的PPT麻烦的地方在于,所分析的模型有两种工况,每种工况有39个模型,每个模型需要输出四种结果。如果每张图片插入一次,需要插入2294=232次,而文本框也要输入这么多次,定位繁琐是一方面,最担心的是出错。于是我尝试将这部分工作用python-pptx模块完成,其他的图表、标题部分由于工作量不大,就采用手工操作的办法。

为了实现这个功能,首先是安装python 3。这部分内容网上都有详细的介绍,此处不在赘述。

其次是安装python-pptx模块。我的工作环境比较特殊,同时需要使用windows和macOS系统。Windows系统使用的技术文档中的办法就可以了:

pip install python-pptx

在我的macOS系统上,由于同时安装了python 2.7(默认版本)和3.7版本,需要针对3.7版本安装模块。根据网上资料及我的测试,采用下面的命令就可以实现:

python3.7 -m pip install python-pptx

配置好这些环境,以下就是我的代码实现部分了。目前这部分代码实现的输入有39个case,每个case文件夹中有四张图片。输出是根据图片类型罗列各个工况的结果。每张PPT有六张图片,图片下方为文字说明。以下代码在windows和macOS系统环境下均已测试通过。

from pptx import Presentation
from pptx.util import Cm

# create presentation
prs = Presentation()

title_slide_layout = prs.slide_layouts[0]
slide = prs.slides.add_slide(title_slide_layout)
title = slide.shapes.title
subtitle = slide.placeholders[1]

# title
title.text = "PPT title"
subtitle.text = "Vincent [email protected]"

# create ppt with images
lst=["disp-full.png","disp-zoom.png","vonMises-full.png","vonMises-zoom.png"]
img_pos=[[1.19,4.96,4.16],[9.13,4.96,4.16],[17.06,4.96,4.16],[1.19,11.59,4.16],[9.13,11.59,4.16],[17.06,11.59,4.16]]
tx_pos=[[3.93,9.33,1.98,1.03],[11.88,9.33,1.98,1.03],[19.62,9.33,1.98,1.03],[3.92,16.44,1.98,1.03],[11.86,16.44,1.98,1.03],[19.6,16.44,1.98,1.03]]

for ipng in range(len(lst)):
    for i in range(39):
        ipos = i%6
        img_path = "case"+str(i+1)+"/"+lst[ipng]

        if ipos == 0:
            blank_slide_layout = prs.slide_layouts[6]
            slide = prs.slides.add_slide(blank_slide_layout)

        left =  Cm(img_pos[ipos][0])
        top = Cm(img_pos[ipos][1])
        height = Cm(img_pos[ipos][2])
        pic = slide.shapes.add_picture(img_path, left, top, height=height)

        txleft = Cm(tx_pos[ipos][0])
        txtop = Cm(tx_pos[ipos][1])
        txwidth = Cm(tx_pos[ipos][2])
        txheight = Cm(tx_pos[ipos][3])
        txBox = slide.shapes.add_textbox(txleft, txtop, txwidth, txheight)
        tf = txBox.text_frame
        tf.text = "case"+str(i+1)

prs.save("Report.pptx")