小猪的Python学习之旅 —— 22.安静!吵到我用TNT了
小豬的Python學習之旅 —— 22.安靜!吵到我用TNT了
標簽:Python
一句話概括本文:
靈感來自于5.15錘子鳥巢發布會上老羅用閃念膠囊一鍵生成了32張PPT,
原理利用Python-pptx庫,通過編寫模板的方式自動生成批量PPT!
引言:
鏘鏘鏘,失蹤人口回歸,距離上一篇文章已過去14天。不是我偷懶不更新,
主要是轉崗打雜了,很雜那種,每天要處理一堆和開發無關的瑣事,
真的是敲碼五分鐘,打雜兩小時…還是當個單純的開發仔好啊。
標題沒錯,是第22篇不是21,不用回去翻,沒看漏,第20篇寫的是爬取Gank.io
接口的所有數據到MySQL,第21篇已經定好利用Flask編寫一個API接口,
代碼是實現了,部署還有些問題,所以還沒些,先占個坑。
本節的話,是最近兩天在折騰的一個東西,因為組內正在整在線早教
相關的東西,老師呢,要做很多的課件,但是大部分的內容都是重復的,
可能就圖片會變下,流程可能會變一點,然后就找到我,讓我想想有沒有辦法
自動生成減少她們的工作量,對,她們想要的就是 自動生成PPT!
還記得5.15錘子鳥巢發布會嗎?不記得?看到這個圖你應該想起什么了~
老羅現場展示了次時代電腦:TNT工作站 ,這里就不吐槽現場演示時的
各種小失誤和理解萬歲了。直播回顧的視頻可以到B站看:
515錘子科技鳥巢發布會全程回顧
發布會直播我是有全程看完的,有個地方吸引了我的注意,在視頻里69:08處,
老羅利用閃念膠囊直接就生成了32張PPT,給人一種錯覺:
臥槽,好屌,以后連PPT都不用自己做了!
其實不然,如果是細心的觀眾基本會發現一個規律,生成的PPT都是非常簡單
的PPT,一個黑色漸變的大背景,配幾行字,或者再配個圖片,PPT動畫也沒有。
來,來給你個這樣的PPT生成給我看:
這種批量生成簡單PPT的套路,我覺得思路無非這樣:
根據情形,定義幾套模板,然后約定一個規則,根據不同的內容調用
不同的模板,進行內容填充。
套路知道了,接下來就是看看Python有沒有支持庫了~
找到兩個pptx和win32com,本節只用前者,因為后者的文檔是真的
看得人頭皮發麻,而且網上的例子非常少…
1.python-pptx庫
官方文檔:http://python-pptx.readthedocs.io/en/latest/index.html
官方倉庫:https://github.com/scanny/python-pptx
安裝庫:pip install python-pptx
對了,因為win32com那個庫要調用微軟的PowerPoint,我把電腦重裝回
Win 10了,索性安裝了最新版的PyCharm,然后發現創建的工程和以前
創建的工程結構不一樣,多了個這樣的東西:
終端運行也變成了:(venv) F:\Python> 這樣,這個就是虛擬環境,
簡單點說就是對開發環境進行隔離,比如你這個項目基于Python 2.x,另一個項目
基于Python 3.x,或者說著兩個項目里依賴的同一個模塊用著不同的版本,通過
虛擬環境可以讓這兩個項目互不干擾,將所需的包安裝到獨立的環境中。
Python中常用的創建和管理虛擬環境的工具有:virtualenv和pyvenv,
Pycharm默認帶有virtualenv,新建的時候就可以看到,具體怎么定制化,
自行百度吧~對了,下載模塊都在Lib/site-packages目錄下!
2.實現流程分析
首先的話,先想想有哪些模板,羅列下:
- 1.只有一張圖片
- 2.只有一條文字
- 3.一條文字和一張圖片
- 4.兩條文字
- 5.四條文字
然后布局大概這樣咯:
接著定義一個規則,數據怎么傳,這里采用最簡單的套路,寫個txt文件,
每行代表一個PPT,參數通過逗號間隔,于是完整的PPT對應這樣的txt文件:
通過逗號分割參數,優先判斷是否有圖片,有的話走模板1,3,
其他再另外判斷。好的,思路有了,接下來開始一步步實現吧。
3.代碼實現
PS:這里不去介紹怎么用,看不懂自己去翻文檔,我也是自己摸索,
有我寫的示例參考,應該覺得很欣慰了。
1.定義一個厘米轉英寸的方法
以為PPT里的位置和大小用到的單位都是厘米,需要轉換下
# 厘米轉英寸 def cm_to_in(cm):return Inches(cm / 2.54)2.編寫模板
先是模板1,傳入Presentation的對象,這個你可以理解成PPT對象,
調用該對象的.slides.add_slide()方法添加一張幻燈片,pptx庫為我們
提供了八個不一樣的模板,喜歡的可以自己一個個試,這里我們直接用第七
張空白幻燈片,下標從0開始,所以是prs.slide_layouts[6],幻燈片
加了之后,調用Presentation的save(ppt文件名)函數打開生成的PPT,
然后點擊設置 -> 幻燈片大小 -> 直接選擇16:9或者設置幻燈片大小,比如我
的,這里的寬度和高度就是我們幻燈片的大小了,后面填充滿屏的圖片就要
用到這個。
然后調用add_picture函數添加一個滿屏圖片:
slide.shapes.add_picture(ppt_bg_path, cm_to_in(0), cm_to_in(0), cm_to_in(25.4), cm_to_in(14.288))然后模板1就寫完了,完成代碼如下:
# 模板1:只有一張圖片 def model_1(prs, pic_path):slide = prs.slides.add_slide(prs.slide_layouts[6])slide.shapes.add_picture(pic_path, cm_to_in(0), cm_to_in(0), cm_to_in(25.4), cm_to_in(14.288))# 調用: presentation = Presentation(ppt_file_name) model_1(presentation, laoluo_bg_path)打開生成的ppt:
喲,成功生成,接著到模板2:
填充滿屏圖片,然后新建一個文本框:
title_box = slide.shapes.add_textbox(cm_to_in(3.89), cm_to_in(5.35), cm_to_in(17.61), cm_to_in(3.59))再接著添加一個文本域:
paragraph = title_box.text_frame.add_paragraph()然后就可以對文本域里進行文字相關的操作了:
paragraph.text = title # 設置文本paragraph.vertical_anchor = MSO_VERTICAL_ANCHOR.MIDDLE # 設置垂直方向對齊方式paragraph.alignment = PP_PARAGRAPH_ALIGNMENT.CENTER # 設置水平方向對齊方式paragraph.font.size = Pt(60) # 設置文本大小,PT代表磅paragraph.font.name = '微軟雅黑' # 設置字體paragraph.font.color.rgb = RGBColor(255, 255, 255) # 設置字體顏色參數傳遞下,調用這個模板2,查看下生成的效果:
接下來如法炮制剩下的三個模板,主要是難點是控件的位置和寬高設置,
有兩種操作:
最簡單的操作:
隨便填個坐標和寬高,運行后打開生成的PPT,自行調整
位置,然后記錄下何時的位置和寬高,然后改代碼。
復雜點的操作:
自行計算,比如模板5,三個小標題,先減去左右的間隔,
然后三等分,循環動態計算小標題的起始位置。
3.配置文件讀取
接下來編寫一個讀取文件內容,調用對應方法的函數,代碼如下
# 讀取配置文件調用模板的方法 def read_rules(prs, filename):if os.path.exists(filename):with open(filename, 'r+', encoding='utf-8') as f:for rule in f:word_list = rule.replace('\n', '').split(',')if 'png' in rule or 'jpg' in rule:if len(word_list) == 1:model_1(prs, os.path.join(c.res_pictures, word_list[0]))else:model_3(prs, word_list[0], os.path.join(c.res_pictures, word_list[1]))else:if len(word_list) == 1:model_2(prs, word_list[0])elif len(word_list) == 2:model_4(prs, word_list[0], word_list[1])elif len(word_list) == 4:model_5(prs, word_list[0], word_list[1], word_list[2], word_list[3])4.代碼執行
調用配置文件讀取的函數
if __name__ == '__main__':t.is_dir_existed(c.outputs_documents_path)ppt_existed(ppt_file_name)presentation = Presentation(ppt_file_name)read_rules(presentation, rules_path)presentation.save(ppt_file_name)運行結果:
4.有些東西要說說
批量生成是挺爽的,不過呢,不支持直接生成動畫哦!!!
然后這種簡單的PPT,其實粘貼復制修改圖片的效率可能比起你一個個
模板編寫快一些…不得不說有些雞肋,哦,對哦,這個還支持生成圖表,
怎么整可以自行查閱官方文檔。
另外的win32com的庫,貌似功能更加強大,可能支持動畫吧,但是文檔是
真的難啃,就沒有深入去研究了,有興趣可以自己去折騰折騰。附上用
win32com這個庫時遇到的問題的解決方法:
- 1.Python3安裝win32com
- 2.哪里有win32com的文檔
微軟官網有,不過看到腦殼痛,介紹個工具:oleview,網上一搜一堆
不過這個用的時候會遇到一個問題,這里順帶記錄下筆者win10電腦遇到的
一些情況:
IVIEWERS.DLL缺失:
網上搜下這個dll文件,下載完把文件復制到Windows/system32,
然后管理員模式打開命令提示符,鍵入:regsvr32 iviewers.dll
注冊這個dll運行庫就可以了。不過呢,win10 64位這樣的執行是會報錯的:
模塊iviewers.dll可能與您正在運行的Windows版本不兼容,檢查該模塊是否與
regsvr.exe的x86或x64版本兼容
你要做的是把dll文件拷貝到Windows/SysWOW64,然后管理員模式打開命令提示符
cd到這個目錄下,接著執行regsvr32 iviewers.dll即可。
如果出現:對DllRegisterServer的調用失敗,錯誤代碼為0x80070005
那是UAC的緣故,你沒有以管理員模式打開命令提示符。
如果解決了,應該能正常打開,左側招到PowerPoint那項,雙擊打開,
然后呢,這個工具不支持查找,你可以把內容全選然后復制到如Sublime Text
這樣的代碼查看工具上,ctrl + f 查找關鍵字,然后一步步定位出實現某個
功能需要用到的一些函數。
小結
本節講解了一波利用Python-pptx批量生成N張PPT的套路,不禁再一次感嘆
人生苦短,我用Python,最后祝六一兒童節快樂~
參考文獻:
- python-pptx庫中文文檔及使用樣例
- python使用win32com的心得
附:最終代碼(都可以在:https://github.com/coder-pig/ReptileSomething 找到):
import pptx import config as c import tools as t from pptx import Presentation from pptx.dml.color import RGBColor from pptx.util import Inches, Pt from pptx.enum.text import MSO_VERTICAL_ANCHOR, PP_PARAGRAPH_ALIGNMENT import osrules_path = os.path.join(c.res_documents, 'ppt_rules.txt') ppt_bg_path = os.path.join(c.res_pictures, 'ppt_bg.png') laoluo_bg_path = os.path.join(c.res_pictures, 'laoluo.jpg') last_bg_path = os.path.join(c.res_pictures, 'last.png') story_bg_path = os.path.join(c.res_pictures, 'story.png') ppt_file_name = os.path.join(c.outputs_documents_path, 'result.pptx')# 厘米轉英寸 def cm_to_in(cm):return Inches(cm / 2.54)# 判斷課件是否存在,不存在的新建一個空白 def ppt_existed(ppt_name):if not os.path.exists(ppt_name):prs = Presentation()prs.slide_height = cm_to_in(14.35)prs.slide_width = cm_to_in(25.5)prs.save(ppt_name)# 模板1:只有一張圖片 def model_1(prs, pic_path):slide = prs.slides.add_slide(prs.slide_layouts[6])slide.shapes.add_picture(pic_path, cm_to_in(0), cm_to_in(0), cm_to_in(25.4), cm_to_in(14.288))# 模板2:只有一個標題 def model_2(prs, title):slide = prs.slides.add_slide(prs.slide_layouts[6])slide.shapes.add_picture(ppt_bg_path, cm_to_in(0), cm_to_in(0), cm_to_in(25.4), cm_to_in(14.288))title_box = slide.shapes.add_textbox(cm_to_in(3.89), cm_to_in(5.35), cm_to_in(17.61), cm_to_in(3.59))paragraph = title_box.text_frame.add_paragraph()paragraph.text = titleparagraph.vertical_anchor = MSO_VERTICAL_ANCHOR.MIDDLEparagraph.alignment = PP_PARAGRAPH_ALIGNMENT.CENTERparagraph.font.size = Pt(60)paragraph.font.name = '微軟雅黑'paragraph.font.color.rgb = RGBColor(255, 255, 255)# 模板3:有字,有圖片 def model_3(prs, title, pic_path):slide = prs.slides.add_slide(prs.slide_layouts[6])slide.shapes.add_picture(ppt_bg_path, cm_to_in(0), cm_to_in(0), cm_to_in(25.4), cm_to_in(14.288))img = slide.shapes.add_picture(pic_path, cm_to_in(0), cm_to_in(0), height=cm_to_in(11.72))img.left = int(prs.slide_width / 2 + (prs.slide_width / 2 - img.width) / 2)img.top = int((prs.slide_height - img.height) / 2)title_box = slide.shapes.add_textbox(cm_to_in(2), cm_to_in(5.35), int(prs.slide_width / 3), cm_to_in(3.59))paragraph = title_box.text_frame.add_paragraph()paragraph.text = titleparagraph.font.size = Pt(44)paragraph.font.name = '微軟雅黑'paragraph.font.color.rgb = RGBColor(255, 255, 255)# 模板4:兩行文字,一大一小 def model_4(prs, title, content):slide = prs.slides.add_slide(prs.slide_layouts[6])slide.shapes.add_picture(ppt_bg_path, cm_to_in(0), cm_to_in(0), cm_to_in(25.4), cm_to_in(14.288))# 一級標題title_box_1 = slide.shapes.add_textbox(cm_to_in(1.27), cm_to_in(2.04), cm_to_in(22.86), cm_to_in(3.18))paragraph_1 = title_box_1.text_frame.add_paragraph()paragraph_1.text = titleparagraph_1.vertical_anchor = MSO_VERTICAL_ANCHOR.MIDDLEparagraph_1.alignment = PP_PARAGRAPH_ALIGNMENT.CENTERparagraph_1.font.size = Pt(44)paragraph_1.font.name = '微軟雅黑'paragraph_1.font.color.rgb = RGBColor(255, 255, 255)# 二級標題title_box_2 = slide.shapes.add_textbox(cm_to_in(7.46), cm_to_in(6.4), cm_to_in(10.47), cm_to_in(2.39))paragraph_2 = title_box_2.text_frame.add_paragraph()paragraph_2.text = titleparagraph_2.vertical_anchor = MSO_VERTICAL_ANCHOR.MIDDLEparagraph_2.alignment = PP_PARAGRAPH_ALIGNMENT.CENTERparagraph_2.font.size = Pt(32)paragraph_2.font.name = '微軟雅黑'paragraph_2.font.color.rgb = RGBColor(255, 255, 255)# 模板5:一行文字,多個小標題 def model_5(prs, title, *content):slide = prs.slides.add_slide(prs.slide_layouts[6])slide.shapes.add_picture(ppt_bg_path, cm_to_in(0), cm_to_in(0), cm_to_in(25.4), cm_to_in(14.288))title_box_1 = slide.shapes.add_textbox(cm_to_in(1.27), cm_to_in(2.04), cm_to_in(22.86), cm_to_in(3.18))paragraph_1 = title_box_1.text_frame.add_paragraph()paragraph_1.text = titleparagraph_1.vertical_anchor = MSO_VERTICAL_ANCHOR.MIDDLEparagraph_1.alignment = PP_PARAGRAPH_ALIGNMENT.CENTERparagraph_1.font.size = Pt(44)paragraph_1.font.name = '微軟雅黑'paragraph_1.font.color.rgb = RGBColor(255, 255, 255)# 動態構建小標題module_width = (prs.slide_width - cm_to_in(1.27) * 2) / len(content)for i in range(0, 3):title_box = slide.shapes.add_textbox(cm_to_in(1.27) + i * module_width, cm_to_in(6.4), module_width,cm_to_in(2.39))paragraph = title_box.text_frame.add_paragraph()paragraph.text = content[i]paragraph.vertical_anchor = MSO_VERTICAL_ANCHOR.MIDDLEparagraph.alignment = PP_PARAGRAPH_ALIGNMENT.CENTERparagraph.font.size = Pt(32)paragraph.font.name = '微軟雅黑'paragraph.font.color.rgb = RGBColor(255, 255, 255)# 讀取配置文件調用模板的方法 def read_rules(prs, filename):if os.path.exists(filename):with open(filename, 'r+', encoding='utf-8') as f:for rule in f:word_list = rule.replace('\n', '').split(',')if 'png' in rule or 'jpg' in rule:if len(word_list) == 1:model_1(prs, os.path.join(c.res_pictures, word_list[0]))else:model_3(prs, word_list[0], os.path.join(c.res_pictures, word_list[1]))else:if len(word_list) == 1:model_2(prs, word_list[0])elif len(word_list) == 2:model_4(prs, word_list[0], word_list[1])elif len(word_list) == 4:model_5(prs, word_list[0], word_list[1], word_list[2], word_list[3])if __name__ == '__main__':t.is_dir_existed(c.outputs_documents_path)ppt_existed(ppt_file_name)presentation = Presentation(ppt_file_name)read_rules(presentation, rules_path)presentation.save(ppt_file_name)來啊,Py交易啊
想加群一起學習Py的可以加下,智障機器人小Pig,驗證信息里包含:
Python,python,py,Py,加群,交易,屁眼 中的一個關鍵詞即可通過;
驗證通過后回復 加群 即可獲得加群鏈接(不要把機器人玩壞了!!!)~~~
歡迎各種像我一樣的Py初學者,Py大神加入,一起愉快地交流學♂習,van♂轉py。
總結
以上是生活随笔為你收集整理的小猪的Python学习之旅 —— 22.安静!吵到我用TNT了的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 手机被锁在耳机模式了
- 下一篇: [转载]析构函数的虚析构和非虚析构调用的