Angular2+ jsPDF and html2canvas File Generation

To generate pdf files in Angular2+ (specifically angular4), first install jspdf

$ npm install jspdf

Then install typings for jspdf,

$ npm install --save @types/jspdf

Import jspdf into app.component.ts

import * as jsPDF from 'jspdf';

Add a download button to app.component.html which calls the dowload() function,

<button (click)="download()" class="btn btn-warning btn-sm">Download results</button>

Using jspdf in app.component.ts

  download(){
    var doc = new jsPDF();
        doc.text(20, 20, 'Hello world!');
        doc.addPage();
        doc.text(20, 20, 'Hi again this I page two');
        doc.save('Test.pdf');
  }

html2canvas enables you to grab the html page or just an element in it and place it in a pdf. First install html2canvas and its typings,

$ npm install --save html2canvas
$ npm install --save @types/html2canvas

Then import this at the top of app.component.ts,

import * as html2canvas from 'html2canvas';

and to call an element on the html page with id of ‘results’,

  download(){
    html2canvas(document.getElementById('results')).then(function(canvas) {
    var img = canvas.toDataURL("image/png");
    var doc = new jsPDF();
    doc.addImage(img,'JPEG',5,20);
    doc.save('testCanvas.pdf');
    });
  }

You could call the whole html page with,

html2canvas(document.body).then(function(canvas) {...

It is possible to instead wrap jsPDF around html2canvas like this,

  generatePDF(){
      var doc = new jsPDF();
      doc.text(50,90,this.problems.length.toString());
      doc.text(50,100,'page 1')
      doc.addPage();
      doc.text(50,100,'page 2')
      html2canvas(document.getElementById('graph')).then(function(canvas) {
      var img = canvas.toDataURL("image/png");
      doc.addImage(img, 'JPEG', 100, 100);
      doc.save('test.pdf');
    });
    // doc.save('test.pdf');//fails to add image to pdf
  }

But then the image is always the last things which runs before the pdf is generated with the line,

doc.save('test.pdf');

So nothing can be added after that. Passing this to the outside of html2canvas does not work either, as in the commented out line above.

Therefore wrapping html2canvas around jsPDF would seem the best way to proceed. However, this will not allow you use an external variable such as in this case this.problems.length.

So to use an external variable such as this.problems.length inside htm2canvas use,

var self = this;

and then reference with ‘self’ inside of ‘this, as in this example below,

generatePDF(){
      console.log("outside: this.problem.length = " + this.problems.length);

    html2canvas(document.getElementById('graph')).then(function(canvas) {
      var self = this;
      console.log("inside: self.problem.length = " + self.problems.length);

      var doc = new jsPDF();
      doc.text(50,100,'page 1');
      var img = canvas.toDataURL("image/png");
      doc.addImage(img, 'JPEG', 100, 100);
      doc.addPage();
      doc.text(50,100,'page 2')
      doc.save('test.pdf');
    });
    // doc.save('test.pdf');//fails to add image to pdf
  }