需求
首先我这是为了从word里面将内容导到ppt里,但表格真的好头疼,又不能直接复制,表格里面又会有各种各样的奇形怪状的合并单元格,怎么做出一毛一样的表格嘞
找到合并了的单元格
首先看说明文档,原本word以及ppt里都有一个is_merge_origin参数,它能获得当前单元格是否是合并单元格的头,但其他的单元格怎么确定它是不是合并了呢?!
有的文章说word里合并了的单元格内容地址是一样的,但我实验了一下并不一样,所以只能直接从内容方面去判断——判断该单元格的内容有没有出现过
思路
本来想边循环着每一个单元格,循环过程中就把单元格也合并了。
但是!
由于合并了的单元格不能再合并,这样的循环方式只能单纯合并行的或者列的
于是就只能选择记录下来需要合并的位置在最后合并
判断是否是合并单元格
首先原本的表格是否是合并单元格
rl和cl分别用来储存列和行已经出现过的文本
循环每个单元格,如果单元格内容与列表中的重复就代表是需要合并的单元格
但不排除个别单元格只是内容相同但没合并,根据实际情况,我设置了个条件:重复文本长度大于一定数量才定为需要合并的
合并位置的记录
遇到第一个重复的文本就记录开始的位置,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)) # 改颜色 或者宽
但是最后改表格的边框颜色和线宽的没起作用,欢迎大佬来帮忙