Oh Dear is the all-in-one monitoring tool for your entire website. We monitor uptime, SSL certificates, broken links, scheduled tasks and more. You'll get a notifications for us when something's wrong. All that paired with a developer friendly API and kick-ass documentation. O, and you'll also be able to create a public status page under a minute. Start monitoring using our free trial now.

Creating beautiful invoices using Tailwind and Laravel PDF

Original – by Freek Van der Herten – 2 minute read

Last week, we released a new package called Laravel PDF that allows you to transform Blade views into PDFs. Under the hood, Chromium is used to perform the transformation. Because Chromium is an up-to-date browser, you can use any modern CSS you like.

Some people have asked if they can use Tailwind to style their documents. And I’m happy to report you can. Let’s take a look at a minimal example to showcase this.

In your project, you need to save a Blade view with content like this. In this view, I used the CDN version of Tailwind (in your project you can use an asset built with vite) and got an invoice layout from one of the many Tailwind template sites.

<html lang="en">
<head>
    <title>Invoice</title>
    <script src="https://cdn.tailwindcss.com"></script>
</head>
<body>

<div class="px-2 py-8 max-w-xl mx-auto">
    <div class="flex items-center justify-between mb-8">
        <div class="flex items-center">
            <div class="text-gray-700 font-semibold text-lg">Your Company Name</div>
        </div>
        <div class="text-gray-700">
            <div class="font-bold text-xl mb-2 uppercase">Invoice</div>
            <div class="text-sm">Date: 01/05/2023</div>
            <div class="text-sm">Invoice #: {{ $invoiceNumber }}</div>
        </div>
    </div>
    <div class="border-b-2 border-gray-300 pb-8 mb-8">
        <h2 class="text-2xl font-bold mb-4">Bill To:</h2>
        <div class="text-gray-700 mb-2">{{ $customerName }}</div>
        <div class="text-gray-700 mb-2">123 Main St.</div>
        <div class="text-gray-700 mb-2">Anytown, USA 12345</div>
        <div class="text-gray-700">johndoe@example.com</div>
    </div>
    <table class="w-full text-left mb-8">
        <thead>
        <tr>
            <th class="text-gray-700 font-bold uppercase py-2">Description</th>
            <th class="text-gray-700 font-bold uppercase py-2">Quantity</th>
            <th class="text-gray-700 font-bold uppercase py-2">Price</th>
            <th class="text-gray-700 font-bold uppercase py-2">Total</th>
        </tr>
        </thead>
        <tbody>
        <tr>
            <td class="py-4 text-gray-700">Product 1</td>
            <td class="py-4 text-gray-700">1</td>
            <td class="py-4 text-gray-700">$100.00</td>
            <td class="py-4 text-gray-700">$100.00</td>
        </tr>
        <tr>
            <td class="py-4 text-gray-700">Product 2</td>
            <td class="py-4 text-gray-700">2</td>
            <td class="py-4 text-gray-700">$50.00</td>
            <td class="py-4 text-gray-700">$100.00</td>
        </tr>
        <tr>
            <td class="py-4 text-gray-700">Product 3</td>
            <td class="py-4 text-gray-700">3</td>
            <td class="py-4 text-gray-700">$75.00</td>
            <td class="py-4 text-gray-700">$225.00</td>
        </tr>
        </tbody>
    </table>
    <div class="flex justify-end mb-8">
        <div class="text-gray-700 mr-2">Subtotal:</div>
        <div class="text-gray-700">$425.00</div>
    </div>
    <div class="text-right mb-8">
        <div class="text-gray-700 mr-2">Tax:</div>
        <div class="text-gray-700">$25.50</div>

    </div>
    <div class="flex justify-end mb-8">
        <div class="text-gray-700 mr-2">Total:</div>
        <div class="text-gray-700 font-bold text-xl">$450.50</div>
    </div>
    <div class="border-t-2 border-gray-300 pt-8 mb-8">
        <div class="text-gray-700 mb-2">Payment is due within 30 days. Late payments are subject to fees.</div>
        <div class="text-gray-700 mb-2">Please make checks payable to Your Company Name and mail to:</div>
        <div class="text-gray-700">123 Main St., Anytown, USA 12345</div>
    </div>
</div>

</body>
</html>

In a Laravel application where Laravel PDF is installed, you can add a controller like this. The above view is saved in resources/views/pdf/invoce.

namespace App\Http\Controllers;

use function Spatie\LaravelPdf\Support\pdf;

class DownloadInvoiceController
{
    public function __invoke()
    {
        return pdf('pdf.invoice', [
            'invoiceNumber' => '1234',
            'customerName' => 'Grumpy Cat',
        ]);
    }
}

When you hit that controller, a PDF like this one will be downloaded.

Neat, right?

This shows how easy it is to create a beautiful invoice using Tailwind and our PDF package. Of course, in a real-world scenario, you would make more things, like the line items and prices, ... dynamic.

To learn more about Laravel PDF, head over to the package's extensive documentation.

Stay up to date with all things Laravel, PHP, and JavaScript.

You can follow me on these platforms:

On all these platforms, regularly share programming tips, and what I myself have learned in ongoing projects.

Every month I send out a newsletter containing lots of interesting stuff for the modern PHP developer.

Expect quick tips & tricks, interesting tutorials, opinions and packages. Because I work with Laravel every day there is an emphasis on that framework.

Rest assured that I will only use your email address to send you the newsletter and will not use it for any other purposes.

Comments

micha avatar

if you choose the word "beautiful" in the title, i would show an example that fits to that ;)

Samuca avatar

For me it's beautiful. Would you care to elaborate ?

Comments powered by Laravel Comments
Want to join the conversation? Log in or create an account to post a comment.