How to Create Multipage PDF from HTML Using jsPDF and html2Canvas

There are a number of tools which can easily create PDF files from JSON or raw data provided. But in some situations, we have rich UI elements like images and data representation in graphs, so in that case, we may require PDF as it is. jsPDF and html2canvas are really powerful tools which can help…

By.

min read

There are a number of tools which can easily create PDF files from JSON or raw data provided. But in some situations, we have rich UI elements like images and data representation in graphs, so in that case, we may require PDF as it is.

jsPDF and html2canvas are really powerful tools which can help you to convert the whole HTML page into a multi-page PDF document, which you can show in iFrame or user can even download it.

See a working demo here.

Let’s get started!

 

Step 1 – First we need to add the jQuery library into our project which is a basic dependency to get this work. Then we need to include the latest jsPDF and Html2Canvas plugins.

<script type="text/javascript" src="lib/jquery.min.js"></script>
<script type="text/javascript" src="lib/jspdf.debug.js"></script>
<script type="text/javascript" src="lib/html2canvas.js"></script>

 

Step 2 – As we have a long HTML page to get converted into multiple PDF pages, so will break the whole HTML page into multiple chunks of pages with the help of selectors like we are using page1, page2 and page3 classes. Each selector or ID will be converted into

Each selector or ID will be converted into the canvas using Html2Canvas plugin and get pasted into PDF new page using the <strong>jsPDF</strong> plugin.

Here we have used a single generatePDF() method having html2canvas called three times to convert three sections of a single HTML page into three pages of PDF file.

html2canvas function will create a canvas and add it as Image in PDF page. Using the addPage() function we are setting the height and width of the new PDF page. We can adjust it dynamically or as per application requirements.

In the setTimeout() we have added code to create download link and iFrame if we want to show PDF created in and in page iFrame. Which we will add in the next step.

    //Generate PDF
    function generatePDF() {
        pdf = "";
		$("#downloadbtn").hide();
		$("#genmsg").show();
        html2canvas($(".print-wrap:eq(0)")[0], { allowTaint: true }).then(function(canvas) {

            calculatePDF_height_width(".print-wrap",0);
            var imgData = canvas.toDataURL("image/png", 1.0);
			pdf = new jsPDF('p', 'pt', [PDF_Width, PDF_Height]);
            pdf.addImage(imgData, 'JPG', top_left_margin, top_left_margin, HTML_Width, HTML_Height);

        });

        html2canvas($(".print-wrap:eq(1)")[0], { allowTaint: true }).then(function(canvas) {

            calculatePDF_height_width(".print-wrap",1);
			
            var imgData = canvas.toDataURL("image/png", 1.0);
            pdf.addPage(PDF_Width, PDF_Height);
            pdf.addImage(imgData, 'JPG', top_left_margin, top_left_margin, HTML_Width, HTML_Height);

        });

        html2canvas($(".print-wrap:eq(2)")[0], { allowTaint: true }).then(function(canvas) {

            calculatePDF_height_width(".print-wrap",2);
			
            var imgData = canvas.toDataURL("image/png", 1.0);
            pdf.addPage(PDF_Width, PDF_Height);
            pdf.addImage(imgData, 'JPG', top_left_margin, top_left_margin, HTML_Width, HTML_Height);


           
                //console.log((page_section.length-1)+"==="+index);
                setTimeout(function() {

                    //Save PDF Doc	
                    pdf.save("HTML-Document.pdf");

                    //Generate BLOB object
                    var blob = pdf.output("blob");

                    //Getting URL of blob object
                    var blobURL = URL.createObjectURL(blob);

                    //Showing PDF generated in iFrame element
                    var iframe = document.getElementById('sample-pdf');
                    iframe.src = blobURL;

                    //Setting download link
                    var downloadLink = document.getElementById('pdf-download-link');
                    downloadLink.href = blobURL;

					$("#sample-pdf").slideDown();
					
					
					$("#downloadbtn").show();
					$("#genmsg").hide();
                }, 0);
        });
    };

We will add a separate function to calculate Heights and Widths of HTML, Canvas and PDF page.

	function calculatePDF_height_width(selector,index){
		page_section = $(selector).eq(index);
		HTML_Width = page_section.width();
		HTML_Height = page_section.height();
		top_left_margin = 15;
		PDF_Width = HTML_Width + (top_left_margin * 2);
		PDF_Height = (PDF_Width * 1.2) + (top_left_margin * 2);
		canvas_image_width = HTML_Width;
		canvas_image_height = HTML_Height;
	}

 

Step 3 – Here we will add HTML content which will be converted into a multipage PDF file.

<!--Generated PDF will load in iFrame when we click on link below-->
<iframe frameBorder="0" id="sample-pdf" style="right:0; top:53px; bottom:0; height:400px; width:100%"></iframe>

<!--Download PDF Link-->
<a id="pdf-download-link" title="Download PDF File">Download PDF file</a>

<!--Create iFrame URL-->
<a id="pdf-showiFrame-link" title="Show PDF in iFrame">Show PDF in iFrame</a>


<div class="print-wrap page1">
<h3>Sample page one for demo</h3>
</div>


<div class="print-wrap page2">
<h3>Sample page two for demo</h3>
</div>


<div class="print-wrap page3">
<h3>Sample page three for demo</h3>
</div>

 

After combining all sections above our final page will look like below:

<html>

<head>
    <title>jsPDF</title>
    <script type="text/javascript" src="lib/jquery.min.js"></script>
    <script type="text/javascript" src="lib/jspdf.debug.js"></script>
    <script type="text/javascript" src="lib/html2canvas.js"></script>
    <script>
	var pdf,page_section,HTML_Width,HTML_Height,top_left_margin,PDF_Width,PDF_Height,canvas_image_width,canvas_image_height;
	
	
	
	function calculatePDF_height_width(selector,index){
		page_section = $(selector).eq(index);
		HTML_Width = page_section.width();
		HTML_Height = page_section.height();
		top_left_margin = 15;
		PDF_Width = HTML_Width + (top_left_margin * 2);
		PDF_Height = (PDF_Width * 1.2) + (top_left_margin * 2);
		canvas_image_width = HTML_Width;
		canvas_image_height = HTML_Height;
	}
	



    //Generate PDF
    function generatePDF() {
        pdf = "";
		$("#downloadbtn").hide();
		$("#genmsg").show();
        html2canvas($(".print-wrap:eq(0)")[0], { allowTaint: true }).then(function(canvas) {

            calculatePDF_height_width(".print-wrap",0);
            var imgData = canvas.toDataURL("image/png", 1.0);
			pdf = new jsPDF('p', 'pt', [PDF_Width, PDF_Height]);
            pdf.addImage(imgData, 'JPG', top_left_margin, top_left_margin, HTML_Width, HTML_Height);

        });

        html2canvas($(".print-wrap:eq(1)")[0], { allowTaint: true }).then(function(canvas) {

            calculatePDF_height_width(".print-wrap",1);
			
            var imgData = canvas.toDataURL("image/png", 1.0);
            pdf.addPage(PDF_Width, PDF_Height);
            pdf.addImage(imgData, 'JPG', top_left_margin, top_left_margin, HTML_Width, HTML_Height);

        });

        html2canvas($(".print-wrap:eq(2)")[0], { allowTaint: true }).then(function(canvas) {

            calculatePDF_height_width(".print-wrap",2);
			
            var imgData = canvas.toDataURL("image/png", 1.0);
            pdf.addPage(PDF_Width, PDF_Height);
            pdf.addImage(imgData, 'JPG', top_left_margin, top_left_margin, HTML_Width, HTML_Height);


           
                //console.log((page_section.length-1)+"==="+index);
                setTimeout(function() {

                    //Save PDF Doc	
                    pdf.save("HTML-Document.pdf");

                    //Generate BLOB object
                    var blob = pdf.output("blob");

                    //Getting URL of blob object
                    var blobURL = URL.createObjectURL(blob);

                    //Showing PDF generated in iFrame element
                    var iframe = document.getElementById('sample-pdf');
                    iframe.src = blobURL;

                    //Setting download link
                    var downloadLink = document.getElementById('pdf-download-link');
                    downloadLink.href = blobURL;

					$("#sample-pdf").slideDown();
					
					
					$("#downloadbtn").show();
					$("#genmsg").hide();
                }, 0);
        });
    };

    </script>
    <style>
    .print-wrap {
        width: 500px;
    }
    </style>
</head>

<body>
    <iframe frameBorder="0" id="sample-pdf" style="right:0; top:53px; bottom:0; height:400px; width:100%"></iframe>
    <a id="pdf-download-link" title="Download PDF File">Download PDF file</a>
    <a id="pdf-showiFrame-link" title="Show PDF in iFrame">Show PDF in iFrame</a>
    <div class="print-wrap page1">
        <h3>Sample page one for demo</h3>
    </div>
    <div class="print-wrap page2">
        <h3>Sample page two for demo</h3>
    </div>
    <div class="print-wrap page3">
        <h3>Sample page three for demo</h3>
    </div>
</body>

</html>

 

That’s all folks!!! Let me know in the comments section if you face any issue in plugin this code sample into your app or if you have any suggestion always welcome.

Other Method: Create a Single canvas of the whole HTML section and break it up for different PDF pages.

Keep smiling 🙂

29 responses to “How to Create Multipage PDF from HTML Using jsPDF and html2Canvas”

  1. Sandeep Avatar

    I have much content in my page it picks only some content as pdf .
    Any suggestions please let me know

    1. Jolly.exe Avatar
      Jolly.exe

      Hi Sandeep, Please make sure all content is visible before conversion to PDF. Let me know if still you face issue.

  2. Hemant Avatar
    Hemant

    if i want to stick the header and footer on every page then what will be the codes?

  3. Hemant Avatar
    Hemant

    thanks for this tutorial

  4. Raf Van den Bosch Avatar
    Raf Van den Bosch

    Does this work correctly in firefox ? I have the impression that the order of the divs is printend randomly in the pdf.

  5. Yusuf Avatar
    Yusuf

    Hi, i have other question, but it still jsPDF problem, i use tab in my html code, and i need to render all, my question is : how to render all tab and merge them into one pdf file ?

    1. Jolly.exe Avatar
      Jolly.exe

      Hey, Yusuf! … What I understand is you have only one tab visible at a time right? But here html2canvas is converting only visible part to canvas… for the same reason I added scroll to top event…. so what you can do is just make tabs visible then run above function to capture then hide other tabs. Hope this helps 🙂

  6. HK Avatar

    Hi,

    I did try out the above mentioned code, but it seem some error on getting the content for page1, page2 and page3 on both iframe and generated PDF. The generated PDF only one blank page. is there anything went wrong with the code?

    1. Jolly.exe Avatar
      Jolly.exe

      Hey! HK please use updated code, there issue with page render… now I have added a timeout of 2 seconds for relaxing initialisation also visit Demo page 🙂

      1. jayesh Avatar

        where is the updated code link?

        1. Jolly.exe Avatar
          Jolly.exe

          Hi Jayesh, current post is having updated code.

  7. Sarita Avatar
    Sarita

    My first page overlaps on last page

    1. Jolly.exe Avatar
      Jolly.exe

      Thanks, Sarita! for sharing your experience… I have updated and modified code… please also visit new Demo link 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *