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>集团-&gt;职级的分布</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>： &nbsp;</p><ul><li>魏国和无集团的平均服务年龄显著高于其他集团，可能与人员稳定性或招聘策略有关。 &nbsp;</li><li>帝王工种在吴、魏、无集团分布较均，但蜀国仅2人，可能需关注其人才结构。 &nbsp;</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>集团-&gt;职级的分布</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>： &nbsp;</p><ul><li>魏国和无集团的平均服务年龄显著高于其他集团，可能与人员稳定性或招聘策略有关。 &nbsp;</li><li>帝王工种在吴、魏、无集团分布较均，但蜀国仅2人，可能需关注其人才结构。 &nbsp;</li><li>职级分布显示魏国存在较高职级人员，而蜀国职级整体偏低，可能反映组织架构差异。</li></ul>",
    
    """


    # 使用前请替换示例图片路径为实际图片路径
    create_unified_ppt(html_string2,"test2.pptx")
    print("带生成完成!")
