跳转到内容

Artisan API 参考

Artisan 包(nextpdf/artisan)对外提供两组相互关联的 API:一组 Chrome 渲染接口——ChromeRendererConfigChromeHtmlRendererChromeSecurityPolicyChromeRenderResultViewportCalculatorBrowserPool ——负责将一段 HTML 片段转换为 Chrome 生成的 PDF;另一组精简的 parser/importer 接口——PdfReaderPageImporterImportedFormXObject,以及辅助用的 tokenizer/xref 类——负责将这份渲染输出嵌回 NextPDF 文件,生成文本可选中的 Form XObject。

先从这里开始:如果你只是想把 HTML 转成 PDF,几乎不需要直接使用这个包。将一个 ChromeRendererConfig 附加到 NextPDF Document,然后调用 writeHtmlChrome()(见 快速入门)。只有当你要把 renderer(渲染器)嵌入 worker,或需要执行解析诊断时,才需要使用下面这些类。「常见任务」下的第一个示例演示了这条单次调用路径。

下面三条流程涵盖几乎所有实际用法,从最高层的单次调用,到显式的渲染与导入管线。每个示例都已对照 nextpdf-Artisan/src 验证(也对照包内的 README.md / ci/tests/)。

将一段 HTML 片段渲染为文本可选中的 PDF——这是标准调用方式。

<?php
declare(strict_types=1);
use NextPDF\Core\Document;
use NextPDF\Artisan\ChromeRendererConfig;
require __DIR__ . '/vendor/autoload.php';
$config = new ChromeRendererConfig(chromeBinaryPath: '/usr/bin/chromium');
$doc = Document::createStandalone();
$doc->setChromeRendererConfig($config);
$doc->addPage();
$doc->writeHtmlChrome('<div style="display:flex;gap:20px"><h2>Revenue</h2><p>$124,500</p></div>');
$doc->save('/tmp/report.pdf');

用途:由 Chrome 完成片段排版,再由桥接层将第 0 页嵌入为 Form XObject,使文本保持可选中。writeHtmlChrome(string $html, ?float $width = null, ?float $height = null): static 会在 $heightnull 时自动调整高度。

自行运行 renderer 并导入页面——这是 writeHtmlChrome() 背后的显式管线,适用于 worker 与自定义放置。

<?php
declare(strict_types=1);
use NextPDF\Artisan\ChromeHtmlRenderer;
use NextPDF\Artisan\ChromeRendererConfig;
use NextPDF\Artisan\ImportedFormXObject;
use NextPDF\Artisan\PageImporter;
use NextPDF\Parser\PdfReader;
$renderer = new ChromeHtmlRenderer(new ChromeRendererConfig(renderTimeout: 30));
try {
$result = $renderer->render($html, widthPt: 595.28);
$reader = new PdfReader($result->getPdfData());
$reader->parse();
$form = (new PageImporter())->import($reader);
} finally {
$renderer->close();
}

用途:渲染成 Chrome PDF 字节、进行解析,再将第 0 页导入为一个可供你放置的 ImportedFormXObject。务必 close() renderer,以释放 Chrome 进程。

从 Framework(框架)风格的数组构建配置——适用于 config/*.php 或包参数,而不是写死构造函数参数。

<?php
declare(strict_types=1);
use NextPDF\Artisan\ChromeRendererConfig;
$config = ChromeRendererConfig::fromArray([
'chrome_binary' => '/usr/bin/chromium',
'render_timeout' => 45,
'max_html_size' => 2_000_000,
'no_sandbox' => false,
]);

用途:将 snake-case 配置数组映射到构造函数;未设置的键会回退到默认值,而 chrome_binary 只有在它是非空字符串时才会套用。

这些类型负责启动并执行一次渲染:先构建一个 ChromeRendererConfig,交给一个 ChromeHtmlRenderer,再调用 render() 获取一个 ChromeRenderResult

符号参数默认行为返回抛出或失败条件备注
new ChromeRendererConfig(?string $chromeBinaryPath = null, int $renderTimeout = 30, string $defaultCss = '', int $maxHtmlSize = 5000000, bool $noSandbox = false)可执行文件路径、超时、CSS、HTML 大小上限、沙箱标志。当可执行文件路径为 null 时自动检测 Chrome;除非显式禁用,否则沙箱保持启用。ChromeRendererConfig预期不会发生。仅在运行环境需要时,才设置 noSandbox
ChromeRendererConfig::fromArray(array $config)chrome_binary, render_timeout, default_css, max_html_size, no_sandbox.缺少的值会套用构造函数的默认值。ChromeRendererConfig类型不符时,可选键会回退到默认值。对应 Framework 风格的配置数组。
new ChromeHtmlRenderer(ChromeRendererConfig $config, ?LoggerInterface $logger = null, ?HtmlSecurityPolicyInterface $htmlSecurityPolicy = null)配置、可选的 logger,以及可选的解析层 HTML 策略。未提供策略时,使用 DefaultHtmlSecurityPolicyChromeHtmlRendererChrome 设置错误会在首次渲染时出现。renderer 会持有一个浏览器池,直到 close() 为止。
ChromeHtmlRenderer::render(string $html, float $widthPt, float $heightPt = 0)html:输入片段;widthPt:纸张宽度;heightPt:目标高度或自动。heightPt <= 0 时自动计算内容高度。ChromeRenderResultChromeRenderException;HTML 大小验证失败。通过 CDP 阻止子资源的网络请求。
ChromeHtmlRenderer::getHtmlSecurityPolicy()无。返回已设置的解析层策略。HtmlSecurityPolicyInterface预期不会发生。与 Chrome 传输层的控制互补。
ChromeHtmlRenderer::close()无。关闭并清空浏览器池。void底层库可能抛出浏览器关闭错误。在 worker 关闭时调用。

当你需要在渲染前自行验证并包装外部 HTML,而不走 ChromeHtmlRenderer::render() 时,可以使用这些 API(后者已经会调用它们)。

符号参数默认行为返回抛出或失败条件备注
ChromeSecurityPolicy::validate(string $html, int $maxSize)HTML 输入与最大字节大小。只有在大小以及受禁止的结构检查都通过时,才接受输入。voidChromeRenderException 或验证异常。接受外部 HTML 时,在浏览器渲染前先执行。
ChromeSecurityPolicy::wrapHtml(string $html, int $viewportWidth, string $defaultCss = '')HTML 片段、viewport 宽度,以及可选的默认 CSS。将片段包装成一份完整的渲染文档。string验证或字符串组装错误。让 renderer 专属的 CSS 与应用程序 HTML 分离。

用这些方法读取一次渲染的输出(ChromeRenderResult),并在设置 viewport 尺寸或计算高度时,在 PDF 点与 Chrome CSS 像素之间换算。

符号参数默认行为返回抛出或失败条件备注
new ChromeRenderResult(string $pdfData, float $widthPt, float $heightPt, float $contentHeightCssPx)原始 PDF 字节、宽度、高度,以及测量到的内容高度。除带类型的构造函数属性外,不做额外验证。ChromeRenderResult预期不会发生。通常由 ChromeHtmlRenderer::render() 返回。
ChromeRenderResult::getPdfData()无。返回 Chrome 生成的原始 PDF 字节。string预期不会发生。嵌入时,与 PdfReaderPageImporter 配合使用。
ChromeRenderResult::getWidthPt()无。返回所请求的宽度(以点为单位)。float预期不会发生。用来决定导入 form 对象的尺寸。
ChromeRenderResult::getHeightPt()无。返回计算出或所请求的高度(以点为单位)。float预期不会发生。自动高度会纳入打印版面的缓冲量。
ViewportCalculator::pointsToCssPx(float $pt)pt:PDF 点。以每 72 PDF 点对应 96 CSS px 进行换算。int预期不会发生。为配合 Chrome 的 viewport 宽度而取整。
ViewportCalculator::cssPxToPoints(float $px)px:CSS 像素。以每 96 CSS px 对应 72 PDF 点进行换算。float预期不会发生。用于自动高度计算。

这是核心导入路径——先用 PdfReader 解析 Chrome PDF 字节,再将 reader 交给 PageImporter::import() 获取可嵌入的页面;其余 PdfReader 方法则用于诊断。

符号参数默认行为返回抛出或失败条件备注
new PdfReader(string $data)data:完整的 PDF 字节。在调用 parse() 之前不会执行解析器。PdfReader预期不会发生。专为 Chrome 生成的 PDF 设计。
PdfReader::parse()无。解析 xref 链与 trailer。voidPdfParseException:当 PDF 结构无效时。访问 object/page 之前必须先调用。
PdfReader::getObject(int $objNum)对象编号。按编号 resolve(解析)对应的已解析对象。PdfObjectPdfParseException:当对象不存在或格式错误时。parse() 之后使用。
PdfReader::getTrailer()无。返回已解析的 trailer 字典。arrayPdfParseException:当 trailer 数据无法获取时。用于诊断与修订分析。
PdfReader::getObjectNumbers()无。返回已解析的对象编号。array解析后预期不会发生。对导入器的诊断很有用。
PdfReader::getPage(int $pageIndex)pageIndex:从零开始的页面 Index(索引)。不会隐式解析。PdfObjectPdfParseException:当不存在或超出范围时。导入器默认使用第 0 页。
PdfReader::getPageContentStream(PdfObject $page)page:已解析的页面对象。解析内容 stream。stringPdfParseException:当 stream 无效时。空 stream 会导致导入器失败。
PdfReader::getPageResources(PdfObject $page)page:已解析的页面对象。解析页面资源。arrayPdfParseException:当资源无效时。资源字典会与 form 对象一并嵌入。
PdfReader::getPageMediaBox(PdfObject $page)page:已解析的页面对象。缺少时回退到类似 A4 的尺寸。array解析失败。返回 PDF 空间坐标。
PdfReader::resolveRef(mixed $value)已解析的值。在适用情况下递归解析对象引用。mixedPdfParseException:当引用无效时。为导入流程而对外开放的内部风格辅助方法。
PdfReader::collectPageResources(PdfObject $page)page:已解析的页面对象。遍历页面资源引用。array解析失败。用于将依赖对象与导入的页面一并嵌入。
PdfReader::getRevisionCount()无。计算已解析的增量修订数量。int解析后预期不会发生。对已签名或经增量更新的 PDF 很有用。
PdfReader::getRevisionXRef(int $index)从零开始的修订索引。返回单一修订的 xref 表。RevisionXRefTablePdfParseException:当索引无效时。用于底层修订诊断。
PdfReader::getRevisions()无。返回所有已解析的修订 xref 表。array解析后预期不会发生。只读的解析器状态视图。
PageImporter::import(PdfReader $reader, int $pageIndex = 0)已解析的 reader 与从零开始的页面索引。省略时导入第一页。ImportedFormXObjectPdfParseException:当无法提取页面时。收集内容 stream、media box、资源,以及被引用的对象。

这些是解析器返回或内部使用的值对象与辅助类——当你需要检查导入的对象、资源、stream 或修订表时会用到。

符号参数默认行为返回抛出或失败条件备注
new ImportedFormXObject(string $contentStream, array $mediaBox, array $embeddedObjects, array $resourcesDict)已解码的内容 stream、media box、嵌入对象,以及资源字典。存储一份自包含的导入 form 内容。ImportedFormXObject预期不会发生。通常由 PageImporter::import() 返回。
ImportedFormXObject::getWidth()无。返回导入 form 的宽度(以点为单位)。float预期不会发生。将 Chrome 输出放进页面时使用。
ImportedFormXObject::getHeight()无。返回导入 form 的高度(以点为单位)。float预期不会发生。自动高度的渲染结果会通过这个值传递。
ImportedFormXObject::getEmbeddedObjects()无。返回导入 form 所需的对象。array预期不会发生。写出端代码会用这些对象来保留资源。
ImportedFormXObject::getResourcesDict()无。返回导入的资源字典。array预期不会发生。构建 form XObject 时使用。
ImportedFormXObject::getMediaBox()无。返回导入的 media box。array预期不会发生。用于放置位置的诊断。
ImportedFormXObject::getContentStream()无。返回导入页面的内容 stream。string预期不会发生。供 writer/import 集成使用。
new PdfObject(int $objectNumber, int $generation, array $dictionary, ?string $rawStreamData = null, ?string $decodedStreamData = null, ?string $rawDictionaryBytes = null)对象编号、生成号、已解析的字典、可选的 stream 字节、可选的已解码 stream,以及可选的原始字典字节。存储已解析的对象状态。PdfObject预期不会发生。由解析器内部创建。
PdfObject::getRawDictionaryBytes()无。在可获取时返回原始字典字节。`stringnull`预期不会发生。
PdfObject::getRawStreamData()无。在可获取时返回未解码的 stream 字节。`stringnull`预期不会发生。
PdfObject::getDictionary()无。返回已解析的字典项。array预期不会发生。只读的解析器视图。
PdfObject::get(string $key)字典键。当键不存在时,返回 nullmixed预期不会发生。让调用端不必自行解析原始字典。
PdfObject::getRef(string $key)字典键。当值是引用时,返回对象引用的 tuple。`arraynull`预期不会发生。
PdfObject::getArray(string $key)字典键。返回数组值,无法获取时返回空数组。array预期不会发生。针对数组值字典项的便利封装。
PdfObject::hasStream()无。检查是否存在 stream 字节。bool预期不会发生。用来辨别仅含字典的对象。
PdfObject::getType()无。读取 /Type`stringnull`预期不会发生。
PdfObject::getSubtype()无。读取 /Subtype`stringnull`预期不会发生。
RevisionExtractor::extractRevision(string $pdfData, PdfReader $reader, int $revision)PDF 字节、一个已解析的 reader,以及从零开始的修订索引。提取单一增量修订。stringPdfParseException:当边界无效时。供解析器测试与诊断使用。
RevisionExtractor::getRevisionBoundaries(string $pdfData, PdfReader $reader)PDF 字节与一个已解析的 reader。找出各增量修订的字节范围。arrayPdfParseException:当 xref 结构格式错误时。有助于分析已签名或经增量更新的 PDF。
流解码器 `StreamDecoder::decode(string $data, stringarray $filter)`(解码方法)stream 字节与一个或多个 PDF 过滤器。依序套用过滤器。stringPdfParseException:当过滤器不受支持或无效时。
new ResourceCollector(PdfReader $reader)已解析的 reader。以空的已收集对象集合开始。ResourceCollector预期不会发生。PdfReader::collectPageResources() 使用。
ResourceCollector::traverse(mixed $value, int $depth = 0)已解析的值与递归深度。遍历资源引用,直到内部深度上限为止。void引用无效时的解析失败。用于页面导入资源闭包的内部辅助方法。
ResourceCollector::getCollected()无。返回已收集的资源对象。array预期不会发生。traverse() 之后调用。
new RevisionXRefTable(int $index, int $xrefOffset, array $xrefEntries, array $trailer, ?int $prevOffset)修订索引、xref 偏移量、xref 条目、trailer,以及可选的前一个偏移量。单一增量修订的不可变快照。RevisionXRefTable预期不会发生。由解析器内部创建。
RevisionXRefTable::getObjectNumbers()无。返回在该修订表中有效的对象编号。array预期不会发生。底层修订诊断 API。
RevisionXRefTable::getActiveObjectCount()无。计算有效对象的数量。int预期不会发生。对解析器断言很有用。
RevisionXRefTable::hasRootUpdate()无。报告该修订是否更新了文档根节点。bool预期不会发生。对增量更新分析很有用。
RevisionXRefTable::getSize()无。返回 xref 表的大小值。int预期不会发生。对应已解析的 PDF xref 元数据。

只有在进行深入解析器诊断或精简 fixture 时才需要这些 API——它们会暴露 PdfReader 底层的词法器与交叉引用机制,一般导入并不需要。

符号参数默认行为返回抛出或失败条件备注
new PdfTokenizer(string $data, int $offset = 0)PDF 字节与可选的起始偏移量。从偏移量零开始。PdfTokenizer预期不会发生。底层词法解析器。
PdfTokenizer::getOffset()无。返回当前字节偏移量。int预期不会发生。用于解析器错误的诊断辅助方法。
PdfTokenizer::setOffset(int $offset)字节偏移量。移动 tokenizer 的游标。voidPdfParseException:当偏移量无效时。请谨慎使用;解析器状态由调用端自行控制。
PdfTokenizer::isEof()无。检查游标是否已到达末尾。bool预期不会发生。底层解析循环辅助方法。
PdfTokenizer::skipWhitespace()无。跳过 PDF 空白与注释后前进。void预期不会发生。在读取 token 前使用。
PdfTokenizer::readToken()无。读取下一个标量 token。`stringintfloat
PdfTokenizer::readName()无。读取一个 PDF name 对象。stringPdfParseException:当 name 格式错误时。解码 name 的转义序列。
PdfTokenizer::readLiteralString()无。读取一个字面字符串。stringPdfParseException:当字符串格式错误时。处理嵌套括号与转义序列。
PdfTokenizer::readHexString()无。读取一个十六进制字符串。stringPdfParseException:当十六进制格式错误时。按解析器规则为奇数长度的十六进制补位。
PdfTokenizer::readNumber()无。读取一个整数或浮点数。`intfloat`PdfParseException:当数字无效时。
PdfTokenizer::readKeyword()无。读取一个 PDF 关键字。stringPdfParseException:当关键字无效时。让关键字解析集中处理。
PdfTokenizer::readDictionary()无。读取一个 PDF 字典。arrayPdfParseException:当字典格式错误时。用于对象、stream 与 trailer。
PdfTokenizer::readArray()无。读取一个 PDF 数组。arrayPdfParseException:当数组格式错误时。递归的解析辅助方法。
PdfTokenizer::readValue()无。读取任何支持的 PDF 值。mixedPdfParseException:当值格式错误时。常见的解析基本操作。
PdfTokenizer::readStreamData(int $length)stream 长度。精确读取所请求的 stream 字节。stringPdfParseException:当 stream 边界无效时。在字典中的 stream 长度解析完成后使用。
PdfTokenizer::peek(int $length = 1)字节数量。向前预读但不移动游标。string预期不会发生。对解析器的分支判断很有用。
PdfTokenizer::searchBackward(string $pattern, int $startFrom = 0)匹配模式与可选的起始偏移量。从末尾或所提供的偏移量往回搜索。`intfalse`预期不会发生。
PdfTokenizer::readLine()无。从当前偏移量读取一行。string预期不会发生。底层扫描辅助方法。
CrossRefParser::parseXRefTable(string $data, int $offset)PDF 字节与 xref 表偏移量。解析传统 xref 表的条目。arrayPdfParseException:当 xref 数据格式错误时。底层解析器 API。
CrossRefParser::parseXRefStream(string $data, int $offset)PDF 字节与 xref stream 偏移量。解析 xref stream 的条目。arrayPdfParseException:当 stream 数据格式错误时。支持现代 PDF 的 xref stream。

EInvoiceServiceFactory 会延迟解析可选的 Premium 电子发票契约(在它们不存在时返回 null)。BrowserPool 是 renderer 自有的 Chrome 生命周期辅助类,只有在长时间运行的 worker 中你才需要直接管理它。

符号参数默认行为返回抛出或失败条件备注
EInvoiceServiceFactory::makeEmbedder()无。返回 null,除非已安装 Premium Pro 的电子发票支持。嵌入器接口 `EmbedderInterfacenull`可选包的构造错误。
EInvoiceServiceFactory::makeValidator()无。返回 null,除非已安装 Premium Enterprise 的验证支持。验证器接口 `ValidatorInterfacenull`可选包的构造错误。
EInvoiceServiceFactory::makeDefaultProfile()无。在可获取时返回默认的电子发票配置文件。配置文件接口 `ProfileInterfacenull`可选包的错误。
EInvoiceServiceFactory::makeSchematronRunner()无。返回 null,除非已安装 Premium Enterprise 的 Schematron 支持。Schematron 执行器接口 `SchematronRunnerInterfacenull`可选包的构造错误。
new BrowserPool(ChromeRendererConfig $config, ?LoggerInterface $logger = null)renderer 配置与可选的 logger。浏览器会在首次调用 getBrowser() 时延迟启动。BrowserPool在浏览器启动前预期不会发生。renderer 自有的生命周期辅助类。
BrowserPool::getBrowser()无。启动或返回当前的 Chrome 浏览器实例。Browser浏览器启动错误。renderer 自有的生命周期辅助类。
BrowserPool::incrementRenderCount()无。递增渲染计数,并在池策略要求时进行轮换。void浏览器生命周期错误。供长时间运行的 worker 使用。
BrowserPool::close()无。关闭受管理的浏览器实例。void浏览器关闭错误。在 worker 关闭时调用。
  • 这个 renderer 并不是用于隔离不受信任 HTML 的浏览器沙箱。渲染前必须先验证大小、资源策略,以及调用端的授权。
  • 解析 API 刻意设计得很窄。它们用于导入 Chrome 输出,并非用于一般 PDF 修复。
  • 在长期运行的 worker 中,必须显式关闭 renderer。