Java 从角度为 5 的字节数组中打开 pdf

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/50260391/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 23:32:02  来源:igfitidea点击:

Open pdf from bytes array in angular 5

javapdfangular5

提问by MPPNBD

I was following the below links for displaying pdf page in new tab in my angular 5 application. But unable to achieve the result.

我正在按照以下链接在我的 angular 5 应用程序的新选项卡中显示 pdf 页面。却达不到效果。

I am consuming the bytes array from spring controller api.

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

PDF Blob is not showing content, Angular 2

PDF Blob 未显示内容,Angular 2

PDF Blob - Pop up window not showing content

PDF Blob - 弹出窗口不显示内容

Angular2 Displaying PDF

Angular2 显示 PDF

I tried the below options but none of them is working.

我尝试了以下选项,但它们都不起作用。

Trial 1

试验 1

Consumed the response as json

将响应作为 json 使用

component.ts

组件.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

服务.ts

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

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

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

}

Trial 2

试验 2

Consumed the response as json

将响应作为 json 使用

component.ts

组件.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

服务.ts

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

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

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

}

Trial 3

试验 3

Consumed the response as bytes

将响应作为字节使用

component.ts

组件.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

服务.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);

}

By all the combination I am only getting two results. Empty pdf document or Failed to load PDF document.

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

enter image description here

在此处输入图片说明

enter image description here

在此处输入图片说明

For understanding posting java spring controller code.

用于理解发布 java spring 控制器代码。

controller.java

控制器.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;
}

采纳答案by MPPNBD

At last, I was able to render pdf. There were two small mistakes from my side.

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

1 st Problem was, I gave 'responseType' inside HttpHeaders which was wrong. It should be outside as below.

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

2 nd Problem was, even though if you mention as responseType : 'arraybuffer', it was unable to take it. For that you need to mention as responseType : 'arraybuffer' as 'json'.(Reference)

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

The corrected and working code below.

下面的更正和工作代码。

Trial 3

试验 3

component.ts (nochanges)

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

服务.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);

}

Referred from the below link

来自以下链接

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

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

回答by Dmitrii Cheremisin

I had the same problem with angular and pdf display. I will describe my solution - use base64 encoded string. All modern browsers support base64.

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

  1. Use import java.util.Base64to decode your byte array

    byte[] bytes = baos.toByteArray();
    
    String string = Base64.getEncoder().encodeToString(bytes);
    
    test.setByteString(string);
    
  2. On the frontend side use standard mime type for pdf and indicate that you are using base64 data:application/pdf;base64,.

    Ref. to mime types: https://en.wikipedia.org/wiki/Media_type

    If you need to open document in a new window:

    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. If you need to open in a new tab, you may simply provide to your html href:

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

    bypassSecurityTrustUrlwill sanitize your url. As I remember there was some problem with angular security, that prevented me from seeing the content.

  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,

    参考 到 mime 类型: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. before checking how it works with angular I would like to recommend you to store the pdf file on a drive and try to open it. I mean, that you should be certainly sure that you file is valid and you may open it with simple reader.

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

Update. The simpliest solution is to use pdf.js library https://github.com/mozilla/pdf.js

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

回答by Chris White

Have you looked for an angular component to wrap pdf.js?

您是否正在寻找一个角度组件来包装 pdf.js?

Sample usage:

示例用法:

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

pdfSrccan be a url stringor a UInt8Array

pdfSrc可以是网址stringUInt8Array