Skip to content

HTML Renderer

Class HtmlRenderer là điểm truy cập chính cho mọi thao tác HTML sang PDF. Nó cung cấp fluent API để tải nội dung, cấu hình output và render PDF document.

Factory Method

Tạo instance renderer với factory static create().

php
use Yeeefang\TcpdfNext\Artisan\HtmlRenderer;

// Cấu hình mặc định (tự phát hiện Chrome)
$renderer = HtmlRenderer::create();

// Với đường dẫn Chrome binary tùy chỉnh
$renderer = HtmlRenderer::create(
    chromePath: '/usr/bin/google-chrome',
);

// Với thư mục tạm tùy chỉnh
$renderer = HtmlRenderer::create(
    chromePath: '/usr/bin/chromium',
    tempDir: '/tmp/artisan-render',
);

Tải nội dung

Từ chuỗi

Truyền HTML thô trực tiếp với loadHtml(). Chuỗi có thể là document HTML đầy đủ hoặc fragment.

php
$renderer->loadHtml('<h1>Hello, World!</h1>');

Khi bạn truyền fragment, Artisan tự động bọc nó trong document <!DOCTYPE html> tối thiểu.

Từ file cục bộ

Tải file .html từ ổ đĩa với loadFile(). Đường dẫn tương đối đến stylesheet, hình ảnh và script trong file được phân giải từ thư mục của file.

php
$renderer->loadFile('/templates/quarterly-report.html');

Từ URL

Tải và render URL trực tiếp với loadUrl(). Trang được tải trong Chrome headless, nên JavaScript thực thi và AJAX call hoàn tất trước khi render.

php
$renderer->loadUrl('https://reports.example.com/q4-2026');

Bạn có thể đặt timeout navigation để tránh treo trên trang chậm:

php
$renderer->loadUrl('https://example.com/dashboard', timeoutMs: 30000);

Method xuất

Lưu ra file

php
$renderer->save('/output/report.pdf');

Lấy dạng chuỗi

Lấy byte PDF thô để xử lý tiếp (vd: lưu database, đính kèm email).

php
$pdfContent = $renderer->toString();

// Ví dụ: lưu database
DB::table('documents')->insert([
    'name'    => 'report.pdf',
    'content' => $pdfContent,
]);

Gửi đến trình duyệt

Stream PDF trực tiếp đến HTTP response với header phù hợp.

php
// Hiển thị inline (trình xem PDF trình duyệt)
$renderer->output('report.pdf', 'inline');

// Bắt buộc tải xuống
$renderer->output('report.pdf', 'download');

Ví dụ đầy đủ: Hóa đơn

php
use Yeeefang\TcpdfNext\Artisan\HtmlRenderer;

$html = <<<'HTML'
<!DOCTYPE html>
<html>
<head>
    <style>
        body { font-family: 'Inter', sans-serif; margin: 20mm; }
        .header { display: flex; justify-content: space-between; align-items: flex-start; }
        .company { font-size: 24px; font-weight: 700; color: #1a237e; }
        .meta { text-align: right; color: #666; font-size: 13px; }
        .grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin: 30px 0; }
        .grid section { padding: 15px; background: #f8f9fa; border-radius: 6px; }
        table { width: 100%; border-collapse: collapse; margin-top: 20px; }
        th { background: #1a237e; color: white; padding: 10px 12px; text-align: left; }
        td { border-bottom: 1px solid #e0e0e0; padding: 10px 12px; }
        tr:nth-child(even) { background: #fafafa; }
        .total { font-weight: 700; font-size: 18px; text-align: right; margin-top: 20px; }
    </style>
</head>
<body>
    <div class="header">
        <div class="company">Acme Corporation</div>
        <div class="meta">
            Invoice #2026-001<br>
            Date: 2026-02-16<br>
            Due: 2026-03-16
        </div>
    </div>
    <div class="grid">
        <section>
            <strong>Bill To</strong><br>
            Jane Smith<br>
            456 Oak Avenue<br>
            Springfield, IL 62704
        </section>
        <section>
            <strong>Ship To</strong><br>
            Jane Smith<br>
            789 Elm Street<br>
            Springfield, IL 62704
        </section>
    </div>
    <table>
        <thead>
            <tr>
                <th>Item</th>
                <th>Qty</th>
                <th>Unit Price</th>
                <th>Amount</th>
            </tr>
        </thead>
        <tbody>
            <tr><td>Web Development</td><td>40 hrs</td><td>$150.00</td><td>$6,000.00</td></tr>
            <tr><td>UI/UX Design</td><td>20 hrs</td><td>$125.00</td><td>$2,500.00</td></tr>
            <tr><td>Annual Hosting</td><td>1</td><td>$1,200.00</td><td>$1,200.00</td></tr>
        </tbody>
    </table>
    <div class="total">Total: $9,700.00</div>
</body>
</html>
HTML;

HtmlRenderer::create()
    ->loadHtml($html)
    ->save('/invoices/2026-001.pdf');

Method Chaining

Mọi setter trên HtmlRenderer trả về $this, cho phép fluent builder pattern.

php
use Yeeefang\TcpdfNext\Artisan\HtmlRenderer;
use Yeeefang\TcpdfNext\Artisan\RenderOptions;
use Yeeefang\TcpdfNext\Artisan\StyleInjector;

HtmlRenderer::create()
    ->loadFile('/templates/report.html')
    ->withOptions(
        RenderOptions::create()
            ->setPageSize('A4')
            ->setLandscape(false)
            ->setMargins(top: 15, right: 10, bottom: 15, left: 10)
            ->setPrintBackground(true)
    )
    ->withStyleInjector(
        StyleInjector::create()
            ->addCss('body { font-size: 12pt; }')
    )
    ->save('/output/styled-report.pdf');

Xử lý lỗi

php
use Yeeefang\TcpdfNext\Artisan\HtmlRenderer;
use Yeeefang\TcpdfNext\Artisan\Exceptions\RenderException;
use Yeeefang\TcpdfNext\Artisan\Exceptions\ChromeNotFoundException;
use Yeeefang\TcpdfNext\Artisan\Exceptions\TimeoutException;

try {
    HtmlRenderer::create()
        ->loadUrl('https://example.com/slow-report')
        ->save('/output/report.pdf');
} catch (ChromeNotFoundException $e) {
    // Không tìm thấy binary Chrome — kiểm tra CHROME_PATH
    logger()->error('Chrome not installed: ' . $e->getMessage());
} catch (TimeoutException $e) {
    // Trang mất quá lâu để tải hoặc render
    logger()->warning('Render timed out: ' . $e->getMessage());
} catch (RenderException $e) {
    // Bất kỳ lỗi render khác
    logger()->error('Render failed: ' . $e->getMessage());
}

Bước tiếp theo

Phân phối theo giấy phép LGPL-3.0-or-later.