vue如何實現二進制流文件導出excel
vue二進制流文件導出excel
問瞭一下其他的後端,他們公司前端是a標簽,後端是給瞭一個地址,a標簽或者window.open()都可以實現。
我們公司是後端返回的二進制流文件,實現瞭一下,親測可以,沒有問題
前端代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <button id="btn">下載</button> <!-- yarn add axios --> <script src="node_modules/axios/dist/axios.min.js"></script> <script> const btn = document.getElementById("btn"); btn.onclick = function () { axios({ method: "post", url: "http://localhost:3000/download", data: { // test: "test data", }, responseType: 'blob' //返回類型 }).then((res) => { let name = '合格率' //註意這裡不可以再加.xlsx瞭,函數中已經封裝瞭 createExcel(res.data, name) //這裡就直接這樣調用方法就行瞭 }); } // vue中可以寫方法 然後再暴露出去 function createExcel(res, name) { let blob = new Blob([res], { type: 'application/vnd.ms-excel' }) let fileName = name + '.xlsx' // 允許用戶在客戶端上保存文件 if (window.navigator.msSaveOrOpenBlob) { navigator.msSaveBlob(blob, fileName) } else { var link = document.createElement('a') link.href = window.URL.createObjectURL(blob) link.download = fileName link.click() //釋放內存 window.URL.revokeObjectURL(link.href) } } // 1.msSaveBlob:隻提供一個保存按鈕 //window.navigator.msSaveBlob(blobObject, 'msSaveBlob_testFile.txt'); // 2.msSaveOrOpenBlob:提供保存和打開按鈕 // window.navigator.msSaveOrOpenBlob(blobObject, 'msSaveBlobOrOpenBlob_testFile.txt'); </script> </html>
後端node
const http = require("http"); const fs = require("fs"); const server = http.createServer((req, res) => { if (req.url === "/download") { res.writeHead(200, { "Content-type": "application/vnd.ms-excel", // 返回 excel // 跨域設置 "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "content-type", }); // 異步讀取文件內容 這裡新建瞭一個test.xlsx的excel fs.readFile("test.xlsx", (err, data) => { // 返回二進制文件流 res.end(data); }); } }); server.listen(3000, () => { console.log("好厲害,3000的服務器起來瞭"); });
關於二進制文件流導出Excel文件的一些坑
實現下載效果
<el-button type="warning" icon="el-icon-download" size="mini" @click="download()">導出</el-button>
//下載操作 download() { return axios({ url: '/download/sms', method: 'post', data: this.queryForm, responseType: 'blob', headers: { 'Content-Type': 'application/json' } }) .then(res => { console.log(res, '返回數據列'); const blob = new Blob([res.data], { type: 'application/vnd.ms-excel' }); console.log(blob, '----------0990'); const fileName = '短信列表.xls'; const linkNode = document.createElement('a'); linkNode.download = fileName; //a標簽的download屬性規定下載文件的名稱 linkNode.style.display = 'none'; linkNode.href = URL.createObjectURL(blob); //生成一個Blob URL document.body.appendChild(linkNode); linkNode.click(); //模擬在按鈕上的一次鼠標單擊 URL.revokeObjectURL(linkNode.href); // 釋放URL 對象 document.body.removeChild(linkNode); }) .catch((err) => { console.log(err); }); return res; },
踩坑
1、剛開始看網上說需要axios原生才能請求,然後就引入瞭axios之後但是一直報錯,導致download的then代碼無法執行,直接走catch,輸出錯誤
研究瞭半天才發現是blob返回沒有code,也沒有message,而我在攔截器中直接設置瞭code的判斷攔截,所以導致請求一直報錯
2、在發送請求時必須要加上responseType: ‘blob’,不然導出的文件是亂碼格式的
3、在then裡面定義的blob new出來的數據需要再走一層,而不是直接輸出
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- vue中如何下載excel流文件及設置下載文件名
- vue導出excel文件流中文亂碼問題及解決
- 一文詳解如何根據後端返回的url下載json文件
- 一次在vue中使用post進行excel表下載的實戰記錄
- js實現下載(文件流式)方法詳解與完整實例源碼