问题描述
我在前端下载 excel 文件时遇到了一些困难,我通过 API 响应获得了该文件,我正在向 Flask 后端发送该文件。
这是我目前所拥有的:
Flask(后端)
...
generator.generate_excel_report()
return send_file(
generator.get_excel_report(),# returns location to generated file
mimetype=sc.CONTENT_TYPE_EXCEL,# application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
as_attachment=True
)
...
我已经通过 Postman 测试了这是否有效,从那里我可以下载这个 excel 报告,一切似乎都没有问题。
Vue.JS(前端)
这里,我向 Flask 后端发出请求,它返回正文中的文件:
/**
* Download Excel version of the report
*/
downloadExcelReport(data) {
SERVICE.post(
`/api/v1/project/${this.projectNumber}/${this.variantName}/${this.buildNumber}/report/excel`,{
responseType: 'arraybuffer'
}).then((response) => getExcelReport(response.data))
},
还有这里的 getExcelReport 函数:
/**
* Make a POST request to the back-end that will generate an Excel sheet
* for the project,and return it.
*/
export function getExcelReport(data) {
const blob = new Blob([data],{ // Make a BLOB object
type : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
});
download(blob,"ExcelReport",'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') // use the DownloadJS library and download the file
}
当我尝试打开生成的 Excel 报告时,它说文件已损坏。我还可以看到字节数要大得多(大约两倍)。
我也用 FileReader 尝试过 StackOverflow 的类似解决方案。有没有其他人知道我在这里做错了什么?
解决方法
我通过以下方式解决了这个问题:
/**
* Download Excel version of the report
*/
downloadExcelReport() {
const fileName = `${this.projectNumber}_${this.variantName}_#${this.buildNumber}_SWF.xlsx`
const apiEndpoint = `/api/v1/project/${this.projectNumber}/${this.variantName}/${this.buildNumber}/report/excel`
const headers = {
'Content-Disposition': `attachment; filename=${fileName}`,'Content-Type':
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',}
SERVICE.post(apiEndpoint,null,{
headers: headers,responseType: 'arraybuffer',})
.then((response) => {
const url = window.URL.createObjectURL(new Blob([response.data]))
const link = document.createElement('a')
link.href = url
link.setAttribute('download',fileName)
document.body.appendChild(link)
link.click()
})
.catch((error) => console.log(error))
},