使用Python将JSON数据还原为PPT文件的实现步骤

Written by

in

文章目录
  • 在上一篇博客中,我们实现了将PPT文件解析为JSON结构的功能。现在,我们将构建其逆向工具——通过JSON数据自动生成PPT文件。这一功能可应用于自动化报告生成、样式复用、数据驱动的PPT创建等场景。本文将详解代码实现与关键步骤。
  • 自动化报告生成结合数据库或API数据,动态生成标准化报告(如财务月报、项目进度)。 样式复用将PPT模板解析为JSON后,可快速生成符合规范的新PPT。 内容迁移将老旧PPT内容迁移到新模板,或跨平台导出(如从PPTX到Google Slides)。
  • 通过上篇博客的解析功能和本篇的生成功能,可实现PPT ↔ JSON的双向转换: # 步骤1:解析现有PPT为JSON python parse_pptx.py input.pptx > parsed.json # 步骤2:修改JSON数据 # 例如:修改文本内容、调整样式 # 步骤3:生成新PPT python generate_pptx.py parsed.json > output.pptx
  • 通过本文的代码,开发者可将结构化JSON数据还原为PPT文件,实现自动化内容生成与样式复用。结合上篇解析功能,这一工具链可应用于: 数据驱动的PPT创建:根据实时数据生成动态报告。 样式标准化:确保所有PPT符合企业模板规范。 版本控制:将PPT内容纳入Git等版本控制系统。 未来可进一步扩展功能,例如: 支持更多形状类型(如线条、SmartArt)。 智能布局调整:根据内容自适应排版。 API集成:与AI模型结合,生成内容并直接渲染为PPT。 通过Python和python-pptx库,PPT的自动化处理从未如此灵活! from pptx import Presentation from pptx.util import Emu, Pt from pptx.enum.shapes import MSO_SHAPE, MSO_SHAPE_TYPE from pptx.enum.text import PP_ALIGN from pptx.enum.dml import MSO_FILL, MSO_LINE_DASH_STYLE from pptx.dml.color import RGBColor import json def hex_to_rgb(rgb_tuple): if not rgb_tuple: return None return RGBColor(*rgb_tuple) def get_alignment(alignment_str): if alignment_str == “PP_ALIGN.LEFT”: return PP_ALIGN.LEFT elif alignment_str == “PP_ALIGN.CENTER”: return PP_ALIGN.CENTER elif alignment_str == “PP_ALIGN.RIGHT”: return PP_ALIGN.RIGHT return PP_ALIGN.LEFT def create_shape(slide, shape_data): shape_type = shape_data[“type”] left = Emu(shape_data[“left”]) top = Emu(shape_data[“top”]) width = Emu(shape_data[“width”]) height = Emu(shape_data[“height”]) if shape_type == MSO_SHAPE_TYPE.TEXT_BOX: shape = slide.shapes.add_textbox(left, top, width, height) elif shape_type == MSO_SHAPE_TYPE.TABLE: rows = len(shape_data.get(“table”, [])) cols = max(len(row) for row in shape_data[“table”]) if shape_data.get(“table”) else 1 shape = slide.shapes.add_table(rows, cols, left, top, width, height).table elif shape_type == MSO_SHAPE_TYPE.PICTURE: image_path = “path/to/your/image.png” # 替换为实际图片路径 shape = slide.shapes.add_picture(image_path, left, top, width, height) else: shape = slide.shapes.add_shape( MSO_SHAPE.RECTANGLE, # 修正后的默认形状类型 left, top, width, height ) shape.rotation = shape_data.get(“rotation”, 0) return shape def apply_style(shape, style_data): fill_data = style_data[“fill”] line_data = style_data[“line”] # 填充样式 fill = shape.fill fill_type_str = fill_data[“type”] if fill_type_str == “MSO_FILL.SOLID”: fill.type = MSO_FILL.SOLID fill.fore_color.rgb = hex_to_rgb(fill_data[“color”]) elif fill_type_str == “MSO_FILL.BACKGROUND”: fill.type = MSO_FILL.BACKGROUND # 边框样式 line = shape.line color = hex_to_rgb(line_data[“color”]) if color: line.color.rgb = color line.width = Emu(line_data[“width”]) # 处理虚线样式(示例) if line_data.get(“dash_style”): dash_style_str = line_data[“dash_style”] line.dash_style = getattr(MSO_LINE_DASH_STYLE, dash_style_str.split(” “)[0]) def apply_text_style(text_frame, text_style_data): for paragraph_data in text_style_data.get(“paragraphs”, []): paragraph = text_frame.add_paragraph() paragraph.text = paragraph_data[“text”] paragraph.level = paragraph_data.get(“level”, 0) paragraph.alignment = get_alignment(paragraph_data.get(“alignment”)) for run_data in paragraph_data.get(“runs”, []): run = paragraph.add_run() run.text = run_data[“text”] font = run.font font.name = run_data[“font”][“name”] font.size = Pt(run_data[“font”][“size”]) if run_data[“font”][“size”] else None font.bold = run_data[“font”].get(“bold”, False) font.italic = run_data[“font”].get(“italic”, False) font.color.rgb = hex_to_rgb(run_data[“font”].get(“color”)) def json_to_pptx(json_path, output_pptx): prs = Presentation() with open(json_path, “r”, encoding=”utf-8″) as f: data = json.load(f) for slide_data in data[“slides”]: slide_layout = prs.slide_layouts[6] # 使用空白版式 slide = prs.slides.add_slide(slide_layout) for shape_data in slide_data[“shapes”]: shape = create_shape(slide, shape_data) apply_style(shape, { “fill”: shape_data[“fill”], “line”: shape_data[“line”] }) if “text_style” in shape_data and hasattr(shape, “text_frame”): text_frame = shape.text_frame apply_text_style(text_frame, shape_data[“text_style”]) if “table” in shape_data and hasattr(shape, “table”): table = shape.table for row_idx, row in enumerate(shape_data[“table”]): for col_idx, cell_data in enumerate(row): cell = table.cell(row_idx, col_idx) cell.text = cell_data[“text”] row_span = cell_data.get(“row_span”, 1) if row_span > 1: cell.merge(table.cell(row_idx + 1, col_idx)) prs.save(output_pptx) if __name__ == “__main__”: input_json = “presentation_info.json” output_pptx = “reconstructed.pptx” json_to_pptx(input_json, output_pptx) 以上就是使用Python将JSON数据还原为PPT文件的实现步骤的详细内容,更多关于Python JSON数据还原为PPT的资料请关注风君子博客其它相关文章! 您可能感兴趣的文章: 使用Python解析PPT文件并生成JSON结构详解 Python实现读取Excel表数据并转为JSON格式文件 使用Python将JSON,XML和YAML数据写入Excel文件 Python获取中国节假日数据记录入JSON文件
  • 目录
    • 引言
    • 核心代码解析
      • 1. 颜色与对齐转换函数
        • hex_to_rgb(rgb_tuple)
        • get_alignment(alignment_str)
      • 2. 创建形状:create_shape
        • 关键逻辑:
      • 3. 应用样式:apply_style
        • 填充样式:
        • 边框样式:
      • 4. 应用文本样式:apply_text_style
        • 示例:
      • 5. 主函数:json_to_pptx
        • 关键步骤:
    • 使用示例
      • 1. 输入JSON结构
        • 2. 生成PPT
        • 关键注意事项
          • 1. 图片路径问题
            • 2. 表格合并单元格
              • 3. 形状类型兼容性
              • 应用场景
                • 完整工具链演示
                  • 总结

                    在上一篇博客中,我们实现了将PPT文件解析为JSON结构的功能。现在,我们将构建其逆向工具——通过JSON数据自动生成PPT文件。这一功能可应用于自动化报告生成、样式复用、数据驱动的PPT创建等场景。本文将详解代码实现与关键步骤。

                    将JSON中的十六进制颜色和对齐方式转换为PPT的API可识别的格式。

                    将十六进制颜色(如#FF0000)转换为RGB对象:

                    def hex_to_rgb(rgb_tuple):
                        if not rgb_tuple:
                            return None
                        return RGBColor(*rgb_tuple)
                    

                    将对齐字符串(如"PP_ALIGN.CENTER")转换为枚举值:

                    def get_alignment(alignment_str):
                        if alignment_str == "PP_ALIGN.LEFT":
                            return PP_ALIGN.LEFT
                        elif alignment_str == "PP_ALIGN.CENTER":
                            return PP_ALIGN.CENTER
                        elif alignment_str == "PP_ALIGN.RIGHT":
                            return PP_ALIGN.RIGHT
                        return PP_ALIGN.LEFT
                    

                    根据JSON数据中的形状类型(如文本框、表格、图片),动态创建对应的PPT形状。

                    def create_shape(slide, shape_data):
                        shape_type = shape_data["type"]
                        left = Emu(shape_data["left"])
                        top = Emu(shape_data["top"])
                        width = Emu(shape_data["width"])
                        height = Emu(shape_data["height"])
                    
                        if shape_type == MSO_SHAPE_TYPE.TEXT_BOX:
                            shape = slide.shapes.add_textbox(left, top, width, height)
                        elif shape_type == MSO_SHAPE_TYPE.TABLE:
                            rows = len(shape_data.get("table", []))
                            cols = max(len(row) for row in shape_data["table"]) if shape_data.get("table") else 1
                            shape = slide.shapes.add_table(rows, cols, left, top, width, height).table
                        elif shape_type == MSO_SHAPE_TYPE.PICTURE:
                            image_path = "path/to/your/image.png"  # 需替换为实际路径
                            shape = slide.shapes.add_picture(image_path, left, top, width, height)
                        else:
                            shape = slide.shapes.add_shape(
                                MSO_SHAPE.RECTANGLE,  # 默认形状
                                left,
                                top,
                                width,
                                height
                            )
                        shape.rotation = shape_data.get("rotation", 0)
                        return shape
                    

                    将JSON中的填充、边框样式应用到形状上。

                    fill.type = MSO_FILL.SOLID  # 或BACKGROUND
                    fill.fore_color.rgb = hex_to_rgb(fill_data["color"])
                    

                    line.color.rgb = hex_to_rgb(line_data["color"])
                    line.width = Emu(line_data["width"])
                    line.dash_style = getattr(MSO_LINE_DASH_STYLE, line_data["dash_style"])
                    

                    根据JSON中的字体、段落设置,构建文本框内容。

                    def apply_text_style(text_frame, text_style_data):
                        for paragraph_data in text_style_data.get("paragraphs", []):
                            paragraph = text_frame.add_paragraph()
                            paragraph.text = paragraph_data["text"]
                            paragraph.alignment = get_alignment(paragraph_data["alignment"])
                            for run_data in paragraph_data["runs"]:
                                run = paragraph.add_run()
                                run.text = run_data["text"]
                                font = run.font
                                font.name = run_data["font"]["name"]
                                font.size = Pt(run_data["font"]["size"])
                                font.bold = run_data["font"].get("bold", False)
                                font.color.rgb = hex_to_rgb(run_data["font"]["color"])
                    

                    读取JSON文件,遍历每页和每个形状,完成PPT重建。

                    • 创建空白幻灯片slide_layout = prs.slide_layouts[6](索引6对应空白版式)。
                    • 遍历形状数据
                    for shape_data in slide_data["shapes"]:
                        shape = create_shape(slide, shape_data)
                        apply_style(shape, style_data)
                        if "text_style" in shape_data:
                            apply_text_style(text_frame, shape_data["text_style"])
                        if "table" in shape_data:
                            # 填充表格内容
                            for row_idx, row in enumerate(shape_data["table"]):
                                for col_idx, cell_data in enumerate(row):
                                    cell = table.cell(row_idx, col_idx)
                                    cell.text = cell_data["text"]
                    

                    假设我们有以下JSON片段(来自上篇博客的输出):

                    {
                      "slides": [
                        {
                          "shapes": [
                            {
                              "type": 1,  // MSO_SHAPE_TYPE.TEXT_BOX
                              "left": 1143000,
                              "top": 1143000,
                              "width": 6858000,
                              "height": 1683600,
                              "fill": {"type": "MSO_FILL.SOLID", "color": "#FF0000"},
                              "text_style": {
                                "paragraphs": [
                                  {
                                    "text": "Hello World",
                                    "alignment": "PP_ALIGN.CENTER",
                                    "runs": [
                                      {
                                        "font": {
                                          "name": "Arial",
                                          "size": 24,
                                          "color": "#FFFFFF"
                                        }
                                      }
                                    ]
                                  }
                                ]
                              }
                            }
                          ]
                        }
                      ]
                    }
                    

                    运行代码后,将得到一个包含红色文本框的PPT文件

                    代码中图片路径为硬编码:

                    image_path = "path/to/your/image.png"
                    

                    需根据JSON中的图片信息动态指定路径,或添加图片路径映射逻辑。

                    当前代码仅填充单元格文本,未处理跨行/列合并。需扩展逻辑:

                    row_span = cell_data.get("row_span", 1)
                    if row_span > 1:
                        cell.merge(table.cell(row_idx + 1, col_idx))
                    

                    • 未支持的形状:如线条、箭头等需扩展create_shape
                    • 默认形状:非文本框/表格/图片的形状默认为矩形。

                    1. 自动化报告生成
                      结合数据库或API数据,动态生成标准化报告(如财务月报、项目进度)。

                    2. 样式复用
                      将PPT模板解析为JSON后,可快速生成符合规范的新PPT。

                    3. 内容迁移
                      将老旧PPT内容迁移到新模板,或跨平台导出(如从PPTX到Google Slides)。

                    通过上篇博客的解析功能和本篇的生成功能,可实现PPT ↔ JSON的双向转换

                    # 步骤1:解析现有PPT为JSON
                    python parse_pptx.py input.pptx > parsed.json
                    
                    # 步骤2:修改JSON数据
                    # 例如:修改文本内容、调整样式
                    
                    # 步骤3:生成新PPT
                    python generate_pptx.py parsed.json > output.pptx
                    

                    通过本文的代码,开发者可将结构化JSON数据还原为PPT文件,实现自动化内容生成与样式复用。结合上篇解析功能,这一工具链可应用于:

                    • 数据驱动的PPT创建:根据实时数据生成动态报告。
                    • 样式标准化:确保所有PPT符合企业模板规范。
                    • 版本控制:将PPT内容纳入Git等版本控制系统。

                    未来可进一步扩展功能,例如:

                    • 支持更多形状类型(如线条、SmartArt)。
                    • 智能布局调整:根据内容自适应排版。
                    • API集成:与AI模型结合,生成内容并直接渲染为PPT。

                    通过Python和python-pptx库,PPT的自动化处理从未如此灵活!

                    from pptx import Presentation
                    from pptx.util import Emu, Pt
                    from pptx.enum.shapes import MSO_SHAPE, MSO_SHAPE_TYPE
                    from pptx.enum.text import PP_ALIGN
                    from pptx.enum.dml import MSO_FILL, MSO_LINE_DASH_STYLE
                    from pptx.dml.color import RGBColor
                    import json
                    
                    
                    def hex_to_rgb(rgb_tuple):
                        if not rgb_tuple:
                            return None
                        return RGBColor(*rgb_tuple)
                    
                    
                    def get_alignment(alignment_str):
                        if alignment_str == "PP_ALIGN.LEFT":
                            return PP_ALIGN.LEFT
                        elif alignment_str == "PP_ALIGN.CENTER":
                            return PP_ALIGN.CENTER
                        elif alignment_str == "PP_ALIGN.RIGHT":
                            return PP_ALIGN.RIGHT
                        return PP_ALIGN.LEFT
                    
                    
                    def create_shape(slide, shape_data):
                        shape_type = shape_data["type"]
                        left = Emu(shape_data["left"])
                        top = Emu(shape_data["top"])
                        width = Emu(shape_data["width"])
                        height = Emu(shape_data["height"])
                    
                        if shape_type == MSO_SHAPE_TYPE.TEXT_BOX:
                            shape = slide.shapes.add_textbox(left, top, width, height)
                        elif shape_type == MSO_SHAPE_TYPE.TABLE:
                            rows = len(shape_data.get("table", []))
                            cols = max(len(row) for row in shape_data["table"]) if shape_data.get("table") else 1
                            shape = slide.shapes.add_table(rows, cols, left, top, width, height).table
                        elif shape_type == MSO_SHAPE_TYPE.PICTURE:
                            image_path = "path/to/your/image.png"  # 替换为实际图片路径
                            shape = slide.shapes.add_picture(image_path, left, top, width, height)
                        else:
                            shape = slide.shapes.add_shape(
                                MSO_SHAPE.RECTANGLE,  # 修正后的默认形状类型
                                left,
                                top,
                                width,
                                height
                            )
                    
                        shape.rotation = shape_data.get("rotation", 0)
                        return shape
                    
                    
                    def apply_style(shape, style_data):
                        fill_data = style_data["fill"]
                        line_data = style_data["line"]
                    
                        # 填充样式
                        fill = shape.fill
                        fill_type_str = fill_data["type"]
                        if fill_type_str == "MSO_FILL.SOLID":
                            fill.type = MSO_FILL.SOLID
                            fill.fore_color.rgb = hex_to_rgb(fill_data["color"])
                        elif fill_type_str == "MSO_FILL.BACKGROUND":
                            fill.type = MSO_FILL.BACKGROUND
                    
                        # 边框样式
                        line = shape.line
                        color = hex_to_rgb(line_data["color"])
                        if color:
                            line.color.rgb = color
                        line.width = Emu(line_data["width"])
                        # 处理虚线样式(示例)
                        if line_data.get("dash_style"):
                            dash_style_str = line_data["dash_style"]
                            line.dash_style = getattr(MSO_LINE_DASH_STYLE, dash_style_str.split(" ")[0])
                    
                    
                    def apply_text_style(text_frame, text_style_data):
                        for paragraph_data in text_style_data.get("paragraphs", []):
                            paragraph = text_frame.add_paragraph()
                            paragraph.text = paragraph_data["text"]
                            paragraph.level = paragraph_data.get("level", 0)
                            paragraph.alignment = get_alignment(paragraph_data.get("alignment"))
                    
                            for run_data in paragraph_data.get("runs", []):
                                run = paragraph.add_run()
                                run.text = run_data["text"]
                                font = run.font
                                font.name = run_data["font"]["name"]
                                font.size = Pt(run_data["font"]["size"]) if run_data["font"]["size"] else None
                                font.bold = run_data["font"].get("bold", False)
                                font.italic = run_data["font"].get("italic", False)
                                font.color.rgb = hex_to_rgb(run_data["font"].get("color"))
                    
                    
                    def json_to_pptx(json_path, output_pptx):
                        prs = Presentation()
                        with open(json_path, "r", encoding="utf-8") as f:
                            data = json.load(f)
                    
                        for slide_data in data["slides"]:
                            slide_layout = prs.slide_layouts[6]  # 使用空白版式
                            slide = prs.slides.add_slide(slide_layout)
                    
                            for shape_data in slide_data["shapes"]:
                                shape = create_shape(slide, shape_data)
                                apply_style(shape, {
                                    "fill": shape_data["fill"],
                                    "line": shape_data["line"]
                                })
                    
                                if "text_style" in shape_data and hasattr(shape, "text_frame"):
                                    text_frame = shape.text_frame
                                    apply_text_style(text_frame, shape_data["text_style"])
                    
                                if "table" in shape_data and hasattr(shape, "table"):
                                    table = shape.table
                                    for row_idx, row in enumerate(shape_data["table"]):
                                        for col_idx, cell_data in enumerate(row):
                                            cell = table.cell(row_idx, col_idx)
                                            cell.text = cell_data["text"]
                                            row_span = cell_data.get("row_span", 1)
                                            if row_span > 1:
                                                cell.merge(table.cell(row_idx + 1, col_idx))
                    
                        prs.save(output_pptx)
                    
                    
                    if __name__ == "__main__":
                        input_json = "presentation_info.json"
                        output_pptx = "reconstructed.pptx"
                        json_to_pptx(input_json, output_pptx)
                    

                    以上就是使用Python将JSON数据还原为PPT文件的实现步骤的详细内容,更多关于Python JSON数据还原为PPT的资料请关注风君子博客其它相关文章!

                    您可能感兴趣的文章:

                    • 使用Python解析PPT文件并生成JSON结构详解
                    • Python实现读取Excel表数据并转为JSON格式文件
                    • 使用Python将JSON,XML和YAML数据写入Excel文件
                    • Python获取中国节假日数据记录入JSON文件

                    站内搜索