純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)網站

相關文章
相關標籤/搜索