【问题标题】:How to download PDF file in angular generated by Springboot at runtime?如何在运行时以 Springboot 生成的角度下载 PDF 文件?
【发布时间】:2020-07-06 12:24:25
【问题描述】:

我正在尝试在 Springboot 服务中下载运行时生成的 PDF 文件(使用 iTextPDF 生成的 PDF),并希望通过 Angular 6.0 在新选项卡中打开该文件。 我尝试关注此How to download a pdf file in angular which is generated on my server(springboot)?,但收到错误为“无法加载 PDF 文档”。 代码有什么问题?

角度组件:

this.service.PrintPDF(this.quotations).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);
    }
  );

角度服务:

PrintPDF(quotations: Quotation[]) {

        let url = this.PDF_URL;
        var authorization = 'Bearer ' + sessionStorage.getItem("key");

        const headers = new HttpHeaders({
            'Content-Type': 'application/json',
            responseType: 'blob',
            "Authorization": authorization
        });

        return this.http.post<Blob>(url, quotations, {
            headers: headers, responseType:'blob' as 'json'}).pipe(map(
            (response) => {
                return response;
            },
            (error) => {console.log(error.json());}
        ));

Springboot 控制器:

@PostMapping(value = "/generatepdf")
    public void downloadFile(@RequestBody List<QuotationDTO> quotationDTOs, HttpServletRequest request, HttpServletResponse response) {

        try {
            quotationService.GeneratePDF(quotationDTOs, request, response);
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

Springboot 服务:

public String  GeneratePDF(java.util.List<QuotationDTO> quotationDTOs, HttpServletRequest request,
                           HttpServletResponse response) throws DocumentException, IOException {

        response.setContentType("application/blob");

        // Response header
        response.setHeader("Pragma", "public");
        response.setHeader("responseType", "blob");
        response.setHeader("Content-Disposition", "attachment; filename=\"" + "Quotation" + "\"");
//        OutputStream os = response.getOutputStream();

        Document document = new Document(PageSize.A4, 50, 50, 5 , 5);
        String current = sdf.format(new Timestamp(System.currentTimeMillis())).toString();
        String reportName = "report"+current;

        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(<Path>));
        document.open();
        // Write Content
        document.close();
        PdfWriter.getInstance(document, response.getOutputStream());

        return reportName+".pdf";
    }

【问题讨论】:

    标签: angular spring-boot


    【解决方案1】:

    我找到了解决问题的方法。我试图从内存中发送 PDF。现在在一个位置创建 pdf 并从该位置发送读取它。 不确定 iTextPDF 是否支持内存 pdf 创建。

    Springboot 服务:

    public Resource GeneratePDF(java.util.List<QuotationDTO> quotationDTOs, HttpServletRequest request)
            throws DocumentException, IOException {
        Document document = new Document(PageSize.A4, 50, 50, 5 , 5);
        String current = sdf.format(new Timestamp(System.currentTimeMillis())).toString();
        String reportName = "report"+current;
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("PATH"));
        document.open();
        //Write PDF
        document.close();
        try {
            Path filePath = this.fileStorageLocation.resolve(reportName+".pdf").normalize();
            Resource resource = new UrlResource(filePath.toUri());
            if (resource.exists()) {
                return resource;
            } else {
                throw new MyFileNotFoundException("File not found " + reportName+".pdf");
            }
        } catch (MalformedURLException ex) {
            throw new MyFileNotFoundException("File not found " + reportName+".pdf", ex);
        }
    }
    

    Springboot 控制器:

    @PostMapping(value = "/generatepdf")
    public ResponseEntity<Resource> downloadFile(@RequestBody List<QuotationDTO> quotationDTOs, HttpServletRequest request) {
    
        try {
            Resource resource = quotationService.GeneratePDF(quotationDTOs, request);
            String contentType = null;
            try {
                contentType = request.getServletContext().getMimeType(resource.getFile().getAbsolutePath());
            } catch (IOException ex) {
            }
            // Fallback to the default content type if type could not be determined
            if(contentType == null) {
                contentType = "application/octet-stream";
            }
            return ResponseEntity.ok()
                    .contentType(MediaType.parseMediaType(contentType))
                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
                    .body(resource);
    
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
    

    角度服务:

    PrintPDF(quotations: Quotation[]) {
        let url = this.PDF_URL;
        var authorization = 'Bearer ' + sessionStorage.getItem("key");
        let headerOptions = new HttpHeaders({
            'Content-Type': 'application/json',
            'Accept': 'application/pdf',
            "Authorization": authorization
            //   'Accept': 'application/octet-stream', // for excel file
        });
        let requestOptions = { headers: headerOptions, responseType: 'blob' as 'blob' };
        this.http.post(url, quotations, requestOptions).pipe(map((data: any) => {
            let blob = new Blob([data], {
                type: 'application/pdf' // must match the Accept type
                // type: 'application/octet-stream' // for excel 
            });
            var link = document.createElement('a');
            link.href = window.URL.createObjectURL(blob);
            // link.download = 'samplePDFFile.pdf';
            link.target = '_blank';
            link.click();
            window.URL.revokeObjectURL(link.href);
    
        })).subscribe((result: any) => {
        });
    }
    

    Angular 组件只是调用 Angular 服务

    【讨论】:

      猜你喜欢
      • 2019-12-21
      • 1970-01-01
      • 2021-07-03
      • 1970-01-01
      • 2018-07-10
      • 2020-01-20
      • 2021-07-13
      • 2013-04-02
      相关资源
      最近更新 更多