如何通过ChromeDriver的executeCustomCommand获取PagedJS渲染HTML生成的PDF的Base64编码
如何通过ChromeDriver的executeCustomCommand获取PagedJS渲染HTML生成的PDF的Base64编码
嘿,我之前也碰到过类似的问题——用PagedJS渲染的发票在Chrome无头模式里能正常显示,但要通过executeCustomCommand拿到Base64格式的PDF确实得踩几个小坑,给你梳理下实操步骤:
首先,先确保你的ChromeDriver和Chrome浏览器版本严格匹配,你用的是135.0.7049.84的driver,对应的Chrome也得是这个版本,不然很容易出现渲染或命令调用的兼容问题。
接下来是ChromeOptions的配置,得给无头模式加上必要的参数,保证PagedJS能正常执行渲染:
$options = new \Facebook\WebDriver\Chrome\ChromeOptions(); $options->addArguments([ '--headless=new', // 用新版无头模式,渲染逻辑和正常Chrome更一致 '--disable-gpu', // 避免GPU渲染干扰无头模式 '--no-sandbox', // 服务器环境下大概率需要这个参数 '--enable-javascript', // 强制开启JS,PagedJS全靠它渲染 '--disable-web-security', // 如果你的HTML有跨域资源(比如外部字体),得加这个 ]);
初始化WebDriver后,加载你的HTML页面一定要等PagedJS完全渲染完成再导出,不然拿到的就是未排版的原始内容。可以通过监听PagedJS的渲染事件,或者等待页面上只有渲染完成才会出现的元素(比如PagedJS生成的.pagedjs_pages容器):
// 加载你的发票HTML(本地文件路径或远程URL都可以) $driver->get('file:///path/to/your/invoice.html'); // 等待PagedJS渲染完成,这里用两种判断方式兜底 $driver->wait()->until(function ($driver) { return $driver->executeScript("return window.PagedJS?.isRendered || document.querySelector('.pagedjs_pages') !== null"); });
最后就是核心的executeCustomCommand调用了,我们要通过Chrome DevTools的Page.printToPDF命令来导出,关键是要设置transferMode为ReturnAsBase64,这样返回的就是Base64编码的PDF内容:
// 调用Chrome DevTools的打印命令,指定返回Base64格式 $result = $driver->executeCustomCommand('Page.printToPDF', [ 'landscape' => false, // 根据你的发票需求设置是否横向 'displayHeaderFooter' => false, // 不需要页眉页脚就设为false 'printBackground' => true, // 必须开启!不然背景色、背景图会丢失 'paperWidth' => 8.5, // 纸张宽度,单位英寸(对应A4的宽度) 'paperHeight' => 11, // 纸张高度,单位英寸(对应A4的高度) 'transferMode' => 'ReturnAsBase64' // 这个参数是拿到Base64的关键 ]); // 从返回结果里提取Base64编码的PDF $pdfBase64 = $result['data']; // 如果要保存成本地文件,直接解码写入即可 file_put_contents('invoice.pdf', base64_decode($pdfBase64));
这里还有几个小提醒:
- 如果你用的是更老版本的ChromeDriver(比如v112之前),
transferMode参数可能叫returnAsBase64,注意大小写差异; - 如果你的HTML里有自定义字体,要确保字体文件能被Chrome无头模式加载到,不然渲染出来的发票会出现字体错乱;
- 等待渲染的逻辑可以根据自己的页面调整,比如加个超时时间,避免无限等待。
备注:内容来源于stack exchange,提问作者Parham Rahimpour
相关产品推荐
相关产品推荐

