office / utils /ppt_utils.py
PerrinT94
初始化:办公工具平台
3373b3e
Raw History Blame Contribute Delete
4.99 kB
from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.enum.text import PP_ALIGN
from pptx.dml.color import RGBColor
import io
def create_ppt(title: str, slides_data: list, template_style: str = "商务") -> bytes:
"""创建PPT"""
prs = Presentation()
# 设置模板颜色
colors = get_template_colors(template_style)
# 添加标题页
add_title_slide(prs, title, colors)
# 添加内容页
for slide_data in slides_data:
add_content_slide(prs, slide_data, colors)
# 保存到内存
buffer = io.BytesIO()
prs.save(buffer)
return buffer.getvalue()
def get_template_colors(style: str) -> dict:
"""获取模板颜色"""
templates = {
"商务": {
"primary": RGBColor(0, 82, 136), # 深蓝
"secondary": RGBColor(0, 120, 215), # 蓝色
"accent": RGBColor(255, 185, 0), # 金色
"text": RGBColor(51, 51, 51), # 深灰
"background": RGBColor(255, 255, 255) # 白色
},
"科技": {
"primary": RGBColor(88, 86, 214), # 紫色
"secondary": RGBColor(0, 200, 150), # 青色
"accent": RGBColor(255, 100, 100), # 红色
"text": RGBColor(30, 30, 30), # 近黑
"background": RGBColor(245, 245, 250) # 浅灰蓝
},
"教育": {
"primary": RGBColor(46, 139, 87), # 绿色
"secondary": RGBColor(70, 130, 180), # 钢蓝
"accent": RGBColor(255, 165, 0), # 橙色
"text": RGBColor(51, 51, 51), # 深灰
"background": RGBColor(255, 255, 255) # 白色
},
"简约": {
"primary": RGBColor(60, 60, 60), # 深灰
"secondary": RGBColor(120, 120, 120), # 中灰
"accent": RGBColor(200, 50, 50), # 红色
"text": RGBColor(51, 51, 51), # 深灰
"background": RGBColor(255, 255, 255) # 白色
}
}
return templates.get(style, templates["商务"])
def add_title_slide(prs, title: str, colors: dict):
"""添加标题页"""
slide_layout = prs.slide_layouts[0] # 标题布局
slide = prs.slides.add_slide(slide_layout)
# 设置标题
title_shape = slide.shapes.title
title_shape.text = title
title_shape.text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER
title_shape.text_frame.paragraphs[0].font.size = Pt(44)
title_shape.text_frame.paragraphs[0].font.color.rgb = colors["primary"]
# 设置副标题
if len(slide.placeholders) > 1:
subtitle = slide.placeholders[1]
subtitle.text = "自动生成的演示文稿"
subtitle.text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER
subtitle.text_frame.paragraphs[0].font.size = Pt(20)
subtitle.text_frame.paragraphs[0].font.color.rgb = colors["secondary"]
def add_content_slide(prs, slide_data: dict, colors: dict):
"""添加内容页"""
slide_layout = prs.slide_layouts[1] # 标题和内容布局
slide = prs.slides.add_slide(slide_layout)
# 设置标题
title_shape = slide.shapes.title
title_shape.text = slide_data.get("title", "")
title_shape.text_frame.paragraphs[0].font.size = Pt(32)
title_shape.text_frame.paragraphs[0].font.color.rgb = colors["primary"]
# 设置内容
if len(slide.placeholders) > 1:
content = slide.placeholders[1]
content.text = ""
for point in slide_data.get("content", []):
p = content.text_frame.add_paragraph()
p.text = point
p.font.size = Pt(18)
p.font.color.rgb = colors["text"]
p.space_after = Pt(12)
p.level = 0
# 添加备注
if slide_data.get("notes"):
notes_slide = slide.notes_slide
notes_slide.notes_text_frame.text = slide_data["notes"]
def create_ppt_from_outline(outline: str, template_style: str = "商务") -> bytes:
"""从大纲文本创建PPT"""
lines = outline.strip().split('\n')
title = lines[0] if lines else "演示文稿"
slides_data = []
current_slide = None
for line in lines[1:]:
line = line.strip()
if not line:
continue
# 判断是否是标题行(以数字开头或以#开头)
if line[0].isdigit() or line.startswith('#') or line.startswith('**'):
if current_slide:
slides_data.append(current_slide)
# 提取标题文本
slide_title = line.lstrip('0123456789.#* ').strip()
current_slide = {"title": slide_title, "content": []}
elif current_slide:
# 作为要点添加
point = line.lstrip('- •* ').strip()
if point:
current_slide["content"].append(point)
if current_slide:
slides_data.append(current_slide)
return create_ppt(title, slides_data, template_style)