如果你有一堆 PPT 要做,他们的格式是一样的,只是填充的内容不一样,那你就可以使用 Python 来减轻你的负担。

PPT 分为内容和格式,用 Python 操作 PPT,就是利用 Python 对 PPT 的内容进行获取和填充,修改 PPT 的格式并不是 Python 的强项。因此,当你有一堆 PPT 要做的时候,先做好一个带格式的 PPT,然后用 Python 复制这个 PPT 文件,然后再对其进行读写。

本文介绍如何使用 python 操作 PPT,用到的模块就是 python-pptx,以下的示例基本满足日常需求,如果要知道更多,可以访问 python-pptx 的官方文档。

python-pptx 模块的安装

  1. pip install python-pptx

读取 PPT

假如文件「测试.pptx」的内容如下:

玩转 PPT - 图1

那么以下代码可以读取其内容:

  1. from pptx import Presentation
  2. prs = Presentation("测试.pptx")
  3. for index, slide in enumerate(prs.slides):
  4. print(f"第 {index+1} 页")
  5. for shape in slide.shapes:
  6. if shape.has_text_frame:
  7. text_frame = shape.text_frame
  8. # print(text_frame.text)
  9. # 如果分段读就用下面的代码
  10. for paragraph in text_frame.paragraphs:
  11. print(paragraph.text)

执行结果如下所示:

玩转 PPT - 图2

写入 PPT

先来个简单点的。

假如要生成如下图所示的 PPT 页

玩转 PPT - 图3

代码可以这样写:

  1. from pptx import Presentation
  2. prs = Presentation()
  3. title_slide_layout = prs.slide_layouts[0]
  4. slide = prs.slides.add_slide(title_slide_layout)
  5. title = slide.shapes.title
  6. subtitle = slide.placeholders[1]
  7. title.text = "Hello, World!"
  8. subtitle.text = "python-pptx was here!"
  9. prs.save('test.pptx')

添加一张幻灯片

幻灯片都有板式,同样的,pptx 提供了 9 种版式让我们选择,分别是:

  1. Title (presentation title slide)
  2. Title and Content
  3. Section Header (sometimes called Segue)
  4. Two Content (side by side bullet textboxes)
  5. Comparison (same but additional title for each side by side content box)
  6. Title Only
  7. Blank
  8. Content with Caption
  9. Picture with Caption

分别对应 PPT 的如下版式,我已经用数据一一标出:

玩转 PPT - 图4

比如现在要添加一张标题和内容的版式,就可以这样写代码:

  1. from pptx import Presentation
  2. prs = Presentation()
  3. SLD_LAYOUT_TITLE_AND_CONTENT = 1 ##标题和内容版式的序号
  4. slide_layout = prs.slide_layouts[SLD_LAYOUT_TITLE_AND_CONTENT]
  5. slide = prs.slides.add_slide(slide_layout)

为幻灯片添加内容

添加内容之前先理解一下形状。从技术上讲,可以在幻灯片上放置 9 种类型的形状:

  1. 形状 - 带有填充和轮廓的自动形状
  2. 文本框 - 没有填充和轮廓的自动形状
  3. 占位符 - 可以出现在幻灯片布局或母版上的自动形状,并在使用该布局的幻灯片上继承,允许添加采用占位符格式的内容
  4. 线路/连接器
  5. 图片
  6. 表格 - 行和列的东西
  7. 图表 – 饼图、折线图等。
  8. 智能艺术 - 尚不支持,但如果存在则保留
  9. 媒体剪辑——视频或音频

每一个幻灯片都有由一个形状树来组织,之所以称为树,是因为它在一般情况下是分层的;形状树中的节点可以是一个组形状,它本身可以包含形状并具有与形状树相同的语义。对于大多数用途,形状树具有列表语义。

获取幻灯片中的形状:

  1. shapes = slide.shapes

自动形状是规则形状。正方形、圆形、三角形、星星之类的。有 182 种不同的形状可供选择。其中 120 个具有调整“手柄”,您可以使用它来改变形状。

许多形状类型共享一组公共属性。我们将在此处介绍其中的许多形状,因为其中一些形状只是 AutoShape 的一种特殊形式。

添加自动形状

以下代码添加一个圆角矩形形状,一英寸见方,并放置在距幻灯片左上角一英寸处:

  1. from pptx.enum.shapes import MSO_SHAPE
  2. from pptx.util import Inches
  3. shapes = slide.shapes
  4. left = top = width = height = Inches(1.0)
  5. shape = shapes.add_shape(
  6. MSO_SHAPE.ROUNDED_RECTANGLE, left, top, width, height
  7. )
  8. prs.save('新建幻灯片.pptx')

有关所有 182 种自动形状类型的列表,具体请参阅官方文档 MSO_AUTO_SHAPE_TYPE 枚举项。

占位符

占位符也是一种形状,有 18 种类型的占位符。标题、中心标题、副标题、正文,内容,图片,剪贴画,图表、表格、智能艺术,日期、页脚、幻灯片编号,媒体剪辑,标题,垂直正文、垂直对象、垂直标题。

幻灯片上的占位符可以为空或已填充。这在图片占位符中最为明显。未填充时,占位符会显示可自定义的提示文本。内容丰富的占位符在为空时也会显示一个或多个内容插入按钮。

纯文本占位符在输入文本的第一个字符时进入“填充”模式,并在删除文本的最后一个字符时返回“未填充”模式。内容丰富的占位符在插入图片等内容时进入填充模式,并在删除该内容时返回未填充模式。为了删除填充的占位符,形状必须被删除两次。第一次删除删除内容并将占位符恢复到未填充模式。额外的删除将删除占位符本身。可以通过重新应用布局来恢复已删除的占位符。

访问占位符

  1. >>> prs = Presentation()
  2. >>> slide = prs.slides.add_slide(prs.slide_layouts[8])
  3. >>> for shape in slide.placeholders:
  4. ... print('%d %s' % (shape.placeholder_format.idx, shape.name))
  5. ...
  6. 0 Title 1
  7. 1 Picture Placeholder 2
  8. 2 Text Placeholder 3

如果已经知道占位符的索引,也可通过索引来访问:

  1. >>> slide.placeholders[1]
  2. <pptx.parts.slide.PicturePlaceholder object at 0x10d094590>
  3. >>> slide.placeholders[2].name
  4. 'Text Placeholder 3'

将内容插入占位符

>>> prs = Presentation()
>>> slide = prs.slides.add_slide(prs.slide_layouts[8])
>>> placeholder = slide.placeholders[1]  # idx key, not position
>>> placeholder.name
'Picture Placeholder 2'
>>> placeholder.placeholder_format.type
PICTURE (18)
>>> picture = placeholder.insert_picture('my-image.png')

如果要插入表格:

from pptx import Presentation
from pptx.util import Inches

prs = Presentation()
title_only_slide_layout = prs.slide_layouts[5]
slide = prs.slides.add_slide(title_only_slide_layout)
shapes = slide.shapes

shapes.title.text = 'Adding a Table'

rows = cols = 2
left = top = Inches(2.0)
width = Inches(6.0)
height = Inches(0.8)

table = shapes.add_table(rows, cols, left, top, width, height).table

# set column widths
table.columns[0].width = Inches(2.0)
table.columns[1].width = Inches(4.0)

# write column headings
table.cell(0, 0).text = 'Foo'
table.cell(0, 1).text = 'Bar'

# write body cells
table.cell(1, 0).text = 'Baz'
table.cell(1, 1).text = 'Qux'

prs.save('write_ppt_table.pptx')

如果要插入图表:

from pptx import Presentation
from pptx.chart.data import CategoryChartData
from pptx.enum.chart import XL_CHART_TYPE
from pptx.util import Inches

# create presentation with 1 slide ------
prs = Presentation()
slide = prs.slides.add_slide(prs.slide_layouts[5])

# define chart data ---------------------
chart_data = CategoryChartData()
chart_data.categories = ['East', 'West', 'Midwest']
chart_data.add_series('Series 1', (19.2, 21.4, 16.7))

# add chart to slide --------------------
x, y, cx, cy = Inches(2), Inches(2), Inches(6), Inches(4.5)
slide.shapes.add_chart(
    XL_CHART_TYPE.COLUMN_CLUSTERED, x, y, cx, cy, chart_data
)

prs.save('write_ppt_chart.pptx')

PPT 转 Pdf

以下方法仅适用于 windows

def PPTtoPDF2(inputFileName, outputFileName, formatType = 32):
    import comtypes.client
    powerpoint = comtypes.client.CreateObject("Powerpoint.Application")
    powerpoint.Visible = 1

    if outputFileName[-3:] != 'pdf':
        outputFileName = outputFileName + ".pdf"
    deck = powerpoint.Presentations.Open(inputFileName)
    deck.SaveAs(outputFileName, formatType) # formatType = 32 for ppt to pdf
    deck.Close()
    powerpoint.Quit()

最后的话

本文抛砖引玉,更多复杂的 PPT 操作,请移步至文末的官方文档。另外,Python 自动化办公系列的文章会同步到个人博客 https://somenzz.cn 上,保持更新,欢迎收藏。

参考文档:

https://python-pptx.readthedocs.io/en/latest/user/quickstart.html