이미지, 표, 리스트
텍스트만으로는 완성된 문서가 되기 어렵습니다. 이 튜토리얼에서는 일상적으로 쓰이는 세 가지 구성 요소인 그림, 표, 글머리 기호 리스트를 추가합니다. 짧은 스크립트 두 개를 작성하며, 각 스크립트는 바로 열어 볼 수 있는 실제 PDF(Portable Document Format) 파일을 만들어 냅니다.
무엇을 만들 것인가
섹션 제목: “무엇을 만들 것인가”01-image.php— 제목과 앰버색 정사각형 이미지를 페이지의 정확한 위치에 배치한 한 페이지짜리 PDF입니다.02-table-and-lists.php— 책 목록을 담은 작은 표와 그 아래 글머리 기호 리스트가 있는 한 페이지짜리 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를 열면 제목, 텍스트
한 줄, 그리고 앰버색 정사각형이 보입니다.
방금 무슨 일이 일어났나
섹션 제목: “방금 무슨 일이 일어났나”- 스크립트는 먼저 Base64 문자열을 이미지 바이트로 되돌려 디코딩한 다음
out/amber-square.png에 씁니다. 이는 스크립트를 자체 완결형으로 만들기 위한 요령일 뿐입니다. 핵심 내용은image()호출부터 시작하며, 이 호출은 기존의 PNG나 JPEG(Joint Photographic Experts Group) 파일도 같은 방식으로 읽습니다. @mkdir(__DIR__ . '/out')는 출력 폴더를 만듭니다.@기호는 폴더가 이미 존재할 때 나오는 무해한 경고를 숨겨 주므로, 스크립트를 연달아 두 번 실행할 수 있습니다.image()는 파일 경로에 더해 위치와 인쇄 크기를 받습니다. 위치와 크기는 포인트 단위로 측정하며, 72포인트가 1인치입니다. 페이지 원점은 왼쪽 위 모서리이므로y: 160은 위에서 아래로 160포인트 내려간 지점을 뜻합니다.- 픽셀과 포인트는 서로 다른 개념입니다. 그림은 8 x 8 픽셀에 불과하지만
width: 96, height: 96은 이를 가로 1과 1/3인치 크기의 정사각형으로 인쇄합니다. 인쇄 크기는 여러분이 정하며, 픽셀 수가 정하지 않습니다. image()는 여러분이 지정한 정확한 위치에 그림을 배치합니다.cell()이 사용하는 작성 위치는 이동시키지 않습니다. 텍스트를 먼저 작성한 다음 이미지를 배치하면 둘이 겹치지 않습니다.- NextPDF는 이미지를 로컬 파일에서만 읽으며, 웹 주소에서는 절대 읽지 않습니다. 파일을 포함하기 전에 실제로 지원되는 이미지인지 확인합니다. 이 방어 장치는 파일 이름이 사용자로부터 올 때 여러분을 보호합니다.
2단계: 표와 글머리 기호 리스트 추가하기
섹션 제목: “2단계: 표와 글머리 기호 리스트 추가하기”표와 리스트는 구조화된 콘텐츠입니다. 구조를 설명하는 가장 빠른 방법은 웹 페이지가 사용하는 것과 동일한 마크업인 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열 표, 그리고 글머리 기호 리스트가 담깁니다.
방금 무슨 일이 일어났나
섹션 제목: “방금 무슨 일이 일어났나”- 스크립트는 두 가지 작성 방식을 한 페이지에서 함께 사용합니다.
cell()은 현재 작성 위치에 큰 제목을 인쇄합니다. 그런 다음writeHtml()이 그 아래로 표와 리스트를 페이지를 따라 흘려보냅니다. ln(8)은 제목과 HTML 콘텐츠 사이에 높이 8포인트의 작은 세로 간격을 추가합니다. 이것이 없으면 둘이 바짝 붙어 버립니다.- 표는 일반적인 표 마크업을 사용합니다. 헤더 행에는
<thead>, 데이터 행에는<tbody>, 헤더 셀에는<th>, 데이터 셀에는<td>를 씁니다.border="1"은 격자선을 그리고,cellpadding="6"은 모든 셀 안에 여유 공간을 더합니다. - 열 너비는
width: 50%와 같은 백분율입니다. 이 값들은 표의 전체 너비를 나누어 가지므로, 페이지 크기가 바뀌어도 레이아웃이 유지됩니다. HTML 표 배치하기 레시피는 헤더, 푸터, 열 크기 지정을 깊이 있게 다룹니다. style속성은 웹의 스타일링 언어인 CSS(Cascading Style Sheets) 선언을 사용합니다. 색상, 정렬, 너비는 여기에 나온 대로 동작합니다. 다른 속성에 의존하기 전에 CSS 지원 매트릭스를 확인합니다.- 글머리 기호 리스트는 항목마다
<li>하나를 넣은<ul>일 뿐입니다. NextPDF가 글머리 기호와 들여쓰기를 대신 그려 줍니다.
무언가 잘못되었다면
섹션 제목: “무언가 잘못되었다면”ImageProcessingException을 언급하는 오류는 이미지 파일을 읽거나 디코딩할 수 없었다는 뜻입니다. 경로를 확인하고, 파일이 PNG나 JPEG 같은 지원되는 형식인지 확인합니다.PageLayoutException을 언급하는 오류는 위치나 크기가 거부되었다는 뜻입니다. 너비와 높이는 0보다 커야 하며, 경로는 웹 주소가 아니라 로컬 파일을 가리켜야 합니다.- 두 오류 모두 엔진 오류 레퍼런스에 설명되어 있습니다.
- 표가 이상하게 렌더링되면 먼저 마크업을 확인합니다. 모든
<tr>행과<td>셀에는 닫는 태그가 필요합니다. - 그 밖의 경우에는 문제 해결 가이드에서 시작합니다.
이제 페이지에 그림, 표, 리스트를 담을 수 있습니다. 다음 튜토리얼에서는 문서가 한 페이지를 넘어 늘어나도록 하고, 헤더, 푸터, 페이지 번호로 문서를 깔끔하게 유지합니다. 오늘 다룬 주제를 더 깊이 파고들고 싶다면, 문서에 이미지 포함하기 레시피가 이미지 형식과 크기 지정 규칙을 다룹니다.