122

I have a content div with the id as "content". In the content div I have some graphs and some tables. I want to download that div as a pdf when user click on download button. Is there a way to do that using javascript or jQuery?

3
  • 1
    code.google.com/p/jspdf is the best library i know of which can do this. Commented Jun 25, 2013 at 9:05
  • How can I use jsPDF for downloading a content in specific div? from what i see in the examples in their site it cant be done. Commented Jun 25, 2013 at 9:12
  • @alvinarul Note that jsPDF is currently not maintained and has some significant performance issues for multi-page documents. Commented Dec 12, 2023 at 1:05

8 Answers 8

132

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'); }); 
Sign up to request clarification or add additional context in comments.

20 Comments

I have a problem here. The css I have added in here is not getting applied in the pdf file. Also I have some graphs too..those r not coming in the pdf. What should I do to get those?
jsPDF doesn't format tables properly either, it just interprets td/th as display:block;
Using the above code we can able to create a pdf only one time. But for the second time it is not working. To make it work, check this answer by @kristof-feys, We need to declare the doc variable inside the click function.
This is nice, just a shame the css doesn't get rendered :/
I gave my days to work with jsPDF, and in the end what I found is, it is not rendering the CSS. My table looks too bad, not able to add any image properly. jsPDF is good for nothing.
|
63

Content inside a <div class='html-content'>....</div> can be downloaded as pdf with styles using jspdf & html2canvas.

You need to refer both js libraries,

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.min.js"></script> <script type="text/javascript" src="https://html2canvas.hertzen.com/dist/html2canvas.js"></script> 

Then call below function,

//Create PDf from HTML... function CreatePDFfromHTML() { var HTML_Width = $(".html-content").width(); var HTML_Height = $(".html-content").height(); var top_left_margin = 15; var PDF_Width = HTML_Width + (top_left_margin * 2); var PDF_Height = (PDF_Width * 1.5) + (top_left_margin * 2); var canvas_image_width = HTML_Width; var canvas_image_height = HTML_Height; var totalPDFPages = Math.ceil(HTML_Height / PDF_Height) - 1; html2canvas($(".html-content")[0]).then(function (canvas) { var imgData = canvas.toDataURL("image/jpeg", 1.0); var pdf = new jsPDF('p', 'pt', [PDF_Width, PDF_Height]); pdf.addImage(imgData, 'JPG', top_left_margin, top_left_margin, canvas_image_width, canvas_image_height); for (var 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),canvas_image_width,canvas_image_height); } pdf.save("Your_PDF_Name.pdf"); $(".html-content").hide(); }); } 

Ref: pdf genration from html canvas and jspdf.

May be this will help someone.

4 Comments

This worked great for me, thanks. It preserves all the styling but it does have some limitations (creates the PDF as an image so it's not searchable; seems to also be slightly blurry).
how to set page break if half of content fails to fit on one page?
Worked very fine to me. The only problem was that some of my SVG icons were not rendered!
Amazing! This worked beautifully for me. In my case, I just needed to export a div that contained a few tables and graphs. Thanks so much!
4

Your solution requires some Ajax method to pass the html to a back-end server that has a html to pdf facility and then returning the pdf output generated back to the browser.

First setting up the client side code, we will setup the jQuery code as

var options = { "url": "/pdf/generate/convert_to_pdf.php", "data": "data=" + $("#content").html(), "type": "post", }; $.ajax(options); 

Then intercept the data from the html2pdf generation script (somewhere from the internet).

convert_to_pdf.php looks like this:

<?php $html = $_POST['data']; $pdf = html2pdf($html); header("Content-Type: application/pdf"); //check this is the proper header for pdf header("Content-Disposition: attachment; filename='some.pdf';"); echo $pdf; ?> 

6 Comments

What did u mean by "has a htmltopdf facility"??
is it ok to refer the same url or should i change it?
You would need a slightly different url so you can differentiate between the two content
how should that url be? Can you give an example??
You'll be screwed if the CSS is linked though because your back-end program won't know where to find the styles unless it can grab the CSS file and apply the styles from within the file.
|
2

AFAIK there is no native jquery function that does this. Best option would be to process the conversion on the server. How you do this depends on what language you are using (.net, php etc.). You can pass the content of the div to the function that handles the conversion, which would return a pdf to the user.

1 Comment

hi dear friend, pay attention to question... Download a div in a HTML page as pdf using javascript
1

Thought I would add my two cents, as some of the answers here are over 10 years old and have some significant performance bottlenecks.

Using @Vishnu S' answer with some minor modifications, we go from 910.52 ms per page to just 112.49 ms per page. A reduction of over 87%!

// SEE: https://www.npmjs.com/package/html-to-image import { toJpeg } from "html-to-image"; // The dimensions of a single A4 page; what we're basing the PDF document on. const A4_MARGIN_PX = 40; const A4_CONTENT_WIDTH_PX = 640; const A4_CONTENT_HEIGHT_PX = A4_CONTENT_WIDTH_PX * A4_PORTRAIT_RATIO; const A4_TOTAL_WIDTH_PX = A4_CONTENT_WIDTH_PX + (A4_MARGIN_PX * 2); const A4_TOTAL_HEIGHT_PX = A4_CONTENT_HEIGHT_PX + (A4_MARGIN_PX * 2); // Will return a data URI string. const htmlToPdf = async (element: HTMLElement): Promise<string> => { const elementBounds = element.getBoundingClientRect(); const pdfBounds = [A4_TOTAL_WIDTH_PX, A4_TOTAL_HEIGHT_PX]; const pdf = new jsPDF("portrait", "px", pdfBounds); // These settings are optional, but I've found they help with file size and retina display support. const pdfAsImage = await toJpeg(element, { quality: 0.95, pixelRatio: 2, }); const totalPages = Math.ceil(elementBounds.height / A4_CONTENT_HEIGHT_PX); for(let pageNum = 0; pageNum < totalPages; pageNum++){ // Add a page as long as it's not the first page, as jsPDF does this automatically. // This will focus the added page, as a side-effect. if(pageNum > 0) pdf.addPage(pdfBounds); pdf.addImage( pdfAsImage, "jpg", // Reposition the image based on the page number. A4_MARGIN_PX, A4_MARGIN_PX - (pageNum * (A4_CONTENT_HEIGHT_PX + (A4_MARGIN_PX * 2))), A4_CONTENT_WIDTH_PX, elementBounds.height ); } return pdf.output("datauristring"); }; 

Comments

0

Yes, it's possible to To capture div as PDFs in JS. You can can check the solution provided by https://grabz.it. They have nice and clean JavaScript API which will allow you to capture the content of a single HTML element such as a div or a span.

So, yo use it you will need and app+key and the free SDK. The usage of it is as following:

Let's say you have a HTML:

<div id="features"> <h4>Acme Camera</h4> <label>Price</label>$399<br /> <label>Rating</label>4.5 out of 5 </div> <p>Cras ut velit sed purus porttitor aliquam. Nulla tristique magna ac libero tempor, ac vestibulum felisvulput ate. Nam ut velit eget risus porttitor tristique at ac diam. Sed nisi risus, rutrum a metus suscipit, euismod tristique nulla. Etiam venenatis rutrum risus at blandit. In hac habitasse platea dictumst. Suspendisse potenti. Phasellus eget vehicula felis.</p> 

To capture what is under the features id you will need to:

//add the sdk <script type="text/javascript" src="grabzit.min.js"></script> <script type="text/javascript"> //login with your key and secret. GrabzIt("KEY", "SECRET").ConvertURL("http://www.example.com/my-page.html", {"target": "#features", "format": "pdf"}).Create(); </script> 

You need to replace the http://www.example.com/my-page.html with your target url and #feature per your CSS selector.

That's all. Now, when the page is loaded an image screenshot will now be created in the same location as the script tag, which will contain all of the contents of the features div and nothing else.

The are other configuration and customization you can do to the div-screenshot mechanism, please check them out here

1 Comment

I think you only get 1,000 free captures and 100 free "scrapes" with grabz.it. So not a permanent solution unless you're willing to pay for it.
0

Here is the method that worked for me (in Vue 2):

 downloadQrCardAsPdf() { const fileName = this.qrEntryCard.title + "-" + this.qrEntryCard.id + "_" + this.qrEntryCard.createdAt + ".pdf"; html2canvas(this.$refs.qrCodeCardDiv).then(function (canvas) { const ctx = canvas.getContext("2d"); const imgData = ctx.getImageData(0,0, canvas.width, canvas.height); const pdf = new jsPDF({unit: 'px', format: [canvas.width, canvas.height]}); pdf.addImage(imgData, 'PNG',0,0, canvas.width, canvas.height); pdf.save(fileName); }); } 

Inspired by the answer of @Vishnu S and developed.

Comments

0
//surround the content you want to print with a div block, with an id. <div id=myDiv > // any content here </div> //then call this function: printDiv(myDiv); // it allows the user to print it, or save it as a pdf function printDiv(x) { var divContents = document.getElementById(x).innerHTML; var a = window.open('', '', 'height=500, width=500'); var date = new Date().toDateString(); a.document.write('<html>'); a.document.write('<head>'); a.document.write('<link rel="stylesheet" href="myCss.css">'); // you can create a specific css just for printing (other css then the css // used for the digital version) a.document.write('</head>'); a.document.write('<body> <div class=head><h1>myTitle</h1></div>'); // add title a.document.write(date); // add printout date a.document.write('</div>'); a.document.write(divContents); a.document.write('</body></html>'); a.document.close(); a.print(); } 

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.