参考:
1.第一步,优化ajax.js
getDownLoad(pageContext, url, param) { var config = axiosProvider.getconfig(pageContext) config.params = param var req = _ajaxRemote.post( url, Object.assign({ responseType: 'blob' }, config) ) return this.downloadBase(req) }, postDownLoad(pageContext, url, data, param) { var config = axiosProvider.getconfig(pageContext) config.params = param var req = _ajaxRemote.post( url, data, Object.assign({ responseType: 'blob' }, config) ) return this.downloadBase(req) }, downloadBase(req) { return new Promise((resolve, reject) => { req .then((res) => { console.log('req.THEN') if (!res) { this.$message.error('下载模板文件失败') return false } const blob = new Blob([res.result], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8', }) const downloadElement = document.createElement('a') const href = window.URL.createObjectURL(blob) //从response的headers中获取filename, 后端response.setHeader("Content-disposition", "attachment; filename=xxxx.docx") 设置的文件名; let contentDisposition = res.headers['content-disposition'] let patt = new RegExp('filename=([^;]+\.[^\.;]+);*') let result = patt.exec(contentDisposition) let filename = decodeURI(result[1]) // let filename = '模块配置.json'; downloadElement.style.display = 'none' downloadElement.href = href downloadElement.download = filename //下载后文件名 document.body.appendChild(downloadElement) downloadElement.click() //点击下载 document.body.removeChild(downloadElement) //下载完成移除元素 window.URL.revokeObjectURL(href) //释放掉blob对象 resolve() }) .catch(() => { reject() }) }) },
2.第二部,后台实现
注意ms.position=0这句话要有,不然返回会报错
如果不添加Access-Control-Expose-Headers的话,Content-Disposition前台会无法获取
也可以直接使用byte[]来返回
代码:
public async Task<IActionResult> export(List<string> rowIDs) { var str = Newtonsoft.Json.JsonConvert.SerializeObject(data); byte[] bytes = Encoding.UTF8.GetBytes(str); //new Microsoft.AspNetCore.StaticFiles.FileExtensionContentTypeProvider().Mappings.TryGetValue(".json", out var contenttype); System.Net.Mime.ContentDisposition cd = new System.Net.Mime.ContentDisposition() { FileName = HttpUtility.UrlEncode("模块配置.json"), Inline = false }; Response.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition"); Response.Headers.Add("Content-Disposition", cd.ToString()); var v = File(bytes, "application/octet-stream"); return v; }
3. 前台实现
由于axios进行了封装,重构了res.data
所以这里Blob的时候有所出入
ajax.postDownLoad(this, "/Module/export", rows) .then(() => { component.loading = false; })
注意如果后台没有在Header中添加Access-Control-Expose-Headers的话,这里res.headers['content-disposition']会无法获取