开发者

使用Python自动化生成PPT并结合LLM生成内容的代码解析

开发者 https://www.devze.com 2025-05-15 09:45 出处:网络 作者: 东方佑
目录核心代码解析1. 提取 PPT 样式到 jsON关键步骤:代码片段:2. 应用 JSON 样式到新 PPT关键步骤:代码片段:结合 LLM 生成内容场景:生成自我介绍 PPT1. 使用 LLM 生成文本内容2. 将 LLM 内容
目录
  • 核心代码解析
    • 1. 提取 PPT 样式到 jsON
      • 关键步骤:
      • 代码片段:
    • 2. 应用 JSON 样式到新 PPT
      • 关键步骤:
      • 代码片段:
  • 结合 LLM 生成内容
    • 场景:生成自我介绍 PPT
      • 1. 使用 LLM 生成文本内容
      • 2. 将 LLM 内容注入 JSON
      • 3. 生成最终 PPT
  • 注意事项
    • 完整示例

      核心代码解析

      1. 提取 PPT 样式到 JSON

      extract_ppt_with_style 函数用于将 PPT 的样式(字体、颜色、段落格式等)提取到 JSON 文件中,方便后续复用。

      关键步骤:

      • 遍历 PPT 的每一页:逐页提取文本框的样式。
      • 记录样式信息:包括字体名称、大小、加粗、斜体、颜色(支持主题色和 RGB 颜色)。
      • JSON 结构示例
      {
        "slide_number": 1,
        "shapes": [
          {
            "shape_name": "Text",
            "paragraphs": [
              {
                "alignment": "LEFT",
                "runs": [
                  {
                    "text": "自我介绍",
                    "font": {
                      "name": "Arial",
                      "size": 24,
                      "bold": true,
                      "italic": false,
                      "color": {
                        "type": "rgb",
                        "rgb": [255, 0, 0]
                      }
                    }
                  }
                ]
              }
            ]
          }
        ]
      }
      

      代码片段:

      def extract_ppt_with_style(ppt_path, output_json):
          prs = Presentation(ppt_path)
          data = []
          for slide_idx, slide in enumerate(prs.slides):android
              slide_data = {
                  "slide_number": slide_idx + 1,
                  "shapes": []
              }
              for shape in slide.shapes:
                  if not shape.has_text_frame:
                      continue
                  text_frame = shape.text_frame
                  text_info = {
                      "shape_name": "Text",  # 强制设置为 "Text" 类型
                      "paragraphs": []
                  }
                  for paragraph in text_frame.paragraphs:
                      para_info = {
                          "alignment": str(paragraph.alignment),
                          "runs": []
                      }
                      for run in paragraph.runs:
                          run_info = {
                              "text": run.text,
                              "font": {
                                  "name": run.font.name,
                                  "size": str(run.font.size) if run.font.size else None,
                                  "bold": run.font.bold,
                                  "italic": run.font.italic,
                                  "color": {
                                      "type": "theme" if run.font.color.type == MSO_THEME_COLOR else "rgb",
                                      "theme_color": run.font.color.theme_color,
                                      "rgb": (run.font.color.rgb[0], run.font.color.rgb[1], run.font.color.rgb[2]) if run.font.color.rgb else None
                                  }
                              }
                          }
                          para_info["runs"].append(run_info)
                      text_info["paragraphs"].append(para_info)
                  slide_data["shapes"].append(text_info)
              data.append(slide_data)
          with open(output_json, 'w', encoding='utf-8') as f:
              json.dump(data, f, indent=2, ensure_ascii=False)
      

      2. 应用 JSON 样式到新 PPT

      apply_styles_to_ppt 函数根据 JSON 文件中的样式信息,将内容和格式应用到模板 PPT 中。

      关键步骤:

      • 读取 JSON 数据:解析字体、颜色等样式信息。
      • 动态设置样式:支持 RGB 颜色、主题色,并兼容十六进制颜色(如 #FF0000)。
      • 生成最终 PPT:将修改后的样式保存为新文件。

      代码片段:

      def apply_styles_to_ppt(template_path, json_path, output_pptx):
          with open(json_path, 'r', encoding='utf-8') as f:
              data = json.load(f)
          prs = Presentation(template_path)
          for slide_idx, slide in enumerate(prs.slides):
              for shape_idx, shape in enumerate(slide.shapes):
                  if not shape.has_text_frame:
                    javascript  continue
                  text_frame = shape.text_frame
                  for paragraph_idx, paragraph in enumerate(text_frame.paragraphs):
                      for run_idx, run in enumerate(paragraph.runs):
                          run_info = data[slide_idx]["shapes"][shape_idx]["paragraphs"][paragraph_idx]["runs"][run_idx]
                          run.text = run_info["text"]  # 替换文本内容
                          run.font.name = run_info["font"]["name"]
                          run.font.size = run_info["font"]["size"]
                          run.font.bold = run_info["font"]["bold"]
                          run.font.italic = run_info["font"]["itahttp://www.devze.comlic"]
                          color_data = run_info["font"]["color"]
                          if color_data["type"] == "rgb":
                              r, g, b = color_data["rgb"]  # 直接解析 RGB 数组
                              run.font.color.rgb = RGBColor(r, g, b)
                          elif color_data["type"] == "hex":
                              hex_color = color_data["hex"].lstrip("#")
                              r = int(hex_color[0:2], 16)
                              g = int(hex_color[2:4], 16)
                              b = int(hex_color[4:6], 16)
                              run.font.color.rgb = RGBColor(r, g, b)
                          elif color_data["type"] == "theme":
                              theme_color = getattr(MSO_THEME_COLOR, color_data["theme_color"], MSO_THEME_COLOR.ACCENT_1)
                              run.font.color.theme_color = theme_color
                          else:
                              run.font.color.rgb = RGBColor(0, 0, 0)  # 默认黑色
          prs.save(output_pptx)
      

      结合 LLM 生成内容

      场景:生成自我介绍 PPT

      假设需要根据用户输入的姓名、职位等信息,自动生成带样式的自我介绍 PPT,可以按以下步骤操作:

      1. 使用 LLM 生成文本内容

      通过调用 LLM(如 GPT-3.5、通义千问等),生成自我介绍的文本内容:

      import openai
      
      def generate_self_introduction(name, role):
          prompt = f"生成一份关于 {name}({role})的自我介绍,要求简洁明了,适合 PPT 展示。"
          response = openai.Completion.create(
              engine="text-davinci-003",
              prompt=prompt,
              max_tokens=150
          )
          return response.choices[0].text.strip()
      

      2. 将 LLM 内容注入 JSON

      将生成的文本内容填充到 JSON 的 text 字段中:

      # 假设提取的 JSON 结构如下:
      json_data = {
          "slide_number": 1,
          "shapes": [
              {
                  "shape_name": "Text",
                  "paragraphs": [
                      {
                          "runs": [
                              {"text": "【待替换的占位符】", ...}
                          ]
                      }
                  ]
              }
          ]
      }
      
      # 替换文本内容
      generated_text = generate_self_introduction("张三", "数据分析师")
      json_data["shapes"][0]["paragraphs"][0]["runs"][0]["text"] = generated_text
      

      3. 生成最终 PPT

      调用 apply_styles_to_ppt 将样式和内容应用到模板中:

      apply_styles_to_ppt("template.pptx", "modified.json", "output.pptx")
      

      注意事项

      1. JSON 格式要求

        • 颜色值需为数组格式(如 rgb: [255, 0, 0])或十六进制字符串(如 "hex": "#FF0000")。
        • 主题色需使用 MSO_THEME_COLOR 枚举名称(如 "ACCENT_1")。
      2. 形状名称标准化

        • 在提取样式时,强制将 shape_name 设置为 "Text",确保后续处理一致性。
      3. 兼容性

        • 确保模板 PPT 的形状结构与 JSON 数据匹配(如位置、层级)。

      完整示例

      if __name__ == '__main__':
          # 1. 提取模板样式到 JSON
          extract_ppt_with_style("template.pptx", "output_styles.json")
          
          # 2. 生成自我介绍文本并修改 JSON
          with open("output_styles.json", "r") as f:
              data = json.load(f)
          # 假设修改第一段文本
          data[0]["shapes"][0]["paragraphs"][0]["runs"][0]["text"] = "我是张三,一名数据分析师..."
          
          # 3. 生成最终 PPT
          apply_styles_to_ppt("template.pptx", "output_styles.json", "new_ppt.pptx")
      

      通过上述方法,你可以自动化生成个性化 PPT,结合 LLM 的内容生成能力,实现从设计到内容的全流程自动化!

      from pptx import Presentation
      from pptx.enum.dml import MSO_THEME_COLOR
      from pptx.dml.color import RGBColor
      import json
      
      
      def extract_ppt_with_style(ppt_path, outputandroid_json):
          prs = Presentation(ppt_path)
          data = []
      
          for slide_idx, slide in enumerate(prs.slides):
              slide_data = {
                  "slide_number": slide_idx + 1,
                  "shapes": []
              }
              for shape in slide.shapes:
                  if not shape.has_text_frame:
                      continue  # 跳过非文本形状
      
                  text_frame = shape.text_frame
                  text_info = {
                      "shape_name": shape.name,
                      "paragraphs": []
                  }
      
                  for paragraph in text_frame.paragraphs:
                      para_info = {
                          "alignment": str(paragraph.alignment),
                          "runs": []
                      }
                      for run in paragraph.runs:
                          run_info = {
                              "text": run.text,
                              "font": {
                                  "name": run.font.name,
                                  "size": str(run.font.size) if run.font.size else None,
                                  "bold": run.font.bold,
                                  "italic": run.font.italic,
                                  "color": {
                                      "type": "theme" if run.font.color.type == MSO_THEME_COLOR else "rgb",
                                      "theme_color": run.font.color.theme_color,
                                      "rgb": (run.font.color.rgb[0], run.font.color.rgb[1],
                                              run.font.color.rgb[2]) if run.font.color.rgb else None
                                  }
                              },
                              # "highlight_color": str(run.highlight_color)  # 修改:从 run 而非 run.font 获取
                          }
                          para_info["runs"].append(run_info)
                      text_info["paragraphs"].append(para_info)
                  slide_data["shapes"].append(text_info)
              data.append(slide_data)
      
          with open(output_json, 'w', encoding='utf-8') as f:
              json.dump(data, f, indent=2, ensure_ascii=False)
      
      
      def apply_styles_to_ppt(template_path, json_path, output_pptx):
          with open(json_path, 'r', encoding='utf-8') as f:
              data = json.load(f)
      
          prs = Presentation(template_path)
      
          for slide_idx, slide in enumerate(prs.slides):
      
              for shape_idx, shape in enumerate(slide.shapes):
                  if not shape.has_text_frame:
                      continue  # 跳过非文本形状
      
                  text_frame = shape.text_frame
      
                  for paragraph_idx, paragraph in enumerate(text_frame.paragraphs):
      
                      for run_idx, run in enumerate(paragraph.runs):
                          run_info = data[slide_idx]["shapes"][shape_idx]["paragraphs"][paragraph_idx]["runs"][run_idx]
      
                          run.text = run_info["text"]
                          run.font.name = run_info["font"]["name"]
                          run.font.size = run_info["font"]["size"]
                          run.font.bold = run_info["font"]["bold"]
                          run.font.size = run_info["font"]["size"]
                          run.font.italic = run_info["font"]["italic"]
      
                          # 假设 run_data 是从 JSON 中读取的字典
                          color_data = run_info["font"]["color"]
      
                          if color_data["type"] == "rgb":
                              # 解析 RGB 值
                              r_str, g_str, b_str = color_data["rgb"]
                              r = r_str
                              g = g_str
                              b = b_str
                              run.font.color.rgb = RGBColor(r, g, b)
                          elif color_data["type"] == "hex":
                              # 解析十六进制颜色
                              hex_color = color_data["hex"].lstrip("#")
                              r = int(hex_color[0:2], 16)
                              g = int(hex_color[2:4], 16)
                              b = int(hex_color[4:6], 16)
                              run.font.color.rgb = RGBColor(r, g, b)
                          elif编程 color_data["type"] == "theme":
                              # 使用主题颜色(如 MSO_THEME_COLOR.ACCENT_1)
                              theme_color_name = color_data["theme_color"]
                              theme_color = getattr(MSO_THEME_COLOR, theme_color_name, MSO_THEME_COLOR.ACCENT_1)
                              run.font.color.theme_color = theme_color
                          else:
                              # 默认颜色(黑色)
                              run.font.color.rgb = RGBColor(0, 0, 0)
      
          prs.save(output_pptx)
      
      
      if __name__ == '__main__':
          # 使用示例
          extract_ppt_with_style("template.pptx", "output_styles.json")
          # 这是一个ppt 模版解析出来的json 结构 name 为 shape 类型保持不变 请 改变 name 为 Text 类型的text ,text 的值进行自我介绍 # 注意:只输出json
          # 使用示例
          apply_styles_to_ppt("template.pptx", "output_styles.json", "new_ppt.pptx")
      

      以上就是使用python自动化生成PPT并结合LLM生成内容的代码解析的详细内容,更多关于Python自动化生成PPT的资料请关注编程客栈(www.devze.com)其它相关文章!

      0

      精彩评论

      暂无评论...
      验证码 换一张
      取 消

      关注公众号