Snappy 是 wkhtmltopdf 的 PHP 封装,需同时安装二进制并配置绝对路径、UTF-8 编码、禁用背景、启用本地文件访问及中文字体支持,否则 PDF 渲染失败。

Snappy 本身不渲染 HTML,它只是 wkhtmltopdf 的 PHP 封装。直接用 composer require knplabs/snappy 不够——你必须同时确保二进制可执行文件存在且可用,否则调用会静默失败或抛出 proc_open(): fork failed 类错误。
安装 Snappy 和 wkhtmltopdf 二进制(推荐方式)
跳过系统级安装,用 Composer 统一管理二进制,能避免 Ubuntu/Debian 旧源包版本低、CentOS 缺少依赖、Windows 路径空格等问题。
- 执行:
composer require knplabs/snappy - 再执行:
composer require h4cc/wkhtmltopdf-amd64 0.12.6(64位 Linux;若为 macOS 或 Windows,请换对应包,如wkhtmltopdf-osx或wkhtmltopdf-windows) - 确认二进制路径:安装后文件在
vendor/h4cc/wkhtmltopdf-amd64/bin/wkhtmltopdf-amd64,不是vendor/bin/ - PHP 进程需对该文件有执行权限:
chmod +x vendor/h4cc/wkhtmltopdf-amd64/bin/wkhtmltopdf-amd64
初始化 Pdf 实例时传入正确路径
Pdf 构造函数第一个参数必须是绝对路径,相对路径或未加扩展名的 wkhtmltopdf 都会失败,尤其在 CLI 和 Web 环境下行为不一致。
- 正确写法:
$snappy = new \Knp\Snappy\Pdf(__DIR__ . '/vendor/h4cc/wkhtmltopdf-amd64/bin/wkhtmltopdf-amd64'); - 错误写法:
new Pdf('wkhtmltopdf')(找不到命令)、new Pdf('vendor/...')(相对路径在 CLI 下解析错) - 可封装成复用逻辑:
$binPath = __DIR__ . '/vendor/h4cc/wkhtmltopdf-amd64/bin/wkhtmltopdf-amd64'; if (!is_executable($binPath)) { throw new RuntimeException('wkhtmltopdf binary not found or not executable'); }
生成 PDF 前必须设的关键选项
默认情况下中文乱码、背景色遮盖内容、本地资源(如 file:// 图片)加载失败——这些不是 Snappy 的 bug,而是 wkhtmltopdf 的默认行为。
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
- 强制 UTF-8:
$snappy->setOption('encoding', 'UTF-8'); - 禁用背景(否则 PDF 里全是灰色块):
$snappy->setOption('no-background', true); - 允许加载本地文件(否则
img src="/assets/logo.png"404):$snappy->setOption('enable-local-file-access', true); - 设置超时(防止长页面卡死):
$snappy->setTimeout(300); - 如需页眉页脚,用 HTML 字符串:
$snappy->setOption('header-html', $headerHtml);,注意该 HTML 不能含外部 CSS/JS,只能内联
中文渲染失败?先检查字体,不是代码问题
即使设置了 encoding,Linux 容器或无桌面环境仍大概率显示方框——因为 wkhtmltopdf 依赖系统字体,而 Alpine/CentOS 默认没装中文字体。
立即学习“PHP免费学习笔记(深入)”;
- Debian/Ubuntu:
apt-get install fonts-wqy-zenhei(文泉驿正黑),然后 symlink 到/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc - Alpine:
apk add ttf-dejavu ttf-droid ttf-freefont,再确认wkhtmltopdf能读到它们(可通过fc-list :lang=zh检查) - 临时验证:在 HTML 中显式指定字体,如
<body style="font-family: 'WenQuanYi Zen Hei', sans-serif;"> - 别指望
Snappy自动处理字体嵌入——它不支持,这是wkhtmltopdf层的限制
generateFromHtml(),而是二进制路径错、字体缺失、enable-local-file-access 没开——这三个点漏掉任意一个,PDF 就要么空白,要么乱码,要么只渲染第一屏。


















