Symfony5中用KnpSnappyBundle+wkhtmltopdf转PDF遇ProtocolUnknownError
解决Symfony 5中KnpSnappyBundle + wkhtmltopdf的ProtocolUnknownError问题
针对你遇到的Exit with code 1 due to network error: ProtocolUnknownError错误,以下是具体的排查和解决步骤:
1. 修正模板中的资源引用路径
这个错误大多是因为HTML中包含的资源(CSS、图片、JS)使用了wkhtmltopdf无法识别的路径格式。
- 使用绝对URL:在Twig模板中,用
absolute_url()配合asset()生成完整的资源URL,确保wkhtmltopdf能正确解析:<link rel="stylesheet" href="{{ absolute_url(asset('css/invoice.css', 'kritek_billing')) }}"> <img src="{{ absolute_url(asset('images/logo.png', 'kritek_billing')) }}" alt="Logo"> - 本地文件协议规范:如果引用的是服务器本地文件而非Web资源,必须使用正确的
file://协议前缀:- Linux/macOS:
file:///var/www/project/public/css/invoice.css - Windows:
file:///C:/xampp/htdocs/project/public/css/invoice.css
- Linux/macOS:
2. 确保PDF生成路径为绝对路径
你的代码中$pdfName使用的是相对路径,可能导致wkhtmltopdf无法定位输出目录。改为绝对路径并确保目录有写入权限:
private function pdfToHtmlAction(): void { $pdfName = uniqid() . "-generated.pdf"; // 使用项目根目录下的可写目录 $pdfPath = $this->getParameter('kernel.project_dir') . '/public/generated_pdfs/' . $pdfName; // 确保目录存在 $filesystem = new \Symfony\Component\Filesystem\Filesystem(); $filesystem->mkdir(dirname($pdfPath)); try { $this->knpSnappyPdf->generateFromHtml( $this->renderView('@KritekBilling/test-invoice-pdf.html.twig'), $pdfPath, [ 'enable-local-file-access' => true, 'no-stop-slow-scripts' => true, ] ); } catch (\Throwable $th) { throw $th; } }
3. 配置KnpSnappyBundle的全局选项
确保在config/packages/knp_snappy.yaml中正确配置wkhtmltopdf的命令行参数,避免代码中重复配置可能出现的问题:
knp_snappy: pdf: enabled: true binary: '%env(WKHTMLTOPDF_PATH)%' options: enable-local-file-access: true no-stop-slow-scripts: true margin-top: 10mm margin-bottom: 10mm
4. 更新wkhtmltopdf版本
部分旧版本的wkhtmltopdf对现代HTML/CSS特性或协议解析存在Bug,安装最新稳定版后,更新环境变量WKHTMLTOPDF_PATH指向新的二进制文件。
5. 调试HTML内容
如果以上步骤无效,先将渲染后的HTML保存到本地文件,手动用wkhtmltopdf命令行测试,排查是否存在无效链接或特殊内容:
// 保存HTML到临时文件 $htmlTempPath = sys_get_temp_dir() . '/' . uniqid() . '.html'; file_put_contents($htmlTempPath, $this->renderView('@KritekBilling/test-invoice-pdf.html.twig')); // 手动执行命令测试(替换为你的wkhtmltopdf路径) // wkhtmltopdf --enable-local-file-access /tmp/xxx.html test.pdf
通过命令行输出的详细错误信息,定位具体的资源或代码问题。
内容的提问来源于stack exchange,提问作者Success Nduka
相关产品推荐
相关产品推荐

