pptx 批量操作幻灯片

本文示例使用python-pptx模块批量生成幻灯片,批量修改导入幻灯片表格内容及格式,以及在指定页插入表格

前言

一个prs对象就是一棵树,它的下面挂载了多张幻灯片slide,而每张幻灯片下有多个shape实例,也就是你在制作幻灯片时的一个个隐形框框。其基本的层次关系如下,而table仅是其shapes集合中的一个子类型。

Presentation -> slide_masters -> slide_layouts
Presentation -> slides -> shapes -> placeholders | note | text_frame ...

安装

pip install python-pptx
  • 依赖
  • Python 2.6, 2.7, 3.3, 3.4, or 3.6
  • lxml
  • Pillow
  • XlsxWriter (to use charting features)

概念

类或关联属性 简介 相关方法
Presentation  演示文稿构造对象 -
slide_masters  幻灯片母版(一个演示文件可以具有多个幻灯片母版) -
slide_layouts    幻灯片布局(属于母版而非prs) -
slides       幻灯片对象组,默认指向第一页                         add_slide
shapes  形状,类似于ps中的画布,每个shap(如table)相当于图层 add_shape
placeholders...     占位符,字典辅助类 -
  • 以下等价

    prs = Presentation()
    prs.slide_masters[0].slide_layouts[0]
    prs.slide_layouts[0]
  • 层次关系
    Presentation -> slide_masters -> slide_layouts
    Presentation -> slides -> shapes -> placeholders | note | text_frame ...

批量创建

无中生有,见码

from pptx import Presentation
from pptx.util import Inches

# 演示文稿根对象,使用默认母版
prs = Presentation()
# 幻灯片布局
title_only_slide_layout = prs.slide_layouts[5]
# prs.slide_masters 幻灯片母版

for i in range(0,5):
    # 1. 当前幻灯片对象
    slide = prs.slides.add_slide(title_only_slide_layout)

    # 2. 当前shapes(背景画布)对象
    shapes = slide.shapes
    shapes.title.text = 'Adding a Table pardon110'+str(i)

    # 3.配置位置尺寸参数
    rows = cols = 2
    left = top = Inches(2.0)
    width = Inches(6.0)
    height = Inches(0.8)

    # 4.在(画布)上添加表格图层(表格是shapes的一种类型)
    table = shapes.add_table(rows, cols, left, top, width, height).table

    # 5.table图层设置
    table.columns[0].width = Inches(2.0)
    table.columns[1].width = Inches(4.0)

    # 6. 表格标题填充
    table.cell(0, 0).text = 'Foo'
    table.cell(0, 1).text = 'Bar'

    # 7. 表格内容填充
    table.cell(1, 0).text = 'Baz'
    table.cell(1, 1).text = 'Qux'

    # # 添加多个表格
    # left = Inches(2.0)
    # top = Inches(6.0)
    # 当前画布上添加另一个表格
    # table = shapes.add_table(rows, cols, left, top, width, height).table
    # table.cell(0, 0).text = 'pardon110'

prs.save('test.pptx')

效果

用pttx模块批量创建幻灯片

定点修改

以上节生成的test.pptx为导入模板源,
修改第2和第4张幻灯片中第一个表格第二行一列的内容,变更原始列宽
并在对应幻灯片内后插入第二个表格,生成了新的修改后的版本change.pptx

from pptx import Presentation
from pptx.util import Inches
from pptx.enum.dml import MSO_THEME_COLOR

# 演示文稿根对象,选择指定模板
prs = Presentation("test.pptx")
# 幻灯片布局
title_only_slide_layout = prs.slide_layouts[5]
# prs.slide_masters 幻灯片母版

for i in range(len(prs.slides)):
    # 修改既有pptx,在第2,4页插入第二张表格,并将所在第一张表格二行一列数据进行修改
    if i not in [1,3]:
        continue
    # 1. 当前幻灯片对象
    slide = prs.slides[i]
    # 2. 当前shapes(背景画布)对象
    shapes = slide.shapes
    # 修改幻灯片主题内容
    shapes.title.text = 'update theme pardon110'+str(i)
    # 修改幻灯片主题背景
    fill = shapes[0].fill
    fill.solid()
    fill.fore_color.theme_color = MSO_THEME_COLOR.ACCENT_1
    fill.fore_color.brightness = -0.25

    # 3.配置位置尺寸参数
    rows = cols = 2
    left = Inches(2.0)
    top = Inches(6.0)
    width = Inches(6.0)
    height = Inches(0.8)

    # 4.在(画布)上增加第二个表格
    shape = shapes.add_table(rows, cols, left, top, width, height)
    table = shape.table

    # 5.table图层设置
    table.columns[0].width = Inches(2.0)
    table.columns[1].width = Inches(4.0)

    # write column headings
    table.cell(0, 0).text = 'name'
    table.cell(0, 1).text = 'action'

    # write body cells
    table.cell(1, 0).text = 'ppt'
    table.cell(1, 1).text = 'txt'

    # 断言当前幻灯片第二个shape是否为表格,则可访问第一个表格实例
    # 更改当前幻灯片第一个表格的第二行第一列内容,并更改其列宽
    # 基于同样的原理可以对指定模板的数据进行增删改查,背景填充,颜色,字体变更....
    if shapes[1].has_table:
        shapes[1].table.cell(1,0).text='pardon_00'+str(i+1)+'_slide'
        shapes[1].table.columns[0].width = Inches(3.0)

prs.save('change.pptx')

效果

生成后的效果快照如下
用 pttx 模块批量创建幻灯片

合理删除

python中的列表 list 是引用类型,同js数组一样。换而言之,若在引用对象列表中通过索引删除元素,则由于删除操作产生索引重建,会出现删除错位。幸运的是,官方标准库以提供了一个基于值删除的方法 remove,其函数签名如下

  remove(self, value, /)
      Remove first occurrence of value.
      Raises ValueError if the value is not present.

pptx官方并没提供一个显式的幻灯片删除接口,但查看slides 对象的源码,有私有属性_sldIdLst指向幻灯片元素集合。因此,删除幻灯片,实质删除幻灯片集合中的某个元素。只需要维护一个映射类型字典,页面指向幻灯片实例元素。然后通过值remove掉指定页码的实例元素即可,如下所示

prs = Presentation("change.pptx")
slist = prs.slides._sldIdLst
# 字典生成式
pages = {i : sld for i, sld in enumerate(prs.slides._sldIdLst }
# 用值删除第2,4 张幻灯片
slist.remove(pages[1])
slist.remove(pages[3])

prs.save("delete.pptx")

效果

pptx 批量操作幻灯片

同样的道理 ,若想在源幻灯片组中插入若干幻灯片,亦应考虑使用值插入。道理如同在列表中插值一样,每插入一个值,原有的列表变量指向的长度会重新发生变化 。用位标索引,被插入位后续元素的下标会因增删发生变化,而非指向源值。

关键

shapes 对象是一个集合类容器,可以数组的形式访问当前页下的多个shape实例,但对于特定shape,如表格,图表 ,艺术字,多媒体(音频)资源,需要先断言后转换具体类实例使用。

class GraphicFrame(BaseShape):
"""
Container shape for table, chart, smart art, and media objects.
Corresponds to a <p:graphicFrame> element in the shape tree.
"""

补充

官方提供的api,已经能够对pptx基本元素增改查。
更多功能请参阅 官方文档 https://python-pptx.readthedocs.io/en/late...

本作品采用《CC 协议》,转载必须注明作者和本文链接
pardon110
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!