跳到內容
getnextpdf.com

HTML 轉 PDF 的輕鬆之道

在這個學習路徑中,您到目前為止都是一次一個呼叫地建立頁面。許多文件用標記語言 (markup,也就是網頁使用的、以標籤為基礎的文字格式)來描述會更快。在這篇教學中,您把一段 Hypertext Markup Language(HTML)交給 NextPDF, 引擎就會替您把頁面畫出來。

一份從單一 HTML 字串渲染而成的單頁報表。它包含一個帶色彩的標題、一段簡短的段落,以及一個附有合計列的表格。您用 Cascading Style Sheets (CSS,控制標記語言外觀的規則語言)替它設定樣式。在先前的教學中,您使用了流暢的 Application Programming Interface(API),也就是串接的方法呼叫。 在這裡,您改以標記語言來描述版面,而由同一個引擎將它渲染出來。

在您的專案資料夾中、與 vendor 並列的位置,建立一個名為 01-html.php 的檔案。貼上這份完整的指令碼:

<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
@mkdir(__DIR__ . '/out');
$document = Document::createStandalone();
$document->setTitle('Monthly reading report');
$document->addPage();
$html = <<<'HTML'
<h1 style="color: #1E3A8A;">Monthly reading report</h1>
<p>This report was rendered from <strong>HTML</strong> with inline
<em>CSS</em>. The table below lists two books and their page counts.</p>
<table border="1" cellpadding="5" cellspacing="0" style="width: 100%;">
<thead>
<tr style="background-color: #1E3A8A; color: #FFFFFF;">
<th style="width: 55%;">Title</th>
<th style="width: 20%; text-align: center;">Format</th>
<th style="width: 25%; text-align: right;">Pages</th>
</tr>
</thead>
<tbody>
<tr>
<td>The Paper Trail</td>
<td style="text-align: center;">Hardcover</td>
<td style="text-align: right;">312</td>
</tr>
<tr style="background-color: #F8FAFC;">
<td>Ink and Bytes</td>
<td style="text-align: center;">Paperback</td>
<td style="text-align: right;">248</td>
</tr>
</tbody>
<tfoot>
<tr style="font-weight: bold;">
<td colspan="2" style="text-align: right;">Total pages:</td>
<td style="text-align: right;">560</td>
</tr>
</tfoot>
</table>
HTML;
$document->writeHtml($html);
$document->save(__DIR__ . '/out/reading-report.pdf');
echo "Wrote out/reading-report.pdf\n";

在專案資料夾中執行這份指令碼:

Terminal window
php 01-html.php

您應該會看到一行輸出:

Wrote out/reading-report.pdf

用任何一款 Portable Document Format(PDF)檢視器開啟 out/reading-report.pdf。標題是深藍色,而表格的標題列也填上了相同的顏色。

  • @mkdir(__DIR__ . '/out'); 會建立輸出資料夾。當資料夾已經存在時, @ 符號會隱藏警告,因此重複執行時也能保持安靜。
  • Document::createStandalone()setTitle()addPage() 的運作方式和先前的教學完全相同。改用標記語言,並不會改變文件設定的任何環節。
  • writeHtml() 會將您的字串由上而下讀取一次,並在目前的位置繪製每個元素。標題與段落會變成帶樣式的文字。表格則會變成一列列經過量測、 帶邊框的儲存格。
  • 行內的 style 屬性承載著 CSS。引擎能理解常見的屬性,例如 colorbackground-colortext-alignwidth
  • 過程中不牽涉瀏覽器,也不需要額外的軟體。這條管線是引擎內部的純 PHP, 因此凡是您的 Composer 安裝能執行的地方,這份指令碼就能執行。

引擎支援的是 HTML 與 CSS 的一個實用子集,並非瀏覽器所接受的全部。凡是落在這個子集之外的內容,都會被默默略過,而不會拋出錯誤。CSS 支援對照表明確記載了確切涵蓋的範圍。 若想更深入地逐步了解這條管線,請參閱將 HTML 繪製為 PDF 頁面

兩條路徑都跑在同一個引擎上,因此請挑選最適合這份文件的那一種。

  • 當文件讀起來像一個網頁時——標題、段落、清單與表格——就選擇 writeHtml()。標記語言寫起來更快,團隊成員也更容易編輯。
  • 當您需要精確的擺放位置時——例如固定的座標,或經過精密量測的儲存格 ——就選擇流暢 API。標記語言帶給您的是流動排版;流暢呼叫帶給您的是掌控權。
  • 在倚賴某個屬性之前,請先查閱 CSS 支援對照表。當某項樣式並未涵蓋時, 請改用流暢呼叫來建構那個部分。

真實世界的 HTML 往往來自您程式碼之外,例如來自表單或資料庫。請把它當成不受信任的輸入,並在渲染之前先加以驗證或清理。預設情況下,內建的管線不會執行任何指令碼,也不會抓取任何遠端資源。即使標記語言本身並不保守, 這項預設也讓渲染器維持保守。若您需要瀏覽器等級的渲染選項,請參閱選擇你的入門路徑

  • Failed to open stream: No such file or directory 通常代表指令碼找不到 vendor/autoload.php。請在您執行 Composer 的那個資料夾中執行它。
  • 遺漏的樣式通常是落在支援子集之外的屬性。引擎會略過它不支援的內容, 而不是直接失敗。請將您的標記語言對照 CSS 支援對照表
  • 渲染期間拋出的例外會指出確切的問題。請到渲染與輸入/輸出錯誤參考文件中查詢它。

至於其他任何問題,請從疑難排解指南開始。

現在您已經能夠一個呼叫接著一個呼叫地建立文件,也能夠從標記語言建立文件。請以接下來該去哪裡 為這個學習路徑收尾。它會為您梳理食譜、參考文件,以及您在這個路徑之後會用到的各種指南。