PatoPan
PatoPan

Reputation: 25

Angular 5 - Display Embedded PDF from byte[]

I'm relatively new to Angular 5.0, and have read the documentation but I can't seem to make any progress. I have a .Net Core 2.0 project with an Angular 5 UI and am passing a byte[] of a PDF file from the API Controller to Angular. I would like to then embed this PDF file via Object/Embed/Iframe in my view. So far I have the following:

Controller:

[HttpGet]
[Route("api/PdfReports/GetReport")]
public byte[] Get()
{
    string directory = System.IO.Directory.GetCurrentDirectory();
    string fileName = "TERM.pdf";
    string filePath = Path.Combine(directory, fileName);            
    byte[] resultArray = System.IO.File.ReadAllBytes(Path.Combine(filePath));
    return resultArray;
}

View:

<div *ngIf="dataLocalUrl != undefined">
    <h5>iframe using local url</h5>
    <iframe width="500" height="600" [attr.src]="dataLocalUrl" type="application/pdf"></iframe>
    <h5>object using local url</h5>
    <object [attr.data]="dataLocalUrl" type="application/pdf" width="100%" height="100%"></object>
    <h5>embed using local url</h5>
    <embed [attr.src]="dataLocalUrl" type="application/pdf" width="100%" height="100%">
</div>

And the component:

import { Component, Inject } from '@angular/core';
import { HttpClient, HttpResponse, HttpHeaders } from '@angular/common/http';
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
import { Observable } from 'rxjs/Observable';
import { Router } from '@angular/router';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';  

@Component({
    selector: 'pdf-display',
    templateUrl: './pdfdisplay.component.html'
})

export class PdfDisplayComponent {
    datalocalURL: any;
    http: HttpClient;
    domSanitizer: DomSanitizer;

    constructor(private httpClient: HttpClient, @Inject('BASE_URL') baseURL: string, sanitizer: DomSanitizer) {
        this.http = httpClient;
        this.domSanitizer = sanitizer;
        this.httpClient.get(baseURL + 'api/PdfReports/GetReport', { responseType: 'arraybuffer' })
            .subscribe((data: any) => {
                var pdfFile = new Blob([data._body], { type: 'application/pdf' });
                this.datalocalURL = this.domSanitizer.bypassSecurityTrustResourceUrl(window.URL.createObjectURL(pdfFile));
            });
    }
}

The problem is though the data is going correctly through the controller, when I debug the component the data always comes back undefined. Can anybody help me out please?

Upvotes: 2

Views: 11610

Answers (2)

Aswathy
Aswathy

Reputation: 189

This works for me!

View :

<div style="display: flex;align-items: center;justify-content: center;">
  <iframe width="800" height="500" src="" type="application/pdf"></iframe>
</div>

Component :

this.service.getData(id).pipe(tap(byteArray=>
{
   let newBlob = new Blob([byteArray], { type: "application/pdf" });
   this.datalocalURL = window.URL.createObjectURL(newBlob);
   document.querySelector("iframe").src = this.datalocalURL;
})).subscribe();

Upvotes: 2

Mark Jensen
Mark Jensen

Reputation: 118

This approach works fine for me:

Controller:

[HttpGet("pdf/{docId}")]
public ActionResult GetPdf(int docId)
{
  var byteArray = get byte array...
  var cd = new System.Net.Mime.ContentDisposition
  {
      FileName = "Pdf_" + docId + ".pdf",
      Inline = true
  };

  Response.Headers.Add("Content-Disposition", cd.ToString());

  return File(outputBytes, "application/pdf");
}

let headers = new HttpHeaders();
headers = headers.set('Accept', 'application/pdf');
this._http.get(url, {headers: headers, responseType: 'blob'}).subscribe(
 res => {
      this.pdfResult = this.domSanitizer.bypassSecurityTrustResourceUrl(
          URL.createObjectURL(res)
      );
  },
  err => {
    // ERROR HANDLING HERE
  });
<iframe [src]="pdfResult" ..../>

Upvotes: 2

Related Questions