0

Is there any way to generate a PDF file from HTML page/content and the PDF should be shown in bootstrap modal without downloading directly.

I tried using jsPDF, but couldn't do as expected. Instead of bootstrap modal its showing in an iframe now.

Below is the sample HTML content which is to be converted in to PDF(without downloading) to show in Bootstrap Modal.

<body>
  <Content will be displayed here>
</body>

Below is the javascript code(jsPDF).

<script src="https://html2canvas.hertzen.com/dist/html2canvas.js"></script>
<script src='../../dist/jspdf.debug.js'></script>
<script>

    var pdf = new jsPDF('p', 'pt', 'letter');
    pdf.html(document.body, {
        callback: function (pdf) {
            var iframe = document.createElement('iframe');
            iframe.setAttribute('style', 'position:absolute;right:0; top:0; bottom:0; height:100%; width:500px');
            document.body.appendChild(iframe);
            iframe.src = pdf.output('datauristring');
        }
    });
</script>
anees ma kader
  • 87
  • 1
  • 1
  • 10
  • Do want to make a "screenshot" of the table only? Or the entire body --> `document.body`? And do you want to use `jsPDF` or `html2canvas` as you have both included them in the document... And besides, are you aware of the fact that you create a `
    ` instead of an `
    – Chiel Jun 29 '20 at 17:40
  • @Chiel, i want entire body. Actually it was iframe and i tried with div but was not working and forget to revert it back. Now i made edits in the question. Actually i dont have any idea which one to use whether html2canvas or jsPDF. This i got when i searched and seems i am nearer to the target since i only need to replace the iframe with html div, most precisely bootstrap modal. Thanks. – anees ma kader Jun 30 '20 at 00:49
  • Does this answer your question? [PDF file to be displayed on the dialog modal via bootstrap](https://stackoverflow.com/questions/35286303/pdf-file-to-be-displayed-on-the-dialog-modal-via-bootstrap) – FluffyKitten Jun 30 '20 at 05:41

1 Answers1

1

I reckon I have found a solution to your problem. Basically it takes a screenshot of your page with html2canvas then it adds that image to to new jsPDF('p', 'pt', 'letter');. Then it creates a bloburl from the canvas to display it in an html <object data="bloburl"> in your modal. I have also added another function that makes it possible to download the pdf as well.

The relevant javascript:

//This will be the pdf object
let pdfFinal = null

function downloadPDF() {
   pdfFinal.save("file.pdf");
}

function showPDF() {
   //Create screenshot of body
   html2canvas(document.body, {scale: 2,scrollY: -window.scrollY}).then(canvas => {
      document.body.appendChild(canvas);
      var imgData = canvas.toDataURL('image/png');

      //add the image to pdf
      var pdf = new jsPDF('L', 'pt', [canvas.width, canvas.height]);
      pdf.addImage(imgData, 'PNG', 0, 0, canvas.width, canvas.height);

      //set the pdfFinal to be later downloaded
      pdfFinal = pdf;
      //Get and set the output of the pdf
      let output = pdf.output('bloburl');
      document.getElementById("pdfObj").height = canvas.height / 4;
      document.getElementById("pdfObj").data = output;
   });
}

This code would have to be included in you <head>:

<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script src="https://html2canvas.hertzen.com/dist/html2canvas.js"></script>
<script src="https://unpkg.com/jspdf@latest/dist/jspdf.min.js"></script>

This modal code from (for simplicities sake) w3schools:

<div class="container">
  <button type="button" onclick="showPDF();" class="btn btn-info btn-lg" data-toggle="modal" data-target="#myModal">Open Modal</button>

  <div class="modal fade" id="myModal" role="dialog">
    <div class="modal-dialog">

      <div class="modal-content">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal">&times;</button>
          <h4 class="modal-title">Modal Header</h4>
        </div>
        <div class="modal-body">
          <p>Here is your pdf.</p>
        </div>
        <center><object id="pdfObj" data="" type="application/pdf" width="90%" height="550">

          </object></center>
        <div class="modal-footer">
          <button type="button" class="btn btn-info" onclick="downloadPDF();">Download</button>
          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        </div>
      </div>

    </div>
  </div>
</div>

Hope this helps! If not please comment

Edit

Now the entire page fits on the pdf. Changes: Added scaling for higher resolution

Chiel
  • 1,324
  • 1
  • 11
  • 30
  • Hi @Chiel, thanks lot, its working. Still there is slight issues that the pdf shown and dowloaded is not fitting properly in the pdf page container(it breaks in right side). Is there any solution to make the content fit in the container body? Also right now entire page content is appending in the pdf. Anyway to restrict it to content from a particular div other than entire page? – anees ma kader Jun 30 '20 at 14:20
  • 1
    @aneesmakader instead of document.body (the entire page) you could also pass document.getElementById(“myDiv”) for example. For the other question i have to test it myself – Chiel Jun 30 '20 at 14:28
  • @aneesmakader I'm not sure what you mean with 'it breaks in right side'. Perhaps it has something to do with scaling. Maybe it helps to put after `document.body` this `, {scale: 1}` so that the line looks like: `html2canvas(document.body, {scale: 1}).then(canvas => {` – Chiel Jun 30 '20 at 15:22
  • it breaks means, after certain width the remaining portion of the html content is trimmed from right. Also, same happens in the bottom as well(it seems only one page is generated). I hope its clarified):- – anees ma kader Jun 30 '20 at 17:23
  • 1
    @aneesmakader Hope this edit solves your problem now! – Chiel Jun 30 '20 at 17:57
  • still only single page is showing by trimming the other pages(not multi page). How can we achieve multi pages by splitting the pages? – anees ma kader Jul 01 '20 at 18:52
  • also the content in the pdf is too small even if it fits the document container. – anees ma kader Jul 01 '20 at 18:59
  • @aneesmakader could you clarify “the content is too small”? Ofcourse the content will look smaller on an a4 because a sheet of paper is smaller than your viewport (screen). – Chiel Jul 02 '20 at 07:53