Mendesain PDF di Laravel menggunakan Tailwind CSS: Teknik 2024 untuk integrasi dan estetika modern, dari instalasi hingga implementasi.
Dalam pelajaran kali ini, kita akan belajar bagaimana cara mendesain pdf di laravel menggunakan tailwind css.
Kita akan benar-benar mulai dari awal pastinya. Pertama sekali, silakan lakukan instalasi laravel nya dengan perintah berikut.
laravel new laravel-pdf
Setelah itu, silakan cd laravel-pdf
untuk melanjutkan instalasi package dari spatie yaitu laravel-pdf dengan menjalankan perintah berikut:
composer require spatie/laravel-pdf
Karena package ini menggunakan browsershot, maka kita perlu juga instalasi package pembantunya melalui yaitu puppeteer.
npm i puppeteer
Untuk tutorial kali ini, karena kita tidak ada setup tailwindcss, jadi sangat sah untuk kita menggunakan cdn.
Dalam hal ini, saya akan mencontohkan untuk membuat invoice yang kira-kira akan di download seorang user nantinya dalam bentuk pdf. Maka oleh karena itu, yang pertama kita akan membuat controller baru dengan nama InvoiceController
. Buka terminal Anda dan silakan jalankan perintah berikut:
php artisan make:controller InvoiceController
Setelah itu, silakan buat 2 method sekaligus yaitu index
dan juga download
seperti berikut:
public function index()
{
return view('invoices/index');
}
Untuk download
nya ini lumayan panjang, karena di sini kita tidak ada persiap data, jadi datanya saya hard code saja sebagai contoh.
public function download()
{
$items = collect([
[
'title' => 'Website redesign',
'description' => 'Redesign the company website with a fresh look.',
'hours' => 50,
'rate' => 125000,
'price' => 50 * 125000,
],
[...],
[...],
]);
return pdf()
->view('pdf.invoice', [
'items' => $items,
'subtotal' => $items->sum('price'),
'tax' => $items->sum('price') * 0.1,
'total' => $items->sum('price'),
])
->download(downloadName: 'invoice-'.now()->format('Y-m-d').'.pdf');
}
Tanda [...]
bisa kalian ganti dengan data yang format nya sama seperti yang di atas. Sehingga seakan-akan item nya lebih dari 1. Perhatikan pada function pdf()
, ini tidak bisa dipakai sebelum kita import di atas, maka oleh karena itu, pastikan Anda telah menambahnya seperti berikut:
use function Spatie\LaravelPdf\Support\pdf;
class InvoiceController extends Controller
{
public function index(...)
public function download(...)
}
Pertama sekali, kita akan langsung membuat view untuk index nya, buat folder dengan nama invoices tepat di dalam views, dan di dalamnya buat 1 file dengan index.blade.php, isi nya simpel saja, bisa langsung dibuat seperti berikut:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Your Invoices</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="antialiased tracking-tight py-24">
<main class="max-w-screen-lg mx-auto text-sm">
<div class="border p-6 shadow-sm max-w-xl bg-white rounded-lg">
<p class="mb-2">
Your invoices ready to download, click the link below to download.
</p>
<a class="underline text-blue-600" href='/invoices/download' target='_blank'>
Download Invoice
</a>
</div>
</main>
</body>
</html>
Melalui halaman ini, user akan mendownload invoice nya.
Setelah itu, silakan buat 1 folder dengan nama pdf, dan di dalam nya buat 1 file dengan nama invoice.blade.php, isi nya bisa dibuat seperti ini saja.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Invoice {{ now()->format('d/m/Y') }}</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
<div class="text-[0.8rem] p-24">
<div class="sm:flex sm:items-center">
<div class="sm:flex-auto">
<h1 class="text-base font-semibold leading-6 text-gray-900">Invoice</h1>
<p class="mt-2 text-gray-600">For work completed from
<time datetime="2024-01-01">{{ now()->firstOfMonth()->format('d M Y') }}</time>
to
<time datetime="2024-31-01">{{ now()->lastOfMonth()->format('d M Y') }}</time>
.
</p>
</div>
</div>
<div class="-mx-4 mt-8 flow-root sm:mx-0">
<table class="min-w-full">
<colgroup>
<col class="w-full sm:w-1/2">
<col class="sm:w-1/6">
<col class="sm:w-1/6">
<col class="sm:w-1/6">
</colgroup>
<thead class="border-b border-gray-300 text-gray-900">
<tr>
<th scope="col" class="py-3.5 pl-4 pr-3 text-left font-semibold text-gray-900 sm:pl-0">Project
</th>
<th scope="col" class="hidden px-3 py-3.5 text-right font-semibold text-gray-900 sm:table-cell">
Hours
</th>
<th scope="col" class="hidden px-3 py-3.5 text-right font-semibold text-gray-900 sm:table-cell">
Rate
</th>
<th scope="col" class="py-3.5 pl-3 pr-4 text-right font-semibold text-gray-900 sm:pr-0">Price
</th>
</tr>
</thead>
<tbody>
@foreach($items as $item)
<tr class="border-b border-gray-200">
<td class="max-w-0 py-5 pl-4 pr-3 sm:pl-0">
<div class="font-medium text-gray-900">{{ $item['title'] }}</div>
<div class="mt-1 text-gray-500">{{ $item['description'] }}</div>
</td>
<td class="hidden px-3 py-5 text-right font-mono text-gray-500 sm:table-cell">{{ $item['hours'] }}</td>
<td class="hidden px-3 py-5 text-right font-mono text-gray-500 sm:table-cell">{{ Number::currency($item['rate'], 'IDR', 'id') }}</td>
<td class="py-5 pl-3 pr-4 text-right font-mono text-gray-500 sm:pr-0">{{ Number::currency($item['price'], 'IDR', 'id') }}</td>
</tr>
@endforeach
</tbody>
<tfoot>
<tr>
<th scope="row" colspan="3"
class="hidden pl-4 pr-3 pt-6 text-right font-normal text-gray-500 sm:table-cell sm:pl-0">
Subtotal
</th>
<th scope="row" class="pl-4 pr-3 pt-6 text-left font-normal text-gray-500 sm:hidden">Subtotal
</th>
<td class="pl-3 pr-4 pt-6 text-right text-gray-500 sm:pr-0">
<span class="font-mono">{{ Number::currency($subtotal, 'IDR', 'id') }}</span>
</td>
</tr>
<tr>
<th scope="row" colspan="3"
class="hidden pl-4 pr-3 pt-4 text-right font-normal text-gray-500 sm:table-cell sm:pl-0">Tax
</th>
<th scope="row" class="pl-4 pr-3 pt-4 text-left font-normal text-gray-500 sm:hidden">Tax</th>
<td class="pl-3 pr-4 pt-4 text-right text-gray-500 sm:pr-0">
<span class="font-mono">{{ Number::currency($tax, 'IDR', 'id') }}</span>
</td>
</tr>
<tr>
<th scope="row" colspan="3"
class="hidden pl-4 pr-3 pt-4 text-right font-semibold text-gray-900 sm:table-cell sm:pl-0">
Total
</th>
<th scope="row" class="pl-4 pr-3 pt-4 text-left font-semibold text-gray-900 sm:hidden">Total
</th>
<td class="pl-3 pr-4 pt-4 text-right font-semibold text-gray-900 sm:pr-0">
<span class="font-mono">{{ Number::currency($total, 'IDR', 'id') }}</span>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
</body>
</html>
Ini adalah desain yang akan menampilkan table dari invoice user.
Setelah view dan controller nya kita siapkan, maka selanjutnya kita bisa membuat route nya, buka file routes/web.php dan kemudian silakan tambahkan 2 route ini:
use App\Http\Controllers\InvoiceController;
/* ... */
Route::get('invoices', [InvoiceController::class, 'index']);
Route::get('invoices/download', [InvoiceController::class, 'download']);
Dengan begitu, sekarang kita bisa terminal dan silakan jalankan aplikasinya, jika Anda menggunakan herd, maka itu bisa dengan langsung mengunjungi laravel-pdf.test/invoices
atau jika tidak, bisa jalan dev server nya dengan menjalankan perintah berikut:
php artisan serve
Dan Anda bisa langsung kunjungi localhost:8000/invoices
. Anda langsung bisa tekan download invoice dan harusnya akan langsung mendownload file dengan nama misalnya invoice-2024-01-27-9.pdf
Jika project kalian sudah di production, dan kalian juga menggunakan ubuntu, kalian > bisa menjalankan perintah berikut ini:
curl -sL https://deb.nodesource.com/setup_21.x | sudo -E bash -
sudo apt-get install -y nodejs gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgbm1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget libgbm-dev libxshmfence-dev
sudo npm install --location=global --unsafe-perm puppeteer@^17
sudo chmod -R o+rx /usr/lib/node_modules/puppeteer/.local-chromium
Tanpa menggunakan package seperti spatie/laravel-pdf
, memang masih bisa membuat PDF di Laravel, namun integrasi Tailwind CSS menjadi tantangan. Tailwind CSS, yang bergantung pada sistem build modern dan JavaScript, sulit diimplementasikan dalam PDF yang biasanya memerlukan CSS murni.
Fitur seperti Flexbox dan utilities Tailwind lainnya tidak akan berfungsi secara langsung dalam pembuatan PDF tanpa alat seperti Browsershot yang memungkinkan rendering HTML dan CSS layaknya browser. Jadi, penggunaan package ini memudahkan integrasi Tailwind CSS dalam desain PDF di Laravel.
Jika Anda suka dengan artikel, maka silakan share ke teman-teman agar mereka mengetaui bagaimana cara design pdf dengan tailwindcss di laravel.
Let's start living like no one can help us in any event, so that when we are helped in certain times, it becomes a plus in itself.