File size: 4,989 Bytes
3373b3e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | 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)
|