首先,安裝xlsx插件git
npm install xlsx
插件文檔地址xlsx官方文檔github
在組件這中引入npm
import XLSX from 'xlsx';
所要導出的數據以下json
// 設置面板標題 settingPanelTitle:"", col:1, // 是否編輯 isEdit:true, // 表頭數據 headerData: { "offerData":{ name:"項目名稱", spec:"規格", unit:"單位", count:"數量", unitPrice:"單價", total:"金額", cardNum:"卡數", comments:"備註" }, "offerData1":{ name:"項目名稱1", spec:"規格1", unit:"單位1", count:"數量1", unitPrice:"單價1", total:"金額1", cardNum:"卡數1", comments:"備註1" } }, // 表格數據 allData:{ "offerData":[ { name:"櫃體1", spec:"sasd", unit:"sadad", count:"5", unitPrice:"145", total:"", cardNum:5, comments:"大師大師多撒好低" }, { name:"櫃體2", spec:"sasd", unit:"sadad", count:"10", unitPrice:"522", total:"", cardNum:5, comments:"大師大師多撒好低" }, { name:"櫃體3", spec:"sasd", unit:"sadad", count:"15", unitPrice:"142", total:"", cardNum:5, comments:"大師大師多撒好低" }, { name:"櫃體4", spec:"sasd", unit:"sadad", count:"20", unitPrice:"22", total:"", cardNum:5, comments:"大師大師多撒好低" }, { name:"櫃體5", spec:"sasd", unit:"sadad", count:"25", unitPrice:"222", total:"", cardNum:5, comments:"大師大師多撒好低" }, { name:"櫃體6", spec:"sasd", unit:"sadad", count:"12", unitPrice:"322", total:"", cardNum:5, comments:"大師大師多撒好低" } ], "offerData1":[ { name:"邊框1", spec:"sasd", unit:"sadad", count:"12", unitPrice:"14522", total:"", cardNum:5, comments:"大師大師多撒好低" }, { name:"邊框2", spec:"sasd", unit:"sadad", count:"12", unitPrice:"14522", total:"", cardNum:5, comments:"大師大師多撒好低" }, { name:"邊框3", spec:"sasd", unit:"sadad", count:"12", unitPrice:"14522", total:"", cardNum:5, comments:"大師大師多撒好低" }, { name:"邊框4", spec:"sasd", unit:"sadad", count:"12", unitPrice:"14522", total:"", cardNum:5, comments:"大師大師多撒好低" }, { name:"邊框5", spec:"sasd", unit:"sadad", count:"12", unitPrice:"14522", total:"", cardNum:5, comments:"大師大師多撒好低" }, { name:"邊框6", spec:"sasd", unit:"sadad", count:"12", unitPrice:"14522", total:"", cardNum:5, comments:"大師大師多撒好低" } ] }, //頁頭部分 pageHead:{ "offerData":[ { name:"訂單號:", isEdit:false }, { name:"客戶名稱:", isEdit:false }, { name:"銷售日期:", isEdit:false }, { name:"聯繫人:", isEdit:false }, { name:"聯繫地址:", isEdit:false } ], "offerData1":[ { name:"訂單號1:", isEdit:false }, { name:"客戶名稱1:", isEdit:false }, { name:"銷售日期1:", isEdit:false }, { name:"聯繫人1:", isEdit:false }, { name:"聯繫地址1:", isEdit:false } ] }, // 頁頭部份內容 pageHeadContent:{ "offerData":[ { name:"1231312313" }, { name:"zoe" }, { name:"2017-10-21" }, { name:"joe" }, { name:"beijibng" } ], "offerData1":[ { name:"2231312313" }, { name:"zoe1" }, { name:"2017-10-21" }, { name:"joe11" }, { name:"beijibng111" } ] }, options: { 'offerData':{ value: 'offerData', label: '報價明細單' }, 'offerData1':{ value: 'offerData1', label: '報價明細單1' } }, value: 'offerData', //選擇的表格 outputData:[], // 導出的數據 outFile: '', // 導出文件el
在ui層放個導出按鈕和a標記模仿導出彈框ui
<button @click=" downloadFile(outputData)" id="export-table" class="btn btn-default">導出</button> <a id="downlink"></a>
點擊導出按鈕觸發this
// 導出功能 downloadFile: function (rs) { // 點擊導出按鈕 //拼接導出的數據 //1.拼接標題 rs.push({title:this.settingPanelTitle}); //2.拼接表頭內容 let headContent={}; //頁頭項 let pHead=this.pageHead[this.value]; //頁頭項對應的內容 let pHeadContent=this.pageHeadContent[this.value]; for(let i in pHead){ headContent[i]=pHead[i].name+""+pHeadContent[i].name; } // console.log(headContent); rs.push(headContent); //3.拼接表頭標題 rs.push(this.headerData[this.value]); //4.拼接表內容 rs.push(...this.allData[this.value]); //5.拼接表尾 rs.push({title:"合計",value:this.settingData[this.value].totalPrice}); // console.log(rs); this.downloadExl(rs, this.settingPanelTitle) }, downloadExl: function (json, downName, type) { // 導出到excel let tmpdata = [] // 用來保存轉換好的json let maxLen=0; //最長的一行 json.map((v, i) => { if(maxLen<Object.keys(v).length){ maxLen=Object.keys(v).length; } return Object.keys(v).map((k, j) => { //取出鍵對應的值 return Object.assign({}, { //拼接輸出的sheet v: v[k], position: (j > 25 ? this.getCharCol(j) : String.fromCharCode(65 + j)) + (i + 1) })} ) }).reduce((prev, next) => prev.concat(next)).forEach(function (v) { tmpdata[v.position] = { //轉換輸出json v: v.v } }) let outputPos = Object.keys(tmpdata) // 設置區域,好比表格從A1到D10 // console.log(outputPos); // 轉化最長的行所對應的區域碼 maxLen=this.getCharCol(maxLen); // console.log(maxLen+outputPos[outputPos.length-1].slice(1)); let tmpWB = { SheetNames: ['mySheet'], // 保存的表標題 Sheets: { 'mySheet': Object.assign({}, tmpdata, // 內容 { '!ref': outputPos[0] + ':' + (maxLen+outputPos[outputPos.length-1].slice(1)) // 設置填充區域 }) } } let tmpDown = new Blob([this.s2ab(XLSX.write(tmpWB, {bookType: (type === undefined ? 'xlsx' : type), bookSST: false, type: 'binary'} // 這裏的數據是用來定義導出的格式類型 ))], { type: '' }) // 建立二進制對象寫入轉換好的字節流 var href = URL.createObjectURL(tmpDown) // 建立對象超連接 this.outFile.download = downName + '.xlsx' // 下載名稱 this.outFile.href = href // 綁定a標籤 this.outFile.click() // 模擬點擊實現下載 setTimeout(function () { // 延時釋放 URL.revokeObjectURL(tmpDown) // 用URL.revokeObjectURL()來釋放這個object URL }, 100) }, // 轉2進制 s2ab(s){ if(typeof ArrayBuffer !== 'undefined'){ let buf =new ArrayBuffer(s.length); let view =new Uint8Array(buf); for(var i=0;i!=s.length;++i) view[i] =s.charCodeAt(i) & 0xFF; return buf; }else{ let buf= new Array(s.length); for(var i=0;i!=s.length;++i) buf[i] =s.charCodeAt(i) & 0xFF; return buf; } }, // 將指定的天然數轉換爲26進製表示。映射關係:[0-25] -> [A-Z]。 getCharCol(n) { let s = '' let m = 0 while (n > 0) { m = n % 26 + 1 s = String.fromCharCode(m + 64) + s n = (n - m) / 26 } return s },
實現效果
spa