Download a Div in a HTML Page as PDF Using JavaScript

Download a div in a HTML page as pdf using javascript

You can do it using jsPDF

HTML:

<div id="content">
<h3>Hello, this is a H3 tag</h3>

<p>A paragraph</p>
</div>
<div id="editor"></div>
<button id="cmd">generate PDF</button>

JavaScript:

var doc = new jsPDF();
var specialElementHandlers = {
'#editor': function (element, renderer) {
return true;
}
};

$('#cmd').click(function () {
doc.fromHTML($('#content').html(), 15, 15, {
'width': 170,
'elementHandlers': specialElementHandlers
});
doc.save('sample-file.pdf');
});

save/download html div as image/pdf

The simplest method for HTML to PDF is to use the browser output e.g. Chrome

Sample Image

And this can be run as a headless print, here I use Windows Edge but you can of course use Edge or Chrome on other platforms. On Windows you may need to run that as Admin, it should be less than one blink, so fast I did not think it was done.

NOTE recently the switch --disable-gpu was removed from the options so may not be needed.

"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --headless --disable-gpu --run-all-compositor-stages-before-draw --print-to-pdf="C:\Users\WDAGUtilityAccount\Desktop\SandBox\division.pdf" --print-to-pdf-no-header "C:\Users\WDAGUtilityAccount\Desktop\SandBox\division.html"

Sample Image

However note that due to cross site security some images are missing so we need to ensure they are local and simply remove the remote part of url

Sample Image

Add this at the end just for a tidy approach </body></html> and use this as your heading

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<!-- saved from url=https://stackoverflow.com/questions/71998862 -->
<html><head>

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" />
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>Lorum Ipsum</title>

<meta name="GENERATOR" content="KJs Template Builder V 2022-04">

<meta http-equiv="Content-Style-Type" content="text/css"><style>
@media print {
@page {
/* For different margins – use the standard CSS margin property: north, east, south, west, here it is one value */
margin: 0;

/* Browser default, customisable by the user if using the print dialogue. */
size: auto;

/* Different width and height. here using stated width="1000" height="500" can be px or pt or cm. For square, just use one value or use name like A6 landscape; note this is over-riding any above size: but we need to bump up for browser rounding*/
size: 1020px 520px;
}
body { margin: 0; }
}
</style></head><body bgcolor="white" text="black" link="blue" vlink="purple" alink="red">

Generate pdf from HTML in div using Javascript

jsPDF is able to use plugins. In order to enable it to print HTML, you have to include certain plugins and therefore have to do the following:

  1. Go to https://github.com/MrRio/jsPDF and download the latest Version.
  2. Include the following Scripts in your project:

    • jspdf.js
    • jspdf.plugin.from_html.js
    • jspdf.plugin.split_text_to_size.js
    • jspdf.plugin.standard_fonts_metrics.js

If you want to ignore certain elements, you have to mark them with an ID, which you can then ignore in a special element handler of jsPDF. Therefore your HTML should look like this:

<!DOCTYPE html>
<html>
<body>
<p id="ignorePDF">don't print this to pdf</p>
<div>
<p><font size="3" color="red">print this to pdf</font></p>
</div>
</body>
</html>

Then you use the following JavaScript code to open the created PDF in a PopUp:

var doc = new jsPDF();          
var elementHandler = {
'#ignorePDF': function (element, renderer) {
return true;
}
};
var source = window.document.getElementsByTagName("body")[0];
doc.fromHTML(
source,
15,
15,
{
'width': 180,'elementHandlers': elementHandler
});

doc.output("dataurlnewwindow");

For me this created a nice and tidy PDF that only included the line 'print this to pdf'.

Please note that the special element handlers only deal with IDs in the current version, which is also stated in a GitHub Issue. It states:

Because the matching is done against every element in the node tree, my desire was to make it as fast as possible. In that case, it meant "Only element IDs are matched" The element IDs are still done in jQuery style "#id", but it does not mean that all jQuery selectors are supported.

Therefore replacing '#ignorePDF' with class selectors like '.ignorePDF' did not work for me. Instead you will have to add the same handler for each and every element, which you want to ignore like:

var elementHandler = {
'#ignoreElement': function (element, renderer) {
return true;
},
'#anotherIdToBeIgnored': function (element, renderer) {
return true;
}
};

From the examples it is also stated that it is possible to select tags like 'a' or 'li'. That might be a little bit to unrestrictive for the most usecases though:

We support special element handlers. Register them with jQuery-style
ID selector for either ID or node name. ("#iAmID", "div", "span" etc.)
There is no support for any other type of selectors (class, of
compound) at this time.

One very important thing to add is that you lose all your style information (CSS). Luckily jsPDF is able to nicely format h1, h2, h3 etc., which was enough for my purposes. Additionally it will only print text within text nodes, which means that it will not print the values of textareas and the like. Example:

<body>
<ul>
<!-- This is printed as the element contains a textnode -->
<li>Print me!</li>
</ul>
<div>
<!-- This is not printed because jsPDF doesn't deal with the value attribute -->
<input type="textarea" value="Please print me, too!">
</div>
</body>

JavaScript Export Div to PDF

You can't set param jsPDF() fucntion as data object. a4 is default format. No need to set. You can visit this link to refer more: https://micropyramid.com/blog/export-html-web-page-to-pdf-using-jspdf/

<script language="javascript">
var cache_width = $('#renderPDF').width(); //Criado um cache do CSS
var a4 = [595.28, 841.89]; // Widht e Height de uma folha a4

$(document).on("click", '#btnPrint', function () {
// Setar o width da div no formato a4
$("#renderPDF").width((a4[0] * 1.33333) - 80).css('max-width', 'none');

// Aqui ele cria a imagem e cria o pdf
html2canvas($('#renderPDF'), {
onrendered: function (canvas) {
var img = canvas.toDataURL("image/jpeg", 1.0);
//var doc = new jsPDF({ unit: 'px', format: 'a4' });//this line error
var doc = new jsPDF('landscape'); // default is portrait
doc.addImage(img, 'JPEG', 20, 20);
doc.save('NOME-DO-PDF.pdf');
//Retorna ao CSS normal
$('#renderPDF').width(cache_width);
}
});
});
</script>

Converting Div into PDF INCLUDING images

One solution is to use the html2canvas or rasterizeHTML library. They create a canvas of the HTML page which you can then add to the PDF using addHTML

$('#cmd').click(function() {
var options = {};
var pdf = new jsPDF('p', 'pt', 'a4');
pdf.addHTML($("#content"), 15, 15, options, function() {
pdf.save('pageContent.pdf');
});
});

Demo

Export HTML page to PDF on user click using JavaScript

This is because you define your "doc" variable outside of your click event. The first time you click the button the doc variable contains a new jsPDF object. But when you click for a second time, this variable can't be used in the same way anymore. As it is already defined and used the previous time.

change it to:

$(function () {

var specialElementHandlers = {
'#editor': function (element,renderer) {
return true;
}
};
$('#cmd').click(function () {
var doc = new jsPDF();
doc.fromHTML(
$('#target').html(), 15, 15,
{ 'width': 170, 'elementHandlers': specialElementHandlers },
function(){ doc.save('sample-file.pdf'); }
);

});
});

and it will work.



Related Topics



Leave a reply



Submit