콘텐츠로 이동
getnextpdf.com

이미지, 표, 리스트

텍스트만으로는 완성된 문서가 되기 어렵습니다. 이 튜토리얼에서는 일상적으로 쓰이는 세 가지 구성 요소인 그림, 표, 글머리 기호 리스트를 추가합니다. 짧은 스크립트 두 개를 작성하며, 각 스크립트는 바로 열어 볼 수 있는 실제 PDF(Portable Document Format) 파일을 만들어 냅니다.

  • 01-image.php — 제목과 앰버색 정사각형 이미지를 페이지의 정확한 위치에 배치한 한 페이지짜리 PDF입니다.
  • 02-table-and-lists.php — 책 목록을 담은 작은 표와 그 아래 글머리 기호 리스트가 있는 한 페이지짜리 PDF입니다.

두 스크립트 모두 완결된 프로그램입니다. 첫 번째 튜토리얼에서 쓰던 프로젝트 폴더를 계속 사용하고, 각 스크립트를 composer.json 옆에 저장합니다.

이 스크립트는 그림을 직접 담고 있습니다. 아주 작은 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> 셀에는 닫는 태그가 필요합니다.
  • 그 밖의 경우에는 문제 해결 가이드에서 시작합니다.

이제 페이지에 그림, 표, 리스트를 담을 수 있습니다. 다음 튜토리얼에서는 문서가 한 페이지를 넘어 늘어나도록 하고, 헤더, 푸터, 페이지 번호로 문서를 깔끔하게 유지합니다. 오늘 다룬 주제를 더 깊이 파고들고 싶다면, 문서에 이미지 포함하기 레시피가 이미지 형식과 크기 지정 규칙을 다룹니다.