12

最全总结 | 聊聊 Python 办公自动化之 PPT(中)

 3 years ago
source link: http://www.cnblogs.com/xingag/p/14225091.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

QJRNne.jpg!mobile

1. 前言

上一篇文章简单地介绍了 PPT 的文档结构,并使用 python-pptx 这个依赖库完成对 PPT 文档最基本的操作

最全总结 | 聊聊 Python 办公自动化之 PPT(上)

作为 PPT 系列篇第 2 篇文章,将覆盖下列内容

  • 表格 Table

  • 图片 Image,包含静态图片、Gif 动态图片

  • 视频 Video

2. 表格 Table

实例化一个幻灯片 Slide 对象后,就可以使用下面的方法插入一个表格

方法:slide.shapes.add_table(rows,cols,left,top,width,height)

参数分别是:

  • rows  表格行数

  • cols  表格列数

  • left  左边距

  • top  上边距

  • width  表格宽度

  • height  表格高度

返回值类型是:pptx.shapes.graphfrm.GraphicFrame

它的 table 属性即为一个表格对象:pptx.table.Table

def insert_table(slide, rows, cols, left, top, width, height, unit=Cm):
    """
    幻灯片中插入一个表格
    :param unit: 默认单位为厘米
    :param slide: 幻灯片对象
    :param rows: 行数
    :param cols: 列数
    :param left: 左边距
    :param top: 上边距
    :param width: 宽度
    :param height: 高度
    :return:
    """
    # 插入一个表格
    table = slide.shapes.add_table(rows, cols, unit(left), unit(top), unit(width), unit(height))

    # 返回表格对象
    return table.table

# 1.创建一个幻灯片 Slide 对象(空白样式)
slide = add_slide(self.presentation, 6)

# 2.插入一个表格
# 参数分别为:幻灯片对象、行数、列数、左边距、上边距、宽度、高度
table = insert_table(slide, 3, 3, 3, 5, 13.6, 5)

2-1  如何重新设置表的行高、列宽?

为了生成表格的美观性,对表的行高、列宽进行调整很有必要

其中,表格对象的 columns、rows 属性分别用于获取所有的列对象、行对象

def set_table_column_width(table, column_index, width, unit=Cm):
    """
    设置表格某一列的宽度
    :param table:
    :param column_index:
    :param width:
    :param unit: 单位默认为厘米
    :return:
    """
    table.columns[column_index].width = unit(width)


def set_table_row_height(table, row_index, height, unit=Cm):
    """
    设置表格某一行的高度
    :param table:
    :param row_index:
    :param height:
    :param unit:
    :return:
    """
    table.rows[row_index].height = unit(height)

# 3.重新设置表的宽度、高度
# 3.1 分别设置第1-3行列宽
set_table_column_width(table, 0, 5)
set_table_column_width(table, 1, 5)
set_table_column_width(table, 2, 5)

# 3.2 分别设置行高
set_table_row_height(table, 0, 1.5)
set_table_row_height(table, 1, 1.2)
set_table_row_height(table, 2, 1.2)

2-2  设置单元格数据

首先,通过行索引、列索引获取对应的单元格对象

# 获取某一个单元格对象
# 注意:索引从0开始
# 比如:获取第一行、第一列的单元格对象
cell = table.cell(0,0)

接着,指定单元格对象的 text 属性值为指定的内容即可

# 设置单元格的值
cell.text = "单元格显示的内容"

这样,我们定义一组数据,就可以按照插入到表格中了

# 4.设置表格数据
datas = [
    ["学员", "姓名", "年龄"],
    ["", "星安果", 23],
    ["", "AirPython", 18]]

# 遍历设置数据到单元格中
for row_index in range(len(table.rows)):
    for column_index in range(len(table.columns)):
        # 获取单元格对象
        cell_temp = table.cell(row_index, column_index)

        # 设置数据
        cell_temp.text = str(datas[row_index][column_index])

2-3  单元格样式调整

调整单元格的样式包含下面 3 步

  • 获取单元格文本对象

  • 拿到文本对象的段落对象

  • 通过段落,指定段落对齐方式及文字的样式

以设置第一行单元格文字加粗、居中显示为例

# 5、设置第一行表头单元格文字加粗居中显示
for column_index in range(len(table.columns)):
    # 1、单元格对象
    cell = table.cell(0, column_index)
    # 2、文本控件的段落
    paragraph = cell.text_frame.paragraphs[0]
    # 3、设置段落样式
    set_parg_font_style(paragraph, font_name='微软雅黑', font_size=23, font_color=[255, 0, 0],
                        font_bold=True)

需要指出的是,单元格中的文本控件除了使用默认的段落,也可以添加新的段落,设置不同的内容及样式

2-4  单元格背景颜色

上一篇文章设置文本框 TextBox 背景的方法同样适用于单元格

def set_widget_bg(widget, bg_rgb_color=None):
    """
    设置【文本框textbox/单元格/形状】的背景颜色
    :param widget:文本框textbox、单元格、形状
    :param bg_rgb_color:背景颜色值
    :return:
    """
    if bg_rgb_color and len(bg_rgb_color) == 3:
        # 1、将形状填充类型设置为纯色
        widget.fill.solid()
        # 2、设置文本框的背景颜色
        widget.fill.fore_color.rgb = RGBColor(bg_rgb_color[0], bg_rgb_color[1], bg_rgb_color[2])

# 设置单元格背景颜色
set_widget_bg(cell, [204, 217, 225])

2-5  合并单元格

语法如下:

# 合并单元格
开始单元格.merge(结束单元格)

以合并单元格并居中显示为例

from pptx.enum.text import MSO_VERTICAL_ANCHOR, MSO_ANCHOR

def set_cell_center(cell):
    """
    设置单元格文字居中显示
    :param cell:
    :return:
    """
    paragraph = cell.text_frame.paragraphs[0]
    paragraph.alignment = PP_ALIGN.CENTER
    cell.vertical_anchor = MSO_ANCHOR.MIDDLE

# 6、单元格合并
# 合并单元格并居中显示
table.cell(1, 0).merge(table.cell(2, 0))
table.cell(1,0).text="合并"
set_cell_center(table.cell(1,0))

经过上面一系列操作,最后在幻灯片中生成的表格如下:

biEnqeN.png!mobile

3. 图片 Image

无论是静态图片,或者是 GIF 动态图片,插入到幻灯片的方式一样

方法:slide.shapes.add_picture(imge_file,left,top,width,height)

参数分别为:

  • image_file  图片路径

  • left  左边距

  • top  上边距

  • width  图片显示宽度

  • height  图片显示高度

def insert_image(slide, pic_path, left, top, width=None, height=None, unit=Inches):
    """
    幻灯片中加入图片(包含静态图片和动态图片)
    :param unit: 单位默认为Inches
    :param pic_path: 文件路径
    :param slide: 幻灯片对象
    :param left: 左边距
    :param top:  上边距
    :param width: 宽度
    :param height: 高度
    :return:
    """
    # 注意:如果width、height都为None时,以图片原始大小展示
    width = unit(width) if width else None
    height = unit(height) if height else None

    pic_obj = slide.shapes.add_picture(image_file=pic_path,
                                       left=unit(left),
                                       top=unit(top),
                                       width=width,
                                       height=height)
    return pic_obj
​
def image_manage(self):
    """
    图片管理
    :return:
    """
    # 插入一张静态图片
    slide = add_slide(self.presentation, 6)

    # 图片路径
    image_path = './1.jpeg'

    # 插入本地图片
    insert_image(slide, image_path, 6, 6, unit=Cm)

需要指出的是,当 width、height 不显式指定,默认值为 None,则按照图片真实大小去显示,当图片很大时,可能会出现展示不全的情况

zyM7fmi.png!mobile

因此,在实际项目中,我们只需要先获取图片的宽高比,然后等比例设置到宽度和高度参数中即可

from PIL import Image

def get_image_aspect_ratio(image_path):
    """
    获取图片的宽高比
    :param image_path:
    :return:
    """
    img = Image.open(image_path)

    # 图片类型:GIF
    image_format = img.format

    # 图片宽、高
    width, height = img.size

    # 图片宽高比
    aspect_ratio = width / height

    return aspect_ratio

# 获取宽、高比
aspect_ratio = get_image_aspect_ratio(image_path)

# 等比例插入图片到PPT中
insert_image(slide, image_path, 6, 6, 6, 6 / aspect_ratio, unit=Cm)

4. 视频 Video

往 PPT 文档中插入视频的方法如下

slide.shapes.add_movie(video_path,left,top,width,height,poster_frame_image)

参数分别为:

  • video_path  视频路径

  • left  左边距

  • top  上边距

  • width  视频显示宽度

  • height  视频显示高度

  • poster_frame_image  视频封面图路径

4-1  获取视频宽高比

为了保证视频在 PPT 中显示完全,我们需要先获取视频的宽、高比

推荐安装 moviepy 依赖库,获取视频的基本信息

# 安装依赖
pip3 install moviepy

接着,构造一个 VideoFileClip 对象,从中获取视频的宽度、高度

from moviepy.editor import VideoFileClip

def get_video_aspect_ratio_and_thumbnail_path(video_path, frame_index):
    """
    获取图片的宽、高比
    :param video_path: 视频路径
    :param frame_index 帧索引
    :return:
    """
    clip = VideoFileClip(video_path)

    # 视频的宽度、高度
    width, height = clip.size

    # 获取宽、高比
    aspect_ratio = width / height

4-2  获取视频帧

视频封面图,我们可以从视频中筛选中一帧,保存到本地

def get_video_frame(clip, frame_index):
    """
    获取视频的某一帧图片
    :param clip:
    :param frame_index:
    :return:
    """
    # 帧数目
    frame_count = math.floor(clip.fps * clip.duration)
    # print('视频帧数目:', frame_count)

    # 保证参数输入有效
    if frame_index < 0 or frame_index > frame_count:
        frame_index = 1

    # 视频所有的帧
    frames = clip.iter_frames()
    # clip.get_frame()

    # 定义输出图片路径
    thumbnail_path = "{}/temp/{}.jpg".format(os.path.abspath(os.path.dirname(__file__)), random_str(10))

    # 遍历,找到对应的帧,保存到本地
    for index, frame in enumerate(frames):
        if frame_index == index:
            # 保持帧图片到本地
            im = Image.fromarray(frame)
            im.save(thumbnail_path)
            break

    return thumbnail_path

4-3  插入视频

最后,将插入视频的操作进行一次封装,传入视频封面图、左边距、上边距、显示宽度,即可以完成视频的插入动作

def insert_video(self):
    """
    插入视频
    :return:
    """
    slide = add_slide(self.presentation, 6)

    video_path = './1.mp4'

    # 获取图片宽高比,并保存一个临时的缩略图到本地
    aspect_ratio, thumbnail_path = get_video_aspect_ratio_and_thumbnail_path(video_path, 120)

    # 将视频插入到PPT中
    insert_video(slide, video_path, thumbnail_path, 3, 3, 4, 4 / aspect_ratio)

# 将视频插入到PPT中
insert_video(slide, video_path, thumbnail_path, 3, 3, 4, 4 / aspect_ratio)

5. 最后

本篇文章讲到了 PPT 文档中关于表格、图片、视频这 3 种常见内容的操作

我已经将全部源码上传到后台,关注公众号「 AirPython 」,后台回复「  ppt 」即可获得全部源码

如果你觉得文章还不错,请大家 点赞、分享、留言 下,因为这将是我持续输出更多优质文章的最强动力!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK