vue項目前端導出word文件(bug解決)


摘要:之前項目中導出價格表是由后端實現,前端只需要調用接口下載word即可,后來業務改變比較大,word模版需要一直改動,后端改起來相對麻煩,后來直接前端自己定義模版,實現下載word文檔。

 

一、需要安裝的依賴

1、docxtemplater

介紹:docxtemplater是一種郵件合並工具,它以編程方式使用,處理條件、循環,並且可以擴展為表格、HTML、圖像等。

安裝方法:cnpm i docxtemplater@^3.9.1

2、FileSaver

介紹:FileSaver.js 是在客戶端保存文件的解決方案,非常適合需要生成文件,或者保存不應該發送到外部服務器的敏感信息的應用。

安裝方法:cnpm i file-saver@^1.3.8

3、jszip

介紹:jszip是一個用於創建、讀取和編輯.zip文件的JavaScript庫,且API的使用也很簡單。

安裝方法:cnpm i jszip@^2.6.1

4、jszip-utils

介紹:jszip-utils是與jszip一起使用的跨瀏覽器的工具庫

安裝方法:cnpm i jszip-utils@^0.0.2

 

二、創建word模版

介紹:根據自己的業務需求創建需要導出的word模版,變量數據使用{變量名}代替,表格內容數據需要使用{#參數名}開始{/參數名}結尾,具體如下圖:

 

注意點:1.模板文件使用vue-cli2的時候,放在static目錄下。使用vue-cli3的時候,放在public目錄下。

            2.文件須以docx結尾。

不然可能出現的問題:提示Uncaught Error: Corrupted zip: missing 7124 bytes.

vue-cli3示例位置如圖:

 

三、html代碼編寫

定義下載事件downloadprice

<div class="download” @click="downloadprice">下載價格表</div>

 

四、script代碼編寫

1.使用的頁面中導入需要的插件:

import Docxtemplater from 'docxtemplater';
import { saveAs } from 'file-saver';
import JSZip from 'jszip';
import JSZipUtils from 'jszip-utils';

2.定義接口數據(這里為定義好的數據,正常情況下通過接口獲取需要在word文檔上展示的數據):

data() {
  return {
      // 導出價格表全部信息
    exportPriceObj: {
      actualPayFee: '179.55',
      deliveryFee: '0.00',
      discountActualFee: '179.55',
      discountFee: '9.45',
      discountRatio: '95',
      nickName: '張三',
      retailTotalFee: '0.00',
      totalFee: '189.00',
    },
    // 導出價格表商品信息
    exportPriceListOne: [
      {
        productColor: '白色',
        productName: '0909測試商品',
        productNo: 1,
        productSize: '4XL(58)',
        productSkuId: 'teydnkn',
        sellingPrice: '10.00',
      },
      {
        productColor: '白色',
        productName: '1955測試商品',
        productNo: 2,
        productSize: 'XL(52)',
        productSkuId: 'teydoja',
        sellingPrice: '40.00',
      }
    ],
  }
}

3.下載word文檔點擊事件方法:

// 下載價格表
downloadprice() {
  let _this = this;
  // 判斷有無附加商品來選擇word模版
  // 讀取並獲得模板文件的二進制內容
  JSZipUtils.getBinaryContent('pricenew.docx', function(error, content) {
    console.log('-----', content);
    // input.docx是模板。我們在導出的時候,會根據此模板來導出對應的數據
    // 拋出異常
    if (error) {
      throw error;
    }
    // 創建一個JSZip實例,內容為模板的內容
    let zip = new JSZip(content);
    console.log('+++++', zip);
    // 創建並加載docxtemplater實例對象
    let doc = new Docxtemplater();
    console.log('/////', doc);
    doc.loadZip(zip);
    console.log('=====', doc);
    // 設置模板變量的值
    doc.setData({
      // 導出價格表全部信息
      ..._this.exportPriceObj,
      // 導出價格表商品信息
      tableone: _this.exportPriceListOne,
    });
    try {
      // 用模板變量的值替換所有模板變量
      doc.render();
    } catch (error) {
      // 拋出異常
      let e = {
        message: error.message,
        name: error.name,
        stack: error.stack,
        properties: error.properties
      };
      console.log(JSON.stringify({ error: e }));
      throw error;
    }
    // 生成一個代表docxtemplater對象的zip文件(不是一個真實的文件,而是在內存中的表示)
    let out = doc.getZip().generate({
      type: 'blob',
      mimeType:
        'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
    });
    // 將目標文件對象保存為目標類型的文件,並命名
    saveAs(out, _this.exportPriceObj.nickName + '的價格表.docx');
  });
},

4.點擊下載后可能會出現的問題:

一、提示Uncaught Error: Corrupted zip: missing 7124 bytes.

錯誤方法如圖:

可能產生的原因是:1.模版文件word放置的位置獲取不到;

                           2.word文檔格式出現錯誤;

解決方法:1.模板文件使用vue-cli2的時候,放在static目錄下。使用vue-cli3的時候,放在public目錄下。

               2.文件須以docx結尾。

正確方法如圖:

 

 

二、提示Uncaught Error: Can't find end of central directory : is this a zip file ?

錯誤方法如圖:

可能產生的原因是:1.你項目里面引用了mockjs文件,它的原理是重寫了XMLHttpRequest,導致你上報插件找不到對應的方法;

解決方法:上線時把項目中引入的mock注釋掉,// import '@/mock';

原理分析:mockjs是一個模擬后台接口的JS庫,它的原理是重寫了XMLHttpRequest,它可以在接口沒出來時非常方便的模擬數據,上線之后      不引用它即可。一般上報插件中會使用原生XMLHttpRequest,而原生XMLHttpRequest已被mockjs覆蓋找不到相應的方法,所以會   出錯。除了mockjs之外,zonejsoboejsfetchjs也有自己的的XMLHttpRequest庫,請慎用。

正確方法如圖:

 

 

三、提示 End of data reached (data length = 0, asked index = 4). Corrupted zip ?

錯誤方法如圖:

 

可能產生的原因:1.你項目上傳上去的word文件為空文件;

解決方法:1.請檢查你上傳到服務器的文件大小是否正確,如果字節為空或者字節大小不對,請替換一個正確的word文件上去;

 

四、其他問題等

請檢查你下載文件方法是否存在緩存,查詢方法如下:

304代表有緩存

 

200代表沒有

解決方法:

JSZipUtils.getBinaryContent('warehouse.docx?random=' + Math.random(), function(error, content) {

在引用文件時在文件后面添加一個隨機數

 

五、導出結果

導出結果如圖:

有問題歡迎留言,帶上問題和代碼截圖,看到后第一時間回復幫忙解答,謝謝!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM