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

1. 前言
作為辦公自動(dòng)化 PPT 系列篇的最后一篇文章,我們將 PPT 中的高級(jí)功能及常用點(diǎn)
文章內(nèi)容將覆蓋:
預(yù)設(shè)形狀 Shape
圖表 Chart
讀取文字內(nèi)容
保存所有圖片
2. 預(yù)設(shè)形狀 Shape
實(shí)際上,PPT 文檔的內(nèi)容區(qū)就是由各類(lèi)形狀 Shape 組成,包含:圖片、文本框、視頻、表格、預(yù)設(shè)形狀
其中,預(yù)設(shè)的普通形狀也相當(dāng)豐富,可以查看下面鏈接

使用下面的方法,可以向幻燈片中插入一個(gè)形狀
slide.shapes.add_shape(autoshape_type_id, left, top, width, height)參數(shù)分別是:
autoshape_type_id? 形狀類(lèi)型
left? 左邊距
top? 上邊距
width? 形狀寬度
height? 形狀高度
我們以插入一個(gè)簡(jiǎn)單的圓角矩形框?yàn)槔?/p>
2-1? 插入形狀
from?pptx.enum.shapes?import?MSO_SHAPE,?MSO_SHAPE_TYPE
def?insert_shape(slide,?left,?top,?width,?height,?autoshape_type_id=MSO_SHAPE.CHEVRON,?unit=Inches):
????"""
????幻燈片中添加形狀
????:param?unit:?單位,默認(rèn)為Inches
????:param?autoshape_type_id:?形狀類(lèi)型
????:param?slide:幻燈片
????:param?left:左邊距
????:param?top:上邊距
????:param?width:寬度
????:param?height:高度
????:return:
????"""
????#?添加一個(gè)形狀
????#?add_shape(self,?autoshape_type_id,?left,?top,?width,?height)
????#?參數(shù)分別為:形狀類(lèi)型、左邊距、上邊距、寬度、高度
????shape?=?slide.shapes.add_shape(autoshape_type_id=autoshape_type_id,
???????????????????????????????????left=unit(left),
???????????????????????????????????top=unit(top),
???????????????????????????????????width=unit(width),
???????????????????????????????????height=unit(height))
????return?shape
#?1、添加一個(gè)圓角矩形
rectangle?=?insert_shape(slide,?2,?2,?16,?8,?autoshape_type_id=MSO_SHAPE.ROUNDED_RECTANGLE,?unit=Cm)
2-2? 設(shè)置形狀屬性
上面方法返回的形狀對(duì)象 ,我們可以進(jìn)一步設(shè)置它的背景顏色及邊框?qū)傩?/p>
比如:設(shè)置背景色為白色;邊框顏色為紅色,寬度為 0.5 厘米
#?2、設(shè)置形狀屬性
#?2.1?背景顏色
set_widget_bg(rectangle,?bg_rgb_color=[255,?255,?255])
#?2.2?邊框?qū)傩?/span>
set_widget_frame(rectangle,?frame_rgb_color=[255,?0,?0],frame_width=0.5)更多形狀可以參考下面鏈接
https://python-pptx.readthedocs.io/en/latest/api/enum/MsoAutoShapeType.html
3. 圖表 Chart
圖表 Chart 是 PPT 中使用很頻繁的一塊內(nèi)容,使用 python-pptx 可以創(chuàng)建各種類(lèi)型的圖表,包含:柱狀圖、餅圖、折線圖、散點(diǎn)圖、3D 圖等
創(chuàng)建圖表的方式如下:
slide.shapes.add_shape(autoshape_type_id, left, top, width, height)
參數(shù)分別是:
autoshape_type_id? 圖表樣式
left? 左邊距
top? 上邊距
width? 圖表顯示寬度
height? 圖表顯示高度
3-1? 創(chuàng)建一個(gè)折線圖
首先,創(chuàng)建一個(gè)圖表數(shù)據(jù)對(duì)象 ChartData
from?pptx.chart.data?import?ChartData
slide?=?add_slide(self.presentation,?6)
#?創(chuàng)建一個(gè)圖表數(shù)據(jù)對(duì)象
chart_data?=?ChartData()
接著,準(zhǔn)備圖表數(shù)據(jù)
#?數(shù)據(jù)類(lèi)別(x軸數(shù)據(jù))
chart_data.categories?=?[2000,?2005,?2010,?2015,?2020]
#?每一年各維度的數(shù)據(jù)(3個(gè)緯度)
#?經(jīng)濟(jì)
chart_data.add_series("經(jīng)濟(jì)",?[60,?65,?75,?90,?95])
#?環(huán)境
chart_data.add_series("環(huán)境",?[95,?88,?84,?70,?54])
#?文化
chart_data.add_series("軍事",[40,?65,?80,?95,?98])
最后,指定圖表類(lèi)型為折線圖 XL_CHART_TYPE.LINE,按照?qǐng)D表數(shù)據(jù)繪制圖表
如果需要繪制其他圖表,可以參考下面鏈接:
https://python-pptx.readthedocs.io/en/latest/api/enum/XlChartType.html
def?insert_chart(slide,?left,?top,?width,?height,?data,?unit=Inches,?chart_type=XL_CHART_TYPE.COLUMN_CLUSTERED):
????"""
????插入圖表
????:param?slide:?幻燈片
????:param?left:?左邊距
????:param?top:?上邊距
????:param?width:?寬度
????:param?height:?高度
????:param?data:?圖表數(shù)據(jù)
????:param unit:?數(shù)據(jù)單位,默認(rèn)為:Inches
????:param chart_type:?圖表類(lèi)型,默認(rèn)是:柱狀圖
????:return:
????"""
????chart_result?=?slide.shapes.add_chart(chart_type=chart_type,
??????????????????????????????????????????x=unit(left),?y=unit(top),
??????????????????????????????????????????cx=unit(width),?cy=unit(height),
??????????????????????????????????????????chart_data=data)
????#?返回圖表
????return?chart_result.chart
#?添加圖表
chart?=?insert_chart(slide,?4,?5,?20,?9,?chart_data,?unit=Cm,?chart_type=XL_CHART_TYPE.LINE)
3-2? 設(shè)置圖表顯示屬性
以設(shè)置圖表圖例、圖表是否顯示平滑、設(shè)置圖表文字樣式為例
#?設(shè)置圖表顯示屬性
#?顯示圖例
chart.has_legend?=?True
#?圖例是否在繪圖區(qū)之外顯示
chart.legend.include_in_layout?=?False
#?設(shè)置圖表是否顯示平滑
chart.series[0].smooth?=?True
chart.series[1].smooth?=?True
chart.series[2].smooth?=?True
#?設(shè)置圖表中文字的樣式
set_font_style(chart.font,?font_size=12,?font_color=[255,?0,?0])
最后生成的折線圖效果圖如下:

4. 讀取內(nèi)容
PPT 文檔的內(nèi)容區(qū)由各種 Shape 組成,并且 shape.has_text_frame 可用于判斷形狀內(nèi)部是否包含文本框
因此,只需要遍歷所有形狀,就可以獲取 PPT 中所有的文本內(nèi)容
def?read_ppt_content(presentation):
????"""
????讀取PPT中所有的內(nèi)容
????:param?presentation:
????:return:
????"""
????#?所有內(nèi)容
????results?=?[]
????#?遍歷所有幻燈片,獲取文本框中的值
????for?slide?in?presentation.slides:
????????for?shape?in?slide.shapes:
????????????#?判斷形狀是否包含文本框
????????????if?shape.has_text_frame:
????????????????content?=?get_shape_content(shape)
????????????????if?content:
????????????????????results.append(content)
????return?results
presentation?=?Presentation("./raw.pptx")
#?1、普通形狀內(nèi)容的所有文本內(nèi)容
contents?=?read_ppt_content(presentation)
print(contents)
但是,對(duì)于圖表 Table 單元格中的文本數(shù)據(jù),沒(méi)法利用這種方式獲取到
我們只能過(guò)濾出形狀類(lèi)型為 TABLE 的形狀,遍歷表中所有行及單元格,獲取文本數(shù)據(jù)
def?read_ppt_file_table(self):
????"""
????讀取PPT中的數(shù)據(jù)
????:return:
????"""
????#?打開(kāi)待讀取的ppt
????presentation?=?Presentation("./raw.pptx")
????for?slide?in?presentation.slides:
????????#?遍歷素有形狀
????????#?形狀:有內(nèi)容的形狀、無(wú)內(nèi)容的形狀
????????for?shape?in?slide.shapes:
????????????#?print('當(dāng)前形狀名稱:',?shape.shape_type)
????????????#?只取表格中的數(shù)據(jù),按照行讀取內(nèi)容
????????????if?shape.shape_type?==?MSO_SHAPE_TYPE.TABLE:
????????????????#?獲取表格行(shape.table.rows)
????????????????for?row?in?shape.table.rows:
????????????????????#?某一行所有的單元格(row.cells)
????????????????????for?cell?in?row.cells:
????????????????????????#?單元格文本框中的內(nèi)容(cell.text_frame.text)
????????????????????????print(cell.text_frame.text)5. 保存圖片
有時(shí)候,我們需要將 PPT 文檔中的所有圖片保存到本地
只需要下面 3 步即可完成
遍歷幻燈片內(nèi)容區(qū)所有形狀
過(guò)濾出形狀類(lèi)型為 MSO_SHAPE_TYPE.PICTURE?的圖片形狀,獲取圖片形狀的二進(jìn)制字節(jié)流
將圖片字節(jié)流寫(xiě)入到文件中
def?save_ppt_images(presentation,?output_path):
????"""
?????保存ppt中所有圖片
????[Python批量導(dǎo)出PPT中的圖片素材](https://www.pythonf.cn/read/49552)
????:param?presentation:
????:param?output_path?保存目錄
????:return:
????"""
????print('幻燈片數(shù)目:',?len(presentation.slides))
????#?遍歷所有幻燈片
????for?index_slide,?slide?in?enumerate(presentation.slides):
????????#?遍歷所有形狀
????????for?index_shape,?shape?in?enumerate(slide.shapes):
????????????#?形狀包含:文字形狀、圖片、普通形狀等
????????????#?過(guò)濾出圖片形狀
????????????if?shape.shape_type?==?MSO_SHAPE_TYPE.PICTURE:
????????????????#?獲取圖片二進(jìn)制字符流
????????????????image_data?=?shape.image.blob
????????????????#?image/jpeg、image/png等
????????????????image_type_pre?=?shape.image.content_type
????????????????#?圖片后綴名
????????????????image_suffix?=?image_type_pre.split('/')[1]
????????????????#?創(chuàng)建image文件夾保存抽出圖片
????????????????if?not?os.path.exists(output_path):
????????????????????os.makedirs(output_path)
????????????????#?圖片保存路徑
????????????????output_image_path?=?output_path?+?random_str(10)?+?"."?+?image_suffix
????????????????print(output_image_path)
????????????????#?寫(xiě)入到新的文件中
????????????????with?open(output_image_path,?'wb')?as?file:
????????????????????file.write(image_data)6. 最后
至此,Python 辦公自動(dòng)化 PPT 系列篇就正式結(jié)束了!在實(shí)際項(xiàng)目中,如果你有遇到其他問(wèn)題,歡迎在評(píng)論區(qū)留言!
我已經(jīng)將全部源碼上傳到后臺(tái),關(guān)注公眾號(hào),后臺(tái)回復(fù)「 ppt?」即可獲得全部源碼
如果你覺(jué)得文章還不錯(cuò),請(qǐng)大家?點(diǎn)贊、分享、留言?下,因?yàn)檫@將是我持續(xù)輸出更多優(yōu)質(zhì)文章的最強(qiáng)動(dòng)力!
