html2canvas + jsPDF cut off image - javascript

I can't get the problem fixed that my image is always cut off in the PDF file. The PDF size seems to be correct but I can't see my entire page as an image.
I have been trying for hours but without success.
Code:
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.3/jspdf.min.js"></script>
<script src="https://html2canvas.hertzen.com/dist/html2canvas.js"></script>
<script src="https://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>
<script>
function addWaterMark(pdf) {
var totalPages = pdf.internal.getNumberOfPages();
for (i = 1; i <= totalPages; i++) {
pdf.setPage(i);
pdf.addImage("data:image/png;base64,......", "JPEG", 20, 40, 130, 30);
}
return pdf;
}
function getPDF(){
var HTML_Width = $("div#mycontent").width();
var HTML_Height = $("div#mycontent").height();
var top_left_margin = 100;
var PDF_Width = HTML_Width+(top_left_margin*2);
var PDF_Height = $("div#mycontent").height();
var canvas_image_width = HTML_Width;
var canvas_image_height = HTML_Height/1.1;
var totalPDFPages = Math.ceil(HTML_Height/PDF_Height)-1;
html2canvas($("div#mycontent")[0],{allowTaint:true},{pagesplit: false},{scrollY: -window.scrollY}).then(function(canvas) {
canvas.getContext('2d');
console.log(canvas.height+" "+canvas.width);
var imgData = canvas.toDataURL("image/jpeg", 0.99);
var pdf = new jsPDF('p', 'pt', [PDF_Width, PDF_Height]);
pdf.addImage(imgData, 'JPEG', top_left_margin, top_left_margin,canvas_image_width,canvas_image_height);
pdf = addWaterMark(pdf);
pdf.save("test.pdf");
});
};
</script>
Now:
Image Now
What i want:
Image what i want
In Developer Tool the Content Height is: 20887
Any Solution for this?

You could try changing to portrait or landscape according to width-height of the image. I was getting some cut images and it got fixed this way.
If width > height use landscape "l", if height > width use portrit "p":
html2canvas(document.getElementById(id_div)).then(canvas => {
var w = document.getElementById(id_div).offsetWidth;
var h = document.getElementById(id_div).offsetHeight;
var img = canvas.toDataURL("image/jpeg", 1);
if(w > h){
var doc = new jsPDF('l', 'mm', [w+100, h+50]);
}
else{
var doc = new jsPDF('p', 'mm', [h+100, w+50]);
}
doc.addImage(img, 'JPEG', 10, 10);
doc.save('chart.pdf');
}).catch(function(e) {
console.log(e.message);
});

Related

Autopaging jspdf when content increases

I'm trying to create a pdf that auto-pages when a content increases.
This is my sample code. Any help would be greatly appreciated :)
HTML code
<div *ngFor="let data of data">
<button click = "previewPdf(data)"> Preview </button>
</div>
Javascript
previewPdf(data) {
var doc = new jsPDF();
let bodyContent = doc.splitTextToSize(data.body, 250);
let lineheight = 6;
let offsety = 5;
this.data.forEach(function(i) {
doc.setFontSize(20);
doc.text(10,10 + lineheight * 0 + offsety, bodyContent);
doc.output("dataurlnewwindow");
});
}
JSON
data[{
"body": "A very long letter content...";
}];
Edit:
I have tried this sample code below and its giving me 2 pages and the last page is blank
previewPdf(data) {
var doc = new jsPDF('p', 'mm', 'a4');
let pageHeight = doc.internal.pageSize.getHeight();
let bodyContent = doc.splitTextToSize(data.body, 250);
let lineheight = 6;
let offsetY = 5;
doc.text(10, 10, bodyContent);
// Before adding new content
let y = 840; // Height position of new content
if (y >= pageHeight) {
doc.addPage();
y = 0 // Restart height position
}
// this.data.forEach(function(i) {
// doc.setFontSize(20);
//
// });
doc.output("dataurlnewwindow");
}
You can use addHTML for that using pagesplit parameter
Edit:
There's another dirty hack where you can calculate the height of the page remaining before adding content
doc = new jsPdf();
pageHeight= pdf.internal.pageSize.height; //get total page height
Then when adding content check height condition like below
pdf.text(x, y, "value");
if (y>=pageHeight)
{
pdf.addPage();
}
Working solution
previewPdf(data) {
var doc = new jsPDF();
var bodyContent = doc.splitTextToSize(data.body, 250);
var pageHeight = doc.internal.pageSize.getHeight();
doc.setFontType("normal");
doc.setFontSize("12");
var y = 15;
for (var i = 0; i < bodyContent.length; i++) {
if (y+10 > pageHeight) {
y = 15;
doc.addPage();
}
doc.text(10, y, bodyContent[i]);
y = y + 7;
}
doc.output('dataurlnewwindow');
}

jsPDF save to serverside

My code is working correct. It's capturing and generating the whole page and prompting download too. But I need this to be saved on my server automatically in "uploads/pdfs/" folder. I actually want to send this through php mail and save it on the server instead of prompting. Please help me.
This is my script:
function makePDF() {
var quotes = document.getElementById('container-fluid');
html2canvas(quotes, {
onrendered: function(canvas) {
//! MAKE YOUR PDF
var pdf = new jsPDF('p', 'pt', 'letter');
for (var i = 0; i <= quotes.clientHeight/980; i++) {
//! This is all just html2canvas stuff
var srcImg = canvas;
var sX = 0;
var sY = 1278*i; // start 980 pixels down for every new page
var sWidth = 990;
var sHeight = 1278;
var dX = 0;
var dY = 0;
var dWidth = 990;
var dHeight = 1278;
window.onePageCanvas = document.createElement("canvas");
onePageCanvas.setAttribute('width', 990);
onePageCanvas.setAttribute('height', 1278);
var ctx = onePageCanvas.getContext('2d');
// details on this usage of this function:
// https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Using_images#Slicing
ctx.drawImage(srcImg,sX,sY,sWidth,sHeight,dX,dY,dWidth,dHeight);
// document.body.appendChild(canvas);
var canvasDataURL = onePageCanvas.toDataURL("image/png", 1.0);
var width = onePageCanvas.width;
var height = onePageCanvas.clientHeight;
//! If we're on anything other than the first page,
// add another page
if (i > 0) {
pdf.addPage(612, 791); //8.5" x 11" in pts (in*72)
}
//! now we declare that we're working on that page
pdf.setPage(i+1);
//! now we add content to that page!
pdf.addImage(canvasDataURL, 'PNG', 0, 0, (width*.62), (height*.62));
}
pdf.save('output.php')
}
});
}

How to save the whole webpage in PDF file using javascript

May i ask how to save the whole webpage as PDF file. I already have a script for saving webpage as PDF file but it can't capture the whole webpage. here's the script: My expectation is to save the whole details of webpage
<script>
function wa(){
genPDF(0,0);
}
function genPDF(x,y){
var doc = new jsPDF();
//alert(document.getElementById("paper").clientWidth);//100.26
var paperwidth = 8.5;
var paperheight = 11;
var ppi = parseFloat(document.getElementById("paper").clientWidth)/paperwidth;
var height = ppi.toFixed(2)*paperheight;//instead of 11 inches
var numpages = Math.ceil(parseFloat(document.getElementById("paper").clientHeight)/height.toFixed(2));
window.scrollTo(0,0);
html2canvas(document.getElementById("paper"),{
onrendered:function (canvas){
var x=0;
while (x<numpages)
{
var y = x*height;
window.scrollTo(0,y);
var img = canvas.toDataURL("image/png");
doc.addImage(img,'JPEG',5,5);
doc.addPage();
x=x+1;
}
doc.save('test.pdf');
}
});`enter code here`
}
</script>
Thank you
try to this man
var pdf = new jsPDF('l', 'mm', [canvas.width, canvas.height]);
var width = pdf.internal.pageSize.width;
var height = pdf.internal.pageSize.height;
pdf.addImage(imgData, 'JPEG', 0, 0, width, height);
pdf.save("download.pdf");

JSPDF Saved file locally gives document [110] error with Acrobat

I have the following JavaScript code https://jsfiddle.net/d72sgwrc/5/ Which suppose to save the image of my screen turn it into Canvas and save it into PDF. Once the file is downloaded on my local machine I am able to view the PDF file within the browser but if I want to open the file on Acrobat PDF viewer I get the following error "There was and error Processing a page. There was a problem readying this document(110). my HTML page is just a table with bunch of generated number.
JS
function exportPDF() {
var pdf = new jsPDF('l', 'px'),
source = $('body')[0];
var canvasToImage = function(canvas) {
var img = new Image();
var dataURL = canvas.toDataURL('image/png');
img.src = dataURL;
return img;
};
var canvasShiftImage = function(oldCanvas, shiftAmt) {
shiftAmt = parseInt(shiftAmt) || 0;
if (!shiftAmt) {
return oldCanvas;
}
var newCanvas = document.createElement('canvas');
newCanvas.height = oldCanvas.height - shiftAmt;
newCanvas.width = oldCanvas.width;
var ctx = newCanvas.getContext('2d');
var img = canvasToImage(oldCanvas);
ctx.drawImage(img, 0, shiftAmt, img.width, img.height, 0, 0, img.width, img.height);
return newCanvas;
};
var canvasToImageSuccess = function(canvas) {
var pdf = new jsPDF('l', 'px'),
pdfInternals = pdf.internal,
pdfPageSize = pdfInternals.pageSize,
pdfScaleFactor = pdfInternals.scaleFactor,
pdfPageWidth = pdfPageSize.width,
pdfPageHeight = pdfPageSize.height,
totalPdfHeight = 0,
htmlPageHeight = canvas.height,
htmlScaleFactor = canvas.width / (pdfPageWidth * pdfScaleFactor),
safetyNet = 0;
while (totalPdfHeight < htmlPageHeight && safetyNet < 15) {
var newCanvas = canvasShiftImage(canvas, totalPdfHeight);
pdf.addImage(newCanvas, 'png', 0, 0, pdfPageWidth, 0, null, 'NONE');
totalPdfHeight += (pdfPageHeight * pdfScaleFactor * htmlScaleFactor);
if (totalPdfHeight < htmlPageHeight) {
pdf.addPage();
}
safetyNet++;
}
pdf.save('test.PDF');
};
html2canvas(source, {
onrendered: function(canvas) {
canvasToImageSuccess(canvas);
}
});
}
exportPDF();
HTML is in JSFiddle as I cant paste it here, I get error https://jsfiddle.net/d72sgwrc/5/
I am using the following JS libraries
https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.2/jspdf.debug.js
https://fastcdn.org/FileSaver.js/1.1.20151003/FileSaver.min.js
https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js
https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.2/jspdf.min.js
I ran into this same issue. Upgrading to jsPDF 1.3.4 solved it for me.
The version of jspdf debug is very important.
<script src="https://code.jquery.com/jquery-3.1.1.js"></script>
<script src="https://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.2/jspdf.debug.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.2/jspdf.min.js"></script>
<script src="https://cdn.rawgit.com/MrRio/jsPDF/master/libs/png_support/png.js"></script>
<script src="https://cdn.rawgit.comMrRio/jsPDF/master/plugins/addimage.js"></script>
<script src="https://cdn.rawgit.com/MrRio/jsPDF/master/libs/png_support/zlib.js"></script>
I have had the same issue, I add all parameters of the function.
// Set PDF
let doc = new jsPDF('p', 'mm', [297, 210]);
doc.addImage(dataURL,
"JPEG", marginPDF, 15, widthImgPDF, heigthImgPDF, "fotoX", "SLOW");
doc.save("Fire Inspection - " + questID + ".pdf");

Import long html into split PDF

My scenario is:
On clicking a button, import datas on a html into a PDF file.
Since this PDF must have some complicated required style, so my first step is to transfer this page into a image using html2canvas.js and then import this image to a PDF with jsPDF.js
And when the data is too large the PDF must be split to hold all the data,to do this,so I used the codes here: https://github.com/MrRio/jsPDF/pull/397
My problem is: on firefox the splited page on PDF on page 2 or 3...cannot be shown, they are totally blank. but on page 1 it is fine. (this is for firefox)
I tested other browsers they are all fine. pls someone could throw some light on how to fix this?
Here is my plnkr:
http://plnkr.co/edit/ElvAsriK2nssq2U9pgKX?p=preview
function initTemplate(){
datas=getData();
var templateData=_.template($('#tpl').html(), datas);
$('#tplW').html(templateData);
getPDF();
// $('#tplW').append(_.template($('#tpl').html(), datas));
// $('body').html( _.template($('#tpl').html(), datas));
}
function getData(){
var htmlData=$(".MsoNormalTable .inner").find("tr.tablerow");
var datas=[];
$.each(htmlData,function(i,v){
var d=[];
var tds=$(v).find("td");
$.each(tds,function(index,val){
d.push($(val).text());
});
datas.push(d);
});
return datas;
}
function getPDF() {
// initTemplate();
html2canvas($('#tplW')[0], {
onrendered: function(canvas){
canvasToImageSuccess(canvas);
}
});
function canvasToImage (canvas){
var img = new Image();
var dataURL = canvas.toDataURL('image/png');
img.src = dataURL;
return img;
};
function canvasShiftImage (oldCanvas,shiftAmt){
shiftAmt = parseInt(shiftAmt) || 0;
if(!shiftAmt){ return oldCanvas; }
var newCanvas = document.createElement('canvas');
newCanvas.height = oldCanvas.height - shiftAmt;
newCanvas.width = oldCanvas.width;
var ctx = newCanvas.getContext('2d');
var img = canvasToImage(oldCanvas);
ctx.drawImage(img,0, shiftAmt, img.width, img.height, 0, 0, img.width, img.height);
return newCanvas;
};
function canvasToImageSuccess (canvas){
var pdf = new jsPDF('l','px'),
pdfInternals = pdf.internal,
pdfPageSize = pdfInternals.pageSize,
pdfScaleFactor = pdfInternals.scaleFactor,
pdfPageWidth = pdfPageSize.width,
pdfPageHeight = pdfPageSize.height,
totalPdfHeight = 0,
htmlPageHeight = canvas.height,
htmlScaleFactor = canvas.width / (pdfPageWidth * pdfScaleFactor),
safetyNet = 0;
while(totalPdfHeight < htmlPageHeight && safetyNet < 15){
var newCanvas = canvasShiftImage(canvas, totalPdfHeight);
pdf.addImage(newCanvas, 'png', 0, 0, pdfPageWidth, 0, null, 'NONE');
totalPdfHeight += (pdfPageHeight * pdfScaleFactor * htmlScaleFactor);
if(totalPdfHeight < htmlPageHeight){
pdf.addPage();
}
safetyNet++;
}
pdf.save('test.pdf');
};
}
You should use canvas-to-blob and FileSaver.js
and modify this line:
pdf.save('test.pdf');
to this:
var data = pdf.output();
var buffer = new ArrayBuffer(data.length);
var array = new Uint8Array(buffer);
for (var i = 0; i < data.length; i++) {
array[i] = data.charCodeAt(i);
}
var blob = new Blob(
[array],
{type: 'application/pdf', encoding: 'raw'}
);
saveAs(blob, "test.pdf");
You can check it out here.
It worked for me on Mac, Firefox.
I found this solution here.

Categories