jsPDF html2Canvas producing a low quality image to PDF using React - javascript

I want to print some HTML to an PDF and am using a combination of html2Canvas and jsPDF to achieve that.
It all works just fine, however, the image quality is quite poor and doesn't look very sharp.
I've done some research but haven't found a solution that actually improves the quality of the image. Any suggestions would be well appreciated.
function printPDF() {
const domElement = document.getElementById("print-pdf");
html2canvas(domElement, {
onclone: (document) => {
document.getElementById("print-button");
},
}).then((canvas) => {
const imgData = canvas.toDataURL("image.png", 1.0);
const doc = new jsPDF();
doc.addImage(imgData, "JPEG", 5, 5);
doc.save(`${leadData.company}-Timo-Huennebeck-Cover-Letter`);
});
}

Related

can't load more than one image while using jsPDF on NextJS

Im trying to create a pdf based on a html, which has 3 images. The html can be seen and there is a button that downloads the html as a pdf file, but only the first image is shown on the downloaded pdf. This is the function that downloads the file (im using jsPDF library):
const savePDF = () => {
const doc = new jsPDF('p', 'pt', 'a4');
const margin = 10;
const certificate = document.querySelector('#doc');
const scale = (doc.internal.pageSize.width - margin * 2) / certificate.offsetWidth;
doc.internal.write(0, 'Tw');
doc.html(certificate, {
x: margin,
y: margin,
html2canvas: {
scale: scale
},
callback: function(doc) {
doc.output('save', {filename: 'pdfFile.pdf'});
}
})
}
Everything else is allright, the text, the tables and the first image of the doc. But for some reason the second and third image arent shown on the downloaded pdf file. I get console message: "Error loading image". All these images are on the public folder of the project, locally. Im working on NextJS.
Btw, all images are set the same way:
<Image src='/image1.png' alt='' width={500} height={500}/>

Ionic 4 html2canvas

I'm trying to capture HTML to image in an Ionic 4 app.
I tried using html2canvas, however, it doesn't work and shows this output in the console:
This is my code:
var element = document.getElementById('capture');
html2canvas(element).then(canvas => {
var imgData = canvas.toDataURL("image/png");
this.socialSharing.share(null, null, imgData);
});
I'm having the same issue. I managed to "fix" it by putting my code out of the <ion-content> tag. My guess is that html2canvas doesn't render shadow DOM elements (which is the case of <ion-content>, as of Ionic 4).
For instance this outputs an empty canvas:
<ion-content>
<div id="capture">
<h1>Test</h1>
</div>
</ion-content>
But the following works:
<div id="capture">
<h1>Test</h1>
</div>
This is not really a solution, but it's good enough for my use...
I was trying this component too but it does not work. The solution I found was to use the dom-to-image library. I attached an example of what I did. You just have to put the file extension you want to convert.
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');
}
}
The latest html2canvas supports shadow dom, like https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js

toDataURL() very slow

I have a report with charts and tables.
I am using the html2canvas with jsPDF to export this report to PDF file.
But the process is taking a long time, more than 11000ms.
I've tried to change the format, the quality, but nothing worked.
See below the code I used:
html2canvas($('#first-page'), {
onrendered: function(canvas) {
firstPage = canvas.toDataURL('image/jpeg', 0.5);
},
background: '#ffffff'
});
I'm doing something wrong or really is a problem?
How I can improve the performance?
You don't need to use toDataUrl.http://jsfiddle.net/davidmather/sxp0meer/3/
html2canvas($('#first-page'), {
onrendered: function(canvas) {
var doc = new jsPDF('p', 'mm');
doc.addImage(canvas, 'PNG', 10, 10);
doc.save('sample-file.pdf');
}
});

convert web page to a pdf with styles

I want to convert a web page to PDF including all the styles I've added.
I've used jspdf.js and html2Canvas. But I got only a blur picture in PDF form.
I've searched for many JavaScript codes but didn't find a correct one.
Script I have written is:
function getPDF() {
html2canvas(document.body, {
onrendered: function(canvas) {
var img = canvas.toDataURL("Image/jpeg");
//window.open(img);
var doc = new jsPDF({
unit: 'px',
format: 'a4'
});
doc.addImage(img, 'JPEG', 0, 0, 440, 627);
doc.save("download");
}
});
}
Thank You!
There may be a few things that are contributing.
Your encoder options for the canvas.toDataURL are missing, so you're getting the defaults. The defaults may be creating a low quality image. Try this for the highest quality JPEG image:
var img = canvas.toDataURL("Image/jpeg", 1.0);
You might also try creating your jsPDF object with measurements, rather than pixels:
var pdf = new jsPDF("p", "mm", "a4"); // jsPDF(orientation, units, format)
And when you add the image, scale it to the dimensions of the page:
pdf.addImage(imgData, 'JPEG', 10, 10, 190, 277); // 190x277 mm # (10,10)mm
See if that gives you a better image quality.

Black image bug when exporting highcharts in Firefox

I am using highcharts to display several graphs on a webpage which display fine.
I have an export function that tries to combine the charts into a pdf. I am getting the svg of the chart and converting it to a jpeg image to be included in a pdf created by jsPDF.
Here is the code I am using to generate the images:
if ($('.chart').length > 0) {
var chartSVG = $('.chart').highcharts().getSVG(),
chartImg = new Image();
chartImg.src = "data:image/svg+xml;base64," + window.btoa(unescape(encodeURIComponent(chartSVG)));
var chartCanvas = document.createElement("canvas");
chartCanvas.width = 600;
chartCanvas.height = 400;
chartCanvas.getContext("2d").drawImage(chartImg, 0, 0, 600, 400);
var chartImgData = chartCanvas.toDataURL("image/jpeg");
}
This works perfectly in Chrome but in Firefox it just returns a black image.
Does anyone know what might be going wrong or has seen a similar issue?
Thanks for your help.
UPDATE
I've updated the code but now no image is appended to the pdf document, either in Chrome or Firefox.
if ($('.sales').length > 0) {
var chartSVG = $('.sales').highcharts().getSVG(),
chartImg = new Image();
chartImg.onload = function () {
var chartCanvas = document.createElement("canvas");
chartCanvas.width = 600;
chartCanvas.height = 400;
chartCanvas.getContext("2d").drawImage(chartImg, 0, 0, 600, 400);
var chartImgData = chartCanvas.toDataURL("image/jpeg");
}
chartImg.src = "data:image/svg+xml;base64," + window.btoa(unescape(encodeURIComponent(chartSVG)));
}
Not sure if I have the code in the correct place.
If I log 'chartImgData' to the console, both browsers generate a dataURI, but Firefox's version differs to Chromes.
UPDATE
Fixed the issue with black images. Now i'm struggling with how to return multiple images - how to nest multiple callbacks or is there another way?
Example: jsfiddle.net/wmuk489c/2
SOLVED
Thanks for your help #RobertLangson. fiddle updated with final working code should anyone need it: http://jsfiddle.net/wmuk489c/3/
FURTHER ISSUES:
My charts are dynamic and so may not always be present. I need to get an image from each graph that exists. If the graph does not exist, the 'getSVG' function fails, see example: http://jsfiddle.net/wmuk489c/4/
How should the img.onload work if the chart doesn't exist? The first chart in the callback may not be present either, so how would this work? Is there a better way to get the images?
setting chartImg.src causes an asynchronous load so you then need to do this...
chartImg.onload = function() {
var chartCanvas = document.createElement("canvas");
chartCanvas.width = 600;
chartCanvas.height = 400;
chartCanvas.getContext("2d").drawImage(chartImg, 0, 0, 600, 400);
var chartImgData = chartCanvas.toDataURL("image/jpeg");
doc.addImage(chartImgData, 'JPEG', 0, 0, 200, 100);
// You can only do this bit after you've added the image so it needs
// to be in the callback too
doc.save('test.pdf');
}
chartImg.src = ...
You've a race condition otherwise and I imagine you just happen to get away with it with the Chrome browser on your PC.
Here's your fiddle fixed.

Categories

Resources