vue如何實(shí)現(xiàn)二進(jìn)制流文件導(dǎo)出excel
vue二進(jìn)制流文件導(dǎo)出excel
問(wèn)了一下其他的后端,他們公司前端是a標(biāo)簽,后端是給了一個(gè)地址,a標(biāo)簽或者window.open()都可以實(shí)現(xiàn)。
我們公司是后端返回的二進(jìn)制流文件,實(shí)現(xiàn)了一下,親測(cè)可以,沒(méi)有問(wèn)題
前端代碼
<!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了,函數(shù)中已經(jīng)封裝了 createExcel(res.data, name) //這里就直接這樣調(diào)用方法就行了 }); } // vue中可以寫(xiě)方法 然后再暴露出去 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() //釋放內(nèi)存 window.URL.revokeObjectURL(link.href) } } // 1.msSaveBlob:只提供一個(gè)保存按鈕 //window.navigator.msSaveBlob(blobObject, 'msSaveBlob_testFile.txt'); // 2.msSaveOrOpenBlob:提供保存和打開(kāi)按鈕 // 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 // 跨域設(shè)置 "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "content-type", }); // 異步讀取文件內(nèi)容 這里新建了一個(gè)test.xlsx的excel fs.readFile("test.xlsx", (err, data) => { // 返回二進(jìn)制文件流 res.end(data); }); } }); server.listen(3000, () => { console.log("好厲害,3000的服務(wù)器起來(lái)了"); });
關(guān)于二進(jìn)制文件流導(dǎo)出Excel文件的一些坑
實(shí)現(xiàn)下載效果
<el-button type="warning" icon="el-icon-download" size="mini" @click="download()">導(dǎo)出</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, '返回?cái)?shù)據(jù)列'); 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標(biāo)簽的download屬性規(guī)定下載文件的名稱 linkNode.style.display = 'none'; linkNode.href = URL.createObjectURL(blob); //生成一個(gè)Blob URL document.body.appendChild(linkNode); linkNode.click(); //模擬在按鈕上的一次鼠標(biāo)單擊 URL.revokeObjectURL(linkNode.href); // 釋放URL 對(duì)象 document.body.removeChild(linkNode); }) .catch((err) => { console.log(err); }); return res; },
踩坑
1、剛開(kāi)始看網(wǎng)上說(shuō)需要axios原生才能請(qǐng)求,然后就引入了axios之后但是一直報(bào)錯(cuò),導(dǎo)致download的then代碼無(wú)法執(zhí)行,直接走catch,輸出錯(cuò)誤
研究了半天才發(fā)現(xiàn)是blob返回沒(méi)有code,也沒(méi)有message,而我在攔截器中直接設(shè)置了code的判斷攔截,所以導(dǎo)致請(qǐng)求一直報(bào)錯(cuò)
2、在發(fā)送請(qǐng)求時(shí)必須要加上responseType: ‘blob’,不然導(dǎo)出的文件是亂碼格式的
3、在then里面定義的blob new出來(lái)的數(shù)據(jù)需要再走一層,而不是直接輸出
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue-router鉤子函數(shù)實(shí)現(xiàn)路由守衛(wèi)
這篇文章主要介紹了vue-router鉤子函數(shù)實(shí)現(xiàn)路由守衛(wèi),對(duì)vue感興趣的同學(xué),可以參考下2021-04-04vue-cropper插件實(shí)現(xiàn)圖片截取上傳組件封裝
這篇文章主要為大家詳細(xì)介紹了vue-cropper插件實(shí)現(xiàn)圖片截取上傳組件封裝,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-05-05vue實(shí)現(xiàn)把頁(yè)面導(dǎo)出成word文件的方法
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)把頁(yè)面導(dǎo)出成word文件的方法,文中的實(shí)現(xiàn)步驟講解詳細(xì),并且有詳細(xì)的代碼示例,需要的小伙伴可以參考一下2023-10-10使用Vue.set()方法實(shí)現(xiàn)響應(yīng)式修改數(shù)組數(shù)據(jù)步驟
今天小編就為大家分享一篇使用Vue.set()方法實(shí)現(xiàn)響應(yīng)式修改數(shù)組數(shù)據(jù)步驟,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-11-11Vue.js中的extend綁定節(jié)點(diǎn)并顯示的方法
在本篇內(nèi)容里小編給大家整理了關(guān)于Vue.js中的extend綁定節(jié)點(diǎn)并顯示的方法以及相關(guān)知識(shí)點(diǎn),需要的朋友們學(xué)習(xí)下。2019-06-06vue.js通過(guò)路由實(shí)現(xiàn)經(jīng)典的三欄布局實(shí)例代碼
本文通過(guò)實(shí)例代碼給大家介紹了vue.js通過(guò)路由實(shí)現(xiàn)經(jīng)典的三欄布局,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2018-07-07element-plus 下拉框?qū)崿F(xiàn)全選的示例代碼
本文主要介紹了element-plus 下拉框?qū)崿F(xiàn)全選的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05echarts3如何清空上一次加載的series數(shù)據(jù)
這篇文章主要介紹了echarts3如何清空上一次加載的series數(shù)據(jù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10