当前位置: 代码网 > it编程>前端脚本>Python > 使用Python将JSON数据还原为PPT文件的实现步骤

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

2025年04月30日 Python 我要评论
引言在上一篇博客中,我们实现了将ppt文件解析为json结构的功能。现在,我们将构建其逆向工具——通过json数据自动生成ppt文件。这一功能可应用于自动化报告生成、样式复用、

引言

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

核心代码解析

1. 颜色与对齐转换函数

将json中的十六进制颜色和对齐方式转换为ppt的api可识别的格式。

hex_to_rgb(rgb_tuple)

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

def hex_to_rgb(rgb_tuple):
    if not rgb_tuple:
        return none
    return rgbcolor(*rgb_tuple)

get_alignment(alignment_str)

将对齐字符串(如"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

2. 创建形状:create_shape

根据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

3. 应用样式:apply_style

将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"])

4. 应用文本样式:apply_text_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"])

5. 主函数:json_to_pptx

读取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"]

使用示例

1. 输入json结构

假设我们有以下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"
                    }
                  }
                ]
              }
            ]
          }
        }
      ]
    }
  ]
}

2. 生成ppt

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

关键注意事项

1. 图片路径问题

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

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

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

2. 表格合并单元格

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

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

3. 形状类型兼容性

  • 未支持的形状:如线条、箭头等需扩展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的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com