Search code examples
javascriptjspdfhtml2canvas

html2canvs how to loop or reuse for multiple div/html dom elements


I am trying to use html2canvas integrating with jspdf for printing multiple tabs.

  printTabsManual() {
    let tabs = document.querySelectorAll('*[id^="GRID_ID-pane"]');
    console.log(tabs.length);
    //const pdf = new jsPDF();
    //console.log(max_h);
    //console.log(max_w);
    let pdf = new jsPDF('l', 'px', [max_h, max_w]);
    for (i = 0; i < tabs.length; i++) {
      html2canvas(tabs[i])
      .then((canvas) => {
        const imgData = canvas.toDataURL('image/png');
        pdf.addImage(imgData, 'JPEG', 0, 0);
      });
    }
    pdf.save("Download.pdf");
  }

I am able to get the tab's div using the query selector, and this code without the loop works really fine if you are dealing with a single div, but it breaks or maybe the implementation is not right for the multiple looping.

I tried to see the logs, it's not able to get the image for second tab's div.

Not sure where I am getting this wrong.


Solution

  • The loop executing an async operation... I believe you untended to execute all of your async tasks and only then to proceed.. so.. let's use Promise.all for that purpose:

    const tasks = tabs.map(tab => html2canvas(tab))
    
    Promise.all(tasks).then(canvases =>
    {
       for (const canvas of canvases)
       {
           const imgData = canvas.toDataURL('image/png');
           pdf.addImage(imgData, 'JPEG', 0, 0);
       }
    
       pdf.save("Download.pdf");
    })
    

    Which means: execute all async tasks, then manipulate their results and save pdf