python pptx 关于在ppt里插入表格,调整合并单元格的问题

python pptx 关于在ppt里插入表格,调整合并单元格的问题

需求

首先我这是为了从word里面将内容导到ppt里,但表格真的好头疼,又不能直接复制,表格里面又会有各种各样的奇形怪状的合并单元格,怎么做出一毛一样的表格嘞

找到合并了的单元格

首先看说明文档,原本word以及ppt里都有一个is_merge_origin参数,它能获得当前单元格是否是合并单元格的头,但其他的单元格怎么确定它是不是合并了呢?!
在这里插入图片描述
有的文章说word里合并了的单元格内容地址是一样的,但我实验了一下并不一样,所以只能直接从内容方面去判断——判断该单元格的内容有没有出现过

思路

本来想边循环着每一个单元格,循环过程中就把单元格也合并了。
但是!
由于合并了的单元格不能再合并,这样的循环方式只能单纯合并行的或者列的
于是就只能选择记录下来需要合并的位置在最后合并

判断是否是合并单元格

首先原本的表格是否是合并单元格
rlcl分别用来储存列和行已经出现过的文本
循环每个单元格,如果单元格内容与列表中的重复就代表是需要合并的单元格
但不排除个别单元格只是内容相同但没合并,根据实际情况,我设置了个条件:重复文本长度大于一定数量才定为需要合并的

合并位置的记录

遇到第一个重复的文本就记录开始的位置,ism改状态,直到遇到不同的文本再记录结束的位置,ism改回去,在重复的这个期间就不写入重复的文本了

rl:储存出现的文本
cstart:记录列合并单元格的开始
cend:记录列合并单元格的结束
cism:记录列是否遇到重复内容
cisw:表示是否要向单元格内写入(列)
start:记录列合并单元格的开始
end:记录行合并单元格的结束

合并

循环结束后,得到了行和列的开始和结束
就判断每个行合并的开始的这一个位置列的记录里面是不是存在,如果存在,就去找这个新的位置的结尾。
总体就是为了把一维的单元格对照成二维的,一次把这一大片需要合并的单元格找全再合并

代码

把完整代码贴在下面了,欢迎优化

rl=[]
cstart=[]
cend=[]
cism=[]
cisw=[]
start = []
end = []
# ism = []
# isw = []
for i in range(0,len(block.columns)):  # 列信息变量初始化
rl.append([])
cstart.append([])
cend.append([])
cism.append(False)
cisw.append(True)
for i in range(0,5):  # 行信息变量初始化
start.append([])
end.append([])
# ism.append(False)
# isw.append(False)
for r in range(len(block.rows)):  # 循环行
# start = -1
# end = -1
ism=False  # 是否有需要合并的
isw=True  # 是否写入
if r%5==0 and r!=0 :
    flag=-1
    print("c",cstart,cend)
    print(start,end)
    for mr in range(len(start)):
        print(mr,flag)
        if len(start[mr]):
            for cs in start[mr]:
                print(flag,"cs",cs)
                if mr in cstart[end[mr][start[mr].index(cs)]]:
                    print("merge1",mr,cs,"to"
                          ,cend[end[mr][start[mr].index(cs)]][cstart[end[mr][start[mr].index(cs)]].index(mr)]
                        ,end[mr][start[mr].index(cs)])
                    table.table.cell(mr, cs).merge(table.table.cell(cend[end[mr][start[mr].index(cs)]][cstart[end[mr][start[mr].index(cs)]].index(mr)]
                                                                   , end[mr][start[mr].index(cs)]))
                    flag=cend[end[mr][start[mr].index(cs)]][cstart[end[mr][start[mr].index(cs)]].index(mr)]#结尾的row
                elif mr<=flag:
                    continue
                else:
                    print("merge2",mr,cs,end[mr][start[mr].index(cs)])
                    print(table.table.cell(mr,cs))
                    table.table.cell(mr,cs).merge(table.table.cell(mr,end[mr][start[mr].index(cs)]))
        else:
            for c in range(len(cstart)):
                if len(cstart[c]):
                    if mr in cstart[c]:
                        print("merge3",mr,c,cend[c][cstart[c].index(mr)])
                        table.table.cell(mr,c).merge(table.table.cell(cend[c][cstart[c].index(mr)],c))
        if mr==flag:
            flag=-1
    '''一页写完后删除第一个段 是空的'''
    if slide.shapes[0].text_frame.paragraphs[0].text == '':
        p = slide.shapes[0].text_frame.paragraphs[0]._element
        p.getparent().remove(p)
        p._p = p._element = None
    '''新建一页'''
    layout = slide_masters[1].slide_layouts[2]  # 第二个模板的第三个样式,两个形状
    slide = ppt.slides.add_slide(layout)
    slide.shapes[1].text = title  # 标题
    para_count = 0
    t=''
    count+=1
    #print("页码:",count)
    slide.shapes[0].text = "续表"
    top=Cm(3.02)
    ccount+=1
    if ccount<math.floor(len(block.rows)/5):
        table = slide.shapes.add_table(5, len(block.columns)
                                       , Cm(slide.shapes[0].left.cm)
                                       , top, Cm(17.67), Cm(4.57))
    else:
        table = slide.shapes.add_table(len(block.rows)-5*ccount, len(block.columns)
                                       , Cm(slide.shapes[0].left.cm)
                                       , top,Cm(17.67),Cm(4.57))
    new=True
    '''更新合并变量'''
    rl = []
    cstart = []
    cend = []
    cism = []
    cisw = []
    start = []
    end = []
    # ism = []
    # isw = []
    for i in range(len(block.columns)):  # 列信息变量初始化
        rl.append([])
        cstart.append([])
        cend.append([])
        cism.append(False)
        cisw.append(True)
    for i in range(0,5):  # 行信息变量初始化
        start.append([])
        end.append([])
        # ism.append(False)
        # isw.append(False)

if new:  # 拆分表格后会变行数
    tr = r - (5*ccount)
else: tr=r
'''
字符数少于6相同的不合并
大于六一并视为合并单元格
'''
cl=[]  # 存放这一行的单元格内容
for c in range(len(block.columns)):  # 循环列
    '''合并单元格 这个似乎没有效果'''

    #print(len(block.cell(r,c).text))
    print(r,c)
    print(block.cell(r,c).text)
    if block.cell(r,c).text not in cl:
        cl.append(block.cell(r,c).text)
        if ism:  # 再次遇到不同的,合并单元格
            print("*************合并**************")
            #print(start,c-1)
            # table.table.cell(tr, start).merge(table.table.cell(tr, c-1))
            end[tr].append(c-1)
            ism=False
            isw=True
    elif len(block.cell(r,c).text)<6:
        isw=True
    else:  # 有重复的
        if not ism:  # 第一次遇到重复
            start[tr].append(c - 1)  # 记下开头位置
            ism=True
            isw=False
        if c==len(block.columns)-1:
            print("------------weiba")
            #print(start,c)
            #table.table.cell(tr, start).merge(table.table.cell(tr, c))
            ism = False
            isw = False
            end[tr].append(c)
    if block.cell(r,c).text not in rl[c]:
        rl[c].append(block.cell(r, c).text)
        if cism[c]:  # 再次遇到不同的,合并单元格
            print("*************合并**************")
            print(cstart[c], tr - 1)
            cend[c].append(tr - 1)
            #table.table.cell(cstart[c],c).merge(table.table.cell(tr - 1, c))
            #cstart[c] = tr
            cism[c] = False
            cisw[c] = True
    elif len(block.cell(r, c).text) < 6:
        cisw[c] = True
    else:  # 有重复的
        #print(not cism[c])
        print("重复了")
        if not cism[c]:
            #print("-----------------")
            cstart[c].append(tr - 1)  # 记下开头位置
            cism[c] = True
            cisw[c] = False
        if r == (len(block.rows) - 1):
            print("------------weiba")
            print(cstart[c], tr)
            # table.table.cell(cstart[c], c).merge(table.table.cell(tr, c))
            cend[c].append(tr)
            cism[c] = False
            cisw[c] = False
    #print(isw)


    '''写入内容 分run'''
    #print(table.table.cell(r,c).text)
    # print(new)
    #print(r,c)
    print(cl,rl)
    print(isw,cisw[c])
    if isw and cisw[c]:
        for i in block.cell(r,c).paragraphs:
            print("para",tr,c)
            para = table.table.cell(tr,c).text_frame.add_paragraph()
            para.font.name = "微软雅黑"
            para.font.size = Pt(12)
            for j in i.runs:
                run = para.add_run()
                run.text=j.text
                #print(j.text)
                run.font.color.rgb = p_rgb(255, 255, 255)
                #run.font.size=Pt(12)
                #run.font.name="微软雅黑"
                if j.font.color.rgb==RGBColor(165,0,33) or (j.font.name!="楷体" and j.font.bold==True):
                    run.font.color.rgb = p_rgb(255, 192, 0)
                    run.font.bold = True
    table.table.cell(tr, c).fill.background()  # 设置透明
    _set_cell_border(table.table.cell(tr, c))  # 改颜色 或者宽

但是最后改表格的边框颜色和线宽的没起作用,欢迎大佬来帮忙

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值