1. 程式人生 > >最全總結 | 聊聊 Python 辦公自動化之 PPT(中)

最全總結 | 聊聊 Python 辦公自動化之 PPT(中)

![image](https://upload-images.jianshu.io/upload_images/1466987-94d5ef8268947038?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ## 1\. 前言 上一篇文章簡單地介紹了 PPT 的文件結構,並使用 python-pptx 這個依賴庫完成對 PPT 文件最基本的操作 [最全總結 | 聊聊 Python 辦公自動化之 PPT(上)](http://mp.weixin.qq.com/s?__biz=MzU1OTI0NjI1NQ==&mid=2247486976&idx=1&sn=053c478d01933a2c9c48f287f7614358&chksm=fc1b70c0cb6cf9d6465224e6c32ab7a052f9729bedeacc272f9a2d9cc71cbefecaf39d55785c&scene=21#wechat_redirect) 作為 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](https://upload-images.jianshu.io/upload_images/1466987-9759d8053a055896?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ## 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](https://upload-images.jianshu.io/upload_images/1466987-f333a2a7965bc1e0?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 因此,在實際專案中,我們只需要先獲取圖片的寬高比,然後等比例設定到寬度和高度引數中即可 ``` 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(上)](http://mp.weixin.qq.com/s?__biz=MzU1OTI0NjI1NQ==&mid=2247486752&idx=1&sn=bc58a3127bad72f2210817c3b4087801&chksm=fc1b73e0cb6cfaf6b1dbe8943d13a805d384ae74f043720a1d048c498405cc1ada93437f58ce&scene=21#wechat_redirect) [最全總結 | 聊聊 Python 辦公自動化之 Excel(中)](http://mp.weixin.qq.com/s?__biz=MzU1OTI0NjI1NQ==&mid=2247486789&idx=1&sn=e565569c17815a897ab6089f9c305d90&chksm=fc1b7385cb6cfa93c17632269677f60439e1738b23c7522eb75a5e8dedc61a5c44e0c681c447&scene=21#wechat_redirect) [最全總結 | 聊聊 Python 辦公自動化之 Excel(下)](http://mp.weixin.qq.com/s?__biz=MzU1OTI0NjI1NQ==&mid=2247486844&idx=1&sn=de68f12d72e3e16289a2ffb0ed578e6d&chksm=fc1b73bccb6cfaaabf05f8548f49a9a6b83debd0997a11a53313b433730bd23189fa8c640e32&scene=21#wechat_redirect) [最全總結 | 聊聊 Python 辦公自動化之 Word(上)](http://mp.weixin.qq.com/s?__biz=MzU1OTI0NjI1NQ==&mid=2247486899&idx=1&sn=d25d979b7cab442a5a062ded7f4cf31a&chksm=fc1b7373cb6cfa6544c802baab9c46aeeb5d0d26830c61ca9c3843bdc57927d0df5da868ae55&scene=21#wechat_redirect) [最全總結 | 聊聊 Python 辦公自動化之 Word(中)](http://mp.weixin.qq.com/s?__biz=MzU1OTI0NjI1NQ==&mid=2247486920&idx=1&sn=eae4316628ea3c6e93d4808d5bafb5c2&chksm=fc1b7308cb6cfa1ef14cd0d345ae81d8e31659d72bc77a7ebee1237ceb6f36f97457cc6ef2c1&scene=21#wechat_redirect) [最全總結 | 聊聊 Python 辦公自動化之 Word(下)](http://mp.weixin.qq.com/s?__biz=MzU1OTI0NjI1NQ==&mid=2247486931&idx=1&sn=a35c0ce2abe8b100178d644ca7e546ee&chksm=fc1b7313cb6cfa05777df17b0b7734c8692aa7a4d3bca28218afc33d7d957617ede4892411b1&scene=21#wechat_redirect) [最全總結 | 聊聊 Python 辦公自動化之 PPT(上)](http://mp.weixin.qq.com/s?__biz=MzU1OTI0NjI1NQ==&mid=2247486976&idx=1&sn=053c478d01933a2c9c48f287f7614358&chksm=fc1b70c0cb6cf9d6465224e6c32ab7a052f9729bedeacc272f9a2d9cc71cbefecaf39d55785c&scene=21#wechat_r