15

I noticed already have a release "addHTML() can now split the canvas into multiple pages" which can find through this link : https://github.com/MrRio/jsPDF/releases/tag/v1.0.138.

May i know how it work? In my case, i just tried it out when click on "save as pdf" button, it just render a single page instead of multiple pages (sometimes didn't worked, i assume because the content is too long to be generated as pdf).

Would appreciate if there are some examples for this case. Thanks!

Attached my codes below:

var pdf = new jsPDF('p', 'pt', 'a4');

pdf.addHTML($(".pdf-wrapper"), function () {
    var string = pdf.output('datauristring');
    pdf.save("test.pdf");
});
Dion Alexander
  • 169
  • 1
  • 1
  • 7

4 Answers4

20

Splitting canvas into multiple pages work by providing a "pagesplit" option:

var pdf = new jsPDF('p', 'pt', 'a4');
var options = {
         pagesplit: true
    };

pdf.addHTML($(".pdf-wrapper"), options, function()
{
    pdf.save("test.pdf");
});
diegocr
  • 1,000
  • 8
  • 13
  • 2
    Hi @diegocr, Thanks for quick answer. I just tried it out to set pagesplit: true on http://mrrio.github.io/jsPDF/ why the result is not good & seems "stretch" into 2 pages..though it can be generated in 1 page only? – Dion Alexander Sep 18 '14 at 10:02
  • addHTML will try to adjust the html element/document to fit the whole width of the PDF page size, which could imply stretching. You can play by providing additional options such as "width" and "height" which are passed directly to html2canvas, or you can use eg options.dim = { w: 400, h : 600 } to pass width/height to the jsPDF engine. Also, check https://github.com/MrRio/jsPDF/issues/339 – diegocr Sep 18 '14 at 10:10
  • I believe the stretching issue has now been fixed in the latest addHtml plugin code. – adam0101 Dec 17 '14 at 16:34
  • I am facing the same problem... pdf is working fine but its not splitting page properly also looking stretched. Any updated answer for this? – Raghbendra Nayak Jun 14 '17 at 05:06
  • $(function() { $('#download_as_pdf').click(function() { jQuery(".loader h3").text("Data is preparing for download, please wait."); jQuery(".loader-wrapper").removeClass("hide"); var pdf = new jsPDF('lanscape'); var options = { pagesplit: true,'background': '#fff' }; pdf.addHTML($('#customer_report_section'), options, function() { jQuery(".loader-wrapper").addClass("hide"); pdf.save(""); }); }); }); – Raghbendra Nayak Jun 14 '17 at 07:27
  • I am using above code but its not splitting the pages properly. – Raghbendra Nayak Jun 14 '17 at 07:28
  • I have used pagSplit, and it successfully splits pages but margin should be at bottom and top of each page. Any one fixed this? Please help me. Thank you in advance – Hardik Chaudhary Nov 29 '17 at 06:33
  • AddHtml is deprecated the callback is never called. use html() . – Thom Kiesewetter Sep 30 '19 at 13:46
  • @ThomKiesewetter Can you please provide a link/document to read about this "html()" function? – Salek Dec 01 '20 at 17:34
  • 1
    @Salek for html support see http://raw.githack.com/MrRio/jsPDF/master/docs/module-html.html#~html – Thom Kiesewetter Dec 01 '20 at 19:41
12

pdf.addHtml doesnot work if there are svg images on the web page.. I copy the solution here: // suppose your picture is already in a canvas var imgData = canvas.toDataURL('image/png'); /* 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 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');
Bansi29
  • 1,053
  • 6
  • 24
Trilok Nagvenkar
  • 896
  • 9
  • 14
11

None of the above helped me so I'll put this here for anyone who arrives at this page looking to use addHTML() to create a single pdf split into multiple pages with a different html element on each page. I used recursion so I'm not sure of the performance implications of this approach. It worked for me to create a 4 page pdf from 4 div elements.

var pdf = new jsPDF('landscape');
        var pdfName = 'test.pdf';

        var options = {};

        var $divs = $('.myDivClass')                //jQuery object of all the myDivClass divs
        var numRecursionsNeeded = $divs.length -1;     //the number of times we need to call addHtml (once per div)
        var currentRecursion=0;

        //Found a trick for using addHtml more than once per pdf. Call addHtml in the callback function of addHtml recursively.
        function recursiveAddHtmlAndSave(currentRecursion, totalRecursions){
            //Once we have done all the divs save the pdf
            if(currentRecursion==totalRecursions){
                pdf.save(pdfName);
            }else{
                currentRecursion++;
                pdf.addPage();
                //$('.myDivClass')[currentRecursion] selects one of the divs out of the jquery collection as a html element
                //addHtml requires an html element. Not a string like fromHtml.
                pdf.addHTML($('.myDivClass')[currentRecursion], 15, 20, options, function(){
                    console.log(currentRecursion);
                    recursiveAddHtmlAndSave(currentRecursion, totalRecursions)
                });
            }
        }

        pdf.addHTML($('.myDivClass')[currentRecursion], 15, 20, options, function(){
            recursiveAddHtmlAndSave(currentRecursion, numRecursionsNeeded);
        });
}
Paddy
  • 595
  • 1
  • 4
  • 14
  • Very nice solution! Code needed a little clean up but works great for me. Need to terminate with a semicolon these two lines...var $divs = $('.myDivClass') and recursiveAddHtmlAndSave(currentRecursion, totalRecursions) and also seems to be an extra closing curly bracket in the last line. – dangre00 Nov 21 '17 at 23:38
  • very nice. works neatly with tables or divs that are on DOM. But how do i make it work with absolute positioned html tags ? – avinash Jun 21 '18 at 10:44
  • 1
    I have a div with some HTML when I tried with the above code it was downloading the PDF but when open the pdf It is not having any content only I can see black background. Below I will add the screenshots please help me. div: https://ibb.co/5h89M4K pdf: https://ibb.co/cQGjDPS – Satya Pendem Apr 20 '20 at 05:22
2

With using pagesplit: true it always stretches the pdf output. Try to use an old version of jsPDF with html2canvas of course.

Sharing the result of my 2 days trial to achieve the multipage PDF generation with addHTML not fromHTML since it looses the CSS rules.

<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.0.272/jspdf.debug.js"></script>

then the PDF should be just fine as follows:

<script>

            $(window).on('load', function(){

                var pdf = new jsPDF('p', 'pt', 'a4');

                var pdfName = 'sample.pdf';

                var options = {
                    format: 'JPEG',
//                    pagesplit: true,
                    "background": '#000',
                };

                var fullPage = $('#Printout_21571')[0],
                    firstPartPage = $('#part-1')[0],
                    secondPartPage = $('#part-2')[0];

                pdf.addHTML(firstPartPage, 15, 20, options, function(){ pdf.addPage() });
                pdf.addHTML(secondPartPage, 15, 20, options, function(){});

                setTimeout(function() {

//                    pdf.save(pdfName);
                    var blob = pdf.output("blob");
                    window.open(URL.createObjectURL(blob));

                }, 600);
            })
        </script>

Hope this would help. Thanks!

Abhijeet K.
  • 537
  • 4
  • 7