angular 5アプリケーションで新しいタブにpdfページを表示するために、以下のリンクをたどっていました。しかし、結果を達成することができませんでした。
私は、スプリングコントローラーAPIからバイト配列を使用しています。
PDF Blobはコンテンツを表示していません、Angular 2
PDF Blob-ポップアップウィンドウにコンテンツが表示されない
以下のオプションを試しましたが、どれも機能していません。
Jsonとして応答を消費しました
component.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);
}
Jsonとして応答を消費しました
component.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);
}
応答をバイトとして消費しました
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 = {
headers: new HttpHeaders(
{
'responseType':'blob' //both combination
//'responseType' : 'arraybuffer'
}
)
};
return this.http.get<any>(url, httpOptions);
}
すべての組み合わせで、2つの結果しか得られません。空のPDFドキュメントまたはロードに失敗しましたPDFドキュメント。
投稿を理解するためにJava spring controller code。
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;
}
ついに、pdfをレンダリングできました。私の側から2つの小さな間違いがありました。
最初の問題は、HttpHeaders内で 'responseType'を指定したことです。以下のように外にある必要があります。
2番目の問題は、responseTypeとして「arraybuffer」と言っても、それを受け取ることができなかったということでした。そのためには、responseTypeとして言及する必要があります: 'json'として 'arraybuffer'。( 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);
}
以下のリンクから参照
angularおよびpdf表示で同じ問題が発生しました。base64でエンコードされた文字列を使用してください。すべての最新のブラウザはbase64をサポートしています。
import Java.util.Base64
を使用してバイト配列をデコードします
byte[] bytes = baos.toByteArray();
String string = Base64.getEncoder().encodeToString(bytes);
test.setByteString(string);
フロントエンド側では、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);
新しいタブで開く必要がある場合は、単にhtml hrefに提供するだけです:
let pdfHref = this.sanitizer.bypassSecurityTrustUrl('data:application/octet-stream;base64,' + content);
bypassSecurityTrustUrl
はURLをサニタイズします。覚えているように、angularセキュリティに問題があり、コンテンツを見ることができませんでした。
PS。 angularの動作を確認する前に、pdfファイルをドライブに保存してから開くことをお勧めします。つまり、ファイルが有効であることを必ず確認してくださいシンプルなリーダーで開くことができます。
更新。最も簡単な解決策は、pdf.jsライブラリを使用することです https://github.com/mozilla/pdf.js
Pdf.jsをラップするangularコンポーネントを探しましたか?
サンプル使用法:
<pdf-viewer [src]="pdfSrc"
[render-text]="true"
style="display: block;">
</pdf-viewer>
pdfSrc
は、URL string
またはUInt8Array