使用Python將JSON數(shù)據(jù)還原為PPT文件的實(shí)現(xiàn)步驟
引言
在上一篇博客中,我們實(shí)現(xiàn)了將PPT文件解析為JSON結(jié)構(gòu)的功能?,F(xiàn)在,我們將構(gòu)建其逆向工具——通過(guò)JSON數(shù)據(jù)自動(dòng)生成PPT文件。這一功能可應(yīng)用于自動(dòng)化報(bào)告生成、樣式復(fù)用、數(shù)據(jù)驅(qū)動(dòng)的PPT創(chuàng)建等場(chǎng)景。本文將詳解代碼實(shí)現(xiàn)與關(guān)鍵步驟。
核心代碼解析
1. 顏色與對(duì)齊轉(zhuǎn)換函數(shù)
將JSON中的十六進(jìn)制顏色和對(duì)齊方式轉(zhuǎn)換為PPT的API可識(shí)別的格式。
hex_to_rgb(rgb_tuple)
將十六進(jìn)制顏色(如#FF0000)轉(zhuǎn)換為RGB對(duì)象:
def hex_to_rgb(rgb_tuple):
if not rgb_tuple:
return None
return RGBColor(*rgb_tuple)
get_alignment(alignment_str)
將對(duì)齊字符串(如"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ù)中的形狀類(lèi)型(如文本框、表格、圖片),動(dòng)態(tài)創(chuàng)建對(duì)應(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" # 需替換為實(shí)際路徑
shape = slide.shapes.add_picture(image_path, left, top, width, height)
else:
shape = slide.shapes.add_shape(
MSO_SHAPE.RECTANGLE, # 默認(rèn)形狀
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文件,遍歷每頁(yè)和每個(gè)形狀,完成PPT重建。
關(guān)鍵步驟:
- 創(chuàng)建空白幻燈片:
slide_layout = prs.slide_layouts[6](索引6對(duì)應(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片段(來(lái)自上篇博客的輸出):
{
"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
運(yùn)行代碼后,將得到一個(gè)包含紅色文本框的PPT文件
關(guān)鍵注意事項(xiàng)
1. 圖片路徑問(wèn)題
代碼中圖片路徑為硬編碼:
image_path = "path/to/your/image.png"
需根據(jù)JSON中的圖片信息動(dòng)態(tài)指定路徑,或添加圖片路徑映射邏輯。
2. 表格合并單元格
當(dāng)前代碼僅填充單元格文本,未處理跨行/列合并。需擴(kuò)展邏輯:
row_span = cell_data.get("row_span", 1)
if row_span > 1:
cell.merge(table.cell(row_idx + 1, col_idx))
3. 形狀類(lèi)型兼容性
- 未支持的形狀:如線條、箭頭等需擴(kuò)展
create_shape。 - 默認(rèn)形狀:非文本框/表格/圖片的形狀默認(rèn)為矩形。
應(yīng)用場(chǎng)景
自動(dòng)化報(bào)告生成
結(jié)合數(shù)據(jù)庫(kù)或API數(shù)據(jù),動(dòng)態(tài)生成標(biāo)準(zhǔn)化報(bào)告(如財(cái)務(wù)月報(bào)、項(xiàng)目進(jìn)度)。樣式復(fù)用
將PPT模板解析為JSON后,可快速生成符合規(guī)范的新PPT。內(nèi)容遷移
將老舊PPT內(nèi)容遷移到新模板,或跨平臺(tái)導(dǎo)出(如從PPTX到Google Slides)。
完整工具鏈演示
通過(guò)上篇博客的解析功能和本篇的生成功能,可實(shí)現(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é)
通過(guò)本文的代碼,開(kāi)發(fā)者可將結(jié)構(gòu)化JSON數(shù)據(jù)還原為PPT文件,實(shí)現(xiàn)自動(dòng)化內(nèi)容生成與樣式復(fù)用。結(jié)合上篇解析功能,這一工具鏈可應(yīng)用于:
- 數(shù)據(jù)驅(qū)動(dòng)的PPT創(chuàng)建:根據(jù)實(shí)時(shí)數(shù)據(jù)生成動(dòng)態(tài)報(bào)告。
- 樣式標(biāo)準(zhǔn)化:確保所有PPT符合企業(yè)模板規(guī)范。
- 版本控制:將PPT內(nèi)容納入Git等版本控制系統(tǒng)。
未來(lái)可進(jìn)一步擴(kuò)展功能,例如:
- 支持更多形狀類(lèi)型(如線條、SmartArt)。
- 智能布局調(diào)整:根據(jù)內(nèi)容自適應(yīng)排版。
- API集成:與AI模型結(jié)合,生成內(nèi)容并直接渲染為PPT。
通過(guò)Python和python-pptx庫(kù),PPT的自動(dòng)化處理從未如此靈活!
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" # 替換為實(shí)際圖片路徑
shape = slide.shapes.add_picture(image_path, left, top, width, height)
else:
shape = slide.shapes.add_shape(
MSO_SHAPE.RECTANGLE, # 修正后的默認(rèn)形狀類(lèi)型
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文件的實(shí)現(xiàn)步驟的詳細(xì)內(nèi)容,更多關(guān)于Python JSON數(shù)據(jù)還原為PPT的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
selenium?UI自動(dòng)化實(shí)戰(zhàn)過(guò)程記錄
如果大家有做過(guò)web的自動(dòng)化測(cè)試,相信對(duì)于selenium一定不陌生,測(cè)試人員經(jīng)常使用它來(lái)進(jìn)行自動(dòng)化測(cè)試,下面這篇文章主要給大家介紹了關(guān)于selenium?UI自動(dòng)化實(shí)戰(zhàn)的相關(guān)資料,需要的朋友可以參考下2021-12-12
利用Python找出刪除自己微信的好友并將他們自動(dòng)化刪除
你是否有微信被刪了好友不自知,還傻傻的給對(duì)方發(fā)消息,結(jié)果出現(xiàn)了下圖中那尷尬的一幕的經(jīng)歷呢?其實(shí)我們可以用Python提前把他們找出來(lái)并自動(dòng)化刪除避免尷尬的2023-01-01
Python學(xué)習(xí)之集合的常用方法總結(jié)
集合并不是一種數(shù)據(jù)處理類(lèi)型,而是一種中間類(lèi)型。集合(set)是一個(gè)無(wú)序、不重復(fù)的元素序列,經(jīng)常被用來(lái)處理兩個(gè)列表進(jìn)行交并差的處理性。本文將詳細(xì)講解集合的一些常用方法,感興趣的可以了解一下2022-03-03
python使用 __init__初始化操作簡(jiǎn)單示例
這篇文章主要介紹了python使用 __init__初始化操作,結(jié)合實(shí)例形式分析了Python面向?qū)ο蟪绦蛟O(shè)計(jì)中使用__init__進(jìn)行初始化操作相關(guān)技巧與注意事項(xiàng),需要的朋友可以參考下2019-09-09
selenium處理元素定位點(diǎn)擊無(wú)效問(wèn)題
這篇文章主要介紹了selenium處理元素定位點(diǎn)擊無(wú)效問(wèn)題,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-06-06
基于nexus3配置Python倉(cāng)庫(kù)過(guò)程詳解
這篇文章主要介紹了基于nexus3配置Python倉(cāng)庫(kù)過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06
python實(shí)現(xiàn)12306登錄并保存cookie的方法示例
這篇文章主要介紹了 python實(shí)現(xiàn)12306登錄并保存cookie的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12

