DomPDF
Module DomPDF tích hợp thư viện dompdf/dompdf vào framework, cho phép tạo file PDF từ HTML, Twig view, hoặc file HTML tĩnh.
Cài đặt
composer require dompdf/dompdf
Đăng ký service provider trong bootstrap/app.php:
use Vietiso\Core\DomPDF\PDFServiceProvider;
$app->register(PDFServiceProvider::class);
Cấu hình
File cấu hình nằm tại config/dompdf.php:
return [
// Ném Exception nếu có cảnh báo từ dompdf
'show_warnings' => false,
// Ghi đè đường dẫn public nếu cần (null = storage/public)
'public_path' => null,
// Font Dejavu Sans thiếu ký tự cho một số entity.
// Tắt nếu cần hiển thị ký hiệu € hoặc £.
'convert_entities' => true,
'options' => [
// Thư mục lưu trữ font (phải có quyền ghi)
'font_dir' => storage_path('fonts'),
'font_cache' => storage_path('fonts'),
// Thư mục tạm (phải có quyền ghi)
'temp_dir' => sys_get_temp_dir(),
// Giới hạn quyền truy cập file — KHÔNG đặt là '/'
'chroot' => realpath(base_path()),
// Các giao thức được phép tải nội dung
'allowed_protocols' => [
'data://' => ['rules' => []],
'file://' => ['rules' => []],
'http://' => ['rules' => []],
'https://' => ['rules' => []],
],
'artifactPathValidation' => null,
'log_output_file' => null,
// Bật font subsetting để giảm kích thước PDF
'enable_font_subsetting' => false,
// Backend render: 'CPDF', 'PDFLib', 'GD', 'auto'
'pdf_backend' => 'CPDF',
// Kiểu media CSS khi render: screen, print, all, ...
'default_media_type' => 'screen',
// Khổ giấy và hướng mặc định
'default_paper_size' => 'a4',
'default_paper_orientation' => 'landscape',
// Font fallback khi không tìm thấy font phù hợp
'default_font' => 'serif',
'dpi' => 96,
'font_height_ratio' => 1.1,
// ⚠️ Chỉ bật enable_php nếu tin tưởng nội dung HTML
'enable_php' => false,
'enable_javascript' => true,
// ⚠️ Bật enable_remote để load ảnh/CSS từ URL bên ngoài
'enable_remote' => true,
'allowed_remote_hosts' => null, // null = cho phép tất cả
// Bật parser HTML5 (luôn bật trong dompdf 2.x)
'enable_html5_parser' => true,
],
];
Sử dụng
Từ HTML string
use Vietiso\Core\DomPDF\Facade\PDF;
$pdf = PDF::loadHTML('<h1>Xin chào!</h1><p>Nội dung PDF.</p>');
return $pdf->download('tai-lieu.pdf');
Từ Twig View
Cách phổ biến nhất — truyền dữ liệu vào template như render view thông thường:
$pdf = PDF::loadView('invoices/detail', [
'invoice' => $invoice,
'items' => $items,
]);
return $pdf->download('hoa-don-' . $invoice->id . '.pdf');
Từ file HTML
$pdf = PDF::loadFile('/path/to/template.html');
return $pdf->stream('bao-cao.pdf');
Xuất PDF
Download
Trả về response buộc trình duyệt tải file về máy:
return PDF::loadView('reports/monthly', $data)
->download('bao-cao-thang.pdf');
Stream (xem trực tiếp)
Trả về response hiển thị PDF ngay trong trình duyệt:
return PDF::loadView('reports/monthly', $data)
->stream('bao-cao-thang.pdf');
Lấy nội dung PDF dưới dạng string
$content = PDF::loadView('invoices/detail', $data)->output();
// Lưu thủ công, gửi email đính kèm, v.v.
Lưu File
Lưu vào đường dẫn tuyệt đối
PDF::loadView('invoices/detail', $data)
->save(storage_path('pdfs/hoa-don-001.pdf'));
Lưu vào Filesystem Disk
PDF::loadView('invoices/detail', $data)
->save('pdfs/hoa-don-001.pdf', disk: 's3');
Nếu cấu hình disk trong config/dompdf.php, có thể bỏ qua tham số thứ hai:
// config/dompdf.php: 'disk' => 's3'
PDF::loadView('invoices/detail', $data)->save('pdfs/hoa-don-001.pdf');
Tùy Chỉnh
Khổ giấy và chiều
$pdf = PDF::loadView('reports/landscape', $data)
->setPaper('a4', 'landscape');
return $pdf->download('bao-cao.pdf');
Các khổ giấy hỗ trợ: a4, a3, letter, legal, ledger, v.v.
Metadata PDF
$pdf = PDF::loadView('invoices/detail', $data)
->addInfo([
'Title' => 'Hóa đơn #001',
'Author' => 'TourDB System',
'Subject' => 'Hóa đơn dịch vụ tour',
]);
Tuỳ chỉnh option runtime
// Một option
$pdf = PDF::loadView('template', $data)
->setOption('enable_remote', true);
// Nhiều option cùng lúc
$pdf = PDF::loadView('template', $data)
->setOptions([
'enable_remote' => true,
'default_font' => 'DejaVu Sans',
]);
// Gộp với options mặc định từ config
$pdf = PDF::loadView('template', $data)
->setOptions(['enable_remote' => true], mergeWithDefaults: true);
Mã hóa PDF (yêu cầu CPDF backend)
$pdf = PDF::loadView('confidential', $data);
$pdf->setEncryption(
password: 'user-password',
ownerpassword: 'owner-password',
pc: ['print'] // quyền được phép
);
return $pdf->download('tai-lieu-mat.pdf');
Truy cập DomPDF instance gốc
$pdf = PDF::loadView('template', $data);
$dompdf = $pdf->getDomPDF();
// Thao tác trực tiếp với Dompdf
Tích hợp Email
Gửi PDF đính kèm qua email:
use Vietiso\Core\DomPDF\Facade\PDF;
use Vietiso\Core\Mail\Facade\Mail;
$pdfContent = PDF::loadView('invoices/detail', ['invoice' => $invoice])
->output();
Mail::send(
to: $customer->email,
view: 'emails.invoice',
data: ['invoice' => $invoice],
attachments: [
[
'data' => $pdfContent,
'name' => 'hoa-don-' . $invoice->id . '.pdf',
'mime' => 'application/pdf',
],
]
);
Lưu ý
- Mỗi lần gọi
PDF::loadView()hoặcPDF::loadHTML()sẽ tạo ra một instance mới (transient binding) — không cần lo lẫn dữ liệu giữa các request. - Để load ảnh và CSS từ local, đặt
public_pathtrỏ đến thư mục chứa assets. DomPDF cần đường dẫn tuyệt đối. - Font tiếng Việt cần nhúng font Unicode (DejaVu Sans hoặc font tùy chỉnh) vào thư mục
font_dir. - Giữ
enable_php = falsetrong môi trường production để tránh rủi ro bảo mật.