Skip to content

Funzionalità Avanzate

Oltre al rendering HTML-to-PDF base, il pacchetto Artisan fornisce utility per unire documenti, iniettare stili globali, catturare screenshot e ottimizzare il comportamento Chrome.

Unione PDF

La classe PdfMerger combina sorgenti HTML multiple in un singolo documento PDF. Ogni sorgente è renderizzata come sezione separata e i risultati sono concatenati in ordine.

php
use Yeeefang\TcpdfNext\Artisan\PdfMerger;
use Yeeefang\TcpdfNext\Artisan\RenderOptions;

$merger = PdfMerger::create();

$merger
    ->addHtml('<h1>Pagina Copertina</h1><p>Rapporto Annuale 2026</p>')
    ->addFile('/templates/chapter-1.html')
    ->addFile('/templates/chapter-2.html')
    ->addUrl('https://charts.example.com/annual-summary')
    ->addHtml('<h1>Appendice</h1><p>Tabelle dati supporto.</p>');

$merger->save('/reports/annual-2026.pdf');

Opzioni Per-Sezione

Ogni sezione può avere i propri RenderOptions. Ad esempio, una pagina copertina in landscape e capitoli in portrait.

php
$coverOptions = RenderOptions::create()
    ->setPageSize('A4')
    ->setLandscape(true)
    ->setPrintBackground(true);

$chapterOptions = RenderOptions::create()
    ->setPageSize('A4')
    ->setLandscape(false)
    ->setDisplayHeaderFooter(true)
    ->setFooterTemplate('
        <div style="font-size: 8px; text-align: center; width: 100%; color: #888;">
            Pagina <span class="pageNumber"></span>
        </div>
    ');

PdfMerger::create()
    ->addHtml('<h1>Copertina</h1>', options: $coverOptions)
    ->addFile('/templates/chapter-1.html', options: $chapterOptions)
    ->addFile('/templates/chapter-2.html', options: $chapterOptions)
    ->save('/reports/merged.pdf');

Iniezione CSS

La classe StyleInjector antepone regole CSS alla pagina renderizzata. Utile per applicare un foglio stile brand globale a template che non controlli.

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

$injector = StyleInjector::create()
    ->addCss('
        body {
            font-family: "Inter", "Noto Sans TC", sans-serif;
            font-size: 11pt;
            line-height: 1.6;
            color: #333;
        }
        h1 { color: #1a237e; }
    ')
    ->addCssFile('/styles/brand.css');

HtmlRenderer::create()
    ->loadFile('/templates/report.html')
    ->withStyleInjector($injector)
    ->save('/output/branded-report.pdf');

Livelli Stile Multipli

Gli stili sono iniettati nell'ordine in cui sono aggiunti. Le regole successive sovrascrivono quelle precedenti, seguendo la specificità CSS standard.

php
$injector = StyleInjector::create()
    ->addCssFile('/styles/reset.css')
    ->addCssFile('/styles/brand.css')
    ->addCss('table { page-break-inside: avoid; }');  // sovrascrive

Screenshot

La classe ScreenshotCapture renderizza HTML a formati immagine invece di PDF. Utile per generare thumbnail, anteprime social media o test regressione visuale.

php
use Yeeefang\TcpdfNext\Artisan\ScreenshotCapture;

// Screenshot pagina completa come PNG
ScreenshotCapture::create()
    ->loadHtml('<h1>Anteprima</h1><p>Questa sarà un\'immagine PNG.</p>')
    ->fullPage(true)
    ->format('png')
    ->save('/output/preview.png');

JPEG con Qualità

php
ScreenshotCapture::create()
    ->loadUrl('https://example.com/dashboard')
    ->format('jpeg')
    ->quality(85)
    ->save('/output/dashboard.jpg');

Configurazione Viewport

php
ScreenshotCapture::create()
    ->loadFile('/templates/email.html')
    ->viewport(width: 1200, height: 800)
    ->deviceScaleFactor(2)  // retina
    ->fullPage(false)
    ->save('/output/email-preview.png');

Configurazione Chrome

Percorso Binario Personalizzato

Artisan auto-rileva Chrome su percorsi OS comuni. Sovrascrivi con chromePath.

php
use Yeeefang\TcpdfNext\Artisan\HtmlRenderer;

$renderer = HtmlRenderer::create(
    chromePath: '/opt/google/chrome/chrome',
);

Oppure imposta la variabile ambiente CHROME_PATH globalmente.

Flag Headless Mode

Artisan passa --headless=new per impostazione predefinita (Chrome 112+). Puoi aggiungere flag extra per ambienti specifici.

php
$renderer = HtmlRenderer::create(
    chromeFlags: [
        '--no-sandbox',            // richiesto in Docker
        '--disable-gpu',           // raccomandato in Docker
        '--disable-dev-shm-usage', // evita problemi /dev/shm
        '--font-render-hinting=none',
    ],
);

Connection Pooling

Per scenari alta produttività, riusa una singola istanza Chrome tra rendering multipli. Questo elimina il costo startup (circa 300--500 ms) per ogni rendering successivo.

php
use Yeeefang\TcpdfNext\Artisan\ChromeBridge;
use Yeeefang\TcpdfNext\Artisan\HtmlRenderer;

// Crea un bridge persistente
$bridge = ChromeBridge::create(chromePath: '/usr/bin/chromium');

// Riusa tra rendering multipli
foreach ($reports as $report) {
    HtmlRenderer::createWithBridge($bridge)
        ->loadHtml($report->html)
        ->save("/output/{$report->id}.pdf");
}

// Chiudi esplicitamente quando finito
$bridge->close();

Gestione Errori

Tutte le eccezioni Artisan estendono Yeeefang\TcpdfNext\Artisan\Exceptions\ArtisanException.

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

try {
    HtmlRenderer::create()->loadUrl($url)->save($path);
} catch (ChromeNotFoundException $e) {
    // Installa Chrome o imposta CHROME_PATH
} catch (TimeoutException $e) {
    // Aumenta timeout o controlla rete
} catch (RenderException $e) {
    // Ispeziona $e->getMessage() per dettagli
}
EccezioneCausa Comune
ChromeNotFoundExceptionChrome non installato, CHROME_PATH incorretto
TimeoutExceptionPagina lenta, promise JS non risolte, problemi rete
RenderExceptionHTML invalido, crash Chrome, fallimento scrittura disco

Consigli Performance

  1. Riusa istanze Chrome -- Usa ChromeBridge per operazioni batch.
  2. Minimizza JavaScript -- Meno JS Chrome deve eseguire, più veloce il rendering.
  3. Inline CSS critico -- Evita recuperi fogli stile esterni quando possibile.
  4. Imposta timeout stretto -- Fallisci velocemente su pagine rotte piuttosto che bloccare la queue.
  5. Usa setPrintBackground(false) -- Salta rendering background quando non ne hai bisogno.

Prossimi Passi

  • Render Options -- Dimensione pagina, margini e template header/footer.
  • Setup Docker -- Eseguire Artisan in ambienti containerizzati.
  • Overview -- Riepilogo pacchetto e installazione.

Rilasciato sotto licenza LGPL-3.0-or-later.