1. 程式人生 > 實用技巧 >前端vue藉助 docxtemplater 匯出 word

前端vue藉助 docxtemplater 匯出 word

原理:需要將頁面中table匯出一個word檔案,在本地做好一個word模板,定義好變數,以這個模板檔案為匯出依賴,將後臺獲取的變數新增進去。

需求:將“倫理審查批件”匯出為word

操作步驟:

1、下載外掛

  npmi docxtemplaterjszip-utilsfile-saverjszip

2、定義word模板:vue3.0將該檔案放在public目錄下,vue2.0將該檔案放在static目錄下

3、引入外掛和定義匯出函式

import docxtemplater from 'docxtemplater'
import JSZipUtils from 'jszip-utils'
import { saveAs } from 
'file-saver' import JSZip from 'jszip'
    exportWord: function() {
      let _this = this
      // 讀取並獲得模板檔案的二進位制內容
      JSZipUtils.getBinaryContent('approvalNo.docx', function(error, content) {
        if (error) throw error // 丟擲異常
        let zip = new JSZip(content) // 建立一個JSZip例項,內容為模板的內容
        let doc = new
docxtemplater().loadZip(zip) // 建立並載入docxtemplater例項物件 doc.setData({ ..._this.approvalNoOrOpinionNoList }) // 設定模板變數的值 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, 'aaa.docx') }) }

  注意:引入路徑和傳入到模板中的引數

實際匯出效果:

頁面完整程式碼:

<template>
  <div class="approvalNo-or-opinionNo-list">
    <el-button type="primary" size="small" @click="exportWord">點選下載</el-button>
    <div id="pdfDom">
      <table cellspacing="0">
        <caption>
          倫理審查批件
        </caption>
        <tr>
          <td class="key-name">批件號</td>
          <td colspan="3">{{ approvalNoOrOpinionNoList.approvalNo }}</td>
        </tr>
        <tr>
          <td class="key-name">專案名稱</td>
          <td colspan="3">{{ approvalNoOrOpinionNoList.projectName }}</td>
        </tr>
        <tr>
          <td class="key-name">專案來源</td>
          <td colspan="3">{{ approvalNoOrOpinionNoList.sponsorName }}</td>
        </tr>
        <tr>
          <td class="key-name">研究單位</td>
          <td colspan="3">{{ approvalNoOrOpinionNoList.researchUnit }}</td>
        </tr>
        <tr>
          <td class="key-name">主要研究者</td>
          <td colspan="3">{{ approvalNoOrOpinionNoList.personName }}</td>
        </tr>
        <tr>
          <td class="key-name">審查類別</td>
          <td>{{ approvalNoOrOpinionNoList.taskStyle }}</td>
          <td class="key-name">審查方式</td>
          <td>{{ approvalNoOrOpinionNoList.taskType }}</td>
        </tr>
        <tr>
          <td class="key-name">審查日期</td>
          <td>{{ approvalNoOrOpinionNoList.auditDate }}</td>
          <td class="key-name">審查地點</td>
          <td>{{ approvalNoOrOpinionNoList.auditAddress }}</td>
        </tr>
        <tr>
          <td class="key-name">審查委員</td>
          <td colspan="3">{{ approvalNoOrOpinionNoList.auditCommittees }}</td>
        </tr>
        <tr>
          <td class="key-name">批准檔案</td>
          <td colspan="3">見附件</td>
        </tr>
        <tr>
          <td colspan="4" class="options">
            {{ approvalNoOrOpinionNoList.auditRemark }}
          </td>
        </tr>
        <tr>
          <td class="key-name">年度/定期<br />跟蹤審查頻率</td>
          <td colspan="3">{{ approvalNoOrOpinionNoList.frequency }}</td>
        </tr>
        <tr>
          <td class="key-name">有效期</td>
          <td colspan="3">{{ approvalNoOrOpinionNoList.effectiveStartDate }} 至 {{ approvalNoOrOpinionNoList.effectiveEndDate }}</td>
        </tr>
        <tr>
          <td class="key-name">聯絡人與聯絡電話</td>
          <td colspan="3">{{ approvalNoOrOpinionNoList.sponsorContacts }} {{ approvalNoOrOpinionNoList.sponsorTel }}</td>
        </tr>
        <tr>
          <td class="key-name">倫理委員會</td>
          <td colspan="3">{{ approvalNoOrOpinionNoList.ethicsCommittee }}</td>
        </tr>
        <tr>
          <td class="key-name">主任簽名</td>
          <td colspan="3">{{ approvalNoOrOpinionNoList.directorAutograph }}</td>
        </tr>
        <tr>
          <td class="key-name">日期</td>
          <td colspan="3">{{ approvalNoOrOpinionNoList.todayDate }}</td>
        </tr>
      </table>
    </div>
  </div>
</template>
<script>
import docxtemplater from 'docxtemplater'
import JSZipUtils from 'jszip-utils'
import { saveAs } from 'file-saver'
import JSZip from 'jszip'
export default {
  data() {
    return {}
  },
  props: {
    approvalNoOrOpinionNoList: {
      type: Object,
      default: {}
    }
  },
  methods: {
    exportWord: function() {
      let _this = this
      // 讀取並獲得模板檔案的二進位制內容
      JSZipUtils.getBinaryContent('approvalNo.docx', function(error, content) {
        if (error) throw error // 丟擲異常
        let zip = new JSZip(content) // 建立一個JSZip例項,內容為模板的內容
        let doc = new docxtemplater().loadZip(zip) // 建立並載入docxtemplater例項物件
        doc.setData({ ..._this.approvalNoOrOpinionNoList }) // 設定模板變數的值
        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, 'aaa.docx')
      })
    }
  }
}
</script>
<style lang="scss">
.approvalNo-or-opinionNo-list {
  height: 350px;
  overflow-y: auto;
  padding-bottom: 20px;
  border-bottom: 1px solid #ccc;
  > #pdfDom {
    table {
      text-align: center;
      border-bottom: 1px solid #ccc;
      width: 93%;
      margin: 0 auto;
      font-family: '楷體', '楷體_GB2312';
      caption {
        font-size: 16px;
        text-align: center;
        line-height: 46px;
        color: #333;
        font-weight: bold;
      }
      td {
        width: 25%;
        height: 32px;
        color: #666;
        border-left: 1px solid #ccc;
        border-top: 1px solid #ccc;
        padding: 0 6px;
      }
      td:last-child {
        border-right: 1px solid #ccc;
      }
      .key-name {
        color: #333;
        font-weight: 600;
      }
      .options {
        padding: 10px;
        text-align: justify;
        text-indent: 2em;
      }
    }
  }
}
</style>
View Code