画像、表、リスト
テキストだけで文書が完成することはめったにありません。このチュートリアルでは、日常的に使う 3 つの構成要素、すなわち画像、表、箇条書きリストを追加します。2 つの小さなスクリプトを書き、それぞれがすぐに開ける本物の PDF (Portable Document Format)ファイルを生成します。
作成するもの
「作成するもの」という見出しのセクション01-image.php— 見出しと琥珀色の正方形画像を含む 1 ページの PDF で、画像はページ上の正確な位置に配置されます。02-table-and-lists.php— 書籍の小さな表と、その下に箇条書きリストを配置した 1 ページの PDF です。
どちらのスクリプトも完結したプログラムです。最初のチュートリアル で使ったプロジェクトフォルダーをそのまま使い、各スクリプトを composer.json の隣に保存してください。
ステップ 1: ページに画像を配置する
「ステップ 1: ページに画像を配置する」という見出しのセクションこのスクリプトは自身の画像を内部に持っています。ごく小さな 8 x 8 ピクセルの PNG (Portable Network Graphics)画像が、Base64 文字列としてスクリプト内に格納されています。Base64 はバイナリデータをプレーンテキストで表記したものなので、ソースコード内に置くことができます。実際のプロジェクトでは、画像ファイルはすでにディスク上に存在するため、この部分は省略することになります。
これを 01-image.php として保存し、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";画面に Wrote out/image.pdf と表示されるはずです。out/image.pdf を開くと、見出し、1 行のテキスト、そして琥珀色の正方形が見つかります。
何が起きたのか
「何が起きたのか」という見出しのセクション- スクリプトはまず Base64 文字列をデコードして画像バイト列に戻し、
out/amber-square.pngに書き出します。これは自己完結型チュートリアルのための工夫にすぎません。本題はimage()の呼び出しから始まり、これは既存の PNG または JPEG (Joint Photographic Experts Group)ファイルを同じ方法で読み込みます。 @mkdir(__DIR__ . '/out')は出力フォルダーを作成します。@記号は、フォルダーがすでに存在するときに発生する無害な警告を隠すので、スクリプトを続けて 2 回実行できます。image()はファイルパスに加えて位置と印刷サイズを受け取ります。位置とサイズはポイント単位で測られ、72 ポイントが 1 インチに相当します。ページの原点は左上隅なので、y: 160は上から 160 ポイント下がった位置を意味します。- ピクセルとポイントは別のものです。画像はわずか 8 x 8 ピクセルですが、
width: 96, height: 96によって、幅 1 と 3 分の 1 インチの正方形として印刷されます。印刷サイズは自分で決めるものであり、ピクセル数が決めるわけではありません。 image()は指定した正確な位置に画像を配置します。cell()が使う書き込み位置は移動しません。先にテキストを書き、その後で画像を配置すれば、両者が衝突するのを防げます。- NextPDF は画像をローカルファイルからのみ読み込み、Web アドレスからは決して読み込みません。埋め込む前に、そのファイルが実在するサポート対象の画像であることを確認します。このガードは、ファイル名がユーザーから渡される場合の安全策になります。
ステップ 2: 表と箇条書きリストを追加する
「ステップ 2: 表と箇条書きリストを追加する」という見出しのセクション表とリストは構造化されたコンテンツです。構造を記述する最も手早い方法は、Web ページで使われるものと同じマークアップである HTML (Hypertext Markup Language)です。NextPDF はサポートされている範囲の HTML を、そのまま PDF ページ上にレンダリングします。ブラウザは一切関与しません。
これを 02-table-and-lists.php として保存し、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";Wrote out/table-and-lists.pdf と表示されるはずです。この PDF には、見出し、濃い色のヘッダー行を持つ 3 列の表、そして箇条書きリストが含まれています。
何が起きたのか
「何が起きたのか」という見出しのセクション- このスクリプトは 1 ページ上で 2 つの書き込みスタイルを併用します。
cell()は現在の書き込み位置に大きな見出しを印刷します。続いてwriteHtml()が、その下に表とリストをページに沿って流し込みます。 ln(8)は見出しと HTML コンテンツの間に、高さ 8 ポイントの小さな垂直の余白を追加します。これがないと、両者は密着してしまいます。- 表は通常の表マークアップを使います。ヘッダー行には
<thead>、データ行には<tbody>、ヘッダーセルには<th>、データセルには<td>を使います。border="1"は罫線を描画し、cellpadding="6"はすべてのセルの内側にゆとりを加えます。 - 列幅は
width: 50%のようにパーセントで指定します。これらは表の全幅を分割するので、ページサイズが変わってもレイアウトは崩れません。HTML テーブルをレイアウトする レシピでは、ヘッダー、フッター、列サイズの指定を詳しく解説しています。 style属性は、Web のスタイリング言語である CSS (Cascading Style Sheets)の宣言を使います。色、配置、幅はここで示したとおりに機能します。他のプロパティに頼る前に、CSS サポートマトリックス を確認してください。- 箇条書きリストは、項目ごとに 1 つの
<li>を持つ単なる<ul>です。NextPDF が箇条書きの記号とインデントを描画してくれます。
うまくいかなかったときは
「うまくいかなかったときは」という見出しのセクションImageProcessingExceptionという名前のエラーは、画像ファイルを読み込めなかった、またはデコードできなかったことを意味します。パスを確認し、ファイルが PNG や JPEG などのサポート対象の形式であることを確認してください。PageLayoutExceptionという名前のエラーは、位置またはサイズが拒否されたことを意味します。幅と高さは 0 より大きくなければならず、パスは Web アドレスではなくローカルファイルを指し示す必要があります。- どちらのエラーも エンジンエラーリファレンス で説明されています。
- 表の描画がおかしい場合は、まずマークアップを確認してください。すべての
<tr>行と<td>セルには閉じタグが必要です。 - それ以外の場合は、トラブルシューティングガイド から始めてください。
次のステップ
「次のステップ」という見出しのセクションこれで、ページに画像、表、リストを扱えるようになりました。次のチュートリアル では、文書を 1 ページを超えて拡張しつつ、ヘッダー、フッター、ページ番号で整然と保つ方法を学びます。今日扱ったトピックをさらに深く掘り下げるには、文書に画像を埋め込む レシピが画像形式とサイズ指定のルールを解説しています。