使用Python將JSON數(shù)據(jù)還原為PPT文件的實現(xiàn)步驟
引言
在上一篇博客中,我們實現(xiàn)了將PPT文件解析為JSON結(jié)構(gòu)的功能?,F(xiàn)在,我們將構(gòu)建其逆向工具——通過JSON數(shù)據(jù)自動生成PPT文件。這一功能可應(yīng)用于自動化報告生成、樣式復用、數(shù)據(jù)驅(qū)動的PPT創(chuàng)建等場景。本文將詳解代碼實現(xiàn)與關(guān)鍵步驟。
核心代碼解析
1. 顏色與對齊轉(zhuǎn)換函數(shù)
將JSON中的十六進制顏色和對齊方式轉(zhuǎn)換為PPT的API可識別的格式。
hex_to_rgb(rgb_tuple)
將十六進制顏色(如#FF0000
)轉(zhuǎn)換為RGB對象:
def hex_to_rgb(rgb_tuple): if not rgb_tuple: return None return RGBColor(*rgb_tuple)
get_alignment(alignment_str)
將對齊字符串(如"PP_ALIGN.CENTER"
)轉(zhuǎn)換為枚舉值:
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. 創(chuàng)建形狀:create_shape
根據(jù)JSON數(shù)據(jù)中的形狀類型(如文本框、表格、圖片),動態(tài)創(chuàng)建對應(yīng)的PPT形狀。
關(guān)鍵邏輯:
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. 應(yīng)用樣式:apply_style
將JSON中的填充、邊框樣式應(yīng)用到形狀上。
填充樣式:
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. 應(yīng)用文本樣式:apply_text_style
根據(jù)JSON中的字體、段落設(shè)置,構(gòu)建文本框內(nèi)容。
示例:
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. 主函數(shù):json_to_pptx
讀取JSON文件,遍歷每頁和每個形狀,完成PPT重建。
關(guān)鍵步驟:
- 創(chuàng)建空白幻燈片:
slide_layout = prs.slide_layouts[6]
(索引6對應(yīng)空白版式)。 - 遍歷形狀數(shù)據(jù):
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: # 填充表格內(nèi)容 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結(jié)構(gòu)
假設(shè)我們有以下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文件
關(guān)鍵注意事項
1. 圖片路徑問題
代碼中圖片路徑為硬編碼:
image_path = "path/to/your/image.png"
需根據(jù)JSON中的圖片信息動態(tài)指定路徑,或添加圖片路徑映射邏輯。
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
。 - 默認形狀:非文本框/表格/圖片的形狀默認為矩形。
應(yīng)用場景
自動化報告生成
結(jié)合數(shù)據(jù)庫或API數(shù)據(jù),動態(tài)生成標準化報告(如財務(wù)月報、項目進度)。樣式復用
將PPT模板解析為JSON后,可快速生成符合規(guī)范的新PPT。內(nèi)容遷移
將老舊PPT內(nèi)容遷移到新模板,或跨平臺導出(如從PPTX到Google Slides)。
完整工具鏈演示
通過上篇博客的解析功能和本篇的生成功能,可實現(xiàn)PPT ↔ JSON的雙向轉(zhuǎn)換:
# 步驟1:解析現(xiàn)有PPT為JSON python parse_pptx.py input.pptx > parsed.json # 步驟2:修改JSON數(shù)據(jù) # 例如:修改文本內(nèi)容、調(diào)整樣式 # 步驟3:生成新PPT python generate_pptx.py parsed.json > output.pptx
總結(jié)
通過本文的代碼,開發(fā)者可將結(jié)構(gòu)化JSON數(shù)據(jù)還原為PPT文件,實現(xiàn)自動化內(nèi)容生成與樣式復用。結(jié)合上篇解析功能,這一工具鏈可應(yīng)用于:
- 數(shù)據(jù)驅(qū)動的PPT創(chuàng)建:根據(jù)實時數(shù)據(jù)生成動態(tài)報告。
- 樣式標準化:確保所有PPT符合企業(yè)模板規(guī)范。
- 版本控制:將PPT內(nèi)容納入Git等版本控制系統(tǒng)。
未來可進一步擴展功能,例如:
- 支持更多形狀類型(如線條、SmartArt)。
- 智能布局調(diào)整:根據(jù)內(nèi)容自適應(yīng)排版。
- API集成:與AI模型結(jié)合,生成內(nèi)容并直接渲染為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數(shù)據(jù)還原為PPT文件的實現(xiàn)步驟的詳細內(nèi)容,更多關(guān)于Python JSON數(shù)據(jù)還原為PPT的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python實現(xiàn)12306登錄并保存cookie的方法示例
這篇文章主要介紹了 python實現(xiàn)12306登錄并保存cookie的方法示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-12-12