HTML 转 PDF,轻松之路
到目前为止,你在本系列中都是逐个调用地构建页面。许多文档若用标记语言(即网页所使用的、基于标签的文本格式)来描述会更快。在本教程中,你把一些 Hypertext Markup Language(HTML)交给 NextPDF,引擎便会为你绘制页面。
你将构建什么
标题为“你将构建什么”的章节一份从单个 HTML 字符串渲染而来的单页报告。它包含一个彩色标题、一个简短段落, 以及一个带合计行的表格。你使用 Cascading Style Sheets(CSS,即控制标记外观的规则语言)为它设置样式。在之前的教程中,你使用的是流式 Application Programming Interface(API),也就是链式方法调用。而这里,你改用标记语言来描述布局,由同一个引擎来渲染它。
第 1 步:从 HTML 渲染带样式的报告
标题为“第 1 步:从 HTML 渲染带样式的报告”的章节在你的项目文件夹中,与 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";在项目文件夹中运行脚本:
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。引擎能够理解诸如color、background-color、text-align和width等常见属性。 - 不涉及任何浏览器,也不需要任何额外软件。该管线是引擎内部的纯 PHP,因此只要你的 Composer 安装能运行的地方,脚本就能运行。
引擎支持 HTML 和 CSS 的一个实用子集,而非浏览器所接受的一切。该子集之外的任何内容都会被悄悄跳过,而不会引发错误。CSS 支持矩阵 准确记录了所涵盖的范围。若要更深入地了解这条管线,请参阅 将 HTML 渲染为 PDF 页面。
何时使用 HTML,何时使用流式 API
标题为“何时使用 HTML,何时使用流式 API”的章节两条路径都运行在同一个引擎上,因此选择适合你文档的那条即可。
- 当文档读起来像一个网页时——包含标题、段落、列表和表格——就选择
writeHtml()。 标记语言编写起来更快,也更便于团队成员编辑。 - 当你需要精确定位时——例如固定位置或精确测量的单元格——就选择流式 API。标记语言带给你的是流式排布,而流式调用带给你的是精确控制。
- 在依赖某个属性之前,请查看 CSS 支持矩阵。 当某个样式未被涵盖时,请改用流式调用来构建这一部分。
安全边界
标题为“安全边界”的章节真实的 HTML 往往来自你代码之外,例如来自表单或数据库。请将其视为不受信任的输入, 在渲染之前对其进行校验或清理。默认情况下,内置管线不运行任何脚本,也不获取任何远程资源。即使标记本身并不保守,这一默认设置也能让渲染器保持保守。如果你需要浏览器级别的渲染选项,请参阅 选择你的路径。
如果出了问题
标题为“如果出了问题”的章节Failed to open stream: No such file or directory通常意味着脚本找不到vendor/autoload.php。请在你运行 Composer 的那个文件夹中运行它。- 样式缺失通常是因为某个属性位于受支持的子集之外。引擎会跳过它不支持的内容, 而不是报错。请将你的标记与 CSS 支持矩阵 进行对照。
- 渲染过程中抛出的异常会指明确切的问题。请在 渲染与输入/输出错误 参考中查找它。
对于其他任何情况,请从 故障排查指南 开始。
下一步
标题为“下一步”的章节现在,你既能逐个调用地构建文档,也能从标记语言构建文档。请通过 接下来去哪里 完成本系列的学习。它梳理了你在本系列之后将会用到的操作手册、参考资料和指南。