Download utils/ppt_utils.py from PerrinT/office: direct link, hf CLI and curl.
- Browser
- Download file 4.99 kB
-
https://huggingface.co/spaces/PerrinT/office/resolve/main/utils/ppt_utils.py
- Command line
-
hf download hf://spaces/PerrinT/office/utils/ppt_utils.py
-
curl -L -o ppt_utils.py https://huggingface.co/spaces/PerrinT/office/resolve/main/utils/ppt_utils.py
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) | |