Invoicing app in Laravel 9 – invoice template using dompdf

We continue our journey towards building an Invoicing app using Laravel 9. In this article we’ll create invoice template utilizing the models and database as created in previous article. So, going through each and every step given in the previous article is prerequisite before you continue here.

Since we now have models and database defined, let’s move onto generating an invoice in PDF format. First, import laravel-dompdf package into the project by executing following command in project’s parent (app) folder:

composer require barryvdh/laravel-dompdf

Next, create a new Blade view file to serve as PDF template by executing following command:

 touch resources/views/invoice.blade.php

Then, insert following code inside resources/views/invoice.blade.php:

<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Invoice - {{$invoice->invoice_number}}</title>
    </head>
    <body style="margin: 20px; font-family: 'dejavu serif'; font-size: 12px;">
    <?php
        $fmt = new NumberFormatter( 'en_US', NumberFormatter::CURRENCY );
        $fmt->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, 2);
        $fmt->setSymbol(NumberFormatter::CURRENCY_SYMBOL, '$');
        $words = new NumberFormatter( 'en_US', NumberFormatter::SPELLOUT );
    ?>
        <br>
        <div>
            <table style="width: 100%;">
                <tr>
                    <td style="width: 40%; text-align: left;">
                        <h4>Ref: {{$invoice->invoice_number}}</h4>
                    </td>
                    <td style="text-align: center;">
                    </td>
                    <td style="width: 40%; text-align: right;">
                        <h1>LOGO HERE</h1>
                    </td>
                </tr>
                <tr>
                    <td style="width: 40%; text-align: left;">
                        <h4>{{ \Carbon\Carbon::parse($invoice->invoice_date)->format('F d, Y')}}</h4>
                    </td>
                    <td style="text-align: center;">
                    </td>
                    <td style="width: 40%; text-align: right;">
                    </td>
                </tr>
                <tr>
                    <td style="width: 60%; text-align: left;">
                        <h4>{{$invoice->customer->name}}
                        <br>{{$invoice->customer->address}}</h4>
                    </td>
                    <td style="text-align: center;">
                    </td>
                    <td style="width: 40%; text-align: right;">
                    </td>
                </tr>
            </table>
        </div>
        <br/>
        <div>
            Description: {{$invoice->description}}
            <br>
            <br>
            <br>
            <table style="border-collapse: collapse; width: 100%; font-size: 10px;">
                <thead>
                <tr>
                    <th style="border: 1px solid gray; width: 80%; background-color: gray; color: white;">Item</th>
                    <th style="border: 1px solid gray; width: 80%; background-color: gray; color: white;">Quantity</th>
                    <th style="border: 1px solid gray; width: 80%; background-color: gray; color: white;">Unit</th>
                    <th style="border: 1px solid gray; width: 80%; background-color: gray; color: white;">Rate</th>
                    <th style="margin: 10px; padding: 10px; border: 1px solid gray;  text-align: center; width: 20%; background-color: gray; color: white;" >Amount</th>
                </tr>
                </thead>
                <tbody>
                @foreach($invoice->invoiceItems as $item)
                <tr>
                    <td style=" border: 1px solid gray;">{{$item->item->name}}</td>
                    <td style=" border: 1px solid gray; text-align: center;">{{$item->quantity}}</td>
                    <td style=" border: 1px solid gray; text-align: center;">{{$item->item->unit}}</td>
                    <td style=" border: 1px solid gray; text-align: center;">{{$item->rate}}</td>
                    <td style=" margin: 10px; padding: 10px; border: 1px solid gray; text-align: right;">{{ $fmt->formatCurrency($item->amount,'') }}</td>
                </tr>
                @endforeach
                <tr>
                    <td style=" border-right: 1px solid gray;" colspan="4"><strong>Total</strong></td>
                    <td style=" margin: 10px; padding: 10px; border-right: 1px solid gray; border-bottom: 5px double gray; text-align: right;"><strong>{{ $fmt->formatCurrency($invoice->amount,'') }}</strong></td>
                </tr>
                </tbody>
            </table>
            <div style="margin: 18px;">
                USD {{$words->format($invoice->amount) }} only.</td>
            </div>
        </div>
    </body>
</html>

Now, amend routes/web.php as follows:

//...

use App\Models\Invoice;
use Barryvdh\DomPDF\Facade\Pdf;

//...

Route::get('/pdf/{id}', function ($id) {
    $invoice = Invoice::find($id);
    $pdf = Pdf::loadView('invoice', compact('invoice'));
    return $pdf->stream($invoice->invoice_number.'.pdf');
})->name('pdf');

In order to check the PDF output, you can run PHP dev server by entering following command:

php artisan serv

And then enter following URL in the browser to generate first invoice in PDF format:

http://localhost:8000/pdf/1

In next articles, we’ll create controllers and frontend using various stacks available to Laravel 9 ecosystem.

5 thoughts on “Invoicing app in Laravel 9 – invoice template using dompdf”

Leave a Comment