html2canvas out of memory - jspdf

Good day, colleagues. I have the problem, html2canvas when generating screenshots I give the error "out of memory" in google chrome.
window.jsPDF = window.jspdf.jsPDF;
let printArea = [...document.querySelectorAll('.print:not([style*="display: none;"])')]
var doc = new jsPDF('l', 'mm', "a4");
let tasks = printArea.map(tab => html2canvas(tab, {scale:2, removeContainer: true}))
Promise.all(tasks).then(canvases =>
{
var boolAdd = false
console.log(canvases)
for (const canvas of canvases)
{
if(true == boolAdd) {
doc.addPage();
}
let imgData = canvas.toDataURL('image/jpeg', 0.6);
const pageHeight = doc.internal.pageSize.getHeight();
const imgWidth = doc.internal.pageSize.getWidth();
var imgHeight = canvas.height * imgWidth / canvas.width;
var heightLeft = imgHeight - 20;
var position = 10;
doc.addImage(imgData, 'JPEG', 20, position, imgWidth - 40, imgHeight);
heightLeft -= pageHeight;
position += heightLeft - imgHeight; // top padding for other pages
doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight, undefined,'FAST');
heightLeft -= pageHeight;
boolAdd = true
}
console.log("report")
doc.save( 'report.pdf');
})
how to fix the error? Or how to free up memory? Alternatively, you can offer another library if you can't make it so that there are no memory problems.
Example
https://embed.plnkr.co/plunk/Zz4iFK
700 > mb

Good day, Comrads. I solved my problem. I replaced library html2canvas on htmlToImage witch method toCanvas. –

Related

jsPDF - multiple pages - rendering HTML always going to page1

We use jsPDF 2.5.1 to render a multi page PDF.
We use the html function to render various DOM elements to each page, and this was working in version 1.x of jsPDF
However now every time we call .html() - it puts it on the first page, rather than the newly added page, here is the code
if (pdfPageIndex < numPdfPages) {
if (pdfPageIndex > 0) {
pdf.addPage();
}
pdf.html(
document.getElementById('pdfPage_' + pdfPageIndex),
{
html2canvas: {
logging: true
},
callback: function(){ return pdfCallback($scope)}});
Please try with below addImage method based on canvas height and width it will render in multiple pages
const data = document.getElementById('pdfPage_');
html2canvas(data).then((canvas:any) => {
const imgWidth = 208;
const pageHeight = 295;
const imgHeight = (canvas.height * imgWidth) / canvas.width;
let heightLeft = imgHeight;
let position = 0;
heightLeft -= pageHeight;
const doc = new jspdf('p', 'mm');
doc.addImage(canvas, 'PNG', 0, position, imgWidth, imgHeight, '', 'FAST');
while (heightLeft >= 0) {
position = heightLeft - imgHeight;
doc.addPage();
doc.addImage(canvas, 'PNG', 0, position, imgWidth, imgHeight, '', 'FAST');
heightLeft -= pageHeight;
}
doc.save('Downld.pdf');
});

PDF pages in wrong order

I have this
$('#create_pdf').on('click', function () {
$('body').scrollTop(0);
createPDF();
});
//create pdf
function createPDF() {
doc = new jsPDF({
unit: 'px',
format: 'a4'
});
const pdfWidth = doc.internal.pageSize.width - 20;
current_div = current_div1;
cache_width = current_div.width();
cache_width = current_div.width();
getCanvas(document.querySelector("#thediv1")).then(function (canvas) {
var img = canvas.toDataURL("image/png", wid = canvas.width, hgt = canvas.height) ;
var hratio = hgt/wid;
const TheHeight = doc.internal.pageSize.width;
const pdfHeight = TheHeight * hratio
doc.addImage(img, 'JPEG', 10, 10, pdfWidth, pdfHeight);
doc.addPage(595, 842);
});
current_div = current_div2;
cache_width = current_div.width();
getCanvas(document.querySelector("#thediv2")).then(function (canvas) {
var img = canvas.toDataURL("image/png", wid = canvas.width, hgt = canvas.height) ;
var hratio = hgt/wid;
const TheHeight = doc.internal.pageSize.width;
const pdfHeight = TheHeight * hratio
doc.addImage(img, 'JPEG', 10, 10, pdfWidth, pdfHeight);
doc.addPage(595, 842);
});
current_div = current_div3;
cache_width = current_div.width();
getCanvas(document.querySelector("#thediv3")).then(function (canvas) {
var img = canvas.toDataURL("image/png", wid = canvas.width, hgt = canvas.height) ;
var hratio = hgt/wid;
const TheHeight = doc.internal.pageSize.width;
const pdfHeight = TheHeight * hratio
doc.addImage(img, 'JPEG', 10, 10, pdfWidth, pdfHeight);
doc.addPage(595, 842);
});
etc etc
current_div = current_div14;
cache_width = current_div.width();
getCanvas(document.querySelector("#thediv14")).then(function (canvas) {
var img = canvas.toDataURL("image/png", wid = canvas.width, hgt = canvas.height) ;
var hratio = hgt/wid;
const TheHeight = doc.internal.pageSize.width;
const pdfHeight = TheHeight * hratio
doc.addImage(img, 'JPEG', 10, 10, pdfWidth, pdfHeight);
doc.addPage(595, 842);
doc.autoPrint();
window.open(doc.output('bloburl'));
});
}
// create canvas object
function getCanvas(Link) {
current_div.width((a4[0] * 1.33333) - 80).css('max-width', 'none');
return html2canvas(Link, {
imageTimeout: 2000,
removeContainer: true
});
}
I have two problems.
I am getting all the pages but not always in the right order. Why is that and what can I do about it?
Is there a way of stopping it from writing to the original page as the width is smaller than the original so it looks terrible. The original page needs to look the same as it did before clicking the print button
Thanks
I used Dompdf in the end. I was much easier

JSPDF leaves white background when margin added

I am using JsPDF to print dynamic resume data and i want to add margin when adding new page to pdf.
Now when resume having a background color and i add margin while generating pdf it leaves the margined area as white and rest is OK.
var data = document.getElementById('box');
html2canvas(data,{scale: 2}).then(canvas => {
var imgData = canvas.toDataURL('image/JPEG');
var imgWidth = 210;
var pageHeight = 295;
var imgHeight = canvas.height * imgWidth / canvas.width;
var heightLeft = imgHeight;
var doc = new jsPDF('p', 'mm', "a4");
var position = 1;
doc.addImage(imgData, 'JPEG', 0, position, imgWidth, imgHeight,'FAST');
heightLeft -= pageHeight;
while (heightLeft >= 0) {
position = heightLeft - imgHeight;
doc.addPage();
doc.addImage(imgData, 'JPEG', 0, position, imgWidth, imgHeight);
heightLeft -= pageHeight;
}
doc.save("Dashboard.pdf");
});
Use 'pt' instead of 'mm' as below, I hope it fixes,
var doc = new jsPDF('p', 'pt', "a4");

Html2Canvas doesn't works... the pdf shows empty

When I run the app and I click on the button, the PDF looks empty.
I was looking for by console.log() and the canvas doesn't show anything.
import { Component, OnInit } from '#angular/core';
import * as jspdf from 'jspdf';
import html2canvas from 'html2canvas';
generatePDF(){
html2canvas(document.getElementById('albaran')).then(canvas => {
// Few necessary setting options
var imgWidth = 208;
var pageHeight = 295;
var imgHeight = canvas.height * imgWidth / canvas.width;
var heightLeft = imgHeight;
const contentDataURL = canvas.toDataURL('image/png')
let pdf = new jspdf('p', 'mm', 'a4'); // A4 size page of PDF
var position = 0;
pdf.addImage(contentDataURL, 'PNG', 0, position, imgWidth, imgHeight)
pdf.save('MYPdf.pdf'); // Generated PDF
});
}
}
Finally, I have found a solution. I use jsPDF and dom-to-image libraries.
https://www.npmjs.com/package/jspdf
https://www.npmjs.com/package/dom-to-image
import * as jsPDF from 'jspdf';
import domtoimage from 'dom-to-image';
exportPdf(){
const div = document.getElementById('pdf');
const options = { background: 'white', height: 845, width: 595 };
domtoimage.toPng(div, options).then((dataUrl) => {
//Initialize JSPDF
const doc = new jsPDF('p', 'mm', 'a4');
//Add image Url to PDF
doc.addImage(dataUrl, 'PNG', 0, 0, 210, 340);
doc.save('pdfDocument.pdf');
}
}
Once you click on the button it will take time while loading an element from DOM so using setTimeout it will work.
import * as html2canvas from 'html2canvas';
import * as jspdf from 'jspdf';
generatePDF() {
setTimeout(() => {
const data = document.getElementById('printdiv');
html2canvas(data).then(canvas => {
// Few necessary setting options
const imgWidth = 208;
const pageHeight = 295;
const imgHeight = canvas.height * imgWidth / canvas.width;
let heightLeft = imgHeight;
const contentDataURL = canvas.toDataURL('image/png');
const pdf = new jspdf('p', 'mm', 'a4'); // A4 size page of PDF
let position = 0;
pdf.addImage(contentDataURL, 'PNG', 0, position, imgWidth, imgHeight);
heightLeft -= pageHeight;
// pdf.text(190, 294, '1');
let count = 1;
while (heightLeft >= 0) {
position = heightLeft - imgHeight;
pdf.addPage();
pdf.addImage(contentDataURL, 'PNG', 0, position, imgWidth, imgHeight);
// pdf.text(150, 10, 'this test meaasage');
count++;
// pdf.text(190, 294, count.toString());
heightLeft -= pageHeight;
}
const date = this.datePipe.transform(new Date(), 'dd/MM/yy');
const text = 'Created At :' + date;
pdf.setTextColor(163, 163, 163);
pdf.text(10, 290, text);
// pdf.text(190, 294, count.toString());
const currentuser = this.localstorgeservice.getCurrentUser();
const url = 'URL:' + this.document.location.href;
pdf.text(10, 280, url.toString());
pdf.text(150, 290, currentuser.userid);
pdf.save(this.bankingchannelname + '.pdf'); // Generated PDF
});
}, 700);
}
Here it is,
$(document).click(function () {
domtoimage.toPng(document.body)
.then(function (blob) {
var pdf = new jsPDF('p', 'mm', 'a4');
pdf.addImage(blob,'PNG', 0, 0, 210, 225);
pdf.save("test.pdf");
that.options.api.optionsChanged();
});
});

Center image doc.addImage jspdf

I am using html2canvas to take screenshot of my page and creating pdf of the images using jspdf. Now, my images are left aligned in the pdf document, I want it to be centered, how can I achieve it?
function pdfmaker() {
var element = $("#timesheet");
document.getElementById("message").style.display = "block";
document.getElementById("logo").style.display = "block";
var firstName = "<?php echo $fname?>";
var lastName = "<?php echo $lname ?>";
var startDate = "<?php echo $startDate?>";
var endDate = "<?php echo $endDate ?>";
html2canvas(element, {
useCORS: true,
onrendered: function(canvas) {
var imgData = canvas.toDataURL("image/png");
var imgWidth = 297; //297
var pageHeight = 297; //297
var imgHeight = canvas.height * imgWidth / canvas.width;
var heightLeft = imgHeight;
// var doc = new jsPDF('l', 'mm',[1350, 1350]);
var doc = new jsPDF('l', 'mm', [420, 297]); //420,297
var position = 5; //0
margins = {
top: 20,
bottom: 10,
left: 45,
width: 522
};
doc.addImage(imgData, 'PNG', 5, position, imgWidth, imgHeight);
heightLeft -= pageHeight;
while (heightLeft >= 5) {
position = heightLeft - imgHeight;
doc.addPage();
doc.addImage(imgData, 'PNG', 5, position, imgWidth, imgHeight);
heightLeft -= pageHeight;
}
doc.save(firstName + '_' + lastName + '_Summary_report_' + startDate + '_' + endDate + ".pdf");
}
});
document.getElementById("message").style.display = "none";
document.getElementById("logo").style.display = "none";
}
You need to define inside the addImage() method, using the coordinate parameters, see: http://raw.githack.com/MrRio/jsPDF/master/docs/module-addImage.html
This is the only way you can do it. For this, I suggest you use the following method doc.internal.pageSize.getWidth(); to calculate the excess values ​​about the image width, which will be centered.

Resources