最近需求是写一个将docx和doc解析后转换为json格式输入到json临时文件中的功能,然后前端读取json文件去渲染做到和文档内容一致,在这里归纳下难点,以及国内网站基本没有相关demo的点。
首先先说下docx和doc的区别吧,区别实际上就是一个好用而另一个反人类,现在创建一个新的文档,office都不会给你选择,直接默认docx,除非你另存为doc或者直接修改后缀,这样的原因是doc这种二进制存储的玩意过于反人类:
docx文件修改后缀为zip后解压,你可以在这个文件夹里面看到所有文档内容信息,样式,图片之类的,doc的话相同操作你啥都看不到。这样就导致你使用poi解析docx和doc的难易程度完全差得十万八千里。
另外poi用来解析doc的hwpf包也写的很乱,对比poi用来解析docx的xwpf包来说,xwpf包看底层会有方法说明,而且命名方式可以让你就算没有方法说明,大致也很容易看得懂这个方法用来干什么的,但是hwpf包就不一样,一堆枚举,方法也很凌乱,阿帕奇官网对于方法的说明几乎没有,再加上国内使用poi的本来就少,大多直接用阿里的poi-tl之类的,而且用poi解析文档的更是少之又少,大多资料都是解析excel的,少之又少里面大多又是解析docx的,doc的又是又是少之又少。希望自己接下来的一些补充能够在国内论坛里贡献一点资料吧(虽然很冷门,但是希望以后有和我做一样事情的程序员能少走点弯路)
最后因为我应届入职不久,代码可能比较稚嫩,希望能给你带来帮助,轻喷。
首先说下docx,doc的解析难点吧。
首先我觉得比较偏门资料比较少的有五个:
一个是解析公式,我所做的需求是将公式转换为latex字符串储存,就是比如将下图这种转换为一个字符串:
x=\frac{-b\pm \sqrt{{b}^{2}-4ac}}{2a}
二是遍历docx文档。单独解析不同的模块,如解析出文档里所有的图片,解析文档中所有表格,解析文档中的所有的文本,这很简单,docx这些方法csdn或者博客园都能找到。但是,这些解析出来的数据结构是没有定位的,你不知道图片与段落之间的关系,表格与段落之间的关系,题注与图片的位置关系。所以你必须要从头到尾去遍历,才能够知道这些之间的位置关系。
三是遍历doc文档,相信我,这个比docx的遍历冷门的多,自己不断尝试的方法摸索出来的,可能还没达到普遍性,但是基本能泛用。
四是将docx和doc文档中的复杂表格转换为html字符串,这个也很冷门,网上资料大多是整个文档全转为html,或者是读取简单地,方方正正,n*m的表格,没有单独处理复杂表格转换为html的的。
主要思路是解析后通过自己写的方法拼接为html,docx的表格转html字符串是在网上找的,poi解析docx用的xwpf包里面对于表格有专门的类读取它的信息,能够得到很完善的表格信息,所以拼接简单,poi解析doc所用的hwpf包解析doc中的表格,没有这些东西,所以很难读取解析复杂表格后拼接为html。这个后面会单独说。
五是编号列表,docx的编号列表网上能找到,但是也很冷门那种,太难找了,而doc的网上根本就没有,方法是靠自己看hwpf底层加上不断测试以及阅读office官网给的一些doc文档信息写出来的。
这里要说一下:docx文档和doc文档实际上是没有存储编号的文本的。
查了下相关资料,说列表段落的编号文本不是硬编码,所以你去文档底层里面是找不到具体的文本内容。xwpf读取docx中列表段落的编号的文本内容是在csdn上找到的,而doc是自己摸索加上office官方给的文档结合推导出来的方法,但是方式都是大同小异,都不是通过poi直接读出来的,而是通过poi获取相关信息,然后在方法里面匹配后进行拼接,从而获取对应的列表段落的编号文本内容,类似于下列图中所示的编号内容:如1. 1) a) 等。
这些都是比较冷门的读取,至少我在做的时候很多都找不到,stack over flow上去询问也很多都没解决,有的是靠自己测试得出的结果。
有时间会将代码上传github并且分享相关jar包,jar包的功能是给要解析的docx文件路径或doc文件路径,以及输出临时文件位置(本来是只要给文件路径,自动生成一个temp文件夹在jar包相同的目录下,然后在temp文件夹下生成相应的解析后的json临时文件,但是老大不让这么做),生成的json文件是顺序从头到尾的,前端解析后渲染就可以复原这个文档内容,文本样式什么都有。