“我想下载一个 .pdf 文件,该文件从基于 spring 的 restful web 服务发送到我的 angular 应用程序。如何下载它,我的 angular 应用程序或 spring boot 上是否缺少一些代码?”
我正在从 Angular 6 应用程序向我的 spring-boot 服务器发送一个 HTTP GET 请求,该服务器会生成一个 .pdf 文件,然后将此 .pdf 文件作为 blob 发送给我, 但是当我尝试在我的 Angular 侧创建一个 blob 并打开 pdf 时,它显示以下错误:
。 ERROR 错误:请求正文既不是 blob 也不是数组缓冲区
我访问了 StackOverflow 上的以下问题,以找到一些解决方案: 1. PDF Blob is not showing content, Angular 2 2. How can I get access to the Angular 2 http response body without converting it to string or json? 3. converting byte stream in HTTPResponse body into a pdf file 4. Send File with SpringBoot to Angular2
在 Angular 应用中: 组件:
服务:getPDF(){ this.apiService.getPDF(this.invoiceId) .subscribe( (data) => { //data.blob() doesnt work properly var file = new Blob([data.blob()], { type: 'application/pdf' }) var fileURL = URL.createObjectURL(file); window.open(fileURL); // if you want to open it in new tab var a = document.createElement('a'); a.href = fileURL; a.target = '_blank'; a.download = 'bill.pdf'; document.body.appendChild(a); a.click(); }, (error) => { console.log('getPDF error: ',error); } ); }
getPDF(invoiceId : number) { this.url = this.main_url + '/invoices/generatepdf/'+invoiceId; const headers = new Headers({ 'Content-Type': 'application/json', "Authorization": authorization, responseType : 'blob'}); return this.http.get(this.url, { headers : headers}) .pipe(map( (response) => { return response; }, (error) => { console.log(error.json()); } )); }
在 Spring 启动中:
Controller :
@RestController @RequestMapping("/invoices") public class InvoiceController { @Autowired InvoiceService invoiceService; @GetMapping(path = "/generatepdf/{invoiceId}") public void generateInvoicePdf(@PathVariable Integer invoiceId, HttpServletRequest request,HttpServletResponse response) { invoiceService.generateInvoicePdf(invoiceId, request, response); }
服务实现:
@Override public String generateInvoicePdf(Integer invoiceId, HttpServletRequest request, HttpServletResponse response) { //createPDF() will create a .pdf file createPDF(pdfFilename, dto, dtoForSupplier); if (pdfFilename != null) { try { File file = new File(pdfFilename); FileInputStream is = new FileInputStream(file); response.setContentType("application/blob"); // Response header response.setHeader("Pragma", "public"); response.setHeader("responseType", "blob"); response.setHeader("Content-Disposition", "attachment; filename=\"" + pdfFilename + "\""); // Read from the file and write into the response OutputStream os = response.getOutputStream(); System.out.println(os); byte[] buffer = new byte[(int) file.length()]; int len; while ((len = is.read(buffer)) != -1) { os.write(buffer, 0, len); } System.out.println(os); os.flush(); os.close(); is.close(); } catch (IOException e) { e.printStackTrace(); } } return pdfFilename; }
我希望在浏览器中下载一个 .pdf 文件并打开它并查看其内容,但我得到了错误:
core.js:15724 ERROR Error: The request body isn't either a blob or an array buffer at Response.push../node_modules/@angular/http/fesm5/http.js.Body.blob (http.js:782) at SafeSubscriber._next (invoice-details.component.ts:212) at SafeSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.__tryOrUnsub (Subscriber.js:196) at SafeSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.next (Subscriber.js:134) at Subscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber._next (Subscriber.js:77) at Subscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (Subscriber.js:54) at MapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/map.js.MapSubscriber._next (map.js:41) at MapSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (Subscriber.js:54) at XMLHttpRequest.onLoad (http.js:1070) at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)>
最佳答案
按照@JBNizet 的建议,我实现了如下可观察对象:
组件:
getPDF(){
this.apiService.getPDF(this.invoiceId)
.subscribe(
(data: Blob) => {
var file = new Blob([data], { type: 'application/pdf' })
var fileURL = URL.createObjectURL(file);
// if you want to open PDF in new tab
window.open(fileURL);
var a = document.createElement('a');
a.href = fileURL;
a.target = '_blank';
a.download = 'bill.pdf';
document.body.appendChild(a);
a.click();
},
(error) => {
console.log('getPDF error: ',error);
}
);
}
服务:
getPDF(invoiceId : number): Observable<Blob>
{
this.url = this.main_url + '/invoices/generatepdf/'+invoiceId;
var authorization = 'Bearer '+sessionStorage.getItem("access_token");
const headers = new HttpHeaders({ 'Content-Type': 'application/json',
"Authorization": authorization, responseType : 'blob'});
return this.httpClient.get<Blob>(this.url, { headers : headers,responseType :
'blob' as 'json'});
}
我引用的 URL:
关于angular - 如何下载我的服务器(springboot)上生成的 Angular pdf文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57497402/