一、使用场景
前端调用后端接口,基于携带的参数下载一个特定的EXCEL模版。
由于后端返回的是二进制数据ArrayBuffer
,前端基于后端返回的ArrayBuffer
,创建a
链接点击下载;如果返回的ArrayBuffer
二进制数据是错误的,那么下载后的excel表格为错误的。
如何拦截错误的二进制文件避免下载呢?
废话不说直接上代码
二、下载规则详情EXCEL模版接口
export const getRuleTemplate = (
params: IGetRuleTemplateParam
): Promise<ArrayBuffer> => {
return axios.get('/logistics/api/download/ruleTemplate', {
params,
responseType: 'arraybuffer',
}) as any
}
三、页面调用接口
// 下载模板
async tempAddress({ callBack }: { callBack: () => void }) {
const params: IGetRuleTemplateParam = {
freight_rule_id: this.currentRow.id,
companyId: this.ruleDetail.company_id,
freight_rule_calculate_type: Number(this.computeValue),
freight_zone_id: this.ruleDetail.freight_zone_id,
}
try {
const res = await getRuleTemplate(params)
const fileReader = new FileReader()
fileReader.readAsText(new Blob([res]))
fileReader.onload = (evt) => {
const result = evt.target?.result as string
try {
// 错误下载
const obj = JSON.parse(result)
this.$message.error(obj.msg)
callBack()
} catch (error) {
// 正确下载
this.createBlobForDownload(res)
callBack()
}
}
} catch (error) {
this.$message.error(JSON.stringify(error))
}
}
private createBlobForDownload(blobParts: BlobPart) {
const blob = new Blob([blobParts], { type: 'application/xlsx' })
const link = document.createElement('a')
link.href = window.URL.createObjectURL(blob)
link.download = `${this.ruleDetail.rule_name || '模版文件'}.xlsx`
link.click()
}
四、总结
- 后端返回的二进制数据ArrayBuffer,通过FileReader进行本地读取。
如果二进制数据为错误的数据时,可以解析为对象{code: 0, msg: '错误的原因'};而正确的二进制数据无法解析为正确的对象,进而走catch代码块,正常下载。利用了这个小技巧!
哈哈哈
FileReader
对象允许 Web 应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用File
或Blob
对象指定要读取的文件或数据。