'possible options to create pdf file using html elements to generate invoice in php and codeigniter

Hello Everyone this could be the most common question asked on stackoverflow, I have an invoice template in html like this demo page. I want to generate an invoice pdf file, When user clicks on button.

Can anyone suggest me the best option to do this task? I have tried jsPDF and html2canvas but it is not working as expected. so if there is any better way to do this please let me know.

Thank You.



Solution 1:[1]

I would suggest using tcpdf which worked out great for me, here is an example where i used it:

    $query = "SELECT * FROM login WHERE type_login='customer'";
    $result=mysqli_query($connect, $query);
    while($row = mysqli_fetch_array($result))
    {
        $output .='
            <tr>
                <td>'.$row["id_login"].'</td>
                <td>'.$row["name_login"].'</td>
                <td>'.$row["user_email"].'</td>
            </tr>
        ';
    }

    return $output;
}

if(isset($_POST["create_pdf"]))
{
    require_once("tcpdf/tcpdf.php");
    $obj_pdf = new TCPDF('P',PDF_UNIT,PDF_PAGE_FORMAT,true,"UTF-8",false);
    $obj_pdf->SetCreator(PDF_CREATOR);
    $obj_pdf->SetTitle("Customer List");
    $obj_pdf->SetHeaderData("","", PDF_HEADER_TITLE, PDF_HEADER_STRING);
    $obj_pdf->SetHeaderFont(Array(PDF_FONT_NAME_MAIN,"",PDF_FONT_SIZE_MAIN));
    $obj_pdf->SetFooterFont(Array(PDF_FONT_NAME_DATA,"",PDF_FONT_SIZE_DATA));
    $obj_pdf->SetDefaultMonospacedFont('helvetica');
    $obj_pdf->SetFooterMargin(PDF_MARGIN_FOOTER);
    $obj_pdf->SetMargins(PDF_MARGIN_LEFT,'5',PDF_MARGIN_RIGHT);
    $obj_pdf->SetPrintHeader(false);
    $obj_pdf->SetPrintFooter(false);
    $obj_pdf->SetAutoPageBreak(TRUE,10);
    $obj_pdf->SetFont('helvetica',"",12);
    $obj_pdf->AddPage();

    $content="";
    $content.='
        <h3 align="center"> Customer List </h3>
        <table border="1" cellspacing="0" cellpadding="5">
            <tr>
                <th width=5%>customer ID</th>
                <th width=10%>Customer Full name</th>
                <th width=15%>Customer Email</th>
            </tr>
    ';

    $content .= fetch_data();
    $content .= '</table>';
    $obj_pdf->writeHTML($content);
    $obj_pdf->Output("sample.pdf","I");



}
?>

<html>
    <head>
        <title>Customer List</title>
        <link rel="stylesheet" type="text/css" href="css/style.css" />
    </head>
    <body>
        <br><br />
        <div class="container" style="width:700px;">
            <h3 align="center"> Customer List </h3>
            <br />
            <div class="table-responsive">
                <table class="table table-bordered" border="1" cellpadding="4">
                    <tr>
                        <td width="5%"><strong>customer ID</strong></td>
                        <td width="10%"><strong>Customer Full name</strong></td>
                        <td width="15%"><strong>Customer Email</strong></td>
                    </tr>
                    <?php
                    echo fetch_data();
                    ?>
                </table>

or alternative if you dont want to use tcpdf:

    if (isset($_POST['txtNameSearch'])){
    $search = $_POST['txtNameSearch'];
$connection = mysqli_connect('localhost', 'root', '', 'bookstore');
    $query = "SELECT * FROM tblproduct right join order_details on tblproduct.prod_id=order_details.prod_id WHERE prod_no = $search ";
    $result=mysqli_query($connection, $query);
    while($row = mysqli_fetch_array($result))
    {
        $output .='
            <tr>
                <td>'.$row["prod_id"].'</td>
                <td>'.$row["prod_name"].'</td>
                <td>'.$row["order_id"].'</td>
                <td>'.$row["quantity"].'</td>
            </tr>
        ';
    }

    return $output;
}
}
}
?>

<!DOCTYPE html>
<html>
<head>
    <title>HTML to PDF</title>
</head>
<body>
            <form method="POST" action="index.php">
            <input type="text" name="txtNameSearch" />
            <input class="src_btn" type="submit" name="btnSearch" value="Search" />
            </form>
    <!-- 
    content of this area will be the content of your PDF file 
    -->
    <div id="HTMLtoPDF">

                <table class="table table-bordered" border="1" cellpadding="4">
                <tr>
                        <td width="25%"><strong>prod_id</strong></td>
                        <td width="25%"><strong>prod_name</strong></td>
                        <td width="25%"><strong>order_id</strong></td>
                        <td width="25%"><strong>quantity</strong></td>
</tr>

    <?php       
    echo fetch_data();

    ?>  

    </div>

    <!-- here we call the function that makes PDF -->
    <a href="#" onclick="HTMLtoPDF()">Download PDF</a>
            <a href="/DEVProject/admin/admin_addnew_user.php"> Back to Admin Panel </a>

If you want i can prepare a download link of the fully working code as well

Solution 2:[2]

If you just want to render the page like a browser, you could try Puppeteer, a way to control a headless browser instance of Chrome or any solution based on WKHTMLPDF (like Snappy). It would literally be (example from the README):

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://news.ycombinator.com', {waitUntil: 'networkidle2'});
  await page.pdf({path: 'hn.pdf', format: 'A4'});

  await browser.close();
})();

Of course, if the page is non-public, it gets tricker, but you could get around that with some hacks.

If what you really want is just to print the page as it is, you could just try a media query for print. That is usually the best way to print a page.

Still, if you really want to print an invoice that looks nice, you should do that server side, not on the client. Trying to generate an invoice to look like the html just seems like an excuse to avoid having to do the manual work of creating a pdf the "proper" way ;)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mohammedis271
Solution 2