一. 需求
后臺(tái)管理系統(tǒng),常會(huì)出現(xiàn)導(dǎo)出excel表格功能;點(diǎn)擊導(dǎo)出按鈕,請(qǐng)求后端接口,需要將接口返回的文件流
導(dǎo)出為excel,實(shí)現(xiàn)前端下載excel文件。
但是,返回的數(shù)據(jù)獲取 response 時(shí)出現(xiàn)亂碼,如圖:
二. 實(shí)現(xiàn)思路
- 調(diào)用后端下載接口,獲取傳遞過(guò)來(lái)的二進(jìn)制數(shù)據(jù)流
- 創(chuàng)建
<a>
標(biāo)簽 - 創(chuàng)建下載鏈接;將Blob對(duì)象轉(zhuǎn)化為一個(gè)URL資源地址,這個(gè)地址是一個(gè)本地地址
- 將a標(biāo)簽添加到body中
- 添加點(diǎn)擊事件,進(jìn)行下載
- 下載完成后移除a標(biāo)簽
三. 了解概念
在寫代碼之前,先來(lái)了解幾個(gè)概念。當(dāng)然也可以跳過(guò)這部分,直接看代碼。
1)responseType
responseType 的作用就是設(shè)置ajax數(shù)據(jù)響應(yīng)的類型,你告訴服務(wù)器,讓服務(wù)器返回什么樣的數(shù)據(jù)類型給你
服務(wù)器響應(yīng)的數(shù)據(jù)類型,可以是 arraybuffer
, blob
, document
, json
, text
, stream
,默認(rèn)是’json’
2)Blob() 構(gòu)造函數(shù)
Blob() 構(gòu)造函數(shù)文檔
Blob() 構(gòu)造函數(shù)返回一個(gè)新的 Blob 對(duì)象
,blob 的內(nèi)容由參數(shù)數(shù)組中給出的值的串聯(lián)組成。(通俗點(diǎn)說(shuō),Blob對(duì)象可以看做是一個(gè)存儲(chǔ)二進(jìn)制數(shù)據(jù)的容器
)
語(yǔ)法:
var aBlob = new Blob( array, options );
參數(shù):
- array 是一個(gè)由ArrayBuffer, ArrayBufferView, Blob, DOMString 等對(duì)象構(gòu)成的
Array
,或者其他類似對(duì)象的混合體,它將會(huì)被放進(jìn) Blob。 - options 是一個(gè)可選的,它可能會(huì)指定如下兩個(gè)屬性:
1)type
,默認(rèn)值為 “”,它代表了將會(huì)被放入到 blob 中的數(shù)組內(nèi)容的 MIME 類型。比如:type: ‘a(chǎn)pplication/x-excel’ 或 type: ‘text/plain’
2)endings
,默認(rèn)值為"transparent",用于指定包含行結(jié)束符\n的字符串如何被寫入。它是以下兩個(gè)值中的一個(gè):“native”,代表行結(jié)束符會(huì)被更改為適合宿主操作系統(tǒng)文件系統(tǒng)的換行符,或者 “transparent”,代表會(huì)保持 blob 中保存的結(jié)束符不變 非標(biāo)準(zhǔn)
示例:
var aFileParts = ['<a id="a"><b id="b">hey!</b></a>']; // 一個(gè)包含 DOMString 的數(shù)組
var MyBlob = new Blob(aFileParts, {type : 'text/html'}); // 得到 blob對(duì)象
console.log(MyBlob, 'MyBlob')
打印結(jié)果:
3)URL.createObjectURL()
官方文檔介紹 URL.createObjectURL()
通過(guò)創(chuàng)建URL對(duì)象指定文件的下載鏈接。
語(yǔ)法:
objectURL = URL.createObjectURL(object);
//參數(shù)object:用于創(chuàng)建 URL 的 File 對(duì)象、Blob 對(duì)象或者 MediaSource 對(duì)象。?
//返回值:包含了一個(gè)對(duì)象 URL,該 URL 可用于指定源 object的內(nèi)容。
示例:
const aFileParts = ['<a id="a"><b id="b">hey!</b></a>'] // 一個(gè)包含 DOMString 的數(shù)組
const MyBlob = new Blob(aFileParts, { type: 'text/html' }) // 得到 blob
const objectURL = window.URL.createObjectURL(MyBlob) // 創(chuàng)建新的URL表示指定的File對(duì)象或者Blob對(duì)象。
console.log(objectURL, 'objectURL')
window.URL.revokeObjectURL(objectURL); // 釋放內(nèi)存
打印結(jié)果:
注意內(nèi)存管理
在每次調(diào)用 createObjectURL() 方法時(shí),都會(huì)創(chuàng)建一個(gè)新的 URL 對(duì)象,即使你已經(jīng)用相同的對(duì)象作為參數(shù)創(chuàng)建過(guò)。當(dāng)不再需要這些 URL 對(duì)象時(shí),每個(gè)對(duì)象必須通過(guò)調(diào)用
URL.revokeObjectURL()
方法來(lái)釋放。
瀏覽器在 document 卸載的時(shí)候,會(huì)自動(dòng)釋放它們,但是為了獲得最佳性能和內(nèi)存使用狀況,你應(yīng)該在安全的時(shí)機(jī)主動(dòng)釋放掉它們。
四. 代碼實(shí)現(xiàn)
在src/utils下新建tool.js(代碼如下),封裝成一個(gè)方法暴露出去,方便其他頁(yè)面調(diào)用。
import XEUtils from 'xe-utils'
export function exportCsv(csv:any, title:string) {
const t = XEUtils.toDateString(Date.now(), 'yyyy-MM-dd') // 當(dāng)前日期
const filename = `${t + title}.csv` // 拼接文件名
const blob = new Blob([csv]) //創(chuàng)建一個(gè)新的 Blob 對(duì)象
const url = window.URL.createObjectURL(blob) // 把一個(gè)blob對(duì)象轉(zhuǎn)化為一個(gè)Blob URL,創(chuàng)建下載鏈接
const downloadLink = document.createElement('a') // 生成一個(gè)a標(biāo)簽
downloadLink.href = url
downloadLink.download = filename // // dowload屬性指定下載后文件名
document.body.appendChild(downloadLink) //將a標(biāo)簽添加到body中
downloadLink.click() // 點(diǎn)擊下載
document.body.removeChild(downloadLink) // 下載完成后移除元素
window.URL.revokeObjectURL(url); // 釋放掉blob對(duì)象
}
其次就是 調(diào)用接口了
在調(diào)用接口 封裝了 axios
所以 在請(qǐng)求后臺(tái)接口時(shí),要在請(qǐng)求頭上要注意加上 responseType: 'blob'
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-451123.html
import request from '@/request/http.ts'
GETMONEYLISTDOWN({ // 資金記錄導(dǎo)出接口
page = 0,
size = 10,
}) {
return request({
method: 'post',
responseType: 'blob', //注意 需要規(guī)定后臺(tái)返回文件流格式
data: Object.assign(
{
page,
pagesize: size,
method: 'Money.Moneylist'
},
tokenQuery()
)
})
},
// 頁(yè)面調(diào)用
import { exportCsv } from '@/utils/tool.ts'
function downLoad(e) {
tableLoading.value = true
const params = Object.assign(apiParams, e)
moneyApi.GETMONEYLISTDOWN(Object.assign({}, params)).then(res => {
// 傳入二進(jìn)制流data和文件名
exportCsv(res.data, '資金記錄')
tableLoading.value = false
}).catch(error => {
tableLoading.value = false
console.log(error)
})
}
可參考:
excel導(dǎo)出-將后端返回的文件流導(dǎo)出為excel文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-451123.html
到了這里,關(guān)于js將后端返回的文件流導(dǎo)出為excel,并自定義下載文件名的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!