104

I want to convert some of my divs into PDF and I've tried jsPDF library but with no success. It seems I can't understand what I need to import to make the library work. I've been through the examples and I still can't figure it out. I've tried the following:

<script type="text/javascript" src="js/jspdf.min.js"></script>

After jQuery and:

$("#html2pdf").on('click', function(){
    var doc = new jsPDF();
    doc.fromHTML($('body').get(0), 15, 15, {
        'width': 170
    });
    console.log(doc);
});

for testing purposes but I receive:

"Cannot read property '#smdadminbar' of undefined"

where #smdadminbar is the first div from the body.

Amal Murali
  • 75,622
  • 18
  • 128
  • 150
Daniela costina Vaduva
  • 1,857
  • 5
  • 20
  • 22
  • the one which worked for me https://github.com/devrajatverma/jsPdfExample – Rajat Dec 11 '18 at 05:57
  • 3
    Note for all who get here trying to figure out `fromHTML` or why it isn't documented in the jsPDF docs: "_We are closing this issue, because we will not support any longer fromHTML and addHTML._" ([from issue#516](https://github.com/MrRio/jsPDF/issues/516#issuecomment-419228701)) – toraritte May 01 '20 at 15:35

7 Answers7

148

you can use pdf from html as follows,

Step 1: Add the following script to the header

<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.2/jspdf.min.js"></script>

or download locally

Step 2: Add HTML script to execute jsPDF code

Customize this to pass the identifier or just change #content to be the identifier you need.

 <script>
    function demoFromHTML() {
        var pdf = new jsPDF('p', 'pt', 'letter');
        // source can be HTML-formatted string, or a reference
        // to an actual DOM element from which the text will be scraped.
        source = $('#content')[0];

        // 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.
        specialElementHandlers = {
            // element with id of "bypass" - jQuery style selector
            '#bypassme': function (element, renderer) {
                // true = "handled elsewhere, bypass text extraction"
                return true
            }
        };
        margins = {
            top: 80,
            bottom: 60,
            left: 40,
            width: 522
        };
        // all coords and widths are in jsPDF instance's declared units
        // 'inches' in this case
        pdf.fromHTML(
            source, // HTML string or DOM elem ref.
            margins.left, // x coord
            margins.top, { // y coord
                'width': margins.width, // max width of content on PDF
                'elementHandlers': specialElementHandlers
            },

            function (dispose) {
                // dispose: object with X, Y of the last line add to the PDF 
                //          this allow the insertion of new lines after html
                pdf.save('Test.pdf');
            }, margins
        );
    }
</script>

Step 3: Add your body content

<a href="javascript:demoFromHTML()" class="button">Run Code</a>
<div id="content">
    <h1>  
        We support special element handlers. Register them with jQuery-style.
    </h1>
</div>

Refer to the original tutorial

See a working fiddle

Simon Bengtsson
  • 7,573
  • 3
  • 58
  • 87
Well Wisher
  • 1,825
  • 1
  • 15
  • 20
  • 4
    Thanks for posting this, but I tried the exact code above (locally) and it generates a blank pdf document. It doesn't work at all with jquery 1.11.0 so i used the same jquery version as used on https://github.com/MrRio/jsPDF/blob/master/examples/js/jquery/jquery-1.7.1.min.js – user1063287 Apr 25 '14 at 09:11
  • Tried your code @Well Wisher , its giving me the following error , for the library file itdself -- Cannot read property 'length' of undefined jspdf.plugin.from_html.js:500 – Learner May 28 '14 at 10:58
  • http://jsfiddle.net/h59sG/ and the libraries which i have used are – Learner May 28 '14 at 12:38
  • Your answer is so valuable. See it @Wellwisher.. The same answer posted two times here itself. Please edit. I don't want someone drop your credit. – Jeeva J Jul 23 '14 at 09:57
  • I have been able to convert pages to PDF fine with this, but I am stumped on how to preserve the styling, or at least not have the output look terrible. I have not been able to find any info or documentation on this. Please have a look at how this pdf outputs: http://devious.runningh20.com/php-runs/dophin/ You can view-source to see the code. – abtecas Jul 16 '15 at 20:24
  • The July 24 2014 code produces a blank page. I've edited this to fit the working fiddle at http://jsfiddle.net/xzz7n/1/ Hopefully it will be peer reviewed soon. Look for an edit date of Oct 28 2015 to know if it is working code. – Brian Layman Oct 28 '15 at 13:13
  • 1
    Yes this is really good,,, But the output of JSPdf is overlapping with another elements of my table elements , How Can i solve it?.... I have changed the size of the fonts and made it as landscape mode , I tried most of the modifications , But nothing is working – Sudhir Belagali Jan 11 '16 at 12:18
  • @SudhirBelagali can you please create a fiddle.? – Well Wisher Mar 01 '16 at 10:26
  • It's really odd that the latest release of jspdf will not work, but if you specifically get the 1.0.272 release and use the above code, it will work. Cannot tell you how frustrating getting blank pages, JS errors about "1 not being defined", etc. – Joyrex Mar 31 '16 at 16:22
  • 1
    I was only able to get this example to work by using the CloudFlare CDNs: or But I agree, documentation, and general variations in code source, contribute to the difficulty of using this plugin. Even these CDNs (which the JSfiddle use) vary from the "download locally" link @Well wisher references above. – Great Scott Aug 25 '16 at 15:54
  • 1
    @Scott i the they removed the link – Well Wisher Aug 26 '16 at 06:24
  • @Well wisher - that's a risk. Which is why I copied and pasted it's contents into a locally-hosted JS file. Problem solved! – Great Scott Aug 26 '16 at 14:42
  • I have this error: Uncaught TypeError: Cannot read property 'split' of null at Object.jsPDFAPI.sHashCode – Hana90 Feb 07 '17 at 11:13
  • Including this script is also very important   – Martin.M May 14 '18 at 16:12
  • I also want to know how to embed a live updating pdf preview like in that jspdf website ! – Ciasto piekarz Dec 22 '18 at 10:28
  • 4
    how do I make this to print my CSS styles? – Mwas Jan 16 '19 at 06:43
  • 3
    FYI. The fiddle provided in this answer uses `.fromHTML` which was deprecated in November 2018. – samurai_jane Aug 03 '19 at 15:22
  • this worked for me after also adding a reference to the jQuery library. – BLESSING Feb 26 '20 at 11:24
  • thanks, I was unable to find what were the inputs of the fromHTML function in nowhere else haha – Tupac Dec 01 '20 at 13:01
19

You only need this link jspdf.min.js

It has everything in it.

<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.2/jspdf.min.js"></script>
user890332
  • 1,315
  • 15
  • 15
  • 2
    Thanks, this was driving me nuts! Using the debug version of jspdf worked, where the other versions in any configuration did not. Maybe minification is breaking it somehow? or I'm doing it wrong. – jookyone Jan 14 '15 at 00:20
  • This really helped me. I was using the original jspdf.js file and it wasn't working. Using jspdf.debug.js did the job. – Francisco Quintero Jun 14 '15 at 23:40
  • Interesting why the production version is not working... I included all the plugins in html page and yet, only this debug version helped. – ilter Aug 04 '15 at 06:57
  • Hi, I tried this but I get error `Error in function FileSaver@http://mrrio.github.io/jsPDF/dist/jspdf.debug.js:5875:18: get_URL(...).createObjectURL is not a function`, same thing if I use the bower version. Any clue? – dbr Mar 06 '16 at 18:38
  • Check the latest version on GitHub and change the URL above accordingly. Latest is 1.3.5. – pasx Apr 09 '18 at 12:52
  • Instead of using a specific version for the library, you can just include the latest stable version by just adding; `` – Ahmet Gokdayi Jun 29 '19 at 13:06
  • @AhmetGokdayi `https://unpkg.com/jspdf@latest/dist/jspdf.min.js` returns `Cannot find "/dist/jspdf.min.js" in jspdf@2.2.0` – omegastripes Dec 20 '20 at 21:02
  • 1
    @omegastripes Looks like they updated the source; `https://unpkg.com/jspdf@latest/dist/jspdf.umd.min.js` – Ahmet Gokdayi Dec 20 '20 at 21:48
14

According to the latest version (1.5.3) there is no fromHTML() method anymore. Instead you should utilize jsPDF HTML plugin, see: https://rawgit.com/MrRio/jsPDF/master/docs/module-html.html#~html

You also need to add html2canvas library in order for it to work properly: https://github.com/niklasvh/html2canvas

JS (from API docs):

var doc = new jsPDF();   

doc.html(document.body, {
   callback: function (doc) {
     doc.save();
   }
});

You can provide HTML string instead of reference to the DOM element as well.

Vitalii Chmovzh
  • 2,825
  • 4
  • 14
  • 28
  • 1
    Doesnt seem to work anymore either - jQuery.Deferred exception: doc.html is not a function TypeError: doc.html is not a function – DropHit Sep 03 '20 at 02:25
  • Did you find a solution? fromHTML is working in the latest download. But, svg elements are not rendered in the downloaded PDF. – mythicalcoder Apr 19 '21 at 13:34
  • @mythicalcoder I actually ended up writing my own class that will take the DOM tree and will construct the actual PDF using internal jsPDF APIs. That way it is actually a text and not a rasterized screenshot of your page. – Vitalii Chmovzh Apr 20 '21 at 17:26
  • Seems much better. Thanks for the reply. – mythicalcoder Apr 22 '21 at 14:16
12

This is finally what did it for me (and triggers a disposition):

function onClick() {
  var pdf = new jsPDF('p', 'pt', 'letter');
  pdf.canvas.height = 72 * 11;
  pdf.canvas.width = 72 * 8.5;

  pdf.fromHTML(document.body);

  pdf.save('test.pdf');
};

var element = document.getElementById("clickbind");
element.addEventListener("click", onClick);
<h1>Dsdas</h1>

<a id="clickbind" href="#">Click</a>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.3/jspdf.min.js"></script>

And for those of the KnockoutJS inclination, a little binding:

ko.bindingHandlers.generatePDF = {
    init: function(element) {

        function onClick() {
            var pdf = new jsPDF('p', 'pt', 'letter');
            pdf.canvas.height = 72 * 11;
            pdf.canvas.width = 72 * 8.5;

            pdf.fromHTML(document.body);

            pdf.save('test.pdf');                    
        };

        element.addEventListener("click", onClick);
    }
};
pim
  • 12,019
  • 6
  • 66
  • 69
  • Is there more to this snippet? When I try to run this I get an error that indicates 'pdf.canvas' is undefined. "Uncaught TypeError: Cannot set property 'height' of undefined" – Ryan Gibbs Feb 02 '18 at 20:27
  • Not sure what you mean? The snippet executes using the same code. So perhaps something is off in your implementation. Can you console.log(pdf) and share the output. – pim Feb 02 '18 at 20:39
  • It must have been a caching issue or something, when I attempted it just now with the console.log() in there, the code executed correctly. I'm still getting the blank page issue, but that's a different story. Thanks. – Ryan Gibbs Feb 02 '18 at 22:05
  • also i have error **"Cannot read property 'addEventListener'"** – Manjitha Teshara Nov 06 '18 at 11:53
  • I am loving this jsPDF() library. BTW if anyone else finds this useful I just figured out the syntax for attaching a callback to run after the PDF has been generated: `pdf.save("myfile.pdf", function(){ alert("pdf generation/save finished!"); });` – Christopher Jun 25 '19 at 13:58
4

how about in vuejs how is it applicable?

function onClick() {
  var pdf = new jsPDF('p', 'pt', 'letter');
  pdf.canvas.height = 72 * 11;
  pdf.canvas.width = 72 * 8.5;

  pdf.fromHTML(document.body);

  pdf.save('test.pdf');
};

var element = document.getElementById("clickbind");
element.addEventListener("click", onClick);
<h1>Dsdas</h1>

<a id="clickbind" href="#">Click</a>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.3/jspdf.min.js"></script>
Antwnina
  • 117
  • 12
3

Shouldn't you also be using the jspdf.plugin.from_html.js library? Besides the main library (jspdf.js), you must use other libraries for "special operations" (like jspdf.plugin.addimage.js for using images). Check https://github.com/MrRio/jsPDF.

Pedro Almeida
  • 658
  • 1
  • 7
  • 10
3

first, you have to create a handler.

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

then write this code in click event:

doc.fromHTML($('body').get(0), 15, 15, {
    'width': 170, 
    'elementHandlers': specialElementHandlers
        });

var pdfOutput = doc.output();
            console.log(">>>"+pdfOutput );

assuming you've already declared doc variable. And Then you have save this pdf file using File-Plugin.

Akshay Tyagi
  • 528
  • 4
  • 7