最近因为工作原因一直在使用python docx提取word中的表格及内嵌文件
发现大家一般使用的提取方法都是直接用enumerate table.rows和row.cells直接读取表格的每行,每列,但是这样会导致一个问题,word中的table很多时候是手画的,或者经过多次编辑,行和列都存在对不齐的现象,如果用这种方法去提取表格则会导致串行。
于是我就想到直接读取表格的xml信息,然后用xml来提取表格信息的方法
##path 文件所在位置
##tb_location 所要提取的表格为文档中的第几个表格
def extract_table(path,tb_loc_dic):
document = Document(path)
tables = document.tables
rel_list=[]
proxy=[]
for p in document.tables:
proxy.append(p._element.xml)
wp_lt=[]
wt_lt=[]
cell_lt=[]
wtr_lt=[]
title_lt=[]
cell0full=""
cell0_lt=[]
wp_lt_2=[]
##wtr 每行
wtr_str=".//{http://schemas.openxmlformats.org/wordprocessingml/2006/main}tr"
## wtc 每个cel
wtc_str=".//{http://schemas.openxmlformats.org/wordprocessingml/2006/main}tc"
##wp 每个cell里每行
wp_str=".//{http://schemas.openxmlformats.org/wordprocessingml/2006/main}p"
## wt 文字
wt_str=".//{http://schemas.openxmlformats.org/wordprocessingml/2006/main}t"
##numPr 编号
wnumpr_str=".//{http://schemas.openxmlformats.org/wordprocessingml/2006/main}numPr"
##合并单元格
wmerge_str=".//{http://schemas.openxmlformats.org/wordprocessingml/2006/main}vMerge"
##对每行的第一个cell 找编号,如果没有编号且有内容,就是title
if tb_loc_dic!=-1:
root=ET.fromstring(proxy[tb_loc_dic])
wtrs=root.findall(wtr_str)
for i in range(len(wtrs)):
cells=wtrs[i].findall(wtc_str)
for j in range(len(cells)):
##一个cell中存在多行的情况 直接append 会丢失换行符
## 在一个wp里的是一行
##在每个wp里找wt 不同wp用\n连接
wps=cells[j].findall(wp_str)
if wps!=[]:
for h in range(len(wps)):
wts=wps[h].findall(wt_str)
if wts!=[] :
wt_lt=[]
for i in range(len(wts)):
if wts[i].text:
wt_lt.append(wts[i].text)
wtfull="".join(wt_lt)
else:
wt_lt=wt_lt
wtfull=wtfull
wp_lt.append(wtfull)
wpfull="\n".join(wp_lt)
wp_lt_2.append( wpfull)
wp_lt=[]
else:
##上下行合并单元格
wvs=cells[j].findall(wmerge_str)
if wvs!=[]:
wpfull="merge"
# cell_lt.append("merge")
else:
wpfull=""
# wt_lt=[]
if wp_lt_2!=[]:
wpfull="\n".join(wp_lt_2)
else:
wpfull=wpfull
cell_lt.append(wpfull)
wp_lt_2=[]
else:
cell_lt.append("")
cell_lt.append(wpfull)
wtr_lt.append(cell_lt)
cell_lt=[]
for i in range(len(wtr_lt)):
for j in range(len(wtr_lt[i])):
if wtr_lt[i][j]=="merge" :
##找到上面行同一位置最后一个不为merge的值
for h in range(0,i):
if wtr_lt[h][j]!="merge":
merge_value=wtr_lt[h][j]
wtr_lt[i][j]=merge_value
else:
pass
else:
pass
return wtr_lt
else:
return []