使用Apache POI生成Word文档不能被office读取的问题

点击量:962

近期应一个妹子的邀请做一些跟了一些和Word,excel相关的读写研究。需求很简单,就是从excel表格里读取一些白名单,然后在Word表格里找到这些匹配项再做相应的处理。因为每次手动操作很麻烦,所以呢妹子就找到了我,问下我能不能写个程序来做这件事。我一想这玩意儿应该挺简单的啊,肯定有开源的库来读写excel和Word,而且能提高妹子的工作效率,所以就欣然答应下来了。
之后就Google了一番看看有木有什么开源的库可以用,果不其然第一个就是Apache的POI项目,然后去官网看API文档。总的来说这个库使用起来还是蛮方便,下面介绍下读写Word和excel的代码:

这个只是读取excel的代码,值得一提是由WorkbookFactory创建出来的Workbook是支持xls和xlsx两种格式的文档,开发者不再需要区分是03还是07格式的excel文件,非常方便。然后读取Word文档却不像读取excel这么方便,他有两套API,一个是HWPFDocument只支持03格式的Word(后缀:doc)还有一个是XWPFDocument 只支持07格式的word(后缀:docx),这两个名字看起来差不多实则使用方法却不一样,下面介绍下读写doc中表格的代码:

自己新建了一个excel和word文档,测试通过,everything goes right,简直so easy嘛。但是当妹子把要处理的文档发给我的时候却遇到了一问题,POI在读取的时候报了一个错:

看报错应该是word文档的格式不对了,怀疑是给出的文档不规范,不是标准的doc文档,所以我又另存为doc文档,然后就可以读取了也成功的生成了output.doc文档,诡异的是使用office打开这个文件时报错了。既然可以读进来了为什么写进去的文档不能被打开呢?
刚开始的时候怀疑是API使用不正确,但是新建一个word文档却没有问题。所以问题就出在了妹子给出的这个文档上面了(这个文档也是程序生成的)。那这个文档跟普通的doc文档到底有什么不一样呢?因为output是由原始文件生成的,所以又把目光锁定到了之前那个报错上面。invalid header signature到底读到了什么?把0x6576206C6D783F3C翻译成文本字符串就是:ev lmx?<,这是啥感觉有点像xml啊。再进一步直接用vim打开这个word文档发现前两行是这样的:

再往后看发现这就是一个xml文件啊,后来查阅资料才知道还有另一种office的格式叫OOXML,全称是Office Open XML由微软公司为Office 2007产品开发的技术规范,现已成为国际文档格式标准,兼容前国际标准开放文档格式和中国文档标准“标文通”(外语简称:UOF)。说白了就是基于XML的word,excel和PowerPoint。据此可以推测妹子的文档很可能是使用freemarker导出XML到word的。但是xml文件怎么了呢?为什么POI就不能打开呢?又去官网看了一圈,发现现在的POI并不支持OOXML格式的文档,他们这样说道:
There is a different format for the XML-based file formats of the Microsoft Office suite which Apache POI does not support yet.
虽然office的产品能兼容这种格式的文档,但是这种标准的文档读写方式是不同于普通的word文档,api层面需要重新写一套来用,遗憾的是POI并不支持,他们项目组还在招募人员开发这个项目。
原因到此就清楚了,但怎么解决这个问题呢?要么就自己解析XML文件,但是这个XML文档的标签实在太多了,解析起来相当麻烦。还有就是让妹子多费点事把表格copy到一个新的.doc文档中也能解决问题,但是并不完美。

发表评论

电子邮件地址不会被公开。 必填项已用*标注