6

I am utilizing jsPDF to generate a PDF from my invoice generating web app. Although the generated PDF works fine for my 17-inch device. The pdf that is generated on other devices is usualy clipped one way or the other.

So I wanted to know, if there is a method for me to generate PDF's without being dependent on the device screen size.

I have been trying to make it resolution independent but nothing seems to work. In this configuration, the pdf is generated fine on my device but not on other smaller devices like a 13-inch mac . But even with same size devices, the inherent display resolutions seems to create some problem.

//Javascript Function that calls and downloads PDF
  document.getElementById('print-invoice-sectionP').style.width = '1300px';
  document.getElementById('pInvoiceContent').style.paddingTop = '145px';

  var doc = new jsPDF('l', 'pt', 'letter');

doc.addHTML(document.getElementById("print-invoice-sectionP"),function() {
     doc.save(''+fInvoiceId+'.pdf');
});
HTML Code
<section id="print-invoice-sectionP" class="nodisplay mdl-grid" style="background: #fff; min-width: 1300px; min-height: 850px;  ">

    <div style="background: url('roshni.png'); background-size: cover; background-repeat: no-repeat; min-width: 1300px; min-height: 850px; "> 

      <div class="mdl-grid mdl-card__supporting-text pText" id="pInvoiceContent" style="color: #000;  min-width: 1300px;  ">
        
        <div style="width: 36%; border-right:solid #000; font-size: 13pt;">
          <h5><strong>To</strong></h5>
          <p><strong><h4 id="pCnameP" ></h4></strong></p>
          <p><span id="pCaddrP" class="pText"></span></p>
          <p id="pCgst" class="pText"></p>
          <p id="pCscode" class="pText"></p>
        </div>

        <div style="width: 30%; border-right:solid #000; margin-left: 10px; padding-top:10px;">
          <p  class="pText">Publication: Daily Roshni, Srinagar</p>
          <p  class="pText" id="gstNoP"></p>
          <p  class="pText">Client: <strong><span id="adClientP"></span></strong></p>
          <p  class="pText">Description: <span id="adDescP"></span></p>
          <p  id="pHSNc"></p>
          <p  class="pText">Page:  <span id='adPageP'></span></p>
          <p  class="pText">Size: <strong><span id="adSizeP"></span> <span id="mUnitPa"></span></strong> (<span id='adWidthP'></span> x <span id='adHeightP'></span>)</p>
          <p  class="pText">Rate: <strong> ₹ <span id="adRateP"></span></strong> per <span id="mUnitPd"></span></p>
        </div>

        <div style="width: 30%; margin-left: 10px; padding-top:10px;" class="margin">
          <p  class="pText" style="min-height: 15%;">Invoice ID : <span id="pInIdP"></span></p>
          <p  class="pText" style="min-height: 15%;">Invoice Date : <span id="pInDateP"></span></p>
          <p  cclass="pText" style="min-height: 15%;">Release Order No. : <span class="pText" id="rOrderNoP"></span></p>
          <p  class="pText" style="min-height: 15%;">Release Order Date : <span id="rOrderDateP"></span></p>
          <p  class="pText" style="min-height: 15%;">Published On : <span id="publishDateP"></span></p>
        </div>

        
        <div class="mdl-card__actions mdl-card--border" style="margin-top: 10px;margin-bottom: 10px; color: #000;"></div>


        <div style="min-width: 20%; border-right:solid #000; margin-right: 10px; margin-left: 10px;">
          <p class="pText"" >Sub Total:</p>
          <strong><span id="sTotalP"></span></strong>
        </div>

        <div id="cChargesDivP" style="min-width: 20%; border-right:solid #000; margin-right: 10px; margin-left: 10px;">
            <p  class="pText">Color Charges @ <span id="cChargesP"></span> % :  </p>
            <strong>₹ <span id="cChargesAmt"></span></strong>
        </div>

        <div id="discountDivP" style="min-width: 20%; border-right:solid #000; padding-right: 10px; margin-left: 10px;">
            <p class="pText">Commission / Discount @ <span id="discountP"></span> % : </p>  
            <strong>₹ <span id="discountAmt"></span></strong>
        </div>
        
        <div id="gstDivP" style="min-width: 20%; margin-right: 10px; margin-left: 10px;" >
            <p  class="pText">IGST @ <span id="gstP"></span> % :  </p>
            <strong>₹ <span id="gstAmt"></span></strong>
        </div>

              
        <div style="width: 100%; ">
        <div class="mdl-card__actions mdl-card--border" style="margin-top: 10px;margin-bottom: 10px;"></div>

        <div style="width: 36%; border-right:solid #000; float: left;">
          <p class="pText">Amount to be Paid</p> 
          <strong><h4 id="gTotalP" style="width: 30%"></h4></strong>
        </div>

        <div style="width: 60%;float: right;">
          <p class="pText">Amount to be Paid In Words</p> 
          <strong><h4 id="gTotalWords" ></h4></strong>
        </div>
      </div>

      </div>
      
    

    </div>
  </section>
Ruhban Shah
  • 71
  • 1
  • 6
  • I would suggest using `pdfMake` package to generate PDFs at the client-side because it provides most of the features, and also takes care of responsiveness, page margins for you. You can find it here: `https://pdfmake.github.io/docs/0.1/` Playground: `http://pdfmake.org/playground.html` – Yogesh Jan 19 '22 at 18:50

1 Answers1

2

The right way to go is to make your page responsive and then use jsPDF. Youy can use this responsive template for your invoices:

Demo responsive invoice

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>A simple, clean, and responsive HTML invoice template</title>
    
    <style>
    .invoice-box{
        max-width:800px;
        margin:auto;
        padding:30px;
        border:1px solid #eee;
        box-shadow:0 0 10px rgba(0, 0, 0, .15);
        font-size:16px;
        line-height:24px;
        font-family:'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;
        color:#555;
    }
    
    .invoice-box table{
        width:100%;
        line-height:inherit;
        text-align:left;
    }
    
    .invoice-box table td{
        padding:5px;
        vertical-align:top;
    }
    
    .invoice-box table tr td:nth-child(2){
        text-align:right;
    }
    
    .invoice-box table tr.top table td{
        padding-bottom:20px;
    }
    
    .invoice-box table tr.top table td.title{
        font-size:45px;
        line-height:45px;
        color:#333;
    }
    
    .invoice-box table tr.information table td{
        padding-bottom:40px;
    }
    
    .invoice-box table tr.heading td{
        background:#eee;
        border-bottom:1px solid #ddd;
        font-weight:bold;
    }
    
    .invoice-box table tr.details td{
        padding-bottom:20px;
    }
    
    .invoice-box table tr.item td{
        border-bottom:1px solid #eee;
    }
    
    .invoice-box table tr.item.last td{
        border-bottom:none;
    }
    
    .invoice-box table tr.total td:nth-child(2){
        border-top:2px solid #eee;
        font-weight:bold;
    }
    
    @media only screen and (max-width: 600px) {
        .invoice-box table tr.top table td{
            width:100%;
            display:block;
            text-align:center;
        }
        
        .invoice-box table tr.information table td{
            width:100%;
            display:block;
            text-align:center;
        }
    }
    </style>
</head>

<body>
    <div class="invoice-box">
        <table cellpadding="0" cellspacing="0">
            <tr class="top">
                <td colspan="2">
                    <table>
                        <tr>
                            <td class="title">
                                <img src="http://nextstepwebs.com/images/logo.png" style="width:100%; max-width:300px;">
                            </td>
                            
                            <td>
                                Invoice #: 123<br>
                                Created: January 1, 2015<br>
                                Due: February 1, 2015
                            </td>
                        </tr>
                    </table>
                </td>
            </tr>
            
            <tr class="information">
                <td colspan="2">
                    <table>
                        <tr>
                            <td>
                                Next Step Webs, Inc.<br>
                                12345 Sunny Road<br>
                                Sunnyville, TX 12345
                            </td>
                            
                            <td>
                                Acme Corp.<br>
                                John Doe<br>
                                john@example.com
                            </td>
                        </tr>
                    </table>
                </td>
            </tr>
            
            <tr class="heading">
                <td>
                    Payment Method
                </td>
                
                <td>
                    Check #
                </td>
            </tr>
            
            <tr class="details">
                <td>
                    Check
                </td>
                
                <td>
                    1000
                </td>
            </tr>
            
            <tr class="heading">
                <td>
                    Item
                </td>
                
                <td>
                    Price
                </td>
            </tr>
            
            <tr class="item">
                <td>
                    Website design
                </td>
                
                <td>
                    $300.00
                </td>
            </tr>
            
            <tr class="item">
                <td>
                    Hosting (3 months)
                </td>
                
                <td>
                    $75.00
                </td>
            </tr>
            
            <tr class="item last">
                <td>
                    Domain name (1 year)
                </td>
                
                <td>
                    $10.00
                </td>
            </tr>
            
            <tr class="total">
                <td></td>
                
                <td>
                   Total: $385.00
                </td>
            </tr>
        </table>
    </div>
</body>
</html>

UPDATE


Combining the responsive solution you can then use a javascript library like Print.js.
Another way to go is to print the page to canvas and then to pdf like an image. You can use htmlcanvas if you prefer this solution. This script allows you to take "screenshots" of webpages or parts of it, directly on the users browser. The screenshot is based on the DOM and as such may not be 100% accurate to the real representation as it does not make an actual screenshot, but builds the screenshot based on the information available on the page.

Instruction of how to take in-browser screenshots using HTML5/Canvas/JavaScript.

Panos Kalatzantonakis
  • 12,525
  • 8
  • 64
  • 85
  • Thank you. I used your concept and made the whole section smaller so as not to be constrained by smaller screen devices. The inherent problem however still persists. I think a better explaination of my problem would be that "How can i add an html section to jsPDF to generate a pdf that looks exactly or mostly similar to the content on my screen without worrying about which device the user is using". – Ruhban Shah Oct 11 '17 at 07:05
  • @RuhbanShah maybe an image of the screen can serve you better. Check the updated answer – Panos Kalatzantonakis Oct 11 '17 at 08:57
  • Yes, that is the process that I am utilising. However I found out that a limitation of HTML canvas is that it only captures that part of screen which would be visible on the end user device. Although it has been reported but a version of html2canvas with this issue resolved hasn't been released yet. Are you aware of any workaround of this particular limitation. Thanks! – Ruhban Shah Oct 13 '17 at 14:37
  • No, I guess you can do more with some css tricks, I've managed to do this with some receipts I printed but I don't know a global solution – Panos Kalatzantonakis Oct 13 '17 at 14:42