Hello all i am using jsPDF along with html2canvas. I have seen in the add.HTML that you can hide some divs. Is it possible to have this ability in html2canvas.
I am actually making a pdf but i want some divs of the main div to not to be printed in the pdf.
This is my html2canvas code.
html2canvas(quotes, {
onrendered: function(canvas) {
//! MAKE YOUR PDF
var pdf = new jsPDF('p', 'pt', 'A4');
for (var i = 0; i <= quotes.clientHeight/980; i++) {
//! This is all just html2canvas stuff
var srcImg = canvas;
var sX = 0;
var sY = 980*i; // start 980 pixels down for every new page
var sWidth = 900;
var sHeight = 980;
var dX = 0;
var dY = 0;
var dWidth = 900;
var dHeight = 980;
window.onePageCanvas = document.createElement("canvas");
onePageCanvas.setAttribute('width', 900);
onePageCanvas.setAttribute('height', 980);
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', 20, 40, (width*.62), (height*.62));
}
//! after the for loop is finished running, we save the pdf.
pdf.save('Test.pdf');
}
});
Any kind of help would be much appreciated. Thankx in advance.
I finally solved this with searching more about html2canvas.
You just need to add
data-html2canvas-ignore="true"
in your html element to hide that div from rendering.
like this
<div class="anyclass" data-html2canvas-ignore="true">any data</div>
Related
I want to generate a pdf file from html template which is not loaded in browser. The basic idea is to load html in some javascript variable and convert it to canvas/pdf without showing on browser.
Right now I am doing this by adding a frame on currently opened page and then removing frame after successfully generating it's pdf. But this is showing some fluctuation on the screen and scrollbar.
Current Code:
$http.get("static/templates/pdf-template.html")
.then(function (response) {
var html_string = response.data;
var iframe = document.createElement('iframe');
iframe.style.width = '100%';
document.body.appendChild(iframe);
setTimeout(function () {
var iframedoc = iframe.contentDocument || iframe.contentWindow.document;
iframedoc.body.innerHTML = html_string;
var divHeight = iframedoc.body.scrollHeight;
var divWidth = iframedoc.body.scrollWidth;
var ratio = divHeight / divWidth;
html2canvas(iframedoc.body, {
onrendered: function (canvas) {
var pdf = new jsPDF();
var width = pdf.internal.pageSize.width;
var height = pdf.internal.pageSize.height;
height = ratio * width;
var imgData = canvas.toDataURL('image/jpeg', 1.0);
pdf.addImage(imgData, 'JPEG', 0, 0, width, height);
pdf.save('pdf');
document.body.removeChild(iframe);
}
});
}, 10);
});
Please suggest solution without using iframe.
I face this issue just now. I didn't any proper way. Even though I get a solution maybe, it will work. you just make your non-wanted portion of html style z-index: -1; and wanted portion of html style z-index: 1;
I have an image on canvas or a set of images that i draw on the canvas. I can draw them fine but I want to change the window level of the image on canvas by dragging the mouse over it. I've seen a lot of external javascript api's but they're quite huge and i don't want to use them for this purpose.
here's my JSFIDDLE that is basically drawing an image on the canvas
this is how my code looks
// Grab the Canvas and Drawing Context
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
// Create an image element
var img = document.createElement('IMG');
// When the image is loaded, draw it
img.onload = function () {
ctx.drawImage(img, 0, 0);
}
// Specify the src to load the image
img.src = "http://imgsv.imaging.nikon.com/lineup/lens/zoom/normalzoom/af-s_dx_18-140mmf_35-56g_ed_vr/img/sample/sample5_l.jpg";
i need something with basic JS or JQuery. it would be great if you can point me in the right direction using a sample code.
Thanks in advance.
If you want to use JavaScript, try something like:
<script>
var c = document.getElementById("drawingboard");
var ctx = c.getContext("2d");
var mouseDown = 0;
document.body.ontouchstart = function() {
mouseDown+=1;
}
document.body.ontouchend = function() {
mouseDown-=1;
}
function draw(event){
ctx.color='gold';
ctx.fillStyle = "lime";
ctx.drawImage(img,event.clientX,event.clientY);}
</script>
This is what I gained after some research:
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const rangeMin = level - window / 2;
const rangeMax = level + window / 2;
const totalSize = canvas.width * canvas.height;
for (let idx = 0; idx < totalSize; idx++) {
if (imageData.data[idx] < rangeMin) {
imageData.data[idx] = 0;
} else if (imageData.data[idx] > rangeMax) {
imageData.data[idx] = 255;
}
}
ctx.putImageData(imageData, 0, 0);
I have a script that uses HTML2Canvas to take a screenshot of a div within the page, and then converts it to a pdf using jsPDF.
The problem is the pdf that is generated is only one page, and the screenshot requires more than one page in some instances. For example the screenshot is larger than 8.5x11. The width is fine, but I need it to create more than one page to fit the entire screenshot.
Here is my script:
var pdf = new jsPDF('portrait', 'pt', 'letter');
$('.export').click(function() {
pdf.addHTML($('.profile-expand')[0], function () {
pdf.save('bfc-schedule.pdf');
});
});
Any ideas how I could modify that to allow for multiple pages?
pdf.addHtml does not work if there are svg images on the web page.
I copy the solution here, based on the picture being in a canvas already.
Here are the numbers (paper width and height) that I found to work. It still creates a little overlap part between the pages, but good enough for me. if you can find an official number from jsPDF, use them.
var imgData = canvas.toDataURL('image/png');
var imgWidth = 210;
var pageHeight = 295;
var imgHeight = canvas.height * imgWidth / canvas.width;
var heightLeft = imgHeight;
var doc = new jsPDF('p', 'mm');
var position = 0;
doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
heightLeft -= pageHeight;
while (heightLeft >= 0) {
position = heightLeft - imgHeight;
doc.addPage();
doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
heightLeft -= pageHeight;
}
doc.save( 'file.pdf');`
you can use page split option of addhtml like this:
var options = {
background: '#fff',
pagesplit: true
};
var doc = new jsPDF(orientation, 'mm', pagelayout);
doc.addHTML(source, 0, 0, options, function () {
doc.save(filename + ".pdf");
HideLoader();`enter code here`
});
Note: This will break the html on multiple pages but these pages will get stretched. Stretching is a issue in addhtml till now and i am still not able to find on internet how to solve this issue.
I was able to get it done using async functionality.
(async function loop() {
var pages = [...]
for (var i = 0; i < pages.length; i++) {
await new Promise(function(resolve) {
html2canvas(pages[i], {scale: 1}).then(function(canvas) {
var img=canvas.toDataURL("image/png");
doc.addImage(img,'JPEG', 10, 10);
if ((i+1) == pages.length) {
doc.save('menu.pdf');
} else {
doc.addPage();
}
resolve();
});
});
}
})();
This is my aproach, also with jspdf and html2canvas which did a very good job for me:
I am using a wrapper node which holds the content to be converted to pdf:
<div id="main-content">
<!-- the content goes here -->
</div>
<!-- and a button somewhere in the dom -->
<a href="javascript:genPDF()">
<i class="far fa-file-pdf"></i> Download PDF
</a>
This is the JS integration ( I only checked this versions ) and call:
<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 type="text/javascript">
const documentSlug = "some Slug";
const documentTitle ="Some Title";
function genPDF(){
let html2pdf = new pdfView();
html2pdf.generate();
}
</script>
And here you can see the pdf generation. I encapsulated the generation part in an extra js object (you need to include this file also):
//assuming jquery is in use
let pdfView = function(){
//assuming documentSlug is a constant set earlier
this.documentSlug = documentSlug;
//assuming documentTitle is a constant set earlier
this.documentTitle = documentTitle;
//in this html node the part which shall be converted to pdf
this.nodeId = "main-content";
};
pdfView.prototype.generate = function(){
let self = this;
this.prepareDocumentToPrint();
//variables
let HTML_Width = $("#"+self.nodeId).width();
let HTML_Height = $("#"+self.nodeId).height();
let top_left_margin = 15;
let PDF_Width = HTML_Width+(top_left_margin*2);
let PDF_Height = (PDF_Width*1.5)+(top_left_margin*2);
this.pdfWidth = PDF_Width;
this.pdfHeight = PDF_Height;
let canvas_image_width = HTML_Width;
let canvas_image_height = HTML_Height;
let totalPDFPages = Math.ceil(HTML_Height/PDF_Height)-1;
html2canvas($("#"+self.nodeId)[0],{allowTaint:true, scale: 2}).then(function(canvas) {
canvas.getContext('2d');
//console.log(canvas.height+" "+canvas.width);
let imgData = canvas.toDataURL("image/jpeg", 1.0);
let pdf = new jsPDF('p', 'mm', [PDF_Width, PDF_Height]);
pdf.addImage(imgData, 'JPG', top_left_margin, top_left_margin,canvas_image_width,canvas_image_height);
pdf = self.addPdfHeader(pdf);
pdf = self.addPdfFooter(pdf, 1);
for (let i = 1; i <= totalPDFPages; i++) {
pdf.addPage(PDF_Width, PDF_Height);
pdf.addImage(imgData, 'JPG', top_left_margin, -(PDF_Height*i)+(top_left_margin*4) + top_left_margin,canvas_image_width,canvas_image_height);
pdf = self.addPdfHeader(pdf);
pdf = self.addPdfFooter(pdf, (i+1));
}
pdf.save(self.documentSlug+".pdf");
self.resetDocumentAfterPrint();
});
};
//this one sets a fixed viewport, to be able to
//get the same pdf also on a mobile device. I also
//have a css file, which holds the rules for the
//document if the body has the .printview class added
pdfView.prototype.prepareDocumentToPrint = function(){
let viewport = document.querySelector("meta[name=viewport]");
viewport.setAttribute('content', 'width=1280, initial-scale=0.1');
$('body').addClass("printview");
window.scrollTo(0,0);
};
pdfView.prototype.addPdfHeader = function(pdf){
pdf.setFillColor(255,255,255);
pdf.rect(0, 0, this.pdfWidth, 40, "F");
pdf.setFontSize(40);
pdf.text("Document: "+this.documentTitle+" - Example Lmtd. Inc. (Whatsoever)", 50, 22);
return pdf;
};
pdfView.prototype.addPdfFooter = function(pdf, pageNumber){
pdf.setFillColor(255,255,255);
pdf.rect(0, pdf.internal.pageSize.height - 40, this.pdfWidth, this.pdfHeight, "F");
pdf.setFontSize(40);
pdf.text("Seite "+pageNumber, 50, pdf.internal.pageSize.height - 20);
return pdf;
};
//and this one resets the doc back to normal
pdfView.prototype.resetDocumentAfterPrint = function(){
$('body').removeClass("printview");
let viewport = document.querySelector("meta[name=viewport]");
viewport.setAttribute('content', 'device-width, initial-scale=1, shrink-to-fit=no');
};
my css example for the .printview case:
body.printview #header,
body.printview footer
{
display: none !important;
}
body.printview{
margin-top: 0px !important;
}
body.printview #main-content{
margin-top: 0px !important;
}
body.printview h1{
margin-top: 40px !important;
}
enjoy
Contributions to #Code Spy for the Link you provided, which was the basis for this aporach.
Found out the solution to this,putting a rectangle as border for each pdf page and also starting the second page and other pages from a litte down by making difference in pageHeight,hope this will resolve for few...
html2canvas(myCanvas).then(function (canvas) {
var imgWidth = 210;
var pageHeight = 290;
var imgHeight = canvas.height * imgWidth / canvas.width;
var heightLeft = imgHeight;
var doc = new jsPDF('p', 'mm');
var position = 0;
var pageData = canvas.toDataURL('image/jpeg', 1.0);
var imgData = encodeURIComponent(pageData);
doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
doc.setLineWidth(5);
doc.setDrawColor(255, 255, 255);
doc.rect(0, 0, 210, 295);
heightLeft -= pageHeight;
while (heightLeft >= 0) {
position = heightLeft - imgHeight;
doc.addPage();
doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
doc.setLineWidth(5);
doc.setDrawColor(255, 255, 255);
doc.rect(0, 0, 210, 295);
heightLeft -= pageHeight;
}
doc.save('file.pdf');
});
};
I am trying to convert html into a pdf client side using jspdf.
The code I have currently is this: (most of this is for pagebreaks
$(document).ready(function() {
$("#runpdf").click(function(event) {
var partsec = $("main_body page1");
html2canvas(document.body, {
logging: true,
profile: true,
allowTaint: true,
letterRendering: true,
onrendered: function(canvas) {
var imageData = canvas.toDataURL("image/jpeg");
var image = new Image();
image = Canvas2Image.convertToJPEG(canvas);
var doc = new jsPDF();
doc.page=1;
//FIRST PAGE****************************************
doc.addImage(imageData, 'JPEG', -115, 5, 440 , 875);
var croppingYPosition = 1250;
count = (image.height) / 3300;
for (var i =1; !(i >= count); i++) {
doc.addPage();
var sourceX = 0;
var sourceY = croppingYPosition;
var sourceWidth = image.width;
var sourceHeight = 1100;
var destWidth = 1600;
var destHeight = 1090;
var destX = -450
var destY = 0;
var canvas1 = document.createElement('canvas');
canvas1.setAttribute('height', 1200);
canvas1.setAttribute('width', destWidth);
var ctx = canvas1.getContext("2d");
ctx.drawImage(image,
sourceX,
sourceY,
sourceWidth,
sourceHeight,
destX,
destY,
destWidth,
destHeight);
var image2 = new Image();
image2 = Canvas2Image.convertToJPEG(canvas1);
image2Data = image2.src;
doc.addImage(image2Data, 'JPEG', 12, 10);
croppingYPosition += 1230;
}
doc.save('test.pdf');
}
});
});
});
However, I would like to, rather than using arbitrary, hard-coded pixel values for setting pagebreaks, have it search for a specific html tag, id, class, or some other identifier to search for at which to make a page break. For example, The code looks down the html until it finds something of class .pagebreak at which point it takes everything above it and stretches it to fit a pdf page (I can do the stretchy part, I just need help with the actual page break) and then looks right after the page break and starts over. Hope this made sense. Thanks!
I have a table(columns aligned differently) which is to be saved as pdf.I converted the table to image using html2canvas and then saved the image into pdf usng jspdf. It works well if the size of the image is less than or equal to page size of pdf but if the image size is bigger than the page size then it saves only first page of pdf(which has only a part of the image) and rest of the image is not displayed/saved in pdf. here the javascript code I used.
$("#btnVC_saveGLSummary").click(function () {
html2canvas($("#tblSaveAsPdf1"), {
onrendered: function (canvas) {
var myImage = canvas.toDataURL("image/jpeg");
var d = new Date().toISOString().slice(0, 19).replace(/-/g, "");
filename = 'report_' + d + '.pdf';
var doc = new jsPDF();
doc.addImage(myImage, 'JPEG', 12, 10);
doc.save(filename);
}
});
});
Any ideas how to get the remaining part of the image on the second page of pdf.
It works for html2canvas and jspdf.
var imgData = canvas.toDataURL('image/png');
var imgWidth = 210;
var pageHeight = 295;
var imgHeight = canvas.height * imgWidth / canvas.width;
var heightLeft = imgHeight;
var doc = new jsPDF('p', 'mm');
var position = 10; // give some top padding to first page
doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
heightLeft -= pageHeight;
while (heightLeft >= 0) {
position += heightLeft - imgHeight; // top padding for other pages
doc.addPage();
doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
heightLeft -= pageHeight;
}
doc.save( 'file.pdf');
I use this method
function makePDF(){
var quotes = document.getElementById('container-fluid');
html2canvas(quotes, {
onrendered: function(canvas) {
//! MAKE YOUR PDF
var pdf = new jsPDF('p', 'pt', 'a4');
for (var i = 0; i <= quotes.clientHeight/980; i++) {
//! This is all just html2canvas stuff
var srcImg = canvas;
var sX = 0;
var sY = 1120*i; // start 980 pixels down for every new page
var sWidth = 778;
var sHeight = 1120;
var dX = 0;
var dY = 0;
var dWidth = 778;
var dHeight = 1120;
window.onePageCanvas = document.createElement("canvas");
onePageCanvas.setAttribute('width', 778);
onePageCanvas.setAttribute('height', 1120);
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(595, 842); //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*.72), (height*.71));
}
//! after the for loop is finished running, we save the pdf.
pdf.save('Test3.pdf');
}
});
}
I hope it will be helpful
Inspired by another stack overflow response
This was answered further up in a similar way, but I felt I wanted to give an example leaving out unnecessary code:
You can easily run through all pages and put 'watermark' texts or other items on every page like this:
let pdf = new jspdf();
// do something that creates multiple pages
for (let pageNumber = 1; pageNumber <= pdf.getNumberOfPages(); pageNumber++) {
pdf.setPage(pageNumber)
pdf.addImage('myImgOnEveryPage.png', 10,10,20,20);
pdf.text('My text on every page, 12, 12);
}
(JSPDF version 2.1.1)
var ctx = canvas.getContext("2d");
ctx.drawImage(image, 0, 1025, sectionWidth, 1250, 0, 0, 1800, 950);
var image2 = new Image();
image2 = Canvas2Image.convertToJPEG(canvas);
image2Data = image2.src;
doc.addImage(image2Data, 'JPEG', -105, 5, 440, 325);
Basically, you get the context of your canvas and then you can use the drawImage function to create a new Image that is a portion of your original canvas. The parameters of drawImage are:
drawImage(img, startX, startY, originalW, originalH, destX, dextY, destW, destH);
Where startX and Y are your starting locations for the clipping on the original images, original W and H are the height and width of your clipping (on the original picture), basically how much to clip, destX and Y are where on your PDF to put the new clipping and destH and W define how big the clipping is when placed on the canvas (they stretch the image once you've clipped it)Hope this helped, Cheers
You can easily do this by adding small tweak in your own code.
$("#btnVC_saveGLSummary").click(function () {
html2canvas($("#tblSaveAsPdf1"), {
onrendered: function (canvas) {
var myImage = canvas.toDataURL("image/jpeg");
var d = new Date().toISOString().slice(0, 19).replace(/-/g, "");
filename = 'report_' + d + '.pdf';
var doc = new jsPDF();
var totalPages = doc.internal.getNumberOfPages();
for(let i = 1; i < totalPages; i++) {
doc.setPage(i);
doc.addImage(myImage, 'JPEG', 12, 10);
}
doc.save(filename);
}
});
});