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


    image

    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  宽度
        :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 
        :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))
    

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

    image

    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  宽度
        :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,则按照图片真实大小去显示,当图片很大时,可能会出现展示不全的情况

    image

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

    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 」即可获得全部源码

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

    推荐阅读

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

  • 相关阅读:
    HDU 1698 Just a Hook (线段树模板题-区间求和)
    spring定时任务详解(@Scheduled注解)
    spring定时任务(@Scheduled注解)
    java反射实现接口重试
    微信开发者工具在线调试
    消息队列应用场景
    Redis、Memcache和MongoDB的区别
    下拉框多选实现回显及sql
    MySQL 中 You can't specify target table '表名' for update in FROM clause错误解决办法
    catch异常
  • 原文地址:https://www.cnblogs.com/xingag/p/14225091.html
Copyright © 2020-2023  润新知