【问题标题】:Open pdf from bytes array in angular 5从角度5的字节数组中打开pdf
【发布时间】:2018-10-19 23:40:02
【问题描述】:

我按照以下链接在我的 Angular 5 应用程序的新选项卡中显示 pdf 页面。但无法达到效果。

我正在使用来自 spring 控制器 api 的字节数组。

PDF Blob is not showing content, Angular 2

PDF Blob - Pop up window not showing content

Angular2 Displaying PDF

我尝试了以下选项,但没有一个有效。

试用 1

将响应作为 json 消费

组件.ts

clickEvent(){
this.service.getPDF().subscribe((response)=>{

  let file = new Blob([response.byteString], { type: 'application/pdf' });            
  var fileURL = URL.createObjectURL(file);
  window.open(fileURL);
})

}

service.ts

getPDF(){
const url = `${this.serviceUrl}/pdf`;

const httpOptions = {
  headers: new HttpHeaders(
    {
      'Accept': 'application/json',
      'responseType':'blob'
    }
  )
};

return this.http.get<any>(url, httpOptions);

}

试用 2

将响应作为 json 消费

组件.ts

clickEvent(){
this.service.getPDF().subscribe((response)=>{

  let file = new Blob([response.byteArray], { type: 'application/pdf' });            
  var fileURL = URL.createObjectURL(file);
  window.open(fileURL);
})

}

service.ts

getPDF(){
const url = `${this.serviceUrl}/pdf`;

const httpOptions = {
  headers: new HttpHeaders(
    {
      'Accept': 'application/json',
      'responseType':'arraybuffer'
    }
  )
};

return this.http.get<any>(url, httpOptions);

}

试用 3

将响应消耗为字节

组件.ts

clickEvent(){
this.service.getPDF().subscribe((response)=>{

  let file = new Blob([response], { type: 'application/pdf' });            
  var fileURL = URL.createObjectURL(file);
  window.open(fileURL);
})

}

service.ts

getPDF(){
const url = `${this.serviceUrl}/pdf`;

const httpOptions = {
  headers: new HttpHeaders(
    {
      'responseType':'blob'                 //both combination
      //'responseType'  : 'arraybuffer'
    }
  )
};

return this.http.get<any>(url, httpOptions);

}

通过所有的组合,我只得到两个结果。 空的 pdf 文档或无法加载 PDF 文档。

为了理解发布 java spring 控制器代码。

controller.java

@GetMapping(value = "/pdf")
public ResTest generatePDF(HttpServletResponse response) throws IOException {
    ResTest test = new ResTest();
    ByteArrayOutputStream baos = docTypeService.createPdf();
    test.setByteArray(baos.toByteArray());
    test.setByteString(new String(baos.toByteArray()));
    return test;
}

【问题讨论】:

    标签: java pdf angular5


    【解决方案1】:

    最后,我能够渲染 pdf。我这边有两个小错误。

    第一个问题是,我在 HttpHeaders 中给出了“responseType”,这是错误的。 它应该在外面,如下所示。

    第二个问题是,即使您提到 responseType : 'arraybuffer',它也无法接受。为此,您需要提及 responseType : 'arraybuffer' as 'json'.(Reference)

    下面的更正和工作代码。

    试用 3

    component.ts(不变)

    clickEvent(){
      this.service.getPDF().subscribe((response)=>{
    
      let file = new Blob([response], { type: 'application/pdf' });            
      var fileURL = URL.createObjectURL(file);
      window.open(fileURL);
    })
    

    service.ts

    getPDF(){
    const url = `${this.serviceUrl}/pdf`;
    
    const httpOptions = {
      'responseType'  : 'arraybuffer' as 'json'
       //'responseType'  : 'blob' as 'json'        //This also worked
    };
    
    return this.http.get<any>(url, httpOptions);
    
    }
    

    参考以下链接

    https://github.com/angular/angular/issues/18586

    【讨论】:

    • 你能帮忙解决这个问题吗stackoverflow.com/questions/63187758/…
    • 像魅力一样工作。第一次尝试:)
    • 太棒了,在 .NET 中,带有 IActionResult,我需要:return File(bytes, "application/pdf");而不是返回 Ok(bytes);
    【解决方案2】:

    我在角度和 pdf 显示方面遇到了同样的问题。我将描述我的解决方案 - 使用 base64 编码的字符串。所有现代浏览器都支持 base64。

    1. 使用import java.util.Base64 解码您的字节数组

      byte[] bytes = baos.toByteArray();
      
      String string = Base64.getEncoder().encodeToString(bytes);
      
      test.setByteString(string);
      
    2. 在前端对 pdf 使用标准 mime 类型,并表明您使用的是 base64 data:application/pdf;base64,

      参考。哑剧类型:https://en.wikipedia.org/wiki/Media_type

      如果您需要在新窗口中打开文档:

      let newPdfWindow = window.open("","Print");
      
      let content = encodeURIComponent(response.byteString);
      
      let iframeStart = "<\iframe width='100%' height='100%' src='data:application/pdf;base64, ";
      
      let iframeEnd = "'><\/iframe>";
      
      newPdfWindow.document.write(iframeStart + content + iframeEnd);
      
    3. 如果您需要在新标签页中打开,您可以简单地提供给您的html href:

      let pdfHref = this.sanitizer.bypassSecurityTrustUrl('data:application/octet-stream;base64,' + content);
      

      bypassSecurityTrustUrl 将清理您的网址。我记得角度安全存在一些问题,导致我看不到内容。

    PS。在检查它如何与 angular 一起工作之前,我想建议您将 pdf 文件存储在驱动器上并尝试打开它。我的意思是,你应该确定你的文件是有效的,你可以用简单的阅读器打开它。

    更新。最简单的解决方案是使用pdf.js库https://github.com/mozilla/pdf.js

    【讨论】:

    【解决方案3】:

    你有没有寻找一个角度组件来包装 pdf.js?

    示例用法:

    <pdf-viewer [src]="pdfSrc" 
        [render-text]="true"
        style="display: block;">
    </pdf-viewer>
    

    pdfSrc 可以是网址stringUInt8Array

    【讨论】:

      【解决方案4】:

      当您进行 AJAX 调用以获取 PDF/文件流时

      var req = this.getYourPDFRequest(fd);
          this.postData(environment.previewPDFRFR, req).then(res => {
            res.blob().then(blob => {
               const fileURL = URL.createObjectURL(blob);
              window.open(fileURL, '', 'height=650,width=840');
            })
          });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-03-27
        • 1970-01-01
        • 2018-11-11
        • 1970-01-01
        • 2018-08-23
        • 2016-06-25
        • 1970-01-01
        相关资源
        最近更新 更多