最全總結 | 聊聊 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 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))

經過上面一系列操作,最後在幻燈片中生成的表格如下:

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 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,則按照圖片真實大小去顯示,當圖片很大時,可能會出現展示不全的情況

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(上)