是有图片,但这也不是rId9呀?
别急,有个文件专门做关联这件事情。它就是解压缩之后的word/_rels/document.xml.rels文件。
打开这个文件:
<?xml version="1.0" encoding="UTF-8" standalone="true"?>
<Relationships>
……
<Relationship Target="media/image1.png" Id="rId9"/>
<Relationship Target="media/image3.png" Id="rId11"/>
<Relationship Target="media/image2.GIF" Id="rId10"/>
</Relationships>
哈哈,这里有档案,记录了哪个id指向哪个文件。于是,我们解析这个文件,就可以拿到对应关系。
然后,遇到pic中id等于rId9的,就把media/image1.png这个图片文件展示出来。
这,就实现了图片的解析。
可以鼓掌了!
3.6 表格标签 w:tbl表格标签<w:tbl>的地位很重,它和段落标签<w:p>平级。
分析整个文档的顶层组成元素,我们不难发现,除了<w:tbl>就是<w:p>。
一开始,我不理解。为什么图表、流程图那么复杂的元素,却不配得到表格那么高的地位。天理何在?
后来,我解析到一个表格后发现。我,好像低估了<w:tbl>大佬的地位。
如果,你看到上面的图没有笑喷。那说明,你可能没有看懂本文。或者是我的笑点出了问题。
单纯表格的结构,其实不复杂。但是,表格里每一个单元格,却可以容纳另一个word文档。表格里面,图片、图表、文本样式,甚至表格里再来一个表格,什么都可以添加,它甚至是包含了<w:p>大佬。<w:tbl>和<w:p>并列,它反而是委屈的。
我们来看一下表格<w:tbl>的基本结构。
<w:tbl>
<w:tblGrid>
<w:gridCol/>
<w:gridCol/>
</w:tblGrid>
<w:tr>
<w:tc><w:p>...</w:p></w:tc>
<w:tc>...</w:tc>
</w:tr>
<w:tr>
...
</w:tr>
</w:tbl>
节点元素中,主要有两部分内容,一个<w:tblGrid>介绍表格列的个数。另一个是<w:tr>包含表格行的信息。 tr是table row的缩写。
其中,<w:tr>里面有<w:tc>,这里面是格子的内容。我们发现其内容,居然是一个它的兄弟节点<w:p>。在此,给表格大佬深深地鞠上一躬。
tc是table cell的缩写,表示单元格的意思。有人可能会说,tc是table column的缩写,表示表格的列。当我后面论述带有合并单元格的表格时,从结构上看,我们会感觉table cell更适合语境。
先说基本表格的解析,如下图所示:
解析的代码参考如下:
w_table = body.childNodes[0] # 拿到表格节点
# 获取所有的行
w_trs = w_table.getElementsByTagName("w:tr")
rows_text = [] # 存放行的文本
for r_index, tr in enumerate(w_trs):
# 获取所有的单元格
cells = tr.getElementsByTagName("w:tc")
cells_text = [] # 存放单元格的文本
for c_index, cell in enumerate(cells):
# 获取所有的文本
wts = cell.getElementsByTagName("w:t")
for wt in wts: # 把文本拼接
cells_text.append(wt.text)
rows_text.append(cells_text)
print(rows_text) # 打印结果,二维数组[[r1c1,r1c2],[r2c1,r2c2]]
运行一下代码,结果如下:
这里面我又挖坑了,除了前面讲w:t时的wt.text陷阱之外。w:tc的内容应该是去解析完整的w:p结构,而这里我只取了w:t文本。这样最简单。因为,我们是要理解表格的结构。因此,其他的可以假装看不见。
但是,也由此可见,做好表格解析的前提,是做好段落解析。因为表格单元格里是段落。
我相信,有了表格的解析结果(二维数组),你很容易就可以把它还原成表格页面用于展示。只需要循环就好,第一层循环行,第二层循环列。
我还是用1分钟写一下代码吧:
rows_text = [['名称', '后缀名'], ['Word', 'docx']]
table_html = ["<table>"]
for row in rows_text:
table_html.append("<tr>")
for cell in row:
table_html.append("<td>" cell "</td>")
table_html.append("</tr>")
table_html.append("</table>")
table_html = "".join(table_html)
print(table_html)
# <table>
# <tr><td>名称</td><td>后缀名</td></tr>
# <tr><td>Word</td><td>docx</td></tr>
# </table>
据我所知,世界上的表格除了上面那种简单的,还有一些稍微复杂的。那就是带有合并单元格的表格。
比如下面这种: