Immagini, tabelle ed elenchi
Il testo da solo raramente basta a comporre un documento finito. In questo tutorial si aggiungono tre elementi costitutivi di uso quotidiano: un’immagine, una tabella e un elenco puntato. Si scrivono due piccoli script e ciascuno produce un vero file PDF (Portable Document Format) che si può aprire immediatamente.
Cosa si costruirà
Sezione intitolata “Cosa si costruirà”01-image.php— un PDF di una sola pagina con un titolo e un’immagine quadrata color ambra, collocata in un punto preciso della pagina.02-table-and-lists.php— un PDF di una sola pagina con una piccola tabella di libri e, sotto di essa, un elenco puntato.
Entrambi gli script sono programmi completi. Continuare a usare la cartella
di progetto del
primo tutorial
e salvare ciascuno script accanto a composer.json.
Passo 1: inserire un’immagine nella pagina
Sezione intitolata “Passo 1: inserire un’immagine nella pagina”Questo script porta con sé la propria immagine. Una minuscola immagine PNG (Portable Network Graphics) di 8 x 8 pixel viaggia all’interno dello script come stringa Base64. Base64 è una trascrizione in testo semplice di dati binari, quindi può stare nel codice sorgente. In un progetto reale questa parte si ometterebbe, perché il file immagine esiste già su disco.
Salvare questo file come 01-image.php ed eseguirlo con php 01-image.php:
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
// A tiny 8 x 8 pixel amber PNG, stored as text inside this script.// In a real project the image file already exists on disk, so you// would skip this block and point image() at your own file.$pngBase64 = 'iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAEUlEQVR42mP4Oo8bK2IYWhIAq6BngWh/dt4AAAAASUVORK5CYII=';
@mkdir(__DIR__ . '/out');
$pngPath = __DIR__ . '/out/amber-square.png';$pngBytes = base64_decode($pngBase64, true);if ($pngBytes === false) { fwrite(STDERR, "The embedded image data is damaged.\n"); exit(1);}file_put_contents($pngPath, $pngBytes);
$document = Document::createStandalone();$document->setTitle('Tutorial: images');$document->addPage();
$document->setFont('helvetica', 'B', 20);$document->cell(0, 26, 'A picture inside a PDF', newLine: true);
$document->setFont('helvetica', '', 12);$document->cell(0, 18, 'The amber square below comes from a tiny PNG file.', newLine: true);
// Place the image 72 points (one inch) from the left edge and// 160 points down from the top, printed as a 96 x 96 point square.$document->image($pngPath, x: 72, y: 160, width: 96, height: 96);
$document->save(__DIR__ . '/out/image.pdf');
echo "Wrote out/image.pdf\n";Sullo schermo dovrebbe comparire Wrote out/image.pdf. Aprendo
out/image.pdf si trovano il titolo, una riga di testo e un quadrato color
ambra.
Cosa è appena successo
Sezione intitolata “Cosa è appena successo”- Lo script decodifica dapprima la stringa Base64 riconvertendola nei byte
dell’immagine e li scrive in
out/amber-square.png. È soltanto l’espediente che rende il tutorial autosufficiente. La lezione inizia dalla chiamataimage(), che legge allo stesso modo qualsiasi file PNG o JPEG (Joint Photographic Experts Group) già esistente. @mkdir(__DIR__ . '/out')crea la cartella di output. Il segno@nasconde l’innocuo avviso che comparirebbe quando la cartella esiste già, così lo script può essere eseguito due volte di seguito.image()accetta il percorso di un file più una posizione e una dimensione di stampa. Posizioni e dimensioni sono misurate in punti, e 72 punti equivalgono a un pollice. L’origine della pagina è l’angolo in alto a sinistra, quindiy: 160significa 160 punti al di sotto del bordo superiore.- Pixel e punti sono cose diverse. L’immagine è di appena 8 x 8 pixel, ma
width: 96, height: 96la stampa come un quadrato largo un pollice e un terzo. È la dimensione di stampa scelta a contare, non il numero di pixel. image()colloca l’immagine nel punto esatto indicato. Non sposta la posizione di scrittura usata dacell(). Scrivere prima il testo e collocare poi le immagini evita che i due elementi si sovrappongano.- NextPDF legge l’immagine solo da un file locale, mai da un indirizzo web. Verifica che il file sia un’immagine reale e supportata prima di incorporarla. Questa protezione è utile quando i nomi dei file provengono dagli utenti.
Passo 2: aggiungere una tabella e un elenco puntato
Sezione intitolata “Passo 2: aggiungere una tabella e un elenco puntato”Tabelle ed elenchi sono contenuti strutturati. Il modo più rapido per descrivere una struttura è l’HTML (Hypertext Markup Language), lo stesso markup usato dalle pagine web. NextPDF esegue il rendering di un insieme supportato di HTML direttamente sulla pagina PDF. Non è coinvolto alcun browser.
Salvare questo file come 02-table-and-lists.php ed eseguirlo con
php 02-table-and-lists.php:
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
@mkdir(__DIR__ . '/out');
$document = Document::createStandalone();$document->setTitle('Tutorial: tables and lists');$document->addPage();
$document->setFont('helvetica', 'B', 20);$document->cell(0, 26, 'A reading list, two ways', newLine: true);$document->ln(8);
$html = <<<'HTML'<h2>The books as a table</h2><table border="1" cellpadding="6" style="width: 100%;"> <thead> <tr style="background-color: #1E3A8A; color: #FFFFFF;"> <th style="width: 50%;">Title</th> <th style="width: 20%; text-align: center;">Year</th> <th style="width: 30%; text-align: right;">Pages</th> </tr> </thead> <tbody> <tr> <td>The Paper Office</td> <td style="text-align: center;">2019</td> <td style="text-align: right;">312</td> </tr> <tr style="background-color: #F8FAFC;"> <td>Ink and Pixels</td> <td style="text-align: center;">2023</td> <td style="text-align: right;">208</td> </tr> </tbody></table>
<h2>Why these two books</h2><ul> <li>Short chapters that fit into a lunch break</li> <li>Worked examples on every page</li> <li>No jargon without an explanation</li></ul>HTML;
$document->writeHtml($html);
$document->save(__DIR__ . '/out/table-and-lists.pdf');
echo "Wrote out/table-and-lists.pdf\n";Sullo schermo dovrebbe comparire Wrote out/table-and-lists.pdf. Il PDF
contiene un titolo, una tabella a tre colonne con una riga di intestazione
scura e un elenco puntato.
Cosa è appena successo
Sezione intitolata “Cosa è appena successo”- Lo script combina entrambi gli stili di scrittura in un’unica pagina.
cell()stampa il titolo grande alla posizione di scrittura corrente.writeHtml()dispone poi la tabella e l’elenco lungo la pagina, al di sotto di esso. ln(8)aggiunge un piccolo spazio verticale, alto otto punti, tra il titolo e il contenuto HTML. Senza di esso i due elementi risulterebbero appiccicati.- La tabella usa il consueto markup delle tabelle:
<thead>per la riga di intestazione,<tbody>per le righe di dati,<th>per le celle di intestazione e<td>per le celle di dati.border="1"disegna le linee della griglia ecellpadding="6"aggiunge spazio all’interno di ogni cella. - Le larghezze delle colonne sono percentuali, come
width: 50%. Suddividono l’intera larghezza della tabella, così che l’impaginazione regga a un cambio di formato pagina. La ricetta Impaginare una tabella HTML tratta in modo approfondito intestazioni, piè di pagina e dimensionamento delle colonne. - Gli attributi
styleusano dichiarazioni CSS (Cascading Style Sheets), il linguaggio di stile del web. Colori, allineamento e larghezze funzionano come mostrato qui. Prima di affidarsi ad altre proprietà, consultare la matrice di supporto CSS. - L’elenco puntato è semplicemente
<ul>con un<li>per ogni voce. NextPDF disegna automaticamente i punti elenco e il rientro.
Se qualcosa è andato storto
Sezione intitolata “Se qualcosa è andato storto”- Un errore che menziona
ImageProcessingExceptionindica che il file immagine non è stato letto o decodificato. Controllare il percorso e verificare che il file sia in un formato supportato come PNG o JPEG. - Un errore che menziona
PageLayoutExceptionindica che una posizione o una dimensione è stata rifiutata. Larghezza e altezza devono essere maggiori di zero e il percorso deve puntare a un file locale, non a un indirizzo web. - Entrambi gli errori sono descritti nel riferimento agli errori del motore.
- Se la tabella viene visualizzata in modo strano, controllare prima il
markup. Ogni riga
<tr>e ogni cella<td>necessita del proprio tag di chiusura. - Per qualsiasi altro caso, iniziare dalla guida alla risoluzione dei problemi.
Passi successivi
Sezione intitolata “Passi successivi”Le pagine possono ora contenere immagini, tabelle ed elenchi. Nel tutorial successivo si lascia crescere un documento oltre la singola pagina, mantenendolo ordinato con intestazioni, piè di pagina e numeri di pagina. Per approfondire gli argomenti di oggi, la ricetta Incorporare immagini in un documento tratta i formati immagine e le regole di dimensionamento.