2789 lines
110 KiB
Python
2789 lines
110 KiB
Python
from pptx import Presentation
|
||
from pptx.util import Inches, Pt, Cm
|
||
from pptx.dml.color import RGBColor
|
||
from pptx.enum.text import PP_ALIGN
|
||
from pptx.enum.text import MSO_ANCHOR # 导入正确的垂直对齐枚举
|
||
from pptx.enum.shapes import MSO_SHAPE
|
||
from pptx.chart.data import ChartData
|
||
from pptx.enum.chart import XL_CHART_TYPE,XL_LABEL_POSITION,XL_LEGEND_POSITION
|
||
from pptx.table import Table
|
||
from lxml import etree
|
||
|
||
from pptx.oxml.xmlchemy import OxmlElement
|
||
|
||
|
||
from parse_html import parse_html_to_ppt
|
||
from init import gcfg
|
||
|
||
|
||
#颜色组
|
||
g_colors =[
|
||
{"name": "深空蓝", "hex": "#0D4D4B", "rgb": (13, 77, 75)},
|
||
{"name": "紫罗兰", "hex": "#4A306D", "rgb": (74, 48, 109)},
|
||
{"name": "海军蓝", "hex": "#003366", "rgb": (0, 51, 102)},
|
||
{"name": "森林绿", "hex": "#22577A", "rgb": (34, 87, 122)},
|
||
{"name": "暗玫瑰红", "hex": "#E0115F", "rgb": (224, 17, 95)},
|
||
{"name": "橄榄绿", "hex": "#556B2F", "rgb": (85, 107, 47)},
|
||
{"name": "深紫", "hex": "#35063E", "rgb": (53, 6, 62)},
|
||
{"name": "宝石蓝", "hex": "#0F52BA", "rgb": (15, 82, 186)},
|
||
]
|
||
|
||
g_colors = g_colors*4
|
||
|
||
#背景
|
||
def apply_gradient_background(prs,slide,style={}):
|
||
"""应用统一的背景"""
|
||
# background = slide.background
|
||
# fill = background.fill
|
||
# fill.gradient()
|
||
# #fill.gradient_angle = 270 # 从上倒下
|
||
# #fill.gradient_angle = 45 # 从左下到右上
|
||
# fill.gradient_stops[0].color.rgb = RGBColor(mc[0], mc[1], mc[2]) # 深蓝
|
||
# fill.gradient_stops[1].color.rgb = RGBColor(255,255,255) # 蓝色
|
||
|
||
|
||
if "bg_image" in style:
|
||
# 设置背景图片
|
||
if style['bg_image'].startswith("/api/img"):
|
||
image_path = f"{gcfg['fs']['path']}/img/{style['bg_image'].split('/')[-1]}"
|
||
else:
|
||
image_path = f"pic/{style['bg_image']}"
|
||
|
||
left = top = Inches(0)
|
||
pic = slide.shapes.add_picture(image_path, left, top, width=prs.slide_width, height=prs.slide_height)
|
||
|
||
pass
|
||
|
||
|
||
|
||
"""0. 图片纯色背景标题"""
|
||
def draw_title_by_image(prs,slide):
|
||
# 将标题图片添加到幻灯片中
|
||
image_path = "pic/101_title.png"
|
||
left = top = 0
|
||
pic = slide.shapes.add_picture(image_path, left, top)
|
||
|
||
# 获取幻灯片尺寸
|
||
slide_width = prs.slide_width
|
||
slide_height = prs.slide_height
|
||
|
||
# 调整图片大小以填充整个幻灯片
|
||
pic.width = slide_width
|
||
pic.height = Cm(3.2)
|
||
|
||
# 可选:将图片置于底层(放在所有形状之后)
|
||
# slide.shapes._spTree.remove(pic._element)
|
||
# slide.shapes._spTree.insert(2, pic._element)
|
||
|
||
|
||
"""1. 竖道矩形标题"""
|
||
def draw_title_by_range(prs,slide,mc):
|
||
|
||
# 先添加矩形标题框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, Cm(0.9),Cm(0.5),Cm(0.5),Cm(2.8)
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
"""2. 竖道矩形+灰色标题框"""
|
||
def draw_title_by_range2(prs,slide,mc):
|
||
|
||
# 先添加矩形标题框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, Cm(0.7),Cm(0.5),Cm(0.5),Cm(2.8)
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
# 灰色标题框
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, Cm(1.5),Cm(0.5),Cm(39),Cm(2.8)
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
#fill.fore_color.rgb = RGBColor(192, 192, 192) # 浅灰色填充
|
||
fill.fore_color.rgb = RGBColor(245, 245, 245) # 浅灰色填充
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
#line.color.rgb = RGBColor(192, 192, 192) # 浅灰色填充
|
||
line.color.rgb = RGBColor(245, 245, 245) # 浅灰色填充
|
||
line.width = Pt(1)
|
||
|
||
|
||
"""3. 两个重叠的正方形标题框"""
|
||
def draw_title_by_square2(prs,slide,mc):
|
||
|
||
# 先添加矩形标题框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, Cm(0.3),Cm(0.9),Cm(1.4),Cm(1.4)
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
# 灰色标题框
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, Cm(0.9),Cm(1.7),Cm(0.9),Cm(0.9)
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(192, 192, 192) # 浅灰色填充
|
||
#fill.fore_color.rgb = RGBColor(245, 245, 245) # 浅灰色填充
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(192, 192, 192) # 浅灰色填充
|
||
#line.color.rgb = RGBColor(245, 245, 245) # 浅灰色填充
|
||
line.width = Pt(1)
|
||
|
||
|
||
|
||
|
||
|
||
"""4. 横线分割标题"""
|
||
def draw_title_by_line(prs,slide,mc):
|
||
|
||
# 先添加矩形标题框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, Cm(1.5),Cm(3.5),Cm(38),Cm(0.05)
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
"""5. 三角形标题"""
|
||
def draw_title_by_triangle(prs,slide,mc):
|
||
|
||
# 先添加三角形标题框(使用矩形形状 MSO_SHAPE.TRIANGLE)
|
||
triangle = slide.shapes.add_shape(
|
||
MSO_SHAPE.ISOSCELES_TRIANGLE,
|
||
Cm(0.1),Cm(1.2),Cm(2.4),Cm(1.3)
|
||
)
|
||
|
||
# 旋转三角形(角度:0-360)
|
||
triangle.rotation = 90 # 旋转180度(顶点朝下)
|
||
|
||
# 设置填充颜色
|
||
fill = triangle.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
|
||
# fill.gradient()
|
||
# fill.gradient_angle = 90 # 从左到右
|
||
# fill.gradient_stops[0].color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色
|
||
# fill.gradient_stops[1].color.rgb = RGBColor(255,255,255) # 白色
|
||
# fill.gradient_stops[1].color.alpha = 0.5 * 100000 # 50 %透明度
|
||
|
||
#获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = triangle.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(0)
|
||
|
||
|
||
|
||
#创建一个只有标题的空白页
|
||
def create_content_blank_slide(prs, title_text, subtitle_text=None,style={}):
|
||
"""创建一个只有标题的空白页"""
|
||
slide_layout = prs.slide_layouts[6] # 空白布局
|
||
slide = prs.slides.add_slide(slide_layout)
|
||
|
||
#开始
|
||
main_color = style["main_color"]
|
||
apply_gradient_background(prs,slide,style)
|
||
|
||
if style["title_style"]==0:
|
||
#白色
|
||
title_font_color = RGBColor(255, 255, 255)
|
||
draw_title_by_image(prs,slide)
|
||
|
||
else:
|
||
#主色
|
||
title_font_color = RGBColor(main_color[0],main_color[1],main_color[2])
|
||
if style["title_style"]==1:
|
||
draw_title_by_range(prs,slide,main_color)
|
||
elif style["title_style"]==2:
|
||
draw_title_by_range2(prs,slide,main_color)
|
||
elif style["title_style"]==3:
|
||
draw_title_by_square2(prs,slide,main_color)
|
||
elif style["title_style"]==4:
|
||
draw_title_by_line(prs,slide,main_color)
|
||
elif style["title_style"]==5:
|
||
draw_title_by_triangle(prs,slide,main_color)
|
||
else:
|
||
draw_title_by_image(prs,slide)
|
||
|
||
# 添加主标题
|
||
left = Cm(1.6)
|
||
top = Cm(-0.3) if subtitle_text else Cm(0.2)
|
||
width = Cm(36)
|
||
height = Cm(2)
|
||
title_box = slide.shapes.add_textbox(left, top, width, height)
|
||
tf = title_box.text_frame
|
||
tf.word_wrap = True
|
||
tf.clear()
|
||
|
||
p = tf.add_paragraph()
|
||
if subtitle_text:
|
||
p.text = title_text
|
||
else:
|
||
p.text = title_text
|
||
p.font.name="微软雅黑"
|
||
p.font.size = Pt(24)
|
||
p.font.color.rgb = title_font_color
|
||
p.font.bold = True
|
||
|
||
# 添加二级标题(如果有)
|
||
if subtitle_text:
|
||
#left = Cm(8.5 if len(title_text)==4 else 8.5+(len(title_text)-4))
|
||
left = Cm(1.6)
|
||
top = Cm(1)
|
||
width = Cm(36)
|
||
height = Cm(1.5)
|
||
subtitle_box = slide.shapes.add_textbox(left, top, width, height)
|
||
tf = subtitle_box.text_frame
|
||
tf.word_wrap = True
|
||
tf.clear()
|
||
|
||
p = tf.add_paragraph()
|
||
p.text = subtitle_text
|
||
p.font.name="微软雅黑"
|
||
p.font.size = Pt(30)
|
||
p.font.color.rgb = title_font_color
|
||
#p.font.italic = True
|
||
return slide
|
||
|
||
|
||
def create_content_list_slide(prs, title_text, subtitle_text=None, content_items=None,style={},index=6):
|
||
"一级内容列表"
|
||
slide = create_content_blank_slide(prs, title_text, subtitle_text,style)
|
||
|
||
main_color = style["main_color"]
|
||
# 添加内容区域,多级列表的内容
|
||
# 布局起始位置
|
||
left_text = Cm(5)
|
||
top_text = Cm(2)
|
||
width_text = Cm(32)
|
||
height_text = Cm(2)
|
||
|
||
mc = main_color
|
||
for i,item in enumerate(content_items[0:6]):
|
||
if style["style"]==1:
|
||
mc = g_colors[index]["rgb"]
|
||
|
||
# 添加内容
|
||
index += 1
|
||
top_text += Cm(2.5)
|
||
|
||
|
||
# 先添加矩形标题框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, left_text-Cm(2), top_text, Cm(2), height_text
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
|
||
#添加顺序号
|
||
text_box = slide.shapes.add_textbox(left_text-Cm(2), top_text, Cm(3), height_text)
|
||
tf = text_box.text_frame
|
||
|
||
# 启用自动换行
|
||
tf.word_wrap = True
|
||
#tf.clear()
|
||
# 删除所有段落
|
||
tf_clean_all(tf)
|
||
|
||
p = tf.add_paragraph()
|
||
p.text = str(index)
|
||
p.font.size = Pt(36)
|
||
p.font.color.rgb = RGBColor(255, 255, 255) #白色字体
|
||
p.font.bold = True
|
||
|
||
# 先添加矩形框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, left_text, top_text, width_text, height_text
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(255,255,255) # 白色填充
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
#添加内容文字
|
||
text_box = slide.shapes.add_textbox(left_text, top_text, width_text, height_text)
|
||
tf = text_box.text_frame
|
||
|
||
# 启用自动换行
|
||
tf.word_wrap = True
|
||
|
||
# 删除所有段落
|
||
tf_clean_all(tf)
|
||
|
||
p = tf.add_paragraph()
|
||
p.text = item["text"]
|
||
p.font.size = Pt(24)
|
||
if len(p.text) >70:
|
||
p.font.size = Pt(18)
|
||
p.font.color.rgb = RGBColor(0, 0, 0)
|
||
p.font.bold = True
|
||
|
||
if len(content_items) >6:
|
||
slide = create_content_list_slide(prs, title_text, subtitle_text,content_items[6:],style,index)
|
||
|
||
|
||
|
||
|
||
def create_content_slide(prs, title_text, subtitle_text=None, content_items=None,style={}):
|
||
"""创建带二级标题的内容页"""
|
||
def layout_card_2_4(slide,count,content_items,mc):
|
||
"""横向卡片式布局, 一级level """
|
||
|
||
#起始位置
|
||
left_text = Cm(3)
|
||
top_text = Cm(6)
|
||
height_text = Cm(14)
|
||
space_width = Cm(1)
|
||
if count==2:
|
||
space_width = Cm(3)
|
||
width_text = Cm(15)
|
||
height_text = Cm(13)
|
||
elif count==3:
|
||
space_width = Cm(2)
|
||
width_text = Cm(10)
|
||
height_text = Cm(10)
|
||
elif count==4:
|
||
top_text = Cm(7)
|
||
width_text = Cm(8)
|
||
height_text = Cm(8)
|
||
|
||
index = 0
|
||
for i,item in enumerate(content_items):
|
||
|
||
level = item.get("level", 0)
|
||
|
||
if level ==1: #一级标题
|
||
if style["style"]==1:
|
||
mc = g_colors[index]["rgb"]
|
||
index +=1
|
||
ol_li = 1
|
||
# 先添加矩形标题框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.ROUNDED_RECTANGLE, left_text, top_text-Cm(1), width_text, Cm(3)
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
# 添加标题
|
||
title_box = slide.shapes.add_textbox(left_text, top_text-Cm(0.8), width_text, Cm(1))
|
||
tf = title_box.text_frame
|
||
|
||
# 清楚之前的格式
|
||
tf_clean_all(tf)
|
||
|
||
p = tf.add_paragraph()
|
||
p.text = item["text"]
|
||
p.alignment = PP_ALIGN.CENTER # 设置段落居中
|
||
p.font.size = Pt(22)
|
||
p.font.color.rgb = RGBColor(255, 255, 255)
|
||
|
||
|
||
# 先添加矩形框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, left_text, top_text+Cm(0.5), width_text, height_text
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(255,255,255) # 白色填充
|
||
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
# 添加内容文字
|
||
text_box = slide.shapes.add_textbox(left_text, top_text, width_text, height_text)
|
||
tf = text_box.text_frame
|
||
|
||
# 启用自动换行
|
||
tf.word_wrap = True
|
||
tf.clear()
|
||
|
||
left_text += width_text+space_width
|
||
#一级标题结束
|
||
continue
|
||
|
||
#添加二级一下的文字
|
||
p = tf.add_paragraph()
|
||
p.font.size = Pt(item.get("size", 18))
|
||
p.font.color.rgb = RGBColor(0, 0, 0)
|
||
p.space_after = Pt(item.get("space_after", 8))
|
||
p.level = item.get("level", 2)-2
|
||
ol_li = output_text_style(p,item,RGBColor(mc[0],mc[1],mc[2]),ol_li,)
|
||
|
||
def layout_seq_2_4(slide,count,content_items,mc):
|
||
"""横向卡片式布局, 二级level 数字序号"""
|
||
|
||
#起始位置
|
||
left_text = Cm(3)
|
||
top_text = Cm(6)
|
||
height_text = Cm(14)
|
||
space_width = Cm(1)
|
||
if count==2:
|
||
space_width = Cm(3)
|
||
width_text = Cm(15)
|
||
height_text = Cm(15)
|
||
elif count==3:
|
||
space_width = Cm(2)
|
||
width_text = Cm(10)
|
||
height_text = Cm(14)
|
||
elif count==4:
|
||
top_text = Cm(7)
|
||
width_text = Cm(8)
|
||
height_text = Cm(13)
|
||
|
||
ol_li = 0
|
||
index=0
|
||
for i,item in enumerate(content_items):
|
||
|
||
level = item.get("level", 0)
|
||
|
||
if level ==2: #二级标题
|
||
ol_li += 1
|
||
if style["style"]==1:
|
||
mc = g_colors[index]["rgb"]
|
||
index +=1
|
||
# 先添加矩形框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, left_text, top_text-Cm(0.5), width_text, height_text
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.background()
|
||
#fill.solid()
|
||
#fill.fore_color.rgb = RGBColor(255,255,255) # 白色填充
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
|
||
# 圆形顺序号
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.OVAL, left_text+(width_text-Cm(3))//2, top_text-Cm(1.5), Cm(3), Cm(3)
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
# 添加序号
|
||
title_box = slide.shapes.add_textbox(left_text+(width_text-Cm(3))//2, top_text-Cm(1), Cm(3), Cm(3))
|
||
tf = title_box.text_frame
|
||
|
||
# 清楚之前的格式
|
||
tf_clean_all(tf)
|
||
|
||
p = tf.add_paragraph()
|
||
p.text = f'{ol_li:02d}'
|
||
p.alignment = PP_ALIGN.CENTER # 设置段落居中
|
||
p.font.size = Pt(42)
|
||
p.font.color.rgb = RGBColor(255, 255, 255)
|
||
|
||
# 添加标题
|
||
title_box = slide.shapes.add_textbox(left_text, top_text+Cm(1.5), width_text, Cm(1))
|
||
tf = title_box.text_frame
|
||
|
||
# 清楚之前的格式
|
||
tf_clean_all(tf)
|
||
tf.word_wrap = True
|
||
|
||
p = tf.add_paragraph()
|
||
p.text = item["text"]
|
||
p.alignment = PP_ALIGN.CENTER # 设置段落居中
|
||
p.font.size = Pt(22)
|
||
p.font.bold = True
|
||
p.font.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
|
||
# 添加内容文字
|
||
text_box = slide.shapes.add_textbox(left_text, top_text+Cm(2), width_text, height_text)
|
||
tf = text_box.text_frame
|
||
|
||
# 启用自动换行
|
||
tf.word_wrap = True
|
||
tf.clear()
|
||
|
||
left_text += width_text+space_width
|
||
#一级标题结束
|
||
continue
|
||
|
||
#添加二级一下的文字
|
||
p = tf.add_paragraph()
|
||
p.font.size = Pt(item.get("size", 18))
|
||
p.font.color.rgb = RGBColor(0, 0, 0)
|
||
p.space_after = Pt(item.get("space_after", 8))
|
||
p.level = item.get("level", 2)-2
|
||
ol_li = output_text_style(p,item,RGBColor(mc[0],mc[1],mc[2]),ol_li,)
|
||
|
||
|
||
def layout_card_5(slide,count,content_items,mc):
|
||
"""五个圆圈, 一级level+矩形的二级 """
|
||
|
||
#起始位置
|
||
left_text = Cm(3)
|
||
top_text = Cm(6)
|
||
height_text = Cm(8)
|
||
space_width = Cm(1)
|
||
width_text = Cm(6)
|
||
|
||
index=0
|
||
for i,item in enumerate(content_items):
|
||
|
||
level = item.get("level", 0)
|
||
|
||
if level ==1: #一级标题
|
||
|
||
if style["style"]==1:
|
||
mc = g_colors[index]["rgb"]
|
||
index +=1
|
||
# 先添加矩形标题框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.OVAL, left_text, top_text, Cm(5), Cm(5)
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
# 添加标题
|
||
title_box = slide.shapes.add_textbox(left_text, top_text+Cm(1.5), Cm(5), Cm(1))
|
||
tf = title_box.text_frame
|
||
|
||
# 清楚之前的格式
|
||
tf_clean_all(tf)
|
||
tf.word_wrap = True
|
||
|
||
p = tf.add_paragraph()
|
||
p.text = item["text"]
|
||
p.alignment = PP_ALIGN.CENTER # 设置段落居中
|
||
p.font.size = Pt(22)
|
||
p.font.color.rgb = RGBColor(255, 255, 255)
|
||
|
||
|
||
# 先添加矩形框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, left_text-Cm(0.3), top_text+Cm(6), width_text, height_text
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
# fill.solid()
|
||
# fill.fore_color.rgb = RGBColor(255,255,255) # 白色填充
|
||
fill.background()
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
# 添加内容文字
|
||
text_box = slide.shapes.add_textbox(left_text-Cm(0.3), top_text+Cm(6), width_text, height_text)
|
||
tf = text_box.text_frame
|
||
|
||
# 启用自动换行
|
||
tf.word_wrap = True
|
||
tf.clear()
|
||
|
||
left_text += width_text+space_width
|
||
#一级标题结束
|
||
continue
|
||
|
||
#添加二级一下的文字
|
||
p = tf.add_paragraph()
|
||
p.text = item["text"]
|
||
p.font.size = Pt(item.get("size", 18))
|
||
p.font.color.rgb = RGBColor(0, 0, 0)
|
||
p.space_after = Pt(item.get("space_after", 8))
|
||
p.level = 0
|
||
if item.get("bold", False):
|
||
p.font.bold = True
|
||
if item.get("bullet", False):
|
||
p.text = "• " + p.text
|
||
|
||
def layout_list_seq(slide,content_items,mc):
|
||
"""带序号的相同列表布局,"""
|
||
|
||
# 布局起始位置
|
||
left_text = Cm(5)
|
||
top_text = Cm(2)
|
||
width_text = Cm(32)
|
||
height_text = Cm(2)
|
||
|
||
index = 0
|
||
|
||
if len(content_items)==1:
|
||
layout_oval_1(slide,content_items[0],mc)
|
||
elif len(content_items)==2:
|
||
layout_oval_2(slide,content_items,mc)
|
||
elif len(content_items)==3:
|
||
layout_oval_3(slide,content_items,mc)
|
||
elif len(content_items)==4:
|
||
layout_oval_4(slide,content_items,mc)
|
||
elif len(content_items)==5:
|
||
layout_oval_5(slide,content_items,mc)
|
||
elif len(content_items) >=6:
|
||
|
||
for i,item in enumerate(content_items[0:6]):
|
||
if style["style"]==1:
|
||
mc = g_colors[i]["rgb"]
|
||
# 添加内容
|
||
|
||
top_text += Cm(2.5)
|
||
index += 1
|
||
|
||
# 先添加矩形标题框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, left_text-Cm(2), top_text, Cm(2), height_text
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
|
||
#添加顺序号
|
||
text_box = slide.shapes.add_textbox(left_text-Cm(2), top_text, Cm(2), height_text)
|
||
tf = text_box.text_frame
|
||
|
||
# 启用自动换行
|
||
tf.word_wrap = True
|
||
#tf.clear()
|
||
|
||
# 删除所有段落
|
||
tf_clean_all(tf)
|
||
|
||
p = tf.add_paragraph()
|
||
p.text = str(index)
|
||
p.font.size = Pt(36)
|
||
p.font.color.rgb = RGBColor(255, 255, 255) #白色字体
|
||
p.font.bold = True
|
||
|
||
# 先添加矩形框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, left_text, top_text, width_text, height_text
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(255,255,255) # 白色填充
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
#添加内容文字
|
||
text_box = slide.shapes.add_textbox(left_text, top_text, width_text, height_text)
|
||
tf = text_box.text_frame
|
||
|
||
# 启用自动换行
|
||
tf.word_wrap = True
|
||
|
||
# 删除所有段落
|
||
tf_clean_all(tf)
|
||
|
||
p = tf.add_paragraph()
|
||
p.text = item["text"]
|
||
p.font.size = Pt(24)
|
||
if len(p.text) >70:
|
||
p.font.size = Pt(18)
|
||
p.font.color.rgb = RGBColor(0, 0, 0)
|
||
p.font.bold = True
|
||
|
||
if len(content_items) >6:
|
||
slide = create_content_list_slide(prs, title_text, subtitle_text,content_items[6:],style)
|
||
|
||
#一级标题,一个圆
|
||
def layout_oval_1(slide,item,mc):
|
||
# 布局起始位置
|
||
left_text = Cm(12)
|
||
top_text = Cm(6)
|
||
width_text = Cm(15)
|
||
height_text = Cm(15)
|
||
|
||
# 先添加圆形标题框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.OVAL, left_text, top_text, width_text,height_text
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
# 添加标题
|
||
title_box = slide.shapes.add_textbox(left_text, top_text+height_text/2-Cm(2), width_text,height_text)
|
||
tf = title_box.text_frame
|
||
|
||
# 清楚之前的格式
|
||
tf_clean_all(tf)
|
||
tf.word_wrap = True
|
||
|
||
p = tf.add_paragraph()
|
||
p.text = item["text"]
|
||
p.alignment = PP_ALIGN.CENTER # 设置段落居中
|
||
p.font.size = Pt(22)
|
||
p.font.color.rgb = RGBColor(255, 255, 255)
|
||
|
||
|
||
#一级标题,两个圆
|
||
def layout_oval_2(slide,items,mc):
|
||
# 布局起始位置
|
||
left_text = Cm(6)
|
||
top_text = Cm(6)
|
||
width_text = Cm(14)
|
||
height_text = Cm(14)
|
||
|
||
for i,item in enumerate(items):
|
||
|
||
if style["style"]==1:
|
||
mc = g_colors[i]["rgb"]
|
||
# 先添加圆形标题框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.OVAL, left_text, top_text, width_text,height_text
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
# 添加标题
|
||
title_box = slide.shapes.add_textbox(left_text+i*Cm(2), top_text+height_text/2-Cm(3), width_text-Cm(2),height_text)
|
||
tf = title_box.text_frame
|
||
|
||
# 清楚之前的格式
|
||
tf_clean_all(tf)
|
||
tf.word_wrap = True
|
||
|
||
p = tf.add_paragraph()
|
||
p.text = item["text"]
|
||
p.alignment = PP_ALIGN.CENTER # 设置段落居中
|
||
if len(item["text"]) <150:
|
||
p.font.size = Pt(22)
|
||
else:
|
||
p.font.size = Pt(16)
|
||
p.font.color.rgb = RGBColor(255, 255, 255)
|
||
left_text += width_text -Cm(2)
|
||
|
||
|
||
|
||
#一级标题,三个圆
|
||
def layout_oval_3(slide,items,mc):
|
||
# 布局起始位置
|
||
left_text = Cm(15.5)
|
||
top_text = Cm(4.3)
|
||
width_text = Cm(9)
|
||
height_text = Cm(9)
|
||
|
||
# 先添加圆形标题框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.OVAL, left_text, top_text, width_text,height_text
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
# 添加标题
|
||
title_box = slide.shapes.add_textbox(left_text, top_text+height_text/2-Cm(2), width_text,height_text)
|
||
tf = title_box.text_frame
|
||
|
||
# 清楚之前的格式
|
||
tf_clean_all(tf)
|
||
tf.word_wrap = True
|
||
|
||
p = tf.add_paragraph()
|
||
p.text = items[0]["text"]
|
||
p.alignment = PP_ALIGN.CENTER # 设置段落居中
|
||
if len(p.text) <50:
|
||
p.font.size = Pt(20)
|
||
else:
|
||
p.font.size = Pt(16)
|
||
p.font.color.rgb = RGBColor(255, 255, 255)
|
||
|
||
# 布局起始位置
|
||
left_text = Cm(11)
|
||
top_text = Cm(12)
|
||
width_text = Cm(9)
|
||
height_text = Cm(9)
|
||
|
||
for i,item in enumerate(items[1:],1):
|
||
if style["style"]==1:
|
||
mc = g_colors[i]["rgb"]
|
||
# 先添加圆形标题框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.OVAL, left_text, top_text, width_text,height_text
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
# 添加标题
|
||
title_box = slide.shapes.add_textbox(left_text, top_text+height_text//2-Cm(2), width_text-Cm(1),height_text)
|
||
tf = title_box.text_frame
|
||
|
||
# 清楚之前的格式
|
||
tf_clean_all(tf)
|
||
tf.word_wrap = True
|
||
|
||
p = tf.add_paragraph()
|
||
p.text = item["text"]
|
||
p.alignment = PP_ALIGN.CENTER # 设置段落居中
|
||
if len(item["text"]) <50:
|
||
p.font.size = Pt(20)
|
||
else:
|
||
p.font.size = Pt(16)
|
||
p.font.color.rgb = RGBColor(255, 255, 255)
|
||
left_text += width_text
|
||
|
||
|
||
|
||
#一级标题,四个圆
|
||
def layout_oval_4(slide,items,mc):
|
||
# 布局起始位置
|
||
left_text = Cm(6.5)
|
||
top_text = Cm(4.5)
|
||
width_text = Cm(8)
|
||
height_text = Cm(8)
|
||
|
||
for i,item in enumerate(items[0:2]):
|
||
if style["style"]==1:
|
||
mc = g_colors[i]["rgb"]
|
||
# 先添加圆形标题框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.OVAL, left_text, top_text, width_text,height_text
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
# 添加标题
|
||
title_box = slide.shapes.add_textbox(left_text, top_text+height_text/2-Cm(2), width_text,height_text)
|
||
tf = title_box.text_frame
|
||
|
||
# 清楚之前的格式
|
||
tf_clean_all(tf)
|
||
tf.word_wrap = True
|
||
|
||
p = tf.add_paragraph()
|
||
p.text = item["text"]
|
||
p.alignment = PP_ALIGN.CENTER # 设置段落居中
|
||
if len(item["text"]) <40:
|
||
p.font.size = Pt(20)
|
||
else:
|
||
p.font.size = Pt(16)
|
||
p.font.color.rgb = RGBColor(255, 255, 255)
|
||
left_text += width_text +Cm(2)
|
||
|
||
# 布局起始位置
|
||
left_text = Cm(17)
|
||
top_text = Cm(13)
|
||
width_text = Cm(8)
|
||
height_text = Cm(8)
|
||
|
||
for i,item in enumerate(items[2:],2):
|
||
if style["style"]==1:
|
||
mc = g_colors[i]["rgb"]
|
||
# 先添加圆形标题框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.OVAL, left_text, top_text, width_text,height_text
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
# 添加标题
|
||
title_box = slide.shapes.add_textbox(left_text, top_text+height_text/2-Cm(2), width_text,height_text)
|
||
tf = title_box.text_frame
|
||
|
||
# 清楚之前的格式
|
||
tf_clean_all(tf)
|
||
tf.word_wrap = True
|
||
|
||
p = tf.add_paragraph()
|
||
p.text = item["text"]
|
||
p.alignment = PP_ALIGN.CENTER # 设置段落居中
|
||
if len(item["text"]) < 50:
|
||
p.font.size = Pt(20)
|
||
else:
|
||
p.font.size = Pt(16)
|
||
p.font.color.rgb = RGBColor(255, 255, 255)
|
||
left_text += width_text +Cm(2)
|
||
|
||
|
||
|
||
#一级标题,5个圆
|
||
def layout_oval_5(slide,items,mc):
|
||
# 布局起始位置
|
||
left_text = Cm(3)
|
||
top_text = Cm(8)
|
||
width_text = Cm(6)
|
||
height_text = Cm(6)
|
||
|
||
for i,item in enumerate(items):
|
||
if style["style"]==1:
|
||
mc = g_colors[i]["rgb"]
|
||
# 先添加圆形标题框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.OVAL, left_text, top_text, width_text,height_text
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
# 添加标题
|
||
title_box = slide.shapes.add_textbox(left_text, top_text+height_text/2-Cm(1.5), width_text,height_text)
|
||
tf = title_box.text_frame
|
||
|
||
# 清楚之前的格式
|
||
tf_clean_all(tf)
|
||
tf.word_wrap = True
|
||
|
||
p = tf.add_paragraph()
|
||
p.text = item["text"]
|
||
p.alignment = PP_ALIGN.CENTER # 设置段落居中
|
||
if len(item["text"]) <40:
|
||
p.font.size = Pt(18)
|
||
else:
|
||
p.font.size = Pt(14)
|
||
p.font.color.rgb = RGBColor(255, 255, 255)
|
||
left_text += width_text + Cm(1)
|
||
|
||
#一级标题+两个二级标题, 天秤
|
||
def layout_1_2(slide,items,mc):
|
||
# 布局起始位置
|
||
left_text = Cm(4)
|
||
top_text = Cm(6)
|
||
width_text = Cm(10)
|
||
height_text = Cm(10)
|
||
|
||
mc0 = mc
|
||
for i,item in enumerate(items[1:]):
|
||
if style["style"]==1:
|
||
mc = g_colors[i]["rgb"]
|
||
# 先添加圆形标题框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.OVAL, left_text, top_text, width_text,height_text
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
# 添加标题
|
||
title_box = slide.shapes.add_textbox(left_text, top_text+height_text/2-Cm(2), width_text,height_text)
|
||
tf = title_box.text_frame
|
||
|
||
# 清楚之前的格式
|
||
tf_clean_all(tf)
|
||
tf.word_wrap = True
|
||
|
||
p = tf.add_paragraph()
|
||
p.text = item["text"]
|
||
p.alignment = PP_ALIGN.CENTER # 设置段落居中
|
||
p.font.size = Pt(22)
|
||
p.font.color.rgb = RGBColor(255, 255, 255)
|
||
left_text += width_text+Cm(14)
|
||
|
||
mc = mc0
|
||
#绘制天平
|
||
# 先添加矩形形状(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, Cm(5), top_text+height_text, Cm(32), Cm(0.5)
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
# 先添加三角形标题框(使用矩形形状 MSO_SHAPE.TRIANGLE)
|
||
triangle = slide.shapes.add_shape(
|
||
MSO_SHAPE.ISOSCELES_TRIANGLE,
|
||
Cm(20),top_text+height_text+Cm(0.5),Cm(2),Cm(2)
|
||
)
|
||
|
||
# 旋转三角形(角度:0-360)
|
||
#triangle.rotation = 90 # 旋转180度(顶点朝下)
|
||
|
||
# 设置填充颜色
|
||
fill = triangle.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
|
||
#获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = triangle.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(0)
|
||
|
||
#一级标题文字
|
||
# 添加标题
|
||
title_box = slide.shapes.add_textbox(Cm(18), top_text+height_text/2, Cm(5),height_text)
|
||
tf = title_box.text_frame
|
||
|
||
# 清楚之前的格式
|
||
tf_clean_all(tf)
|
||
tf.word_wrap = True
|
||
|
||
p = tf.add_paragraph()
|
||
p.text = items[0]["text"]
|
||
p.alignment = PP_ALIGN.CENTER # 设置段落居左
|
||
p.font.size = Pt(24)
|
||
p.font.color.rgb = RGBColor(mc[0],mc[1],mc[2])
|
||
|
||
|
||
#一级标题+3或5个二级标题, 晾衣杆
|
||
def layout_1_3_5(slide,content_items,count,mc):
|
||
""""""
|
||
|
||
#起始位置
|
||
left_text = Cm(3)
|
||
top_text = Cm(10)
|
||
height_text = Cm(14)
|
||
space_width = Cm(1)
|
||
if count==3:
|
||
space_width = Cm(2)
|
||
width_text = Cm(10)
|
||
height_text = Cm(8)
|
||
elif count==5:
|
||
space_width = Cm(1)
|
||
width_text = Cm(6)
|
||
height_text = Cm(6)
|
||
|
||
mc0 = mc
|
||
for i,item in enumerate(content_items[1:]):
|
||
level = item.get("level", 0)
|
||
if level ==2: #二级标题
|
||
if style["style"]==1:
|
||
mc = g_colors[i]["rgb"]
|
||
#晾衣杆-竖子梁 先添加矩形框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, left_text+width_text//2, Cm(7.5), Cm(0.2), Cm(1.5)
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
# 先添加矩形标题框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.ROUNDED_RECTANGLE, left_text, top_text-Cm(1), width_text, Cm(3)
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
# 添加标题
|
||
title_box = slide.shapes.add_textbox(left_text, top_text-Cm(0.8), width_text, Cm(1))
|
||
tf = title_box.text_frame
|
||
|
||
# 清楚之前的格式
|
||
tf_clean_all(tf)
|
||
|
||
#标题内容少则放入标题框
|
||
if len(item["text"])<=6:
|
||
p = tf.add_paragraph()
|
||
p.text = item["text"]
|
||
p.alignment = PP_ALIGN.CENTER # 设置段落居中
|
||
p.font.size = Pt(22)
|
||
p.font.color.rgb = RGBColor(255, 255, 255)
|
||
else:
|
||
# 白色圆点装饰
|
||
# 先添加圆形标题框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.OVAL, left_text+width_text-Cm(1), top_text-Cm(0.5), Cm(0.5), Cm(0.5)
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(255, 255, 255) # 主色填充
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(255, 255, 255) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
|
||
# 先添加矩形框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, left_text, top_text+Cm(0.5), width_text, height_text
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(255,255,255) # 白色填充
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
# 添加内容文字
|
||
text_box = slide.shapes.add_textbox(left_text, top_text, width_text, height_text)
|
||
tf = text_box.text_frame
|
||
|
||
# 启用自动换行
|
||
tf.word_wrap = True
|
||
tf.clear()
|
||
|
||
#标题内容多则放入如容框
|
||
if len(item["text"])>6:
|
||
p = tf.add_paragraph()
|
||
p.text = item["text"]
|
||
p.font.size = Pt(22)
|
||
if count==5:
|
||
p.font.size = Pt(20)
|
||
p.font.color.rgb = RGBColor(0, 0, 0)
|
||
|
||
|
||
left_text += width_text+space_width
|
||
#一级标题结束
|
||
continue
|
||
|
||
#添加二级一下的文字
|
||
p = tf.add_paragraph()
|
||
p.text = item["text"]
|
||
p.font.size = Pt(item.get("size", 18))
|
||
p.font.color.rgb = RGBColor(0, 0, 0)
|
||
p.space_after = Pt(item.get("space_after", 8))
|
||
if item.get("bold", False):
|
||
p.font.bold = True
|
||
if item.get("bullet", False):
|
||
p.text = "• " + p.text
|
||
|
||
|
||
mc = mc0
|
||
#一级标题
|
||
# 先添加矩形标题框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.ROUNDED_RECTANGLE, Cm(15), Cm(4), Cm(10), Cm(2)
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
# 添加标题
|
||
title_box = slide.shapes.add_textbox(Cm(15), Cm(4.5), Cm(10), Cm(2))
|
||
tf = title_box.text_frame
|
||
|
||
# 清楚之前的格式
|
||
tf_clean_all(tf)
|
||
p = tf.add_paragraph()
|
||
p.text = content_items[0]["text"]
|
||
p.alignment = PP_ALIGN.CENTER # 设置段落居中
|
||
p.font.size = Pt(24)
|
||
p.font.color.rgb = RGBColor(255, 255, 255)
|
||
|
||
#晾衣杆-竖主梁 先添加矩形框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, Cm(20), Cm(6), Cm(0.2), Cm(1.5)
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
#晾衣杆-横梁 先添加矩形框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, Cm(4), Cm(7.5), Cm(32), Cm(0.3)
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
|
||
#一个主圆+n个矩形
|
||
def layout_1_4_6(slide,content_items,n,main_color):
|
||
"""1级的一个框+二级的4个横向布局"""
|
||
#二级框列表
|
||
index=0
|
||
width_text = Cm(12)
|
||
if n==4:
|
||
height_text = Cm(5)
|
||
elif n==6:
|
||
height_text = Cm(3)
|
||
|
||
top_start = Cm(7)
|
||
left_text = Cm(3)
|
||
|
||
mc0 = main_color
|
||
for item in content_items[1:]:
|
||
level = item.get("level", 0)
|
||
|
||
if level ==2:
|
||
if style["style"]==1:
|
||
main_color = g_colors[index]["rgb"]
|
||
if index %2==0: #左边
|
||
left_text = Cm(3)
|
||
else:
|
||
left_text = Cm(3+12+10)
|
||
|
||
index_level = index//2
|
||
|
||
top_text = top_start + index_level*height_text+ Cm(1)*index_level
|
||
#print(index,top_text,index_level)
|
||
|
||
# 先添加矩形形状(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, left_text, top_text, width_text, height_text
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(main_color[0],main_color[1],main_color[2]) # 主色填充
|
||
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(main_color[0],main_color[1],main_color[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
text_box = slide.shapes.add_textbox(left_text+Cm(index%2), top_text, width_text-Cm(1), height_text)
|
||
hr = text_box.text_frame
|
||
|
||
# 启用自动换行
|
||
hr.word_wrap = True
|
||
tf_clean_all(hr)
|
||
|
||
p = hr.add_paragraph()
|
||
p.text = item["text"]
|
||
p.font.name="微软雅黑"
|
||
p.font.size = Pt(22)
|
||
p.font.color.rgb = RGBColor(255, 255, 255)
|
||
index +=1
|
||
else:
|
||
|
||
p = hr.add_paragraph()
|
||
p.text = item["text"]
|
||
p.font.name="微软雅黑"
|
||
p.font.size = Pt(item.get("size", 18))
|
||
|
||
#白色
|
||
p.font.color.rgb = RGBColor(255, 255, 255)
|
||
if item.get("bold", False):
|
||
p.font.bold = True
|
||
if item.get("bullet", False):
|
||
p.text = "• " + p.text
|
||
|
||
# 最后画园,布局起始位置
|
||
left_text = Cm(15)
|
||
top_text = Cm(7)
|
||
width_text = Cm(10)
|
||
height_text = Cm(10)
|
||
|
||
|
||
#外面的白色大圆
|
||
main_color = mc0
|
||
# 先添加圆形标题框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.OVAL, left_text-Cm(1), top_text-Cm(1), width_text+Cm(2),height_text+Cm(2)
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(255,255,255) # 主色填充
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(255,255,255) # 主色填充
|
||
line.width = Pt(0)
|
||
|
||
# 先添加圆形标题框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.OVAL, left_text, top_text, width_text,height_text
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(main_color[0],main_color[1],main_color[2]) # 主色填充
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(main_color[0],main_color[1],main_color[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
# 添加标题
|
||
title_box = slide.shapes.add_textbox(left_text, top_text+height_text/2-Cm(1), width_text,height_text)
|
||
tf = title_box.text_frame
|
||
|
||
# 清楚之前的格式
|
||
tf_clean_all(tf)
|
||
tf.word_wrap = True
|
||
|
||
p = tf.add_paragraph()
|
||
p.text = content_items[0]["text"]
|
||
p.alignment = PP_ALIGN.CENTER # 设置段落居中
|
||
p.font.size = Pt(36)
|
||
p.font.bold = True
|
||
p.font.color.rgb = RGBColor(255, 255, 255)
|
||
|
||
|
||
|
||
def create_codes_slide():
|
||
#根据code内容合理的划分slide
|
||
codes=[]
|
||
code_index=0
|
||
for item in content_items:
|
||
codes.append(item)
|
||
if item.get("code",False):
|
||
if code_index==0:
|
||
layout_blockquote_code(prs,slide,title_text,subtitle_text,codes,main_color,style)
|
||
code_index +=1
|
||
codes=[]
|
||
else:
|
||
create_content_slide(prs, title_text, subtitle_text, codes,style)
|
||
#end for
|
||
|
||
#开始
|
||
main_color = style["main_color"]
|
||
slide = create_content_blank_slide(prs,title_text,subtitle_text,style)
|
||
|
||
# 添加内容区域,多级列表的内容
|
||
if content_items:
|
||
#识别列表内容
|
||
level_1=0
|
||
level_2=0
|
||
level_3=0
|
||
blockquote_code=False
|
||
codes=0 #代码块数量
|
||
for item in content_items:
|
||
level = item.get("level",0)
|
||
if level==1:
|
||
level_1 +=1
|
||
elif level==2:
|
||
level_2 +=1
|
||
elif level==3:
|
||
level_3 +=1
|
||
if item.get("blockquote",False):
|
||
blockquote_code = True
|
||
if item.get("code",False):
|
||
blockquote_code = True
|
||
codes +=1
|
||
|
||
#布局
|
||
if blockquote_code:
|
||
if codes >=2:
|
||
create_codes_slide() #需要根据内容切成多张ppt
|
||
else:
|
||
layout_blockquote_code(prs,slide,title_text,subtitle_text,content_items,main_color,style)
|
||
elif content_items[0].get("number",False) and level_2 in (2,3,4): #数字需要的二级
|
||
layout_seq_2_4(slide,level_2,content_items,main_color)
|
||
elif ((level_1>0 and level_2==0 and level_3==0) or
|
||
(level_1==0 and level_2>0 and level_3==0) or
|
||
(level_1==0 and level_2==0 and level_3>0)) :
|
||
#级别都相同,按顺序列表处理
|
||
layout_list_seq(slide,content_items,main_color)
|
||
elif content_items[0].get("level",0)==1 and level_1 >=2 and level_1<=4 and (level_2 >0 or level_3 >0):
|
||
layout_card_2_4(slide,level_1,content_items,main_color)
|
||
elif content_items[0].get("level",0)==1 and level_1==5 and (level_2 >0 or level_3 >0):
|
||
layout_card_5(slide,level_1,content_items,main_color)
|
||
elif content_items[0].get("level",0)==1 and level_1==1 and level_2 in (4,6):
|
||
layout_1_4_6(slide,content_items,level_2,main_color)
|
||
elif content_items[0].get("level",0)==1 and level_1==1 and level_2 ==2:
|
||
layout_1_2(slide,content_items,main_color)
|
||
elif content_items[0].get("level",0)==1 and level_1==1 and level_2 in (3,5):
|
||
layout_1_3_5(slide,content_items,level_2,main_color)
|
||
else:
|
||
if len(content_items)<=12:
|
||
layout_normal(slide,subtitle_text,content_items,style)
|
||
else:
|
||
i=0
|
||
while 1:
|
||
layout_normal(slide,subtitle_text,content_items[i:i+12],style)
|
||
i +=12
|
||
if i< len(content_items):
|
||
slide = create_content_blank_slide(prs,title_text,subtitle_text,style)
|
||
else:
|
||
break
|
||
return slide
|
||
|
||
|
||
#引用提示的布局,这个需要单独处理,引用的矩形框
|
||
def layout_blockquote_code(prs,slide,title_text,subtitle_text,content_items,mc,style):
|
||
"""文字列表布局"""
|
||
# 起始未知
|
||
left_text = Cm(2)
|
||
top_text = Cm(4)
|
||
width_text = Cm(36)
|
||
height_text = Cm(2)
|
||
|
||
ol_li = 1
|
||
if "ol" in style:
|
||
ol_li = style["ol"]
|
||
for i,item in enumerate(content_items):
|
||
left_text_0 = left_text
|
||
width_text_0 = width_text
|
||
height_text_0 = height_text
|
||
|
||
if top_text+i*height_text > Cm(20): #还有内容,则放到一页处理
|
||
#print(len(content_items[i:]),content_items[i:])
|
||
style["ol"] = ol_li
|
||
create_content_slide(prs,title_text, subtitle_text,content_items[i:],style)
|
||
break
|
||
if item.get("blockquote",False):
|
||
left_text_0 = left_text+Cm(4.5)
|
||
width_text_0 = width_text-Cm(6)
|
||
# 先添加矩形标题框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, left_text_0-Cm(0.5), top_text+i*height_text, Cm(0.5), height_text+Cm(0.5)
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
# 先添加矩形框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, left_text_0, top_text+i*height_text, width_text_0, height_text+Cm(0.5)
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(255,255,255) # 白色填充
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
#代码框
|
||
if item.get("code",False):
|
||
left_text_0 = left_text+Cm(4.5)
|
||
width_text_0 = width_text-Cm(6)
|
||
height_text_0 = Cm(12)
|
||
# 灰色标题框
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, left_text_0, top_text+i*height_text, width_text_0, height_text_0
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
#fill.fore_color.rgb = RGBColor(192, 192, 192) # 浅灰色填充
|
||
fill.fore_color.rgb = RGBColor(245, 245, 245) # 浅灰色填充
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
#line.color.rgb = RGBColor(192, 192, 192) # 浅灰色填充
|
||
line.color.rgb = RGBColor(245, 245, 245) # 浅灰色填充
|
||
line.width = Pt(1)
|
||
|
||
#文字内容
|
||
text_box = slide.shapes.add_textbox(left_text_0, top_text+i*height_text, width_text_0, height_text_0)
|
||
tf = text_box.text_frame
|
||
|
||
# 启用自动换行
|
||
tf_clean_all(tf)
|
||
tf.word_wrap = True
|
||
|
||
if item.get("level", 0)==1:
|
||
ol_li = 1
|
||
p = tf.add_paragraph()
|
||
p.font.name="微软雅黑"
|
||
p.font.size = Pt(item.get("size", 18))
|
||
|
||
#默认黑色
|
||
p.font.color.rgb = RGBColor(0, 0, 0)
|
||
p.space_after = Pt(item.get("space_after", 8))
|
||
p.level = item.get("level", 0)
|
||
if p.level==3:
|
||
p.font.color.rgb = RGBColor(102, 102, 102) #浅灰色
|
||
ol_li = output_text_style(p,item,RGBColor(mc[0],mc[1],mc[2]),ol_li)
|
||
#下方保持点距离
|
||
if item.get("blockquote",False):
|
||
top_text +=Cm(1)
|
||
if item.get("code",False):
|
||
top_text +=Cm(13)
|
||
|
||
|
||
|
||
#按照段落的样式进行输出
|
||
def output_text_style(p,item,color,index=0):
|
||
if item.get("number", False):
|
||
run2 = p.add_run()
|
||
run2.text = f'{index:02d}. '
|
||
|
||
font2 = run2.font
|
||
font2.color.rgb = color
|
||
font2.size = Pt(18)
|
||
|
||
run3 = p.add_run()
|
||
run3.text = item["text"]
|
||
index += 1
|
||
elif item.get("bullet", False):
|
||
run2 = p.add_run()
|
||
run2.text = "• "
|
||
|
||
font2 = run2.font
|
||
font2.color.rgb = color
|
||
font2.size = Pt(18)
|
||
|
||
run3 = p.add_run()
|
||
run3.text = item["text"]
|
||
else:
|
||
p.text = item["text"] #普通
|
||
if item.get("bold", False):#粗体
|
||
p.font.bold = True
|
||
return index
|
||
|
||
|
||
def layout_normal(slide,subtitle_text,content_items,style):
|
||
"""文字列表布局"""
|
||
mc = style["main_color"]
|
||
# 添加内容文字
|
||
left_text = Cm(2)
|
||
top_text = Cm(4.5 if subtitle_text else 3.5)
|
||
width_text = Cm(36)
|
||
height_text = Cm(8)
|
||
text_box = slide.shapes.add_textbox(left_text, top_text, width_text, height_text)
|
||
tf = text_box.text_frame
|
||
|
||
# 启用自动换行
|
||
tf.word_wrap = True
|
||
tf.clear()
|
||
ol_li = 1
|
||
if "ol" in style:
|
||
ol_li = style["ol"]
|
||
for item in content_items:
|
||
if item.get("level", 0)==1:
|
||
ol_li = 1
|
||
p = tf.add_paragraph()
|
||
p.font.name="微软雅黑"
|
||
p.font.size = Pt(item.get("size", 18))
|
||
|
||
#默认黑色
|
||
p.font.color.rgb = RGBColor(0, 0, 0)
|
||
p.space_after = Pt(item.get("space_after", 8))
|
||
p.level = item.get("level", 0)
|
||
if p.level==3:
|
||
p.font.color.rgb = RGBColor(102, 102, 102) #浅灰色
|
||
ol_li = output_text_style(p,item,RGBColor(mc[0],mc[1],mc[2]),ol_li)
|
||
style["ol"] = ol_li
|
||
|
||
|
||
|
||
def create_table_slide(prs, title_text, subtitle_text, headers, data,content,style=None):
|
||
"""创建带表格的数据页"""
|
||
|
||
slide = create_content_slide(prs, title_text, subtitle_text,None,style)
|
||
|
||
mc = style["main_color"]
|
||
if len(content) >5: #新的一页单独放表格
|
||
slide = create_content_slide(prs, title_text, subtitle_text,None,style)
|
||
else:
|
||
if len(content)>=1:
|
||
#直接在表格旁做个sumari的总结
|
||
# 添加内容位置
|
||
left_text = Cm(30)
|
||
top_text = Cm(5.5 if subtitle_text else 4.5)
|
||
width_text = Cm(10)
|
||
height_text = Cm(14)
|
||
|
||
|
||
# 先添加矩形标题框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, left_text, top_text, width_text, Cm(0.7)
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
# 先添加矩形框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, left_text, top_text+Cm(0.7), width_text, height_text
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
#fill.solid()
|
||
#fill.fore_color.rgb = RGBColor(255,255,255) # 白色填充
|
||
fill.background()
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
# 添加内容文字
|
||
text_box = slide.shapes.add_textbox(left_text, top_text, width_text, height_text)
|
||
tf = text_box.text_frame
|
||
|
||
# 启用自动换行
|
||
tf.word_wrap = True
|
||
tf.clear()
|
||
|
||
ol_li = 1
|
||
for item in content:
|
||
p = tf.add_paragraph()
|
||
p.font.size = Pt(item.get("size", 18))
|
||
p.font.color.rgb = RGBColor(0, 0, 0)
|
||
#p.space_after = Pt(item.get("space_after", 8))
|
||
#p.level = item.get("level", 0)
|
||
ol_li = output_text_style(p,item,RGBColor(mc[0],mc[1],mc[2]),ol_li)
|
||
|
||
|
||
# 计算表格位置和大小
|
||
left = Cm(2)
|
||
top = Cm(4 if len(content) >3 else 8) #内容多就新的一页
|
||
width = Cm(26.5)
|
||
|
||
height = Cm(12 if len(data) >10 else 8) #表格数据比较多
|
||
|
||
# 创建表格 (行数=数据行数+1,列数=标题数)
|
||
if not data[0]: #为空
|
||
data=data[1:] #去掉第一行的空行
|
||
|
||
if headers == data[0]: # 和表头相同
|
||
data=data[1:] #去掉第一行的空行
|
||
|
||
rows = len(data) + 1
|
||
cols = len(headers)
|
||
shape = slide.shapes.add_table(rows, cols, left, top, width, height)
|
||
|
||
table = shape.table
|
||
|
||
# 设置表格样式
|
||
table.first_row = True # 强调第一行
|
||
table.horz_banding = True # 横向条纹
|
||
|
||
# 设置表头
|
||
for col_idx, header in enumerate(headers):
|
||
cell = table.cell(0, col_idx)
|
||
cell.text = header
|
||
cell.fill.solid()
|
||
cell.fill.fore_color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
cell.text_frame.paragraphs[0].font.color.rgb = RGBColor(255, 255, 255)
|
||
cell.text_frame.paragraphs[0].font.bold = True
|
||
cell.text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER
|
||
|
||
# 填充表格数据
|
||
for row_idx, row_data in enumerate(data, start=1):
|
||
for col_idx, cell_data in enumerate(row_data):
|
||
cell = table.cell(row_idx, col_idx)
|
||
cell.text = str(cell_data)
|
||
cell.fill.solid()
|
||
cell.fill.fore_color.rgb = RGBColor(245, 245, 245) #浅灰色
|
||
cell.fill.fore_color.alpha = 0.2 # 半透明白色
|
||
cell.text_frame.paragraphs[0].font.color.rgb = RGBColor(0, 0, 0) # 黑色文字
|
||
cell.text_frame.paragraphs[0].alignment = PP_ALIGN.LEFT
|
||
|
||
# #边框线(赞不支持)
|
||
# for border_side in ["top", "bottom", "left", "right"]:
|
||
# border = getattr(cell, f"{border_side}_border")
|
||
# border.fill.background() # 清除任何填充色,确保只应用线条样式
|
||
# border.color.rgb = RGBColor(0, 64, 128)
|
||
# border.size = Cm(0.1)
|
||
|
||
# 设置表格边框
|
||
for cell in table.iter_cells():
|
||
cell.margin_left = Cm(0.1)
|
||
cell.margin_right = Cm(0.1)
|
||
cell.margin_top = Cm(0.05)
|
||
cell.margin_bottom = Cm(0.05)
|
||
cell.vertical_anchor = MSO_ANCHOR.MIDDLE
|
||
|
||
#设置表格动画
|
||
# if content:
|
||
# # 获取表格的 XML 元素
|
||
# graphic_frame = shape._element
|
||
|
||
# # 创建飞入动画(从左侧进入的路径动画)
|
||
# anim = OxmlElement("p:anim")
|
||
# anim.set("xmlns:p", "http://schemas.openxmlformats.org/presentationml/2006/main")
|
||
# anim.set("xmlns:a", "http://schemas.openxmlformats.org/drawingml/2006/main")
|
||
# anim.set("type", "entr") # 进入动画类型
|
||
# anim.set("effect", "flyIn") # 飞入效果
|
||
# anim.set("from", "left") # 从左侧进入
|
||
|
||
# # 设置动画参数(可选)
|
||
# anim_motion = OxmlElement("p:animMotion")
|
||
# anim_motion.set("path", "M 0 0 L 0.5 0") # 路径参数(水平移动)
|
||
# anim_motion.set("origin", "layout")
|
||
# anim.append(anim_motion)
|
||
|
||
# # 设置触发方式(单击时触发)
|
||
# anim.set("trigger", "onClick")
|
||
|
||
# # 附加动画到表格对象
|
||
# graphic_frame.append(anim)
|
||
|
||
return slide
|
||
|
||
|
||
def create_chart_slide(prs, title_text, subtitle_text, chart_type, data,style):
|
||
"""创建图表的数据页"""
|
||
slide = create_content_slide(prs, title_text, subtitle_text,None,style)
|
||
|
||
#半透明白色背景
|
||
left_content = Cm(2)
|
||
top_content = Cm(7 if subtitle_text else 6) # 根据是否有二级标题调整位置
|
||
width_content = Cm(28.5)
|
||
height_content = Cm(15 if len(data) >10 else 12 )
|
||
content_box = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, left_content, top_content, width_content, height_content
|
||
)
|
||
content_box.fill.solid()
|
||
content_box.fill.fore_color.rgb = RGBColor(255, 255, 255)
|
||
content_box.fill.fore_color.alpha = 0.2 # 20%透明度
|
||
content_box.line.color.rgb = RGBColor(200, 230, 255)
|
||
|
||
# 和前端颜色一致
|
||
colors = [
|
||
"#FF6384", # 对应 rgba(255,99,132,1)
|
||
"#36A2EB", # 对应 rgba(54, 162, 235, 1)
|
||
"#FFCE56", # 对应 rgba(255, 206, 86, 1)
|
||
"#4BC0C0", # 对应 rgba(75, 192, 192, 1)
|
||
"#9966FF", # 对应 rgba(153, 102, 255, 1)
|
||
"#FF9F40", # 对应 rgba(255, 159, 64, 1)
|
||
"#FF6347", # 新增:对应 rgba(255, 99, 71, 1),番茄红
|
||
"#90EE90", # 新增:对应 rgba(144, 238, 144, 1),淡绿
|
||
"#ADD8E6", # 新增:对应 rgba(173, 216, 230, 1),浅天蓝
|
||
"#FFC0CB" # 新增:对应 rgba(255, 192, 203, 1),浅粉
|
||
]
|
||
|
||
# 添加图表数据
|
||
if data:
|
||
chart_data = ChartData()
|
||
|
||
chart_data.categories = data["categories"]
|
||
del data["categories"]
|
||
for lable, series in data.items():
|
||
chart_data.add_series(lable, series)
|
||
|
||
# 添加图表
|
||
left_chart = Cm(3)
|
||
top_chart = Cm(8)
|
||
width_chart = Cm(25)
|
||
height_chart = Cm(12 if len(data) >10 else 10 )
|
||
|
||
if chart_type=="[chart][bar]":
|
||
xl_chart_type=XL_CHART_TYPE.COLUMN_CLUSTERED
|
||
elif chart_type=="[chart][line]":
|
||
xl_chart_type=XL_CHART_TYPE.LINE
|
||
elif chart_type=="[chart][bar_line]":
|
||
xl_chart_type=XL_CHART_TYPE.BAR_CLUSTERED
|
||
elif chart_type=="[chart][area]":
|
||
xl_chart_type=XL_CHART_TYPE.AREA
|
||
else:
|
||
xl_chart_type=XL_CHART_TYPE.BAR_STACKED
|
||
|
||
chart = slide.shapes.add_chart(
|
||
xl_chart_type,left_chart, top_chart, width_chart, height_chart, chart_data
|
||
)
|
||
|
||
# 设置数据标签
|
||
plot = chart.chart.plots[0]
|
||
plot.has_data_labels = True
|
||
data_labels = plot.data_labels
|
||
data_labels.show_value = True # 显示数值
|
||
data_labels.position = XL_LABEL_POSITION.OUTSIDE_END # 标签位置
|
||
# 设置数据标签的字体大小
|
||
data_labels.font.size = Pt(6) # 假设你想要设置字体大小为12磅
|
||
|
||
# 设置图例
|
||
chart.chart.has_legend = True # 确保图例可见
|
||
chart.chart.legend.position = XL_LEGEND_POSITION.BOTTOM # 设置图例位置为底部
|
||
chart.chart.legend.include_in_layout = False # 不让图例覆盖图表
|
||
|
||
# 设置图表颜色
|
||
if len(chart.chart.series) ==1:
|
||
#只有一个series
|
||
for idx, point in enumerate(chart.chart.series[0].points):
|
||
if idx < len(colors): # 确保颜色数量足够
|
||
fill = point.format.fill
|
||
fill.solid()
|
||
fill.fore_color.alpha = 0.2 # 20%透明度
|
||
fill.fore_color.rgb = RGBColor.from_string(colors[idx][1:])
|
||
else:
|
||
data_labels.show_value = False # 显示数值
|
||
data_labels.position = XL_LABEL_POSITION.OUTSIDE_END # 标签位置
|
||
#设置图表颜色 - 为每个系列分配一种颜色
|
||
for idx, serie in enumerate(chart.chart.series):
|
||
if idx < len(colors): # 确保颜色数量足够
|
||
fill = serie.format.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor.from_string(colors[idx][1:]) # 移除前缀'#'
|
||
|
||
# # 设置图表颜色以匹配主题
|
||
# chart.chart.plots[0].series[0].format.fill.solid()
|
||
# chart.chart.plots[0].series[0].format.fill.fore_color.rgb = RGBColor(100, 180, 255)
|
||
# chart.chart.plots[0].series[1].format.fill.solid()
|
||
# chart.chart.plots[0].series[1].format.fill.fore_color.rgb = RGBColor(200, 230, 255)
|
||
|
||
return slide
|
||
|
||
|
||
#删除所有段落
|
||
def tf_clean_all(tf):
|
||
for para in list(tf.paragraphs):
|
||
tf._element.remove(para._element)
|
||
|
||
|
||
def create_image_layout_slide(prs, title_text, subtitle_text, images,content_items=None,style=None):
|
||
"""创建图片布局页面"""
|
||
slide = create_content_slide(prs, title_text, subtitle_text,None,style)
|
||
|
||
mc = style["main_color"]
|
||
|
||
# 清除默认内容区域
|
||
for shape in slide.shapes:
|
||
if shape.shape_type == MSO_SHAPE.ROUNDED_RECTANGLE:
|
||
sp = shape._element
|
||
sp.getparent().remove(sp)
|
||
|
||
# 根据图片数量决定布局
|
||
if len(images) == 1:
|
||
# 单张大图布局
|
||
left = Cm(3)
|
||
top = Cm(5 if subtitle_text else 4)+Cm(0.5)
|
||
width = Cm(26)
|
||
height = Cm(15)
|
||
pic = slide.shapes.add_picture(images[0]["path"], left, top, width, height)
|
||
|
||
# 添加图片说明
|
||
if "caption" in images[0]:
|
||
left_cap = Cm(3)
|
||
top_cap = Cm(20 if subtitle_text else 19)
|
||
width_cap = Cm(25)
|
||
height_cap = Cm(1)
|
||
cap = slide.shapes.add_textbox(left_cap, top_cap, width_cap, height_cap)
|
||
tf = cap.text_frame
|
||
p = tf.add_paragraph()
|
||
if images[0]["caption"]:
|
||
p.text = images[0]["caption"]
|
||
else:
|
||
p.text = "主图"
|
||
p.font.size = Pt(18)
|
||
p.font.color.rgb = RGBColor(mc[0],mc[1],mc[2])
|
||
p.alignment = PP_ALIGN.CENTER
|
||
|
||
# 在图片的右侧添加内容区域,可以多级列表
|
||
if content_items:
|
||
# 添加内容位置
|
||
left_text = Cm(30)
|
||
top_text = Cm(5.5 if subtitle_text else 4.5)
|
||
width_text = Cm(10)
|
||
height_text = Cm(14)
|
||
|
||
|
||
# 先添加矩形标题框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, left_text, top_text, width_text, Cm(0.7)
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
# 先添加矩形框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, left_text, top_text+Cm(0.7), width_text, height_text
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
# fill.solid()
|
||
# fill.fore_color.rgb = RGBColor(255,255,255) # 白色填充
|
||
fill.background()
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
# 添加内容文字
|
||
text_box = slide.shapes.add_textbox(left_text, top_text, width_text, height_text)
|
||
tf = text_box.text_frame
|
||
|
||
# 启用自动换行
|
||
tf.word_wrap = True
|
||
tf.clear()
|
||
|
||
ol_li = 1
|
||
for item in content_items:
|
||
p = tf.add_paragraph()
|
||
p.font.size = Pt(item.get("size", 18))
|
||
p.font.color.rgb = RGBColor(0, 0, 0)
|
||
#p.space_after = Pt(item.get("space_after", 8))
|
||
#p.level = item.get("level", 0)
|
||
ol_li = output_text_style(p,item,RGBColor(mc[0],mc[1],mc[2]),ol_li)
|
||
|
||
elif len(images) == 2:
|
||
# 两张图片并排布局
|
||
# 第一张图片
|
||
left1 = Cm(2)
|
||
top1 = Cm(5 if subtitle_text else 4)+Cm(0.5)
|
||
width1 = Cm(13)
|
||
height1 = Cm(15)
|
||
pic1 = slide.shapes.add_picture(images[0]["path"], left1, top1, width1, height1)
|
||
|
||
# 第二张图片
|
||
left2 = Cm(16)
|
||
top2 = Cm(5 if subtitle_text else 4)+Cm(0.5)
|
||
width2 = Cm(13)
|
||
height2 = Cm(15)
|
||
pic2 = slide.shapes.add_picture(images[1]["path"], left2, top2, width2, height2)
|
||
|
||
# 添加图片说明
|
||
for i, img in enumerate(images):
|
||
if "caption" in img:
|
||
left_cap = Cm(2 if i == 0 else 19)
|
||
top_cap = Cm(20 if subtitle_text else 19)
|
||
width_cap = Cm(13)
|
||
height_cap = Cm(1)
|
||
cap = slide.shapes.add_textbox(left_cap, top_cap, width_cap, height_cap)
|
||
tf = cap.text_frame
|
||
p = tf.add_paragraph()
|
||
if img["caption"]:
|
||
p.text = img["caption"]
|
||
else:
|
||
p.text = f"图片{i+1}"
|
||
p.font.size = Pt(12)
|
||
p.font.color.rgb = RGBColor(mc[0],mc[1],mc[2])
|
||
p.alignment = PP_ALIGN.CENTER
|
||
|
||
# 在图片的右侧添加内容区域,可以多级列表
|
||
if content_items:
|
||
# 添加内容文字
|
||
left_text = Cm(30)
|
||
top_text = Cm(5.5 if subtitle_text else 4.5)
|
||
width_text = Cm(10)
|
||
height_text = Cm(14)
|
||
|
||
# 先添加矩形标题框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, left_text, top_text, width_text, Cm(0.7)
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
# 先添加矩形框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, left_text, top_text+Cm(0.7), width_text, height_text
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
# fill.solid()
|
||
# fill.fore_color.rgb = RGBColor(255,255,255) # 白色填充
|
||
fill.background()
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
text_box = slide.shapes.add_textbox(left_text, top_text, width_text, height_text)
|
||
tf = text_box.text_frame
|
||
|
||
# 启用自动换行
|
||
tf.word_wrap = True
|
||
tf.clear()
|
||
|
||
ol_li = 1
|
||
for item in content_items:
|
||
p = tf.add_paragraph()
|
||
p.font.size = Pt(item.get("size", 18))
|
||
p.font.color.rgb = RGBColor(0, 0, 0)
|
||
#p.space_after = Pt(item.get("space_after", 8))
|
||
#p.level = item.get("level", 0)
|
||
ol_li = output_text_style(p,item,RGBColor(mc[0],mc[1],mc[2]),ol_li)
|
||
|
||
elif len(images) >= 3:
|
||
# 三张级以上图片网格布局
|
||
|
||
#仅三张图片的相关配置和内容布局
|
||
if len(images)==3:
|
||
#图变大
|
||
img_size = Cm(12)
|
||
#位置下移
|
||
top = Cm(8 if subtitle_text else 7)
|
||
|
||
# 在图片的上方添加内容区域,可以多级列表
|
||
if content_items:
|
||
# 添加内容
|
||
left_text = Cm(3)
|
||
top_text = Cm(4)
|
||
width_text = Cm(36)
|
||
height_text = Cm(3.5)
|
||
|
||
|
||
# 先添加矩形标题框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, left_text-Cm(0.5), top_text, Cm(0.5), height_text
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
# 先添加矩形框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, left_text, top_text, width_text, height_text
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
# fill.solid()
|
||
# fill.fore_color.rgb = RGBColor(255,255,255) # 白色填充
|
||
fill.background()
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
#添加内容文字
|
||
text_box = slide.shapes.add_textbox(left_text, top_text, width_text, height_text)
|
||
tf = text_box.text_frame
|
||
|
||
# 启用自动换行
|
||
tf.word_wrap = True
|
||
#tf.clear()
|
||
|
||
# 删除所有段落
|
||
tf_clean_all(tf)
|
||
|
||
ol_li = 1
|
||
for item in content_items:
|
||
p = tf.add_paragraph()
|
||
p.font.size = Pt(item.get("size", 18))
|
||
p.font.color.rgb = RGBColor(0, 0, 0)
|
||
#p.space_after = Pt(item.get("space_after", 8))
|
||
#p.level = item.get("level", 0)
|
||
ol_li = output_text_style(p,item,RGBColor(mc[0],mc[1],mc[2]),ol_li)
|
||
else:
|
||
#图变小
|
||
img_size = Cm(8)
|
||
#位置考上
|
||
top = Cm(5 if subtitle_text else 4)+Cm(0.5)
|
||
#内容在右侧
|
||
# 在图片的右侧添加内容区域,可以多级列表
|
||
if content_items:
|
||
# 添加内容文字
|
||
left_text = Cm(30)
|
||
top_text = Cm(5.5 if subtitle_text else 4.5)
|
||
width_text = Cm(10)
|
||
height_text = Cm(16)
|
||
|
||
# 先添加矩形标题框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, left_text, top_text-Cm(0.7), width_text, Cm(0.7)
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
# 先添加矩形框(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, left_text, top_text, width_text, height_text
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
# fill.solid()
|
||
# fill.fore_color.rgb = RGBColor(255,255,255) # 白色填充
|
||
fill.background()
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(mc[0],mc[1],mc[2]) # 主色填充
|
||
line.width = Pt(1)
|
||
|
||
|
||
text_box = slide.shapes.add_textbox(left_text, top_text, width_text, height_text)
|
||
tf = text_box.text_frame
|
||
|
||
# 启用自动换行
|
||
tf.word_wrap = True
|
||
tf.clear()
|
||
|
||
ol_li = 1
|
||
for item in content_items:
|
||
p = tf.add_paragraph()
|
||
p.font.size = Pt(item.get("size", 18))
|
||
p.font.color.rgb = RGBColor(0, 0, 0)
|
||
#p.space_after = Pt(item.get("space_after", 8))
|
||
#p.level = item.get("level", 0)
|
||
ol_li = output_text_style(p,item,RGBColor(mc[0],mc[1],mc[2]),ol_li)
|
||
|
||
gap = Cm(1)
|
||
|
||
#开始画图
|
||
# 第一行
|
||
for i in range(min(3, len(images))):
|
||
left = Cm(2) + (img_size + gap) * i
|
||
pic = slide.shapes.add_picture(images[i]["path"], left, top, img_size, img_size)
|
||
if "caption" in images[i]:
|
||
left_cap = left
|
||
top_cap = top + img_size + Cm(0.5)
|
||
width_cap = img_size
|
||
height_cap = Cm(1)
|
||
cap = slide.shapes.add_textbox(left_cap, top_cap, width_cap, height_cap)
|
||
tf = cap.text_frame
|
||
p = tf.add_paragraph()
|
||
if images[i]["caption"]:
|
||
p.text = images[i]["caption"]
|
||
else:
|
||
p.text = f"图片{i+1}"
|
||
p.font.size = Pt(12)
|
||
p.font.color.rgb = RGBColor(mc[0],mc[1],mc[2])
|
||
p.alignment = PP_ALIGN.CENTER
|
||
|
||
# 第二行(如果有4张以上图片)
|
||
img_size = Cm(4)
|
||
gap = Cm(1)
|
||
for i in range(3, len(images)):
|
||
left = Cm(3) + (img_size + gap) * (i - 3)
|
||
top = Cm(16 if subtitle_text else 15)
|
||
pic = slide.shapes.add_picture(images[i]["path"], left, top, img_size, img_size)
|
||
|
||
if "caption" in images[i] and images[i]["caption"]:
|
||
left_cap = left
|
||
top_cap = top + img_size + Cm(0.5)
|
||
width_cap = img_size
|
||
height_cap = Cm(1)
|
||
cap = slide.shapes.add_textbox(left_cap, top_cap, width_cap, height_cap)
|
||
tf = cap.text_frame
|
||
p = tf.add_paragraph()
|
||
p.text = images[i]["caption"]
|
||
p.font.size = Pt(12)
|
||
p.font.color.rgb = RGBColor(mc[0],mc[1],mc[2])
|
||
p.alignment = PP_ALIGN.CENTER
|
||
|
||
return slide
|
||
|
||
# ===== 封面幻灯片 =====
|
||
def create_main_slide(prs, title_text, subject_text,content=None,style={}):
|
||
# ===== 封面幻灯片 =====
|
||
slide_layout = prs.slide_layouts[6] # 空白布局
|
||
slide = prs.slides.add_slide(slide_layout)
|
||
apply_gradient_background(prs,slide,style)
|
||
|
||
#主图
|
||
image_path = "pic/101_main.png"
|
||
# 将图片添加到幻灯片中
|
||
left = top = 0
|
||
pic = slide.shapes.add_picture(image_path, left, top)
|
||
|
||
# 获取幻灯片尺寸
|
||
slide_width = prs.slide_width
|
||
slide_height = prs.slide_height
|
||
|
||
# 调整图片大小以填充整个幻灯片
|
||
pic.width = slide_width
|
||
pic.height = slide_height
|
||
|
||
#添加宽屏主题
|
||
left = Cm(2)
|
||
top = Cm(5)
|
||
width = Cm(36)
|
||
height = Cm(6)
|
||
subtitle_box = slide.shapes.add_textbox(left, top, width, height)
|
||
tf = subtitle_box.text_frame
|
||
tf.word_wrap = True
|
||
|
||
p = tf.add_paragraph()
|
||
#粗体
|
||
p.font.bold = True
|
||
p.text = title_text
|
||
p.font.name="微软雅黑"
|
||
p.font.size = Pt(66)
|
||
p.font.color.rgb = RGBColor(255, 255, 255)
|
||
p.alignment = PP_ALIGN.LEFT
|
||
|
||
top = Cm(8.5)
|
||
if len(title_text)>15:
|
||
top = Cm(11)
|
||
# 添加副标题
|
||
if subject_text:
|
||
left = Cm(2)
|
||
width = Cm(36)
|
||
height = Cm(4)
|
||
title_box = slide.shapes.add_textbox(left, top, width, height)
|
||
tf = title_box.text_frame
|
||
tf.word_wrap = True
|
||
|
||
p = tf.add_paragraph()
|
||
p.text = subject_text
|
||
p.font.name="微软雅黑"
|
||
#非粗体
|
||
p.font.bold = False
|
||
p.font.size = Pt(34)
|
||
p.font.color.rgb = RGBColor(255, 255, 255)
|
||
p.alignment = PP_ALIGN.LEFT
|
||
top +=Cm(1)
|
||
|
||
#白色分割线
|
||
left = Cm(2.5)
|
||
top = top+Cm(2)
|
||
width = Cm(3)
|
||
height = Cm(0.5)
|
||
# 添加矩形形状(使用矩形形状 MSO_SHAPE.RECTANGLE)
|
||
shape = slide.shapes.add_shape(
|
||
MSO_SHAPE.RECTANGLE, left, top, width, height
|
||
)
|
||
|
||
# 获取矩形的填充对象并设置为白色
|
||
fill = shape.fill
|
||
fill.solid()
|
||
fill.fore_color.rgb = RGBColor(255, 255, 255) # 白色填充
|
||
|
||
# 获取矩形的轮廓(边框)并可选地设置颜色或隐藏
|
||
line = shape.line
|
||
line.color.rgb = RGBColor(255, 255, 255) # 默认黑色边框
|
||
line.width = Pt(1) # 边框宽度为 1 磅
|
||
|
||
top_begin=top
|
||
# 添加其它标题或内容
|
||
if content:
|
||
for i, line in enumerate(content):
|
||
left = Cm(2)
|
||
top = top_begin+Cm(1)*i
|
||
width = Cm(36)
|
||
height = Cm(4)
|
||
subtitle_box = slide.shapes.add_textbox(left, top, width, height)
|
||
tf = subtitle_box.text_frame
|
||
#换行
|
||
tf.word_wrap = True
|
||
p = tf.add_paragraph()
|
||
p.font.name="微软雅黑"
|
||
p.text = line["text"]
|
||
p.font.size = Pt(20)
|
||
p.font.color.rgb = RGBColor(255, 255, 255)
|
||
p.alignment = PP_ALIGN.LEFT
|
||
#end
|
||
|
||
|
||
# ===== 目录幻灯片 =====
|
||
def create_catalog_slide(prs,catalogs,main_color,style):
|
||
slide_layout = prs.slide_layouts[6] # 空白布局
|
||
slide = prs.slides.add_slide(slide_layout)
|
||
apply_gradient_background(prs,slide,style)
|
||
|
||
#背景图
|
||
image_path = "pic/101_catalog.png"
|
||
# 将图片添加到幻灯片中
|
||
left =0
|
||
top = 0
|
||
pic = slide.shapes.add_picture(image_path, left, top)
|
||
|
||
# 获取幻灯片尺寸
|
||
slide_width = prs.slide_width
|
||
slide_height = prs.slide_height
|
||
|
||
# 调整图片大小以填充整个幻灯片
|
||
pic.width = Cm(12)
|
||
pic.height = slide_height
|
||
|
||
if len(catalogs) <=8:
|
||
start = Cm(2)
|
||
line_h = Cm(2.5)
|
||
height = Cm(2)
|
||
else:
|
||
start = Cm(1)
|
||
line_h = Cm(1.5)
|
||
height = Cm(1.5)
|
||
|
||
# 添加目录
|
||
for i,catalog in enumerate(catalogs):
|
||
top = start + line_h*i
|
||
left = Cm(16)
|
||
width = Cm(24)
|
||
|
||
title_box = slide.shapes.add_textbox(left, top, width, height)
|
||
tf = title_box.text_frame
|
||
tf.word_wrap = True
|
||
tf.clear()
|
||
|
||
#一段的第一行
|
||
p = tf.add_paragraph()
|
||
|
||
#前面部分
|
||
run1 = p.add_run()
|
||
run1.text = f"{i+1:02d}"
|
||
run1.font.name="微软雅黑"
|
||
run1.font.size = Pt(32)
|
||
run1.font.color.rgb = RGBColor(main_color[0],main_color[1],main_color[2])
|
||
run1.font.bold = True
|
||
|
||
run2 = p.add_run()
|
||
run2.text = " "+catalog
|
||
run2.font.name="微软雅黑"
|
||
run2.font.size = Pt(22)
|
||
run2.font.color.rgb = RGBColor(0, 0, 0)
|
||
run2.font.bold = True
|
||
|
||
|
||
# 目录装饰字样
|
||
left = Cm(0.5)
|
||
top = Cm(0.5)
|
||
width = Cm(8)
|
||
height = Cm(15)
|
||
contact_box = slide.shapes.add_textbox(left, top, width, height)
|
||
tf = contact_box.text_frame
|
||
|
||
p = tf.add_paragraph()
|
||
p.text = "content\n目录"
|
||
p.font.name="微软雅黑"
|
||
p.font.size = Pt(60)
|
||
p.font.color.rgb = RGBColor(255, 255, 255)
|
||
p.font.bold = True
|
||
p.alignment = PP_ALIGN.LEFT
|
||
p.space_after = Pt(16)
|
||
|
||
|
||
|
||
|
||
|
||
# ===== 引导幻灯片 =====
|
||
def create_guide_slide(prs,title,guide,style):
|
||
slide_layout = prs.slide_layouts[6] # 空白布局
|
||
slide = prs.slides.add_slide(slide_layout)
|
||
apply_gradient_background(prs,slide,style)
|
||
|
||
#背景图
|
||
image_path = "pic/101_catalog_w.png"
|
||
# 将图片添加到幻灯片中
|
||
left =0
|
||
top = Cm(6)
|
||
pic = slide.shapes.add_picture(image_path, left, top)
|
||
|
||
# 获取幻灯片尺寸
|
||
slide_width = prs.slide_width
|
||
slide_height = prs.slide_height
|
||
|
||
# 调整图片大小以填充整个幻灯片
|
||
pic.width = slide_width
|
||
pic.height = Cm(10)
|
||
|
||
# 序号
|
||
left = Cm(2)
|
||
top = Cm(6)
|
||
width = Cm(16)
|
||
height = Cm(10)
|
||
contact_box = slide.shapes.add_textbox(left, top, width, height)
|
||
tf = contact_box.text_frame
|
||
|
||
p = tf.add_paragraph()
|
||
p.text = guide
|
||
p.font.name="微软雅黑"
|
||
p.font.size = Pt(240)
|
||
p.font.color.rgb = RGBColor(255, 255, 255)
|
||
p.font.bold = True
|
||
p.alignment = PP_ALIGN.CENTER
|
||
p.space_after = Pt(16)
|
||
|
||
# 添加副标题
|
||
left = Cm(18)
|
||
top = Cm(12) if len(title) <10 else Cm(10)
|
||
width = Cm(22)
|
||
height = Cm(4)
|
||
title_box = slide.shapes.add_textbox(left, top, width, height)
|
||
tf = title_box.text_frame
|
||
tf.word_wrap = True
|
||
tf.clear()
|
||
|
||
p = tf.add_paragraph()
|
||
p.text = title
|
||
p.font.name="微软雅黑"
|
||
p.font.size = Pt(60)
|
||
if len(title) >10:
|
||
p.font.size = Pt(50)
|
||
if len(title) >20:
|
||
p.font.size = Pt(40)
|
||
if len(title) >30:
|
||
p.font.size = Pt(26)
|
||
|
||
p.font.color.rgb = RGBColor(255, 255, 255)
|
||
p.font.bold = True
|
||
|
||
# ===== 结束幻灯片 =====
|
||
def create_end_slide(prs,style):
|
||
slide_layout = prs.slide_layouts[6] # 空白布局
|
||
slide = prs.slides.add_slide(slide_layout)
|
||
apply_gradient_background(prs,slide,style)
|
||
|
||
#背景图
|
||
image_path = "pic/101_main.png"
|
||
# 将图片添加到幻灯片中
|
||
left = top = 0
|
||
pic = slide.shapes.add_picture(image_path, left, top)
|
||
|
||
# 获取幻灯片尺寸
|
||
slide_width = prs.slide_width
|
||
slide_height = prs.slide_height
|
||
|
||
# 调整图片大小以填充整个幻灯片
|
||
pic.width = slide_width
|
||
pic.height = slide_height
|
||
|
||
|
||
# 添加主标题
|
||
left = Cm(prs.slide_width/Cm(1)/2-5)
|
||
top = Cm(15)
|
||
width = Cm(30)
|
||
height = Cm(2)
|
||
title_box = slide.shapes.add_textbox(left, top, width, height)
|
||
tf = title_box.text_frame
|
||
tf.word_wrap = True
|
||
tf.clear()
|
||
|
||
p = tf.add_paragraph()
|
||
p.text = "欢迎指正,感谢聆听!"
|
||
p.font.name="微软雅黑"
|
||
p.font.size = Pt(36)
|
||
p.font.color.rgb = RGBColor(255, 255, 255)
|
||
p.font.bold = True
|
||
|
||
#产品logo
|
||
img_width = Cm(8)
|
||
img_height = Cm(4)
|
||
print(prs.slide_width,prs.slide_width/Cm(1),prs.slide_width/Cm(1)/2-3)
|
||
left = Cm(prs.slide_width/Cm(1)/2-4) #屏幕中央
|
||
top = Cm(6)
|
||
#添加logo
|
||
if gcfg["fs"]["logo"]!="":
|
||
pic = slide.shapes.add_picture(f'{gcfg["fs"]["path"]}/img/{gcfg["fs"]["logo"]}', left, top, img_width, img_height)
|
||
else:
|
||
pic = slide.shapes.add_picture(f'ui/images/logo2.jpg', left, top, img_width, img_height)
|
||
|
||
# 在内容区域添加slogan和网址
|
||
left = Cm(12)
|
||
top = Cm(11)
|
||
width = Cm(16)
|
||
height = Cm(3)
|
||
contact_box = slide.shapes.add_textbox(left, top, width, height)
|
||
tf = contact_box.text_frame
|
||
|
||
p = tf.add_paragraph()
|
||
p.text = gcfg["fs"]["slogan"]
|
||
p.font.size = Pt(28)
|
||
p.font.color.rgb = RGBColor(255, 255, 255)
|
||
p.font.bold = True
|
||
p.alignment = PP_ALIGN.CENTER
|
||
p.space_after = Pt(16)
|
||
|
||
p = tf.add_paragraph()
|
||
p.text = gcfg["fs"]["url"]
|
||
p.font.size = Pt(18)
|
||
p.font.color.rgb = RGBColor(200, 230, 255)
|
||
p.alignment = PP_ALIGN.CENTER
|
||
p.space_before = Pt(10)
|
||
|
||
|
||
|
||
|
||
#入口函数,根据html创建ppt
|
||
def create_unified_ppt(html,output_filename,style):
|
||
# 创建一个16:9宽屏演示文稿对象
|
||
prs = Presentation()
|
||
#prs.slide_width = Inches(13.333) # 16:9的宽度
|
||
#prs.slide_height = Inches(7.5) # 16:9的高度
|
||
|
||
prs.slide_width = Inches(16) # 16:9的宽度
|
||
prs.slide_height = Inches(9) # 16:9的高度
|
||
|
||
ppt = parse_html_to_ppt(html)
|
||
|
||
for slide in ppt:
|
||
print(slide)
|
||
if slide["type"]=="main":
|
||
create_main_slide(prs,slide["title"],slide["subtitle"],slide["content"],style)
|
||
elif slide["type"]=="text":
|
||
create_content_slide(
|
||
prs,slide["title"],slide["subtitle"],slide["content"],style
|
||
)
|
||
elif slide["type"]=="image":
|
||
create_image_layout_slide(
|
||
prs,slide["title"],slide["subtitle"],slide["images"],slide["content"],style
|
||
)
|
||
elif slide["type"]=="chart":
|
||
create_chart_slide(
|
||
prs,slide["title"],slide["subtitle"],slide["chart_type"],slide["data"],style
|
||
)
|
||
elif slide["type"]=="table":
|
||
create_table_slide(
|
||
prs,slide["title"],slide["subtitle"],slide["header"],slide["data"],slide["content"],style
|
||
)
|
||
elif slide["type"]=="guide":
|
||
create_guide_slide(
|
||
prs,slide["title"],slide["guide"],style
|
||
)
|
||
elif slide["type"]=="catalog":
|
||
create_catalog_slide(
|
||
prs,slide["data"],style["main_color"],style
|
||
)
|
||
else:
|
||
pass
|
||
|
||
create_end_slide(prs,style)
|
||
# 保存演示文稿
|
||
prs.save(output_filename)
|
||
|
||
if __name__ == "__main__":
|
||
html_string ="""
|
||
<h1>K3GPT数据分析智能体</h1>
|
||
<h3>三国工资表分析</h3>
|
||
<p>制作日期: 2024-12-24</p>
|
||
<h2>要求</h2><h5>按如下分析三国详情:1不同集团的人数,2不同集团不同级别的人数,3不同集团的平均服务年龄,4不同集团工种帝王人数</h5>
|
||
<h2>数据分析</h2><h3>集团分布</h3><p>[chart][bar]</p><pre><code >{\"categories\":[\"魏\",\"吴\",\"无\",\"蜀\"],\"count\":[3,3,3,2]}</code></pre>
|
||
<h3>集团->职级的分布</h3><p>[chart][bar]</p><pre><code >{\"L4\":[10,9,7,1],\"L3\":[8,0,4,1],\"L5\":[6,9,6,3],\"L6\":[4,5,3,2],\"L7\":[3,4,3,2],\"L8\":[2,2,2,0],\"L9\":[1,1,1,0],\"L2\":[0,0,1,0],\"categories\":[\"吴\",\"魏\",\"蜀\",\"无\"]}</code></pre>
|
||
<h3>不同集团对应的司龄(年)的常见六指标分析</h3><p>[chart][bar]</p><pre><code >{\"categories\":[\"蜀\",\"魏\",\"无\",\"吴\"],\"总和\":[397,586,179,560],\"平均值\":[14.703703703703704,19.533333333333335,19.88888888888889,16.470588235294116],\"中位数\":[12,19,20,15],\"最小值\":[5,10,8,5],\"最大值\":[40,35,30,40],\"个数\":[27,30,9,34]}</code></pre>
|
||
<h3>表格1</h3><table style=\"width: auto;\"><tbody><tr><th colSpan=\"1\" rowSpan=\"1\" width=\"auto\">序号</th><th colSpan=\"1\" rowSpan=\"1\" width=\"auto\">姓名</th><th colSpan=\"1\" rowSpan=\"1\" width=\"auto\">集团</th><th colSpan=\"1\" rowSpan=\"1\" width=\"auto\">工种</th><th colSpan=\"1\" rowSpan=\"1\" width=\"auto\">职级</th><th colSpan=\"1\" rowSpan=\"1\" width=\"auto\">工资(万)</th><th colSpan=\"1\" rowSpan=\"1\" width=\"auto\">司龄(年)</th></tr><tr><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">1</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">曹操</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">魏</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">帝王</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">L9</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">10</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">30</td></tr><tr><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">2</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">刘备</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">蜀</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">帝王</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">L9</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">9.8</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">25</td></tr><tr><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">3</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">孙权</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">吴</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">帝王</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">L9</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">9.5</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">40</td></tr><tr><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">53</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">孙策</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">吴</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">帝王</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">L8</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">8</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">10</td></tr><tr><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">54</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">孙坚</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">吴</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">帝王</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">L7</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">7</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">15</td></tr><tr><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">55</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">刘禅</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">蜀</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">帝王</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">L7</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">6</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">40</td></tr><tr><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">56</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">曹丕</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">魏</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">帝王</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">L8</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">8.5</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">15</td></tr><tr><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">57</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">曹叡</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">魏</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">帝王</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">L7</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">7</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">10</td></tr><tr><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">97</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">袁绍</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">无</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">帝王</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">L7</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">6</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">20</td></tr><tr><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">98</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">袁术</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">无</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">帝王</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">L6</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">5</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">15</td></tr><tr><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">100</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">刘表</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">无</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">帝王</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">L6</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">4.5</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">25</td></tr></tbody></table>
|
||
<h2>小结</h2><p>根据分析结果,三国工资表的详细情况如下:</p><ol><li>集团人数分布 吴国:34人 魏国:30人 蜀国:27人 无集团:9人</li><li>集团-职级人数分布 吴国主要职级为L4(10人)、L3(8人)、L5(6人) 魏国最高职级达L9(1人),L5(9人)占比较大 蜀国职级分布较均衡,L4(7人)、L5(6人)为主</li><li>平均服务年龄 魏国平均19.53年(最高) 吴国16.47年 蜀国14.70年(最低) 无集团19.89年(可能包含临时人员)</li><li>帝王工种分布 吴国、魏国、无集团各有3名帝王,蜀国2名 帝王多集中在高级职级(L6-L9)</li></ol><p><strong>分析点评</strong>: </p><ul><li>魏国和无集团的平均服务年龄显著高于其他集团,可能与人员稳定性或招聘策略有关。 </li><li>帝王工种在吴、魏、无集团分布较均,但蜀国仅2人,可能需关注其人才结构。 </li><li>职级分布显示魏国存在较高职级人员,而蜀国职级整体偏低,可能反映组织架构差异。</li></ul>",
|
||
|
||
"""
|
||
#自定义的目录和引导
|
||
html_string2 ="""
|
||
<h1>K3GPT数据分析智能体</h1>
|
||
<h3>三国工资表分析</h3>
|
||
<p>制作日期: 2024-12-24</p>
|
||
<p>[catalogs]<pre><code>["要求","数据分析","结论"]</code></pre></p>
|
||
<guide>要求</guide>
|
||
<h2>要求</h2><h5>按如下分析三国详情:1不同集团的人数,2不同集团不同级别的人数,3不同集团的平均服务年龄,4不同集团工种帝王人数</h5>
|
||
<guide>数据分析过程</guide>
|
||
<h2>数据分析</h2><h3>集团分布</h3><p>[chart][bar]</p><pre><code >{\"categories\":[\"魏\",\"吴\",\"无\",\"蜀\"],\"count\":[3,3,3,2]}</code></pre>
|
||
<h3>集团->职级的分布</h3><p>[chart][bar]</p><pre><code >{\"L4\":[10,9,7,1],\"L3\":[8,0,4,1],\"L5\":[6,9,6,3],\"L6\":[4,5,3,2],\"L7\":[3,4,3,2],\"L8\":[2,2,2,0],\"L9\":[1,1,1,0],\"L2\":[0,0,1,0],\"categories\":[\"吴\",\"魏\",\"蜀\",\"无\"]}</code></pre>
|
||
<h3>不同集团对应的司龄(年)的常见六指标分析</h3><p>[chart][bar]</p><pre><code >{\"categories\":[\"蜀\",\"魏\",\"无\",\"吴\"],\"总和\":[397,586,179,560],\"平均值\":[14.703703703703704,19.533333333333335,19.88888888888889,16.470588235294116],\"中位数\":[12,19,20,15],\"最小值\":[5,10,8,5],\"最大值\":[40,35,30,40],\"个数\":[27,30,9,34]}</code></pre>
|
||
<h3>表格1</h3><table style=\"width: auto;\"><tbody><tr><th colSpan=\"1\" rowSpan=\"1\" width=\"auto\">序号</th><th colSpan=\"1\" rowSpan=\"1\" width=\"auto\">姓名</th><th colSpan=\"1\" rowSpan=\"1\" width=\"auto\">集团</th><th colSpan=\"1\" rowSpan=\"1\" width=\"auto\">工种</th><th colSpan=\"1\" rowSpan=\"1\" width=\"auto\">职级</th><th colSpan=\"1\" rowSpan=\"1\" width=\"auto\">工资(万)</th><th colSpan=\"1\" rowSpan=\"1\" width=\"auto\">司龄(年)</th></tr><tr><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">1</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">曹操</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">魏</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">帝王</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">L9</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">10</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">30</td></tr><tr><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">2</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">刘备</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">蜀</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">帝王</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">L9</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">9.8</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">25</td></tr><tr><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">3</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">孙权</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">吴</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">帝王</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">L9</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">9.5</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">40</td></tr><tr><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">53</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">孙策</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">吴</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">帝王</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">L8</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">8</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">10</td></tr><tr><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">54</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">孙坚</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">吴</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">帝王</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">L7</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">7</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">15</td></tr><tr><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">55</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">刘禅</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">蜀</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">帝王</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">L7</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">6</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">40</td></tr><tr><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">56</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">曹丕</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">魏</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">帝王</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">L8</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">8.5</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">15</td></tr><tr><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">57</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">曹叡</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">魏</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">帝王</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">L7</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">7</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">10</td></tr><tr><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">97</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">袁绍</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">无</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">帝王</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">L7</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">6</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">20</td></tr><tr><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">98</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">袁术</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">无</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">帝王</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">L6</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">5</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">15</td></tr><tr><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">100</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">刘表</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">无</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">帝王</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">L6</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">4.5</td><td colSpan=\"1\" rowSpan=\"1\" width=\"auto\">25</td></tr></tbody></table>
|
||
<guide>结论</guide>
|
||
<h2>小结</h2><p>根据分析结果,三国工资表的详细情况如下:</p><ol><li>集团人数分布 吴国:34人 魏国:30人 蜀国:27人 无集团:9人</li><li>集团-职级人数分布 吴国主要职级为L4(10人)、L3(8人)、L5(6人) 魏国最高职级达L9(1人),L5(9人)占比较大 蜀国职级分布较均衡,L4(7人)、L5(6人)为主</li><li>平均服务年龄 魏国平均19.53年(最高) 吴国16.47年 蜀国14.70年(最低) 无集团19.89年(可能包含临时人员)</li><li>帝王工种分布 吴国、魏国、无集团各有3名帝王,蜀国2名 帝王多集中在高级职级(L6-L9)</li></ol><p><strong>分析点评</strong>: </p><ul><li>魏国和无集团的平均服务年龄显著高于其他集团,可能与人员稳定性或招聘策略有关。 </li><li>帝王工种在吴、魏、无集团分布较均,但蜀国仅2人,可能需关注其人才结构。 </li><li>职级分布显示魏国存在较高职级人员,而蜀国职级整体偏低,可能反映组织架构差异。</li></ul>",
|
||
|
||
"""
|
||
|
||
|
||
# 使用前请替换示例图片路径为实际图片路径
|
||
create_unified_ppt(html_string2,"test2.pptx")
|
||
print("带生成完成!")
|