2

I have html2canvas installed and imported in home.page.ts in my Ionic4 angular test project. I have a plain 100px X 100px, yellow background div with a single line of text. I am passing this div to html2canvas to be downloaded as png. html2canvas is listing all steps (no errors) in the console and generating the png with the same size as the given div but the div is empty.It does not have the color of the div or the text.

Changing the size of the div takes effect properly meaning the generated image has the same size as the div. This test project demonstrate the issue - https://stackblitz.com/edit/html2cavasionic4test.

Here is my home.page.ts

import { Component } from '@angular/core';
import * as html2canvas from 'html2canvas';


@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {
  selected = 1;
  list: any = [{ id: 0, text: '0' }, { id: 1, text: 1 }];
  changed(e) {
    console.log(this.selected);
  }
  onPrintClicked(){
    let div = document.getElementById("h2cTest");
    const options = {allowTaint:true, background: "yellow", height: div.clientHeight, width: div.clientWidth };
    html2canvas.default(div, options)
    .then((canvas)=>{
      var myImage = canvas.toDataURL("image/png");
      console.log("image done");
      this.downloadURI("data:" + myImage, "yourImage.png");
    })
    .catch(()=>{})
  }
  downloadURI(uri, name) {
    var link = document.createElement("a");
    link.download = name;
    link.href = uri;
    link.click();
    //after creating link you should delete dynamic link
    //clearDynamicLink(link); 
  }

}

On my local machine I created a plain html/javascript page with the same functionality as in the stackblitz project above and included the script html2canvs.min.js on the page. This simple page is working as expected and generating proper image.

html2Canvas is expected to generate the image of the div but it is generating blank image. Is there something wrong with the setup?

Update

App tag was the problem.

amrahs
  • 49
  • 2
  • 6
  • Did you find a solution? If so, could you comment how? – aleQ Apr 19 '19 at 10:53
  • 1
    @aleQ As I mentioned in my update the problem was ion-app tag. html2canvas seems to be not able to parse the tag properly. One of the solutions is to move the element out of ion-app tag. – amrahs Apr 20 '19 at 14:10
  • @amrahs this question is very useful, I'm having the same bug in my project. If you can please tell how you solved it. The app-ion tag is the highest in the hierarchy, so how did you get it outside of it? – noam steiner Jul 23 '19 at 22:56
  • @noamsteiner Sorry for the late response, didn't get any notification from SO. Anyways, for me moving the source div out of app-root worked (in index.html). But since html2canvas traverse through the whole html from root every time and for some other reasons, we eventually decided to move away from html2canvas and use the combination of CanvasContext.drawImage and svg because our source was basically a combination of image and svg paths. – amrahs Sep 01 '19 at 07:18

1 Answers1

4

https://www.npmjs.com/package/dom-to-image -> works better than html2canvas https://www.npmjs.com/package/jspdf ->if you need to save to pdf

page.ts

import * as jsPDF from 'jspdf'; 
//or     import jsPDF from 'jspdf'; 
import domtoimage from 'dom-to-image';

captureScreen() {
  const div = document.getElementById('pdfContent');
  const divHeight = div.clientHeight;
  const divWidth = div.clientWidth;
  const options = { background: 'white', width: divWidth, height: divHeight };

  domtoimage.toPng(div, options).then((imgData) => {
    const doc = new jsPDF('p', 'mm', [divWidth, divHeight]);
    const imgProps = doc.getImageProperties(imgData);
    const pdfWidth = doc.internal.pageSize.getWidth();
    const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;
    doc.addImage(imgData, 'PNG', 0, 0, pdfWidth, pdfHeight);
    doc.save('pdfDocument.pdf');
  });
}

page.html

<ion-button (click)="captureScreen('pdfContent')">
  <ion-icon name="print" size='small' slot="icon-only"></ion-icon>
</ion-button>

<div id="pdfContent">
  <h1>Testing this to pdf</h1>
</div>

worked on ionic 5 (see more here image-in-ionic4-angular)

Note: current version of jsPDF is giving errors. This is npm install jspdf@1.5.3 --save working ok

You can see the example here of the site: Site

and of the generated pdf

pdf

Mansour Alnasser
  • 4,446
  • 5
  • 40
  • 51
Inês Gomes
  • 4,313
  • 1
  • 24
  • 32
  • Quality of PDF is reduced while use the above feature – Viplav Soni Sep 27 '20 at 16:14
  • 1
    @ViplavSoni yes a little.... Depends what you need ... for what I need is ok. The charts don't work in Safari. I edit the answer and set an example from chrome. :-) – Inês Gomes Sep 28 '20 at 12:01
  • 1
    ```TypeError: Cannot read property 'toPng' of undefined``` I'm getting this error in ionic 5 angular – Mayank Kataria Mar 21 '21 at 10:59
  • @MayankKataria Do you have? import domtoimage from 'dom-to-image'; and in package.json "dom-to-image": ... ? – Inês Gomes Mar 22 '21 at 12:39
  • Yes I've imported domtoimage. I replaced ```import domtoimage from 'dom-to-image';``` to ```const domtoimage = require('dom-to-image');``` and now everything is working fine. Thanks. – Mayank Kataria Mar 22 '21 at 12:43