I am trying to export graphs from HTML to pdf using html2canvas library. I am first taking all the divs using a for loop and generating corresponding image for them, and once all the conversion is done, I am calling doc.save("file.pdf");
function to save it. However, I have to call doc.save() function inside a timeout after the for loop is done, since html2canvas('div_id').then()
which is responsible to converting html to images, is returning a promise and converting the html to image asynchronously. Is there a way where I can use promise and not setTimeout method. I am not able to come up with a solution using promise.
exportGraphonClick() {
var metrics = ["1", "2", "3","4","5","6"];
var pageCount;
var doc = new jsPDF("p", "mm");
// loop
metrics.map((key,index) =>{
let id_val = `graph-id-${index}`; // creating IDs
const input = document.getElementById(id_val);
// html to pdf
html2canvas(input).then((canvas) => {
const imgData = canvas.toDataURL('image/JPEG');
var width = 300;
doc.addImage(imgData, 'JPEG', 10, 40, width, 100);
doc.addPage();
pageCount = doc.internal.getNumberOfPages();
});
})
// saving pdf
setTimeout(()=> {
doc.save("file.pdf");
},2000)
}
You can make the function used in map
async
, and await
the call to html2canvas
. This will return an array of unresolved Promises. Promise.all()
returns a new Promise
that will resolve when all provided promises resolve.
metrics = metrics.map(async (key, index) => {
let id_val = `graph-id-${index}`; // creating IDs
const input = document.getElementById(id_val);
// html to pdf
let canvas = await html2canvas(input);
const imgData = canvas.toDataURL('image/JPEG');
let width = 300;
doc.addImage(imgData, 'JPEG', 10, 40, width, 100);
doc.addPage();
pageCount = doc.internal.getNumberOfPages();
})
// saving pdf
Promise.all(metrics)
.then(() => doc.save("file.pdf"))
.catch(err => console.log(err));