Open PDF Typescript

1

I'm trying to show a PDF with Typescript, it comes to base64 and I decode it to see the array of bytes.

The PDF of opens, but blank, the pages coincide, but it is all without content.

The content in base64 I leave here PDF in Base64

Regarding the code I use to do it, it is as follows.

In the service there is a call to the API, which is the one that returns the content.

getDescargaFactura(idFacturaVenta): Observable<any> {
    const httpHeaders = new HttpHeaders({
      'Content-Type': 'application/json',
      Authorization: this.token
    });
    const options = {
      headers: httpHeaders
    };
    const body = { IdFactura: idFacturaVenta };
    return this.http.post<any>(this.urlApi + 'Facturas/GetFacturasPDF', body, options);
  }

And in the controlled one, I show the PDF.

descargaFactura(datos: any) {
    this._facturasService
      .getDescargaFactura(datos.IdFacturaVentaCabecera)
      .subscribe(data => {
        this.pdfFactura = this._funcionesService.decodificarToken(data);
        const newBlob = new Blob([window.atob(this.pdfFactura.PDFBase64)], {
          type: 'application/pdf'
        });

        if (window.navigator && window.navigator.msSaveOrOpenBlob) {
          window.navigator.msSaveOrOpenBlob(newBlob);
          return;
        }

        const datos = window.URL.createObjectURL(newBlob);
        const link = document.createElement('a');
        link.href = datos;
        link.download = 'file.pdf';
        link.click();
      });
  }

I have done several tests and I can only show the PDF without content, I do not know if it is due to a coding issue or by Angular himself.

    
asked by Diego 28.11.2018 в 11:04
source

2 answers

1

The solution has been the following:

Change the response in the service. Adding the Observable<Blob> and the header responseType: 'blob' as 'json'

getDescargaFactura(idContratoDocumento): Observable<Blob> {
    const httpHeaders = new HttpHeaders({
      'Content-Type': 'application/json',
      Authorization: this.token
    });
    const options = {
      headers: httpHeaders,
      responseType: 'blob' as 'json'
    };
    const body = { IdContratoDocumento: idContratoDocumento };
    return this.http.post<any>(
      this.urlApi + 'Facturas/GetFacturaPDF',
      body,
      options
    );
  }

Once this has been modified, in the component, the response of the service to the blob object has been added directly

descargaFactura(datos: any) {
    this._facturasService
      .getDescargaFactura(datos.IdContratoDocumento)
      .subscribe(
        data => {
          const file = new Blob([data], { type: 'application/pdf' });
          const fileURL = URL.createObjectURL(file);
          window.open(fileURL);
        }
      );
  }
    
answered by 30.11.2018 / 14:32
source
-2

You also have to add this import.

import { ResponseContentType, Headers } from '@angular/http';

In the function that you have in the service you have to add the type of data you want to collect.

    getDescargaFactura(idFacturaVenta): Observable<any> {
        const httpHeaders = new Headers({
            Authorization': this.token
        }); 
        const options = {
            headers: httpHeaders,
            responseType: ResponseContentType.Blob
        };
        const body = { IdFactura: idFacturaVenta };
        return this.http.post<any>(this.urlApi + 'Facturas/GetFacturasPDF', body, options);
  }

In the function you have in the controller you have to add the file type. Also, I have added some commented lines, suggesting that you use the saveAS library.

    descargaFactura(datos: any) {
        this._facturasService
          .getDescargaFactura(datos.IdFacturaVentaCabecera)
          .subscribe(data => {
           this.pdfFactura = this._funcionesService.decodificarToken(data);

          var contentType = 'application/pdf';
          const newBlob = new Blob([data._body], {   type: contentType})

           if (window.navigator && window.navigator.msSaveOrOpenBlob) {
             window.navigator.msSaveOrOpenBlob(newBlob);
             return;
           }

           const datos = window.URL.createObjectURL(newBlob);
           const link = document.createElement('a');
           link.href = datos;
           link.download = 'file.pdf';
           link.click();
    /****
    *
    * Esto sería otra opcion de descarga. Faltaría añadir una libreria y su import 
    * import { saveAs } from 'file-saver';

        const file = new File([newBlob ], 'nombrearchivo.xlsx',{ type: contentType});
        saveAs(file);
    */
      });

  }
    
answered by 28.11.2018 в 14:09