Day 24 โ Export Data ke PDF dengan DomPDF โ
Fase: 3 โ Fitur Lanjutan | Minggu: 5 | Hari: Kamis
๐ฏ Tujuan Hari Ini โ
- Menginstal dan mengkonfigurasi package Barryvdh DomPDF untuk Laravel.
- Membuat view Blade khusus yang dioptimalkan untuk tampilan PDF.
- Mengimplementasikan endpoint untuk mengunduh laporan peminjaman dalam format PDF.
- Memahami perbedaan pendekatan PDF vs Excel dan kapan menggunakan masing-masing.
๐ Penjelasan: PDF vs Excel โ Kapan Menggunakan Mana? โ
| Kriteria | Excel | |
|---|---|---|
| Tujuan | Presentasi, cetak resmi | Analisis, pivot, edit data |
| Format | Tetap (tidak bisa diedit) | Fleksibel |
| Cocok untuk | Surat, laporan formal, faktur | Rekap data, laporan operasional |
| Dikirim ke | Klien, pimpinan, arsip | Internal tim, akunting |
Untuk laporan peminjaman yang harus dicetak dan ditandatangani, PDF adalah pilihan tepat.
๐ง Step-by-Step โ
Step 1: Install Package DomPDF โ
bash
composer require barryvdh/laravel-dompdfPublish konfigurasi:
bash
php artisan vendor:publish --provider="Barryvdh\DomPDF\ServiceProvider"Step 2: Buat Blade View Khusus PDF โ
Buat file view baru khusus untuk layout PDF. View ini harus menggunakan HTML murni dengan inline CSS karena DomPDF memiliki dukungan CSS yang terbatas.
html
{{-- resources/views/loans/pdf.blade.php --}}
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<title>Laporan Peminjaman Aset</title>
<style>
/* CSS harus inline atau dalam tag <style> */
body {
font-family: Arial, sans-serif;
font-size: 12px;
color: #333;
}
.header {
text-align: center;
border-bottom: 2px solid #333;
padding-bottom: 10px;
margin-bottom: 20px;
}
.header h1 {
font-size: 18px;
margin: 0;
}
.header p {
margin: 4px 0;
color: #555;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 15px;
}
th {
background-color: #2d6a4f;
color: white;
padding: 8px;
text-align: left;
font-size: 11px;
}
td {
padding: 7px 8px;
border-bottom: 1px solid #ddd;
font-size: 11px;
}
tr:nth-child(even) {
background-color: #f5f5f5;
}
.badge-pending {
background: #f0ad4e;
color: white;
padding: 2px 6px;
border-radius: 3px;
}
.badge-returned {
background: #5cb85c;
color: white;
padding: 2px 6px;
border-radius: 3px;
}
.footer {
margin-top: 20px;
text-align: right;
font-size: 10px;
color: #888;
}
.summary-box {
background: #e8f5e9;
border: 1px solid #4caf50;
padding: 10px;
border-radius: 4px;
margin-bottom: 15px;
}
</style>
</head>
<body>
<div class="header">
<h1>SIMAS โ Sistem Manajemen Aset Sederhana</h1>
<p>Laporan Data Peminjaman Aset</p>
<p>Dicetak: {{ now()->format('d F Y, H:i') }} WIB</p>
</div>
<div class="summary-box">
<strong>Ringkasan:</strong>
Total Peminjaman: <strong>{{ $loans->count() }}</strong> |
Sedang Dipinjam: <strong>{{ $loans->where('status', 'pending')->count() }}</strong> |
Sudah Dikembalikan: <strong>{{ $loans->where('status', 'returned')->count() }}</strong>
</div>
<table>
<thead>
<tr>
<th>No.</th>
<th>Nama Peminjam</th>
<th>Aset yang Dipinjam</th>
<th>Jml</th>
<th>Tgl Pinjam</th>
<th>Tgl Kembali</th>
<th>Status</th>
</tr>
</thead>
<tbody>
@foreach ($loans as $i => $loan)
<tr>
<td>{{ $i + 1 }}</td>
<td>{{ $loan->borrower_name }}</td>
<td>{{ $loan->asset->name ?? '-' }}</td>
<td>{{ $loan->quantity }}</td>
<td>{{ $loan->loan_date->format('d/m/Y') }}</td>
<td>{{ $loan->return_date ? $loan->return_date->format('d/m/Y') : '-' }}</td>
<td>
@if ($loan->status === 'returned')
<span class="badge-returned">Dikembalikan</span>
@else
<span class="badge-pending">Dipinjam</span>
@endif
</td>
</tr>
@endforeach
</tbody>
</table>
<div class="footer">
<p>Dokumen ini digenerate otomatis oleh sistem. Sahkan dengan tanda tangan pejabat berwenang.</p>
</div>
</body>
</html>Step 3: Tambahkan Route dan Logic PDF โ
php
// routes/web.php
use Barryvdh\DomPDF\Facade\Pdf;
use App\Models\Loan;
Route::get('/loans/export/pdf', function () {
$loans = Loan::with('asset')->latest()->get();
$pdf = Pdf::loadView('loans.pdf', ['loans' => $loans]);
// Atur ukuran dan orientasi kertas
$pdf->setPaper('a4', 'landscape'); // landscape untuk tabel yang lebar
// Download langsung:
return $pdf->download('laporan-peminjaman-' . date('Ymd') . '.pdf');
// Atau tampilkan di browser (tidak download):
// return $pdf->stream('laporan-peminjaman.pdf');
})->name('loans.export.pdf');Step 4: Tambahkan Tombol Export PDF di Blade โ
html
{{-- resources/views/loans/index.blade.php --}}
<div class="d-flex justify-content-between align-items-center mb-3">
<h1>Riwayat Peminjaman</h1>
<div class="d-flex gap-2">
<a href="{{ route('loans.create') }}" class="btn btn-primary">
+ Catat Peminjaman
</a>
<a href="{{ route('loans.export.excel') }}" class="btn btn-success">
<i class="bi bi-file-earmark-excel"></i> Excel
</a>
<a href="{{ route('loans.export.pdf') }}" class="btn btn-danger">
<i class="bi bi-file-earmark-pdf"></i> PDF
</a>
</div>
</div>๐งช Uji Coba Mandiri โ
- [ ] Kunjungi halaman
/loansโ klik tombol "PDF" โ file.pdfter-download. - [ ] Buka PDF โ pastikan tabel tampil rapi, ada header institusi.
- [ ] Pastikan badge status "Dipinjam" dan "Dikembalikan" tampil dengan warna yang berbeda.
- [ ] Coba ubah orientasi dari
landscapekeportraitโ lihat perbedaannya. - [ ] Pastikan ringkasan di atas tabel menampilkan jumlah yang benar.
โ ๏ธ Keterbatasan DomPDF โ
WARNING
DomPDF memiliki keterbatasan CSS yang perlu diketahui:
- Tidak mendukung Flexbox dan CSS Grid.
- Tidak mendukung external CSS (Bootstrap dari CDN tidak akan berfungsi).
- Semua styling harus berada dalam tag
<style>atau inline. - Gambar harus menggunakan path absolut (
storage_path(...)) atau Base64.
Cara Menampilkan Gambar di PDF (Jika Diperlukan) โ
php
// Untuk menampilkan gambar di PDF, konversi ke Base64
$imagePath = storage_path('app/public/' . $asset->photo);
$imageData = base64_encode(file_get_contents($imagePath));
$imageMime = mime_content_type($imagePath);
$imageBase64 = 'data:' . $imageMime . ';base64,' . $imageData;html
{{-- Di view PDF --}}
<img src="{{ $imageBase64 }}" width="80">TIP
Untuk PDF yang lebih kompleks dengan grafik dan chart, pertimbangkan menggunakan Browsershot (berbasis Puppeteer) atau layanan seperti wkhtmltopdf. Namun untuk laporan tabel sederhana, DomPDF sudah lebih dari cukup.