【Python实战】自动化生成PPT演示文稿:python-pptx+AI内容生成+图表嵌入

张开发
2026/6/7 13:32:39 15 分钟阅读
【Python实战】自动化生成PPT演示文稿:python-pptx+AI内容生成+图表嵌入
一、项目背景1.1 痛点分析PPT制作是职场高频场景但传统方式效率极低环节手工方式时间找模板搜索下载2小时填内容手动输入3小时调排版反复调整3小时做图表Excel复制2小时改配色逐页修改1小时总计-11小时一份30页PPT就要一天半改3版就是4天。1.2 技术需求核心需求AI自动生成PPT内容大纲自动创建幻灯片并填充内容自动插入数据图表支持自定义模板和配色一键导出标准.pptx文件二、技术架构原始内容 → AI生成大纲 → 创建幻灯片 → 填充内容 → 插入图表 → 导出PPT↑ ↑ ↑ ↑ ↑ ↑文本/数据 DashScope python-pptx python-pptx matplotlib python-pptxQwen3技术栈 - **python-pptx**PPT创建和编辑 - **DashScope/Qwen3**AI生成内容大纲 - **matplotlib**图表生成 - **pandas**数据处理 - **Pillow**图片处理 --- ## 三、环境准备 ### 3.1 安装依赖 bash pip install python-pptx dashscope matplotlib pandas pillow3.2 配置# config.py DASHSCOPE_API_KEY your-api-key-here # PPT配色方案 COLOR_SCHEMES { business: { primary: 2C3E50, secondary: 3498DB, accent: 2ECC71, text: 333333, background: FFFFFF }, tech: { primary: 0D1B2A, secondary: 2196F3, accent: 00BCD4, text: EEEEEE, background: 1B2838 }, vibrant: { primary: FF6B6B, secondary: 4ECDC4, accent: 45B7D1, text: 333333, background: FFFFFF } }四、核心模块实现4.1 AI内容生成模块用Qwen3自动生成PPT大纲和每页内容import dashscope import json import re class ContentGenerator: def __init__(self, api_key): dashscope.api_key api_key def generate_outline(self, topic, raw_content, page_count12): AI生成PPT大纲 prompt f 你是一位PPT设计专家。请根据以下信息生成PPT大纲。 主题{topic} 原始内容{raw_content[:3000]} 页数要求{page_count}页 请返回JSON格式 {{ title: PPT标题, subtitle: 副标题, slides: [ {{ page: 1, type: cover, title: 封面标题, subtitle: 副标题 }}, {{ page: 2, type: toc, title: 目录, items: [章节1, 章节2, 章节3] }}, {{ page: 3, type: content, title: 页面标题, bullets: [要点1, 要点2, 要点3] }}, {{ page: 4, type: chart, title: 数据图表页标题, chart_type: bar/line/pie, chart_data: {{labels: [], values: []}} }}, {{ page: 12, type: end, title: 谢谢, subtitle: QA }} ] }} 规则 1. 封面页1张、目录页1张、结尾页1张 2. 内容页每页3-5个要点 3. 至少2页数据图表页 4. 内容要有逻辑递进关系 5. 标题简洁有力不超过15字 response dashscope.Generation.call( modelqwen3-72b, messages[{role: user, content: prompt}], result_formatmessage ) content response.output.choices[0].message.content json_match re.search(r\{.*\}, content, re.DOTALL) if json_match: return json.loads(json_match.group()) return None def generate_speaker_notes(self, slide_content): AI生成演讲稿 prompt f 请为以下PPT页面生成演讲稿口语化1-2分钟 标题{slide_content.get(title, )} 要点{slide_content.get(bullets, [])} 要求 - 口语化不要念稿感 - 每个要点展开1-2句 - 有过渡语连接各点 - 总时长控制在1-2分钟 response dashscope.Generation.call( modelqwen3-72b, messages[{role: user, content: prompt}], result_formatmessage ) return response.output.choices[0].message.content4.2 图表生成模块用matplotlib生成图表并保存为图片供PPT嵌入import matplotlib.pyplot as plt import matplotlib matplotlib.rcParams[font.sans-serif] [SimHei] matplotlib.rcParams[axes.unicode_minus] False class ChartFactory: def __init__(self, color_schemebusiness): self.colors list(COLOR_SCHEMES[color_scheme].values())[:5] def create_chart(self, chart_type, data, title, output_path): 根据类型生成图表 fig, ax plt.subplots(figsize(10, 6)) if chart_type bar: self._bar_chart(ax, data, title) elif chart_type line: self._line_chart(ax, data, title) elif chart_type pie: self._pie_chart(ax, data, title) elif chart_type radar: plt.close() fig plt.figure(figsize(8, 8)) ax fig.add_subplot(111, projectionpolar) self._radar_chart(ax, data, title) plt.tight_layout() plt.savefig(output_path, dpi200, bbox_inchestight, transparentTrue) plt.close() return output_path def _bar_chart(self, ax, data, title): 柱状图 labels data[labels] values data[values] bars ax.bar(labels, values, color[#3498DB, #2ECC71, #E74C3C, #F39C12, #9B59B6][:len(labels)]) ax.set_title(title, fontsize16, fontweightbold, pad15) ax.spines[top].set_visible(False) ax.spines[right].set_visible(False) for bar in bars: height bar.get_height() ax.text(bar.get_x() bar.get_width()/2., height, f{height:,.0f}, hacenter, vabottom, fontsize12, fontweightbold) def _line_chart(self, ax, data, title): 折线图 labels data[labels] values data[values] ax.plot(labels, values, markero, color#3498DB, linewidth2.5, markersize8) ax.fill_between(range(len(labels)), values, alpha0.15, color#3498DB) ax.set_title(title, fontsize16, fontweightbold, pad15) ax.grid(True, alpha0.3) ax.spines[top].set_visible(False) ax.spines[right].set_visible(False) def _pie_chart(self, ax, data, title): 饼图 labels data[labels] values data[values] colors [#3498DB, #2ECC71, #E74C3C, #F39C12, #9B59B6][:len(labels)] wedges, texts, autotexts ax.pie( values, labelslabels, autopct%1.1f%%, colorscolors, startangle90, textprops{fontsize: 12} ) for autotext in autotexts: autotext.set_fontweight(bold) ax.set_title(title, fontsize16, fontweightbold, pad15)4.3 PPT构建模块用python-pptx创建专业级PPTfrom pptx import Presentation from pptx.util import Inches, Pt, Emu from pptx.dml.color import RGBColor from pptx.enum.text import PP_ALIGN, MSO_ANCHOR from pptx.enum.shapes import MSO_SHAPE class PPTBuilder: def __init__(self, template_pathNone, color_schemebusiness): if template_path: self.prs Presentation(template_path) else: self.prs Presentation() self.prs.slide_width Inches(13.33) self.prs.slide_height Inches(7.5) self.scheme COLOR_SCHEMES[color_scheme] def add_cover(self, title, subtitle): 封面页 slide self.prs.slides.add_slide(self.prs.slide_layouts[6]) # 空白布局 # 背景色 bg slide.background fill bg.fill fill.solid() fill.fore_color.rgb RGBColor.from_string(self.scheme[primary]) # 标题 txBox slide.shapes.add_textbox(Inches(1), Inches(2), Inches(11), Inches(2)) tf txBox.text_frame tf.word_wrap True p tf.paragraphs[0] p.text title p.font.size Pt(44) p.font.bold True p.font.color.rgb RGBColor(0xFF, 0xFF, 0xFF) p.alignment PP_ALIGN.CENTER # 副标题 txBox2 slide.shapes.add_textbox(Inches(1), Inches(4.2), Inches(11), Inches(1)) tf2 txBox2.text_frame p2 tf2.paragraphs[0] p2.text subtitle p2.font.size Pt(22) p2.font.color.rgb RGBColor(0xCC, 0xCC, 0xCC) p2.alignment PP_ALIGN.CENTER def add_toc(self, title, items): 目录页 slide self.prs.slides.add_slide(self.prs.slide_layouts[6]) # 标题 self._add_title(slide, title) # 目录项 for i, item in enumerate(items): y_pos Inches(2.2 i * 0.8) # 编号圆形 shape slide.shapes.add_shape( MSO_SHAPE.OVAL, Inches(1.5), y_pos, Inches(0.5), Inches(0.5) ) shape.fill.solid() shape.fill.fore_color.rgb RGBColor.from_string(self.scheme[secondary]) shape.line.fill.background() tf shape.text_frame tf.paragraphs[0].text str(i 1) tf.paragraphs[0].font.size Pt(16) tf.paragraphs[0].font.color.rgb RGBColor(0xFF, 0xFF, 0xFF) tf.paragraphs[0].font.bold True tf.paragraphs[0].alignment PP_ALIGN.CENTER tf.vertical_anchor MSO_ANCHOR.MIDDLE # 文字 txBox slide.shapes.add_textbox(Inches(2.3), y_pos, Inches(8), Inches(0.5)) tf txBox.text_frame tf.paragraphs[0].text item tf.paragraphs[0].font.size Pt(20) tf.paragraphs[0].font.color.rgb RGBColor.from_string(self.scheme[text]) tf.vertical_anchor MSO_ANCHOR.MIDDLE def add_content(self, title, bullets, notesNone): 内容页 slide self.prs.slides.add_slide(self.prs.slide_layouts[6]) # 标题 self._add_title(slide, title) # 要点 txBox slide.shapes.add_textbox(Inches(1), Inches(2), Inches(11), Inches(4.5)) tf txBox.text_frame tf.word_wrap True for i, bullet in enumerate(bullets): if i 0: p tf.add_paragraph() else: p tf.paragraphs[0] p.text f ● {bullet} p.font.size Pt(18) p.font.color.rgb RGBColor.from_string(self.scheme[text]) p.space_after Pt(16) # 演讲稿备注 if notes: slide.notes_slide.notes_text_frame.text notes def add_chart_slide(self, title, chart_image_path): 图表页 slide self.prs.slides.add_slide(self.prs.slide_layouts[6]) # 标题 self._add_title(slide, title) # 插入图表图片 slide.shapes.add_picture( chart_image_path, Inches(1.5), Inches(1.8), Inches(10), Inches(5) ) def add_end(self, title谢谢, subtitleQA): 结尾页 slide self.prs.slides.add_slide(self.prs.slide_layouts[6]) bg slide.background fill bg.fill fill.solid() fill.fore_color.rgb RGBColor.from_string(self.scheme[primary]) txBox slide.shapes.add_textbox(Inches(1), Inches(2.5), Inches(11), Inches(2)) tf txBox.text_frame p tf.paragraphs[0] p.text title p.font.size Pt(48) p.font.bold True ...(truncated)...

更多文章