2

In my node/express app I create a pdf file with node-html-pdf:

exports.getTestPdf = async function(req, res) {
  // set page format
  const options = { format: 'A4' };

  // define content
  const html = `
  <html>
    <head>
      <meta charset="utf8">
      <title>PDF Test</title>
      <style>
      .page {
        position: relative;
        height: 90mm;
        width: 50mm;
        display: block;
        page-break-after: auto;
        margin: 50px;
        overflow: hidden;
      }
      </style>
    </head>
    <body>
      <div class="page">
        Page 1
      </div>
      <div class="page">
        Page 2
      </div>
    </body>
  </html>
  `;

  // set header
  res.set('Content-type', 'application/pdf');

  // create and stream file to client
  pdf.create(html).toStream(function(err, stream){
    stream.pipe(res);
  });

  // check: the file is created with content when saved server side
  // pdf.create(html, options).toFile('./pdf-test.pdf', function(err, res) {
  //   if (err) return console.log(err);
  //   console.log(res); // { filename: pathtofile/pdf-test.pdf' }
  // });
}

This file will be received in an Angular 2 frontend.

Service:

@Injectable()
export class PdfService {

  constructor (private http: Http) {}

  getPdf (): any {
    return this.http.get('api/test-pdf')
                    .map(res => res)
                    .catch(this.handleError);
  }
}

Controller:

pdf(){
    this.userService.getPdf().subscribe(
      response => {
        // create hidden dom element (so it works in all browsers)
        let a = document.createElement("a");
        a.setAttribute('style', 'display:none;');
        document.body.appendChild(a);

        var blob = new Blob([response._body], { type: 'application/pdf' });
        let url = window.URL.createObjectURL(blob);
        a.href = url;
        a.download = 'MerapiExport.pdf';
        a.click();
      },
      error =>  this.errorMessage = <any>error
    );
  }

When I activate my pdf() function via a button an empty pdf file will be downloaded. Any ideas why the file is empty and has no content?

Luke
  • 185
  • 1
  • 3
  • 16

1 Answers1

3

I have found a solution: You need to import ResponseContentType from @angular/http and change the response content type from json (Standard) to array buffer.

Edited code:

Backend node/express

exports.getTestPdf = async function(req, res) {
  // set page format
  const options = { format: 'A4' };

  // define content
  const html = `
  <html>
    <head>
      <meta charset="utf8">
      <title>PDF Test</title>
      <style>
      .page {
        position: relative;
        height: 90mm;
        width: 50mm;
        display: block;
        page-break-after: auto;
        margin: 50px;
        overflow: hidden;
      }
      </style>
    </head>
    <body>
      <div class="page">
        Page 1a
      </div>
      <div class="page">
        Page 2a
      </div>
    </body>
  </html>
  `;

  // set header
  res.set('Content-type', 'application/pdf');

  // create and stream file to client
  pdf.create(html).toStream(function(err, stream){
    stream.pipe(res);
  });
}

Angular 2 service:

 getPdf (): any {
    return this.http.get('api/user-pdf', {
                       responseType: ResponseContentType.ArrayBuffer //magic
                     })
                    .map(res => this.downloadFile(res))
                    .catch(this.handleError);
  }

  private downloadFile(data){
        let blob = new Blob([data._body], { type: 'application/pdf' });
        let url = window.URL.createObjectURL(blob);
        window.open(url);
      }

Angular 2 controller

pdf(){
    console.log('start download')
    this.userService.getPdf().subscribe(
      response => {
        console.log('end download');
      },
      error =>  this.errorMessage = <any>error
    );
  }
Luke
  • 185
  • 1
  • 3
  • 16
  • Ideas from: http://stackoverflow.com/questions/35138424/how-do-i-download-a-file-with-angular2 – Luke Feb 23 '17 at 14:35