纯js解析docx文件探索

纯前端解析.docx文件

前段时间作过一个纯前端解析.docx文件的需求,只须要解析文件的内容展现在页面上便可,需求听上去还挺简单的,然而我仍是踩了到了巨坑。前端

前端解析工具

  • mammath

从各个网站上搜到了很多的解析方法,这里我发现了mammoth,这个插件功能仍是很强大的,结合H5和mammoth,很快我就写下了一个解析docx文件的方法:git

function parseStandFile(file){
          var reader = new FileReader();
          reader.onloadend = function(event) {
            var arrayBuffer = reader.result;
      
            mammoth.extractRawText({arrayBuffer: arrayBuffer}).then(function (resultObject) {
              $result.innerHTML = resultObject.value
              console.log(resultObject.value)
            })
          };
          reader.readAsArrayBuffer(file);
      }

ps: $result:文档文本显示的dom节点github

到这一步,仍是很顺利的,本身建立一个docx文件,上传展现都很顺利,然而,当我拿来客户的文件,上手操做的时候,发现解析出来竟让是一片空白(unbelievable)!!!
因而我又企图从茫茫互联网中获取答案,然而一无所得sad。可是在查找的过程当中发现docx文件压缩以后能看到文件的构成,因而我压缩了目标文件,发现文件目录以下:image.pngnpm

当我打开docProps/app.xml:
image.png
发现客户文件里的压缩文件跟个人彷佛不太同样,多是客户用的word版本跟个人不太同样之类的缘由吧,然而需求仍是要实现的,这时我发现压缩文件夹下面的word/document.xml里存放的就是docx文件的内容,因此个人思路是先解压docx文件这个小妖精,而后找包含内容的文件,最后进行xml文件的匹配解析app

  • JSZip

很容易在网上就能找到js解压缩的工具,对比了几个以后,我决定使用JSZip,使用方式也很简单,官网打开一目了然。因而我很快就写好了又一个解析方法:dom

JSZip.loadAsync($file.files[0])    //获取文件                         
        .then(function(zip) {
          let standalone
          zip.forEach(function (relativePath, zipEntry){
              parsePOIFile($file.files[0])   //解析文件内容,考虑兼容问题,单独写一个方法
          })
function parsePOIFile(file){
        JSZip.loadAsync(file)                              
        .then(function(zip) {
          var str = ''
          zip.forEach(function (relativePath, zipEntry) { 
              if(zipEntry.name==='word/document.xml'){ //目标文件document
                   zip.file(relativePath).async("string").then(function (data) {
                  data.match(/<w:t>[\s\S]*?<\/w:t>/ig).forEach((item)=>{
                      str += item.slice(5,-6)
                    });
                    //以上match方式参考某网友,不记得是哪一个blog了
                    $result.innerHTML = str
                });
              }
            });
        }, function (e) {
            $result.append($("<div>", {
                "class" : "alert alert-danger",
                text : "Error reading " + file.name + ": " + e.message
            }));
        });
      }

至此,客户文件就成功解析了。
然而,我发现,用我本身的office建立的文件,就不能解析了(土拨鼠的咆哮),毕竟两个文件内容不同,因而我决定也兼容一下个人版本(强迫症使我劳累)
在代码zip.file(relativePath).async("string").then(function (data)中,我打印出来data寻找他们的区别,发现两种文件的docProps/core.xml内容,有这个明显的区别:image.pngasync

我决定获取该节点的standarlone属性,先获取到core.xml,而后执行不一样的解析方法:工具

if(zipEntry.name==='docProps/core.xml'){
zip.file(relativePath).async("string").then(function (data) {
   let parser=new DOMParser();
   xmlDoc=parser.parseFromString(data,"text/xml");
   standalone = xmlDoc.getElementsByTagName("cp:coreProperties")[0].getAttribute("xmlns:dcmitype")
        if(standalone){
          parseStandFile(file)   //解析标准文件
        } else {
          parsePOIFile(file)
        }
      })
    }

终于,两个文件都能成功解析了,内心很是有成就感,感悟就是:要从事物的本质思考问题(扶眼镜.jpg)网站

相关文章
相关标签/搜索