如何后台生成Google饼图并通过laravel-dompdf转为PDF?
解决方案:后端生成Google饼图并嵌入PDF(无需前端JS)
由于dompdf不支持JavaScript,直接渲染Google Charts的HTML肯定行不通。这里有两种靠谱的后端-only方案,都是我实际项目里用过的,分享给你:
方案一:用无头浏览器渲染图表并截图(保留Google Charts样式)
这种方法可以完美复用Google Charts的样式,通过无头浏览器在后端执行JS渲染图表,再截图成图片,最后嵌入PDF。推荐用Laravel生态的spatie/browsershot包,它封装了Puppeteer,用起来很方便。
步骤:
安装依赖
首先安装browsershot包,以及Puppeteer(需要Node.js环境):composer require spatie/browsershot npm install puppeteer生成图表HTML字符串
不用创建公共路由,直接在代码里构造Google Charts的HTML内容,比如:$chartHtml = ' <html> <head> <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script> <script type="text/javascript"> google.charts.load("current", {"packages":["corechart"]}); google.charts.setOnLoadCallback(drawChart); function drawChart() { var data = google.visualization.arrayToDataTable([ ["Task", "Hours per Day"], ["Work", 11], ["Eat", 2], ["Commute", 2], ["Watch TV", 2], ["Sleep", 7] ]); var options = { title: "My Daily Activities" }; var chart = new google.visualization.PieChart(document.getElementById("piechart")); chart.draw(data, options); } </script> </head> <body> <div id="piechart" style="width: 900px; height: 500px;"></div> </body> </html>';用Browsershot生成截图
把上面的HTML传入Browsershot,生成图片并保存到存储目录:use Spatie\Browsershot\Browsershot; $imagePath = storage_path('app/public/charts/piechart.png'); // 确保目录存在 if (!file_exists(dirname($imagePath))) { mkdir(dirname($imagePath), 0755, true); } Browsershot::html($chartHtml) ->setNodeBinary('/usr/bin/node') // 根据你的Node路径调整 ->setPuppeteerPath('/usr/bin/node_modules/puppeteer/lib/esm/puppeteer/puppeteer.js') // 调整路径 ->waitForFunction('google.visualization.PieChart !== undefined') // 等待图表加载完成 ->waitFor(1000) // 额外等待1秒确保渲染完成 ->save($imagePath);嵌入图片到PDF
在你的PDF Blade视图里,引用生成的图片:<img src="{{ public_path('storage/charts/piechart.png') }}" alt="Pie Chart">然后用dompdf生成PDF即可。
方案二:用PHP原生图表库(无需JS,纯后端)
如果不想依赖Node.js和无头浏览器,可以用纯PHP的图表库直接生成饼图图片。推荐phplot/phplot,轻量且容易上手。
步骤:
安装PHPlot
composer require phplot/phplot生成饼图图片
写代码生成饼图并保存:use PHPlot\PHPlot; $imagePath = storage_path('app/public/charts/piechart.png'); if (!file_exists(dirname($imagePath))) { mkdir(dirname($imagePath), 0755, true); } // 准备数据 $data = [ ['Work', 11], ['Eat', 2], ['Commute', 2], ['Watch TV', 2], ['Sleep', 7], ]; // 初始化PHPlot $plot = new PHPlot(900, 500); $plot->SetImageBorderType('plain'); $plot->SetPlotType('pie'); $plot->SetDataType('text-data-single'); $plot->SetDataValues($data); // 设置标题和样式 $plot->SetTitle('My Daily Activities'); $plot->SetPieLabelType('value'); // 显示数值标签 $plot->SetLegend($data); // 设置图例 // 生成图片并保存 $plot->SetOutputFile($imagePath); $plot->DrawGraph();嵌入到PDF
和方案一一样,在Blade视图里引用图片路径,用dompdf生成PDF即可。
注意事项
- 不管用哪种方案,都要确保存储目录有读写权限。
- 方案一中,如果你的服务器没有Node.js,需要先安装Node环境。
- 可以把生成图片的逻辑封装成一个服务类,方便复用。
内容的提问来源于stack exchange,提问作者jaroApp
相关产品推荐
相关产品推荐

