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)