Python使用python-pptx庫實(shí)現(xiàn)PPT自動化
做了這么多年技術(shù),PPT還真是躲不開。每次開會前熬夜做PPT,改來改去煩死人。
不是字體對不齊,就是配色不統(tǒng)一,搞得人焦頭爛額。
有時(shí)候明明內(nèi)容都準(zhǔn)備好了,光調(diào)整格式就得花上大半天。
直到我發(fā)現(xiàn)了python-pptx這個(gè)寶藏庫,整個(gè)人都輕松了。
一個(gè)腳本搞定的事兒,干嘛要手動點(diǎn)來點(diǎn)去?
寫好代碼一鍵生成,不僅省時(shí)省力,而且格式統(tǒng)一,看著特別專業(yè)。
說真的,我剛開始也不信這玩意能這么厲害。
但是當(dāng)我用它處理了一個(gè)真實(shí)項(xiàng)目,把原來要忙活一下午的工作縮短到十來分鐘,我就知道這東西真沒吹牛。
關(guān)鍵是不會出錯(cuò),格式統(tǒng)一,看著特別專業(yè)。
這個(gè)庫最大的優(yōu)勢就是自動化程度高。
你想想看,手動做PPT的時(shí)候要點(diǎn)多少次鼠標(biāo)?要調(diào)整多少次格式?
用代碼的話,寫一次模板,以后就可以一鍵生成,而且格式永遠(yuǎn)統(tǒng)一,不會出現(xiàn)字體大小不一致的尷尬。
python-pptx是啥?
說白了就是用Python代碼來操作PPT的工具庫。
它能讓你用代碼來創(chuàng)建、修改和自動化處理PPT文件,比手動操作效率高出幾十倍。
裝起來賊簡單,一行命令就搞定:
pip install python-pptx
裝好就能用,不用管什么Office啊WPS的,跨平臺也沒問題。
在Windows、Mac還是Linux上都能完美運(yùn)行,這就避免了很多環(huán)境配置的麻煩。
不過要記得,這個(gè)庫只支持.pptx格式,老版本的.ppt得先另存為新格式。
這是因?yàn)?pptx采用了更現(xiàn)代的XML格式,便于程序讀寫和處理。
如果你手上有老版本的PPT文件,記得先用Office或WPS另存為.pptx格式再處理。
python-pptx的功能相當(dāng)強(qiáng)大,從簡單的文本編輯到復(fù)雜的圖表制作都能搞定。
它不僅能處理文字、圖片、形狀這些基本元素,還能創(chuàng)建各種圖表,設(shè)置動畫效果,甚至能處理母版和布局。
對于需要批量處理PPT或者經(jīng)常制作格式統(tǒng)一的PPT的人來說,這簡直就是一個(gè)神器。
從零開始搞個(gè)PPT
來看看最基礎(chǔ)的PPT制作:
from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.enum.text import PP_ALIGN
from pptx.dml.color import RGBColor
class PPTCreator:
def __init__(self):
self.prs = Presentation()
def add_title_slide(self, title, subtitle=None):
"""添加標(biāo)題頁"""
slide = self.prs.slides.add_slide(self.prs.slide_layouts[0])
title_shape = slide.shapes.title
subtitle_shape = slide.placeholders[1]
# 設(shè)置標(biāo)題
title_shape.text = title
title_shape.text_frame.paragraphs[0].font.size = Pt(44)
title_shape.text_frame.paragraphs[0].font.bold = True
title_shape.text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER
# 設(shè)置副標(biāo)題
if subtitle:
subtitle_shape.text = subtitle
subtitle_shape.text_frame.paragraphs[0].font.size = Pt(32)
return slide
def save(self, filename):
"""保存PPT文件"""
self.prs.save(filename)
# 使用示例
ppt = PPTCreator()
ppt.add_title_slide("超級厲害的PPT", "powered by Python")
ppt.save('demo.pptx')
這就整出來一個(gè)PPT了,是不是比手動點(diǎn)點(diǎn)點(diǎn)快多了?
而且格式統(tǒng)一,不會出現(xiàn)字體大小不一致的尷尬。
用代碼生成的PPT,每個(gè)標(biāo)題、每個(gè)段落的字體大小都完全一致,不會出現(xiàn)手動調(diào)整時(shí)可能產(chǎn)生的細(xì)微差異。
特別是在做系列PPT的時(shí)候,這種統(tǒng)一性顯得尤為重要,能讓整個(gè)作品看起來更專業(yè)、更有質(zhì)感。
花式玩法
光整個(gè)標(biāo)題頁太基礎(chǔ)了,來點(diǎn)花活:
class FancyPPTCreator(PPTCreator):
def add_content_slide(self, title, content_list, layout_idx=1):
"""添加內(nèi)容頁"""
slide = self.prs.slides.add_slide(self.prs.slide_layouts[layout_idx])
# 設(shè)置標(biāo)題
title_shape = slide.shapes.title
title_shape.text = title
title_shape.text_frame.paragraphs[0].font.size = Pt(36)
# 設(shè)置內(nèi)容
body_shape = slide.shapes.placeholders[1]
tf = body_shape.text_frame
# 添加項(xiàng)目符號
for idx, item in enumerate(content_list):
p = tf.add_paragraph()
p.text = item
p.font.size = Pt(18)
p.font.name = '微軟雅黑'
# 設(shè)置不同層級的縮進(jìn)
level = 0 if idx == 0 else 1
p.level = level
return slide
def add_two_column_slide(self, title, left_content, right_content):
"""添加雙欄內(nèi)容頁"""
slide = self.prs.slides.add_slide(self.prs.slide_layouts[3])
# 設(shè)置標(biāo)題
title_shape = slide.shapes.title
title_shape.text = title
# 左側(cè)內(nèi)容
left_shape = slide.shapes.add_textbox(
Inches(1), Inches(1.5),
Inches(3.5), Inches(5)
)
left_tf = left_shape.text_frame
left_tf.text = left_content
# 右側(cè)內(nèi)容
right_shape = slide.shapes.add_textbox(
Inches(5), Inches(1.5),
Inches(3.5), Inches(5)
)
right_tf = right_shape.text_frame
right_tf.text = right_content
return slide
溫馨提示:字體得是系統(tǒng)里有的,不然會用默認(rèn)字體替代哦!
圖表繪制大法
數(shù)據(jù)展示少不了圖表,來整個(gè)漂亮的:
class ChartPPTCreator(FancyPPTCreator):
def add_chart_slide(self, title, chart_data, chart_type=None):
"""添加圖表頁"""
slide = self.prs.slides.add_slide(self.prs.slide_layouts[6])
# 設(shè)置標(biāo)題
title_shape = slide.shapes.title
title_shape.text = title
# 創(chuàng)建圖表數(shù)據(jù)
chart_data = CategoryChartData()
# 添加類別
categories = chart_data['categories']
values = chart_data['values']
series_name = chart_data.get('series_name', '數(shù)據(jù)')
chart_data.categories = categories
chart_data.add_series(series_name, values)
# 設(shè)置圖表類型
if chart_type is None:
chart_type = XL_CHART_TYPE.COLUMN_CLUSTERED
# 添加圖表
x, y = Inches(2), Inches(2)
cx, cy = Inches(6), Inches(4.5)
chart = slide.shapes.add_chart(
chart_type, x, y, cx, cy, chart_data
).chart
# 設(shè)置圖表樣式
self._style_chart(chart)
return slide
def _style_chart(self, chart):
"""設(shè)置圖表樣式"""
# 設(shè)置標(biāo)題
chart.has_title = True
chart.chart_title.text_frame.paragraphs[0].font.size = Pt(18)
# 設(shè)置圖例
chart.has_legend = True
chart.legend.position = XL_LEGEND_POSITION.BOTTOM
# 設(shè)置網(wǎng)格線
chart.value_axis.has_major_gridlines = True
chart.value_axis.major_gridlines.format.line.color.rgb = RGBColor(200, 200, 200)
def add_multi_series_chart(self, title, data_dict):
"""添加多系列圖表"""
slide = self.prs.slides.add_slide(self.prs.slide_layouts[6])
chart_data = CategoryChartData()
chart_data.categories = data_dict['categories']
# 添加多個(gè)系列
for series_name, values in data_dict['series'].items():
chart_data.add_series(series_name, values)
# 添加圖表
x, y = Inches(2), Inches(2)
cx, cy = Inches(6), Inches(4.5)
chart = slide.shapes.add_chart(
XL_CHART_TYPE.LINE, x, y, cx, cy, chart_data
).chart
self._style_chart(chart)
return slide
高級圖片處理
PPT里插圖片是常事,來看看怎么玩:
class ImagePPTCreator(ChartPPTCreator):
def add_image_slide(self, title, image_path, position=None):
"""添加圖片頁"""
slide = self.prs.slides.add_slide(self.prs.slide_layouts[6])
# 設(shè)置標(biāo)題
title_shape = slide.shapes.title
title_shape.text = title
# 處理圖片
img_path = self._process_image(image_path)
# 設(shè)置圖片位置
if position is None:
position = {
'left': Inches(2),
'top': Inches(2),
'width': Inches(6),
'height': Inches(4.5)
}
# 添加圖片
slide.shapes.add_picture(
img_path,
position['left'],
position['top'],
position['width'],
position['height']
)
return slide
def _process_image(self, image_path, max_size_mb=2):
"""處理圖片尺寸和大小"""
from PIL import Image
import os
# 創(chuàng)建臨時(shí)文件夾
if not os.path.exists('temp'):
os.makedirs('temp')
# 復(fù)制圖片到臨時(shí)文件
temp_path = os.path.join('temp', os.path.basename(image_path))
img = Image.open(image_path)
# 壓縮圖片直到小于指定大小
while os.path.getsize(image_path) > max_size_mb * 1024 * 1024:
width, height = img.size
img = img.resize((int(width*0.8), int(height*0.8)))
img.save(temp_path)
return temp_path
批量制作神器
要是要做一堆類似的PPT,手動改不得累死?整個(gè)批量處理:
class BatchPPTCreator(ImagePPTCreator):
def batch_create(self, data_list, template_path=None):
"""批量創(chuàng)建PPT"""
for item in data_list:
# 使用模板或創(chuàng)建新PPT
if template_path:
self.prs = Presentation(template_path)
else:
self.prs = Presentation()
try:
# 創(chuàng)建標(biāo)題頁
self.add_title_slide(
item['title'],
item.get('subtitle')
)
# 創(chuàng)建內(nèi)容頁
if 'content' in item:
self.add_content_slide(
"主要內(nèi)容",
item['content']
)
# 創(chuàng)建圖表頁
if 'chart_data' in item:
self.add_chart_slide(
"數(shù)據(jù)分析",
item['chart_data']
)
# 創(chuàng)建圖片頁
if 'images' in item:
for img in item['images']:
self.add_image_slide(
img['title'],
img['path']
)
# 保存文件
output_path = f"output/{item['title']}.pptx"
self.save(output_path)
print(f"創(chuàng)建成功:{output_path}")
except Exception as e:
print(f"處理 {item['title']} 時(shí)出錯(cuò):{str(e)}")
continue
模板套用大法
每次從零開始太麻煩?用模板啊:
class TemplatePPTCreator(BatchPPTCreator):
def apply_template(self, template_path, data):
"""應(yīng)用模板"""
self.prs = Presentation(template_path)
# 遍歷所有頁面
for slide_idx, slide in enumerate(self.prs.slides):
# 遍歷頁面中的所有形狀
for shape in slide.shapes:
if not shape.has_text_frame:
continue
# 替換文本中的占位符
text_frame = shape.text_frame
for paragraph in text_frame.paragraphs:
for run in paragraph.runs:
for key, value in data.items():
placeholder = f'{{{key}}}'
if placeholder in run.text:
run.text = run.text.replace(
placeholder,
str(value)
)
def create_from_template(self, template_path, data_list):
"""批量使用模板創(chuàng)建PPT"""
for item in data_list:
try:
# 應(yīng)用模板
self.apply_template(template_path, item)
# 保存文件
output_path = f"output/{item['title']}.pptx"
self.save(output_path)
print(f"創(chuàng)建成功:{output_path}")
except Exception as e:
print(f"處理 {item['title']} 時(shí)出錯(cuò):{str(e)}")
continue
實(shí)用工具函數(shù)
來點(diǎn)實(shí)用小工具:
class PPTUtils:
@staticmethod
def check_font(font_name):
"""檢查字體是否可用"""
from matplotlib.font_manager import FontManager
fm = FontManager()
font_list = [f.name for f in fm.ttflist]
return font_name in font_list
@staticmethod
def convert_to_pdf(pptx_path):
"""轉(zhuǎn)換PPT為PDF"""
import comtypes.client
powerpoint = comtypes.client.CreateObject("Powerpoint.Application")
powerpoint.Visible = True
ppt = powerpoint.Presentations.Open(pptx_path)
pdf_path = pptx_path.replace('.pptx', '.pdf')
ppt.SaveAs(pdf_path, 32) # 32 是PDF格式
ppt.Close()
powerpoint.Quit()
@staticmethod
def merge_ppts(ppt_list, output_path):
"""合并多個(gè)PPT"""
merged_ppt = Presentation()
for ppt_path in ppt_list:
ppt = Presentation(ppt_path)
for slide in ppt.slides:
# 復(fù)制頁面
new_slide = merged_ppt.slides.add_slide(
merged_ppt.slide_layouts[
slide.slide_layout.index
]
)
# 復(fù)制所有形狀
for shape in slide.shapes:
el = shape.element
new_el = deepcopy(el)
new_slide.shapes._spTree.insert_element_before(
new_el,
'p:extLst'
)
merged_ppt.save(output_path)
使用示例
來個(gè)完整的使用示例:
def main():
# 創(chuàng)建PPT生成器
creator = TemplatePPTCreator()
# 準(zhǔn)備數(shù)據(jù)
data_list = [
{
'title': '2023年度報(bào)告',
'subtitle': '技術(shù)部',
'content': [
'項(xiàng)目完成情況',
'技術(shù)創(chuàng)新',
'團(tuán)隊(duì)建設(shè)',
'未來規(guī)劃'
],
'chart_data': {
'categories': ['Q1', 'Q2', 'Q3', 'Q4'],
'series': {
'項(xiàng)目數(shù)': [10, 15, 12, 18],
'完成率': [0.8, 0.85, 0.9, 0.95]
}
},
'images': [
{
'title': '團(tuán)隊(duì)照片',
'path': 'images/team.jpg'
}
]
}
]
# 批量生成PPT
creator.batch_create(data_list)
# 轉(zhuǎn)換為PDF
PPTUtils.convert_to_pdf('output/2023年度報(bào)告.pptx')
if __name__ == '__main__':
main()
這些代碼夠你玩一陣子了。
不過記住啊,代碼寫完得測試,別一上來就真實(shí)PPT,要是把老板的報(bào)告搞壞了可就尷尬了。
還有個(gè)事兒,這些代碼我都實(shí)際用過,不同Python版本可能會有點(diǎn)差異,用的時(shí)候記得看看版本兼容性。
要是遇到問題,就打印下錯(cuò)誤信息,基本都能解決。
寫代碼也要講究性價(jià)比,能用簡單方法解決的問題,咱就別上重型武器了。
畢竟,能跑起來的代碼才是好代碼!
以上就是Python使用python-pptx庫實(shí)現(xiàn)PPT自動化的詳細(xì)內(nèi)容,更多關(guān)于Python PPT自動化的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Django 博客實(shí)現(xiàn)簡單的全文搜索的示例代碼
這篇文章主要介紹了Django 博客實(shí)現(xiàn)簡單的全文搜索的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02
使用pyecharts在jupyter notebook上繪圖
這篇文章主要介紹了使用pyecharts在jupyter notebook上繪圖,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2017-07-07
python基于pygame實(shí)現(xiàn)飛機(jī)大作戰(zhàn)小游戲
這篇文章主要為大家詳細(xì)介紹了python基于pygame實(shí)現(xiàn)飛機(jī)大作戰(zhàn)小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-11-11
Pandas之缺失數(shù)據(jù)的實(shí)現(xiàn)
這篇文章主要介紹了Pandas之缺失數(shù)據(jù)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
python GUI庫圖形界面開發(fā)之PyQt5訪問系統(tǒng)剪切板QClipboard類詳細(xì)使用方法與實(shí)例
這篇文章主要介紹了python GUI庫圖形界面開發(fā)之PyQt5訪問系統(tǒng)剪切板QClipboard類詳細(xì)使用方法與實(shí)例,需要的朋友可以參考下2020-02-02
python按照行來讀取txt文件全部內(nèi)容(去除空行處理掉\t,\n后以列表方式返回)
這篇文章主要介紹了python按照行來讀取txt文件全部內(nèi)容 ,去除空行,處理掉\t,\n后,以列表方式返回,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06
Python實(shí)戰(zhàn)之外星人入侵游戲示例代碼
這篇文章主要介紹了利用Python編寫的外星人入侵游戲的示例代碼,文中的代碼講解詳細(xì),對我們學(xué)習(xí)Python有一定的幫助,感興趣的可以學(xué)習(xí)一下2022-01-01

