前端vue藉助 docxtemplater 匯出 word
阿新 • • 發佈:2020-12-04
原理:需要將頁面中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 = newdocxtemplater().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