从API响应(Vue.JS -前端,flask -后端)下载excel文件



我在前端下载excel文件时遇到了一些困难,我通过API响应获得,这是我对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
)
...

我已经测试过,这是通过邮差,从那里我可以下载这个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报告时,它说文件已损坏。我还可以看到字节数要大得多(大约大两倍)。

我也尝试过类似的解决方案从StackOverflow与FileReader。还有人知道我哪里做错了吗?

我用以下方法解决了这个问题:

/**
* 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))
},

最新更新