最全總結(jié) | 聊聊 Python 辦公自動(dòng)化之 PPT(上)
點(diǎn)擊上方“AirPython”,選擇“加為星標(biāo)”
第一時(shí)間關(guān)注 Python 技術(shù)干貨!

1. 前言
自動(dòng)化辦公,非 Python 莫屬!
從本篇文章開始,我們繼續(xù)聊聊自動(dòng)化辦公中另外一個(gè)常用系列:PPT
2. 準(zhǔn)備一下
Python 操作 PPT 最強(qiáng)大的依賴庫是:python-pptx
所以,在開始操作之前,我們需要在虛擬環(huán)境下安裝這個(gè)依賴庫
#?安裝依賴
pip3?install?python-pptx
3. PPT 結(jié)構(gòu)
首先,我們需要了解一個(gè) PPT 文檔的頁面結(jié)構(gòu)

一個(gè) PPT 文檔對(duì)應(yīng)一個(gè)?Presentation 對(duì)象
一個(gè)?Presentation 包含多個(gè) Slide 對(duì)象,每一個(gè) Slide 代表一個(gè)幻燈片
每一張幻燈片的內(nèi)容都是由各種形狀 Shape 組成
其次,PPT 中的內(nèi)容元素都是由各種形狀構(gòu)成
比如:文字框、圖片、占位符、表格、普通形狀等
通過翻看源碼,發(fā)現(xiàn)他們都定義在 MSO_SHAPE_TYPE? 類中

最后,我們需要了解一下 PPT 中的?版式模板
使用?Presentation 對(duì)象的?屬性方法?slide_layouts?可以獲取內(nèi)置的 11 種母版樣式
#?使用Presentation獲取PPT內(nèi)置的11種版式樣式
#?版式索引從0開始
slide_layout?=?presentation.slide_layouts[slide_style_index]
他們分別是:
Title Slide 標(biāo)題幻燈片
Title and Content? ? 標(biāo)題和內(nèi)容幻燈片
Section Header? ? 節(jié)標(biāo)題幻燈片
Two Content? ? 兩欄內(nèi)容幻燈片
Comparison? ? 比較幻燈片
Title Only? ? 僅標(biāo)題的幻燈片
Blank? ? 空白幻燈片
Content with Caption? ? 內(nèi)容和標(biāo)題的幻燈片
Picture with Caption? ? 圖片和標(biāo)題的幻燈片
Title and Vertical Text 標(biāo)題和豎排內(nèi)容
Vertical Title and Text 豎排標(biāo)題和文本
當(dāng)然,也可以在?Microsoft PPT / WPS 中查看對(duì)應(yīng)母版的樣式
這里補(bǔ)充一下,除了內(nèi)置的版式樣式,也可以通過占位符 PlaceHolder 去自定義母版,滿足一些特定的場(chǎng)景需求
4.?幻燈片管理
一個(gè) PPT 文件是由一個(gè)或多張幻燈片組成
1-1??那如何添加一張一張幻燈片呢?
這里,只需要通過下面 3 個(gè)步驟
實(shí)例化一個(gè)?Presentation 對(duì)象
通過內(nèi)置的版本樣式,新建一個(gè)版本樣式 Layout
通過版本樣式 Layout,添加一張幻燈片
def?add_slide(presentation,?slide_style_index):
????"""
????在PPT文檔中,以內(nèi)置的版式添加幻燈片
????:param?presentation:文檔對(duì)象
????:param?slide_style_index:版式索引
????:return:
????"""
????#?PPT版式樣式
????#?內(nèi)置有11種版式樣式
????#?0:Title Slide 標(biāo)題幻燈片
????# 1:Title and Content ?標(biāo)題和內(nèi)容
????# 2:Section Header ??節(jié)標(biāo)題
????# 3:Two Content ??兩欄內(nèi)容
????# 4:Comparison ?比較
????# 5:Title Only ?僅標(biāo)題
????# 6:Blank ?空白
????# 7:Content with Caption ??內(nèi)容和標(biāo)題
????# 8:Picture with Caption ??圖片和標(biāo)題
????# 9:Title and Vertical Text ?標(biāo)題和豎排內(nèi)容
????# 10:Vertical Title and Text ?豎排標(biāo)題和文本
????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 對(duì)象的?slides 屬性 會(huì)返回當(dāng)前 PPT 文檔中所有的幻燈片對(duì)象列表
def?get_slides(presentation):
????"""
????獲取所有的幻燈片
????:param?presentation:
????:return:
????"""
????#?所有幻燈片
????slides?=?presentation.slides
????#?幻燈片數(shù)目
????slide_num?=?len(slides)
????return?slides,?slide_num
def?get_slide(presentation,?slide_index):
????"""
????根據(jù)索引,獲取某一個(gè)幻燈片
????: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('現(xiàn)有幻燈片:',?slides)
print('幻燈片數(shù)目:',?slide_num)
#?1.2.2?獲取某一個(gè)幻燈片
slide?=?get_slide(self.presentation,?1)
print(slide.shapes)
1-3??如果需要?jiǎng)h除某一張幻燈片,如何破?
這個(gè)也簡(jiǎn)單,只需要先獲取目前幻燈片對(duì)象,然后使用下面方法移除即可
def?del_slide(presentation,?slide_index=0):
????"""
????刪除某一張幻燈片
????:param?presentation:
????:param?slide_index:?索引
????:return:
????"""
????#?所有幻燈片的列表
????slides?=?list(presentation.slides._sldIdLst)
????#?根據(jù)索引,刪除某一張幻燈片
????presentation.slides._sldIdLst.remove(slides[slide_index])
#?1.3?根據(jù)索引,刪除PPT文檔中某一張幻燈片
#?比如:刪除第4張幻燈片
del_slide(self.presentation,?3)5. 文字及段落
我們首先需要指定一個(gè)幻燈片對(duì)象 Slide,它可以是已有的幻燈片,也可以是新建的一張幻燈片
接著,使用幻燈片對(duì)象的 slide.shapes?屬性,獲取當(dāng)前幻燈片中的所有形狀 Shape 組成的隊(duì)列
最后利用形狀隊(duì)列的下面這個(gè)函數(shù)添加一個(gè)文本框,函數(shù)返回值為一個(gè):文本框?qū)ο?/span>
add_textbox( left , top , width , height )?
該函數(shù)參數(shù)分別為:
left??左邊距
top? 上邊距
width? 文字框?qū)挾?/p>
height? 文字框高度
這里需要引出另外一個(gè)概念:文字形狀
PS:文字形狀便于在文字框中添加段落和設(shè)置樣式,通過「文本框?qū)ο?/span>」的屬性函數(shù)?text_frame 獲取
def?insert_textbox(slide,?left,?top,?width,?height,?unit=Inches):
????"""
????幻燈片中添加文本框
????:param?unit:?單元,默認(rèn)設(shè)置為Inches
????:param?slide:?幻燈片對(duì)象
????: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
為了便于使用,我對(duì)幻燈片中插入文字框這一動(dòng)作進(jìn)行了一次封裝
長(zhǎng)度單位默認(rèn)設(shè)置為:Inches,也可以自定義為厘米等單位
接下來,我們來操作文字框及段落的常見操作
1-1??插入文本框,并設(shè)置默認(rèn)段落內(nèi)容
插入文本框的同時(shí),文本框形狀對(duì)象會(huì)自帶一個(gè)段落,可以對(duì)這個(gè)段落設(shè)置內(nèi)容
#?2、往幻燈片中插入一個(gè)文本框,返回一個(gè)文本框?qū)ο蠛鸵粋€(gè)文本框形狀對(duì)象
textbox,?tf?=?insert_textbox(slide,?8,?2,?10,?4,?unit=Cm)
#?2.1?默認(rèn)的段落
paragraph_default?=?tf.paragraphs[0]
paragraph_default.text?=?"設(shè)置段落默認(rèn)的內(nèi)容"
1-2? 文本框中新增一個(gè)段落
查看源碼發(fā)現(xiàn),文本框形狀對(duì)象是?TextFrame 的子類,因此可以使用?TextFrame 類中的?add_paragraph() 函數(shù)添加一個(gè)新的段落
#?2.2?添加一個(gè)新的段落
paragraph_new?=?tf.add_paragraph()
#?2.3?給段落設(shè)置內(nèi)容
paragraph_new.text?=?"歡迎關(guān)注公眾號(hào):AirPython\n每周分享 Python 原創(chuàng)技術(shù)干貨!"
1-3??設(shè)置段落及文字樣式
和 Word 一樣,使用 python-pptx 同樣可以設(shè)置 PPT 文檔的段落樣式
其中
對(duì)齊方式:對(duì)齊方式是針對(duì)段落的,只需要指定段落對(duì)象的?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):
????"""
????設(shè)置段落中文本的樣式,包含:字體名稱、顏色、大小、是否加粗、是否斜體
????:param?paragraph_alignment:?段落對(duì)齊方式
????:param?paragraph:
????:param?font_name:
????:param?font_color:
????:param?font_size:
????:param?font_bold:
????:param?font_italic:
????:return:
????"""
????#?對(duì)齊方式
????#?注意:對(duì)齊方式是針對(duì)段落的
????paragraph.alignment?=?paragraph_alignment
????#?獲取段落中字體對(duì)象
????font?=?paragraph.font
????#?設(shè)置字體樣式
????set_font_style(font,?font_name,?font_color,?font_size,?font_bold,?font_italic)
????return?font
段落文字屬性:使用段落對(duì)象的 font 屬性獲取字體對(duì)象,接著設(shè)置字體名稱、大小、顏色、是否斜體、加粗
def?set_font_style(font,?font_name=None,?font_color=None,?font_size=-1,?font_bold=False,?font_italic=False):
????"""
????設(shè)置字體樣式
????: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)
????#?是否加粗,默認(rèn)不加粗
????font.bold?=?font_bold
????#?是否傾斜,默認(rèn)不傾斜
????font.italic?=?font_italic
1-4??設(shè)置文字框的背景顏色
設(shè)置文字框背景顏色只需要 2 步
將形狀的填充類型設(shè)置為純色
設(shè)置文字框的背景顏色
def?set_widget_bg(widget,?bg_rgb_color=None):
????"""
????設(shè)置【文本框textbox/單元格/形狀】的背景顏色
????:param?widget:文本框textbox、單元格、形狀
????:param?bg_rgb_color:背景顏色值
????:return:
????"""
????if?bg_rgb_color?and?len(bg_rgb_color)?==?3:
????????#?1、將形狀填充類型設(shè)置為純色
????????widget.fill.solid()
????????#?2、設(shè)置文本框的背景顏色
????????widget.fill.fore_color.rgb?=?RGBColor(bg_rgb_color[0],?bg_rgb_color[1],?bg_rgb_color[2])
#?4、設(shè)置文字框的背景顏色
set_widget_bg(textbox,?[0,?255,?0])
需要指出的是,該方法同樣適用于設(shè)置表格單元格、普通形狀的背景顏色
1-5 文本框的自動(dòng)對(duì)齊
一旦文本框設(shè)置一段很長(zhǎng)的文字,單行可能顯示不完全
這時(shí)候,我們只需要設(shè)置文字形狀的?word_wrap?值為 True,則可以讓文本框的文字自動(dòng)換行顯示
#?5、設(shè)置文本框的文字自動(dòng)對(duì)齊
tf.word_wrap?=?True6. 最后
受限于篇幅,本篇文章僅聊到了 PPT 的結(jié)構(gòu)、幻燈片管理、段落及文字;更多復(fù)雜操作、項(xiàng)目實(shí)戰(zhàn),會(huì)在后面的文章中進(jìn)行說明
要獲取全部源碼,關(guān)注公眾號(hào),后臺(tái)回復(fù)「 ppt?」即可獲得全部源碼
如果你覺得文章還不錯(cuò),請(qǐng)大家?點(diǎn)贊、分享、留言?下,因?yàn)檫@將是我持續(xù)輸出更多優(yōu)質(zhì)文章的最強(qiáng)動(dòng)力!
