Office文件内容解析
微软官方文档:
doc格式:https://docs.microsoft.com/en-us/openspecs/office_file_formats/ms-doc
xls格式:https://docs.microsoft.com/en-us/openspecs/office_file_formats/ms-xls
ppt格式:https://docs.microsoft.com/en-us/openspecs/office_file_formats/ms-ppt
OLE复合文件格式:https://docs.microsoft.com/en-us/openspecs/windows_protocols/MS-CFB
doc、xls、ppt文件都属于OLE复合文件,在OLE基础上存储
OLE格式解析
以xls为例:复合文件以一个Header+多个Sector形式进行存储。
Header为512B,保存文件的基础信息,前8各字节一定是0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1。其余信息见图。
Sector分为Directory,FAT,miniFAT,DIFAT, user-defined data,Range Lock共6种类型。Sector大小固定(默认为512B),由Header信息指定。通过ID标识,从0开始。
Directory存放文件信息目录,用于指向数据所在SectorID等。
FAT存放当前Sector下一Sector的ID。用4B数组存储,下标i即为SectorID为i下一Sector的ID。
miniFAT中使用miniSector存放数据。miniSector大小固定(默认为64B),由Header信息指定。所以一般miniFAT类型的Sector中有8(512 / 64)个miniSector。其余类型解析文件是使用不多,具体见官方文档。
Directory是OLE文档的目录结构,包含多个Entry,具体结构见图,一般xls文件的文本信息在名为WorkBook的DirectoryEntry中所指向的Sector中,doc文件的文本信息在名为WordDocument的DirectoryEntry中所指向的Sector中,ppt文件的文本信息在名为PowerPoint Document的DirectoryEntry中所指向的Sector中。
具体格式文本数据解析
通过Directory找到文本数据所在的Sector后,不断读取数据,然后解析通过doc,xls,ppt格式解析数据。
1.doc
以doc为例,通过Directory找到WordDocument起始SectorID为0,doc格式数据最开始是Fib(File Information Block)结构,Fib包含FibBase,FibRgLw97等结构,具体见官方文档。
SectorID为0的Sector的512B数据如下,红框圈起来的为FibRgLw97结构,22个4B的Uint32整型数据:
FibRgLw97中的第1个Int32,为Word Document中有意义的字节数(即Word Document之后的字节数都可以忽略)。第4个Int32,为文档中正文(Main document)的总字数。
FibRgLw97中的第5个Int32,为文档中页脚(Footnote subdocument)的总字数。
FibRgLw97中的第6个Int32,为文档中页眉(Header subdocument)的总字数。
FibRgLw97中的第7个Int32,为文档中批注(Comment subdocument)的总字数。
FibRgLw97中的第8个Int32,为文档中尾注(Endnote subdocument)的总字数。
FibRgLw97中的第10个Int32,为文档中文本框(Textbox subdocument)的总字数。
FibRgLw97中的第11个Int32,为文档中页眉文本框(Textbox Subdocument of the header)的总字数。
2.xls和ppt
xls和ppt结构类似,由rectype(Record)+reclen(rectype所占字节数)+data(除去rectype和reclen剩余字节数)循环保存数据。具体rectype种类见官方文档,在文档提取中我们只需找到文本所在的rectype进行提取即可。rectype可嵌套。
参考资料:
https://www.cnblogs.com/mayswind/archive/2013/03/26/2983499.html
https://www.cnblogs.com/mayswind/archive/2013/03/17/2962205.html
Java开源office提取库POI:https://poi.apache.org/components/index.html