“我想将从基于Spring的静态Web服务发送的.pdf文件下载到我的angular应用程序。如何下载它,我在我的angular应用程序或spring boot上缺少一些代码吗?”
我正在将来自Angular 6应用程序的HTTP GET请求发送到我的spring- boot服务器,该服务器会生成一个.pdf文件,然后将该.pdf文件作为blob发送给我,但是当我尝试在我的有角度的一侧创建blob时,打开pdf文件,它显示以下错误:
。错误错误:请求正文不是Blob或数组缓冲区
在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 Boot中:
控制器:
@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错误错误:Response.push ../ node_modules/@angular/http/fesm5/http.js.Body.blob(http.js:782)上的请求正文不是blob或数组缓冲区),位于SafeSubscriber.push的SafeSubscriber.push ../ node_modules / rxjs / _esm5 / internal / Subscriber.js.SafeSubscriber .__ tryOrUnsub(Subscriber.js:196)的SafeSubscriber._next(invoice- details.component.ts:212)。 ./node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.next(Subscriber.js:134)位于Subscriber.push ../ node_modules / rxjs / _esm5 / internal / Subscriber.js.Subscriber._next(Subscriber.js :77),位于MapSubscriber.push ../ node_modules / rxjs / _esm5 / internal / operators / map的Subscriber.push ../ node_modules / rxjs / _esm5 / internal / Subscriber.js.Subscriber.next(Subscriber.js:54)处MapSubscriber.push上的.js.MapSubscriber._next(map.js:41)。/node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next(Subscriber.js:54)在XMLHttpRequest.onLoad(http.js:1070)在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'}); }
我引用的网址: