我有一个按钮定义为:
<button pButton type="button" label="Download" data-icon="fa-cloud-download" (click)="download()"></button>
Run Code Online (Sandbox Code Playgroud)
其中download方法委托给服务,并且服务调用与后法的API:
download(model:GlobalModel) {
let downloadURL = base + "rest/process/download";
let body = JSON.stringify(model);
let headers = new Headers({'Content-Type': 'application/json'});
let options = new RequestOptions({headers: headers});
this.http.post('http://localhost:48080/rest/process/download', body, options)
.toPromise()
.then(
response => {
console.log(response);
var mediaType = 'application/zip';
var blob = new Blob([response.blob()], {type: mediaType});
var filename = 'project.zip';
saveAs(blob, filename);//FileSaver.js libray
});
}
Run Code Online (Sandbox Code Playgroud)
但到目前为止,该blob()方法尚未实现,并且还有其他答案,_body但有一个打字稿错误,如"_body is private".
浏览器显示下载窗口,但是当我下载文件已损坏且无法打开时(我检查postman并且文件从服务器生成正常).
我怎样才能正确下载文件?...如果不可能,有可用的解决方法吗?
这是一个简单的工作示例 /sf/answers/3009466421/
将控制器修改为POST:
[HttpPost("realisationsFilterExcel")]
public FileResult exportExcell([FromBody] FilterRealisation filter)
{
var contentType = "application/octet-stream";
HttpContext.Response.ContentType = contentType;
PaginationSet<RealisationReportViewModel> itemsPage = _realisationRepository.GetRealisationReportFilter(filter, User);
RealisationsReportExcell reportExcell = new RealisationsReportExcell();
var filedata = reportExcell.GetReport(itemsPage);
FileContentResult result = new FileContentResult(filedata, contentType)
{
FileDownloadName = "report.xlsx"
};
return result;
}
Run Code Online (Sandbox Code Playgroud)
需要FileSaver作为dep:
npm install file-saver --save
npm install @types/file-saver --save
Run Code Online (Sandbox Code Playgroud)
将方法DownloadComponent angular2修改为POST
@Input() filter: any;
public downloadFilePost() {
this.http.post(this.api, this.filter, { responseType: ResponseContentType.Blob })
.subscribe(
(response: any) => {
let blob = response.blob();
let filename = 'report.xlsx';
FileSaver.saveAs(blob, filename);
});
}
Run Code Online (Sandbox Code Playgroud)
运用
<download-btn [filter]="myFilter" api="api/realisations/realisationsFilterExcel"></download-btn>
Run Code Online (Sandbox Code Playgroud)
我终于使用答案中解释的技巧解决了:/sf/answers/2593595581/
在这里我描述一下我的特殊方法,以防万一:
download(model:GlobalModel) {
// Xhr creates new context so we need to create reference to this
let self = this;
var pending:boolean = true;
// Create the Xhr request object
let xhr = new XMLHttpRequest();
let url = BASE + "/download";
xhr.open('POST', url, true);
xhr.setRequestHeader("Content-type", "application/json");
xhr.responseType = 'blob';
// Xhr callback when we get a result back
// We are not using arrow function because we need the 'this' context
xhr.onreadystatechange = function () {
// We use setTimeout to trigger change detection in Zones
setTimeout(() => {
pending = false;
}, 0);
// If we get an HTTP status OK (200), save the file using fileSaver
if (xhr.readyState === 4 && xhr.status === 200) {
var blob = new Blob([this.response], {type: 'application/zip'});
saveAs(blob, 'project.zip');
}
};
// Start the Ajax request
xhr.send(JSON.stringify(model));
}
Run Code Online (Sandbox Code Playgroud)
http不幸的是,目前angular2对象还不完整,这个解决方案虽然有用,但感觉很糟糕。
| 归档时间: |
|
| 查看次数: |
20739 次 |
| 最近记录: |