我尝试从 api 返回的 HttpResponseMessage 下载 xlsx 文件,但下载后打开 xlsx 文件时出现错误。
错误:Excel 无法打开文件“文件名”,因为文件格式或文件扩展名无效。
我的 AngularJS 代码
public downloadFile(url: string): ng.IPromise<any> {
return fetch(url).then((data => {
let filename: string = this.getFileName(data);
let binaryData = [];
binaryData.push(data);
let downloadLink = document.createElement('a');
downloadLink.href = window.URL.createObjectURL(new Blob(binaryData, { type: 'application/vnd.ms-excel' }));
downloadLink.setAttribute('download', filename);
document.body.appendChild(downloadLink);
downloadLink.click();
}));
}
我的C#代码:
HttpResponseMessage response = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
response.Content = new ByteArrayContent(byteArray);
response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
response.Content.Headers.ContentDisposition.FileName = FileName;
response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(mediaTypeHeader);
response.Content.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");
return response;
AngularJS 代码:
public downloadFile(url: string): ng.IPromise<any> {
return fetch(url)
.then(response => {
return response.blob();
})
.then(blob => {
let filename: string = 'file.xlsx'; // Change this to your desired file name
let downloadLink = document.createElement('a');
downloadLink.href = window.URL.createObjectURL(blob);
downloadLink.setAttribute('download', filename);
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink); // Clean up after download
});
}
C#代码:
内容类型为“application/vnd.ms-excel”,这可能不适合 xlsx 文件。您可能需要将其设置为“application/vnd.openxmlformats-officedocument.spreadsheetml.sheet”,这是 xlsx 文件的适当 MIME 类型。
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = new ByteArrayContent(byteArray);
response.Content.Headers.ContentDisposition = new
System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
response.Content.Headers.ContentDisposition.FileName = FileName;
response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.Content.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");
return response;
有时在后端一切正常,你可以编写和阅读工作簿
后端:
byte[] excelBytes = generarExcel(productos);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"));
headers.setContentDispositionFormData("filename", "productos.xlsx");
return new ResponseEntity<>(excelBytes, headers, HttpStatus.OK);
但问题是前端缺少一些东西,你需要有一个 responseType: 'arraybuffer' 所以:
前端:
$http({ method: 'GET',
url: 'http://tu-servidor/productos/excel',
responseType: 'arraybuffer'
})
.then(function(response) {
var blob = new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
var objectUrl = URL.createObjectURL(blob);
var a = document.createElement('a');
a.href = objectUrl;
a.download = 'filename.xlsx';
document.body.appendChild(a);
a.click();
window.setTimeout(function() {
URL.revokeObjectURL(objectUrl);
document.body.removeChild(a);
}, 100);
})