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

最全總結 | 聊聊 Python 辦公自動化之 PDF(上)

![image](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/154067dc596943998213c8b5d250ad4d~tplv-k3u1fbpfcp-zoom-1.image) ## 1\. 前言 自動化辦公,非 Python 莫屬! 從本篇文章開始,我們繼續聊聊自動化辦公中另外一個常用系列:PPT ## 2\. 準備一下 Python 操作 PPT 最強大的依賴庫是:python-pptx 所以,在開始操作之前,我們需要在虛擬環境下安裝這個依賴庫 ``` # 安裝依賴 pip3 install python-pptx ``` ## 3\. PPT 結構 首先,我們需要了解一個 PPT 文件的頁面結構 ![image](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8cd17fc6772b471bbca7c40d4de40ed9~tplv-k3u1fbpfcp-zoom-1.image) * 一個 PPT 文件對應一個 Presentation 物件 * 一個 Presentation 包含多個 Slide 物件,每一個 Slide 代表一個幻燈片 * 每一張幻燈片的內容都是由各種形狀 Shape 組成 其次,PPT 中的內容元素都是由各種形狀構成 比如:文字框、圖片、佔位符、表格、普通形狀等 通過翻看原始碼,發現他們都定義在 MSO_SHAPE_TYPE  類中 ![image](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/910d29619bbb4c018a0572d29f5bde1f~tplv-k3u1fbpfcp-zoom-1.image) 最後,我們需要了解一下 PPT 中的 版式模板 使用 Presentation 物件的 屬性方法 slide_layouts 可以獲取內建的 11 種母版樣式 ``` # 使用Presentation獲取PPT內建的11種版式樣式 # 版式索引從0開始 slide_layout = presentation.slide_layouts[slide_style_index] ``` 他們分別是: * Title Slide 標題幻燈片 * Title and Content    標題和內容幻燈片 * Section Header    節標題幻燈片 * Two Content    兩欄內容幻燈片 * Comparison    比較幻燈片 * Title Only    僅標題的幻燈片 * Blank    空白幻燈片 * Content with Caption    內容和標題的幻燈片 * Picture with Caption    圖片和標題的幻燈片 * Title and Vertical Text 標題和豎排內容 * Vertical Title and Text 豎排標題和文字 當然,也可以在 Microsoft PPT / WPS 中檢視對應母版的樣式 這裡補充一下,除了內建的版式樣式,也可以通過佔位符 PlaceHolder 去自定義母版,滿足一些特定的場景需求 ## 4. 幻燈片管理 一個 PPT 檔案是由一個或多張幻燈片組成 1-1  那如何新增一張一張幻燈片呢? 這裡,只需要通過下面 3 個步驟 * 例項化一個 Presentation 物件 * 通過內建的版本樣式,新建一個版本樣式 Layout * 通過版本樣式 Layout,新增一張幻燈片 ``` def add_slide(presentation, slide_style_index): """ 在PPT文件中,以內建的版式新增幻燈片 :param presentation:文件物件 :param slide_style_index:版式索引 :return: """ # PPT版式樣式 # 內建有11種版式樣式 # 0:Title Slide 標題幻燈片 # 1:Title and Content 標題和內容 # 2:Section Header 節標題 # 3:Two Content 兩欄內容 # 4:Comparison 比較 # 5:Title Only 僅標題 # 6:Blank 空白 # 7:Content with Caption 內容和標題 # 8:Picture with Caption 圖片和標題 # 9:Title and Vertical Text 標題和豎排內容 # 10:Vertical Title and Text 豎排標題和文字 slide_layout = presentation.slide_layouts[slide_style_index] # 通過樣式Layout,新增一張幻燈片 slide = presentation.slides.add_slide(slide_layout) return slide # 1.1 新增幻燈片 slide1 = add_slide(self.presentation, 0) slide2 = add_slide(self.presentation, 1) slide3 = add_slide(self.presentation, 2) slide4 = add_slide(self.presentation, 3) ``` 1-2  獲取已有的幻燈片或某一張幻燈片? Presentation 物件的 slides 屬性 會返回當前 PPT 文件中所有的幻燈片物件列表 ``` def get_slides(presentation): """ 獲取所有的幻燈片 :param presentation: :return: """ # 所有幻燈片 slides = presentation.slides # 幻燈片數目 slide_num = len(slides) return slides, slide_num def get_slide(presentation, slide_index): """ 根據索引,獲取某一個幻燈片 :param presentation: :param slide_index:頁面索引,從0開始 :return: """ slides, slide_num = get_slides(presentation=presentation) return slides[slide_index] # 1.2.1 獲取所幻燈片 slides, slide_num = get_slides(self.presentation) print('現有幻燈片:', slides) print('幻燈片數目:', slide_num) # 1.2.2 獲取某一個幻燈片 slide = get_slide(self.presentation, 1) print(slide.shapes) ``` 1-3  如果需要刪除某一張幻燈片,如何破? 這個也簡單,只需要先獲取目前幻燈片物件,然後使用下面方法移除即可 ``` def del_slide(presentation, slide_index=0): """ 刪除某一張幻燈片 :param presentation: :param slide_index: 索引 :return: """ # 所有幻燈片的列表 slides = list(presentation.slides._sldIdLst) # 根據索引,刪除某一張幻燈片 presentation.slides._sldIdLst.remove(slides[slide_index]) # 1.3 根據索引,刪除PPT文件中某一張幻燈片 # 比如:刪除第4張幻燈片 del_slide(self.presentation, 3) ``` ## 5\. 文字及段落 我們首先需要指定一個幻燈片物件 Slide,它可以是已有的幻燈片,也可以是新建的一張幻燈片 接著,使用幻燈片物件的 slide.shapes 屬性,獲取當前幻燈片中的所有形狀 Shape 組成的佇列 最後利用形狀佇列的下面這個函式新增一個文字框,函式返回值為一個:文字框物件 add_textbox( left , top , width , height )  該函式引數分別為: * left  左邊距 * top  上邊距 * width  文字框寬度 * height  文字框高度 這裡需要引出另外一個概念:文字形狀 PS:文字形狀便於在文字框中新增段落和設定樣式,通過「文字框物件」的屬性函式 text_frame 獲取 ``` def insert_textbox(slide, left, top, width, height, unit=Inches): """ 幻燈片中新增文字框 :param unit: 單元,預設設定為Inches :param slide: 幻燈片物件 :param left: 左邊距 :param top: 上邊距 :param width: 寬度 :param height: 高度 :return: """ # 文字框 textbox = slide.shapes.add_textbox(left=unit(left), top=unit(top), width=unit(width), height=unit(height)) # 文字框形狀 tf = textbox.text_frame return textbox, tf ``` 為了便於使用,我對幻燈片中插入文字框這一動作進行了一次封裝 長度單位預設設定為:Inches,也可以自定義為釐米等單位 接下來,我們來操作文字框及段落的常見操作 1-1  插入文字框,並設定預設段落內容 插入文字框的同時,文字框形狀物件會自帶一個段落,可以對這個段落設定內容 ``` # 2、往幻燈片中插入一個文字框,返回一個文字框物件和一個文字框形狀物件 textbox, tf = insert_textbox(slide, 8, 2, 10, 4, unit=Cm) # 2.1 預設的段落 paragraph_default = tf.paragraphs[0] paragraph_default.text = "設定段落預設的內容" ``` 1-2  文字框中新增一個段落 檢視原始碼發現,文字框形狀物件是 TextFrame 的子類,因此可以使用 TextFrame 類中的 add_paragraph() 函式新增一個新的段落 ``` # 2.2 新增一個新的段落 paragraph_new = tf.add_paragraph() # 2.3 給段落設定內容 paragraph_new.text = "歡迎關注公眾號:AirPython\n每週分享 Python 原創技術乾貨!" ``` 1-3  設定段落及文字樣式 和 Word 一樣,使用 python-pptx 同樣可以設定 PPT 文件的段落樣式 其中 對齊方式:對齊方式是針對段落的,只需要指定段落物件的 alignment 的屬性值即可 ``` def set_parg_font_style(paragraph, font_name=None, font_color=None, font_size=-1, font_bold=False, font_italic=False, paragraph_alignment=PP_ALIGN.CENTER): """ 設定段落中文字的樣式,包含:字型名稱、顏色、大小、是否加粗、是否斜體 :param paragraph_alignment: 段落對齊方式 :param paragraph: :param font_name: :param font_color: :param font_size: :param font_bold: :param font_italic: :return: """ # 對齊方式 # 注意:對齊方式是針對段落的 paragraph.alignment = paragraph_alignment # 獲取段落中字型物件 font = paragraph.font # 設定字型樣式 set_font_style(font, font_name, font_color, font_size, font_bold, font_italic) return font ``` 段落文字屬性:使用段落物件的 font 屬性獲取字型物件,接著設定字型名稱、大小、顏色、是否斜體、加粗 ``` def set_font_style(font, font_name=None, font_color=None, font_size=-1, font_bold=False, font_italic=False): """ 設定字型樣式 :param font: :param font_name: :param font_color: :param font_size: :param font_bold: :param font_italic: :return: """ # 字型名稱 if font_name: font.name = font_name # 字型顏色 if font_color and len(font_color) == 3: font.color.rgb = RGBColor(font_color[0], font_color[1], font_color[2]) # 字型大小 if font_size != -1: font.size = Pt(font_size) # 是否加粗,預設不加粗 font.bold = font_bold # 是否傾斜,預設不傾斜 font.italic = font_italic ``` 1-4  設定文字框的背景顏色 設定文字框背景顏色只需要 2 步 * 將形狀的填充型別設定為純色 * 設定文字框的背景顏色 ``` 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]) # 4、設定文字框的背景顏色 set_widget_bg(textbox, [0, 255, 0]) ``` 需要指出的是,該方法同樣適用於設定表格單元格、普通形狀的背景顏色 1-5 文字框的自動對齊 一旦文字框設定一段很長的文字,單行可能顯示不完全 這時候,我們只需要設定文字形狀的 word_wrap 值為 True,則可以讓文字框的文字自動換行顯示 ``` # 5、設定文字框的文字自動對齊 tf.word_wrap = True ``` ## 6\. 最後 受限於篇幅,本篇文章僅聊到了 PPT 的結構、幻燈片管理、段落及文字;更多複雜操作、專案實戰,會在後面的文章中進行說明 要獲取全部原始碼,關注公眾號「 **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)