Laravel使用Snappy导出PDF时amchart热力图无法显示问题咨询
排查步骤
- 确认wkhtmltopdf版本:必须安装带QtWebkit补丁的完整版wkhtmltopdf,包管理器默认安装的精简版普遍缺失JS渲染、SVG渲染支持,版本要求至少为0.12.5及以上带补丁版本。
- 检查JS执行等待配置:默认情况下wkhtmltopdf不会等待JS执行完成就启动PDF渲染,amchart初始化、渲染需要一定时间,未配置等待时间会导致图表还没生成就被截断。
- 检查图表容器尺寸:当前代码中
chartdiv未设置固定宽高,wkhtmltopdf无法识别百分比宽高对应的实际像素值,会导致图表初始化失败。 - 检查动画配置:amchart默认的初始化动画、过渡效果会延长渲染时间,未关闭的情况下大概率出现渲染未完成就生成PDF的问题。
- 检查资源加载路径:amchart相关JS库必须使用绝对路径或者直接内嵌到视图中,wkhtmltopdf无法识别相对路径的静态资源,引入JS时建议用
public_path()生成本地绝对路径。 - 检查JS语法兼容性:wkhtmltopdf依赖的QtWebkit内核不支持ES6及以上语法,如果使用的是较高版本的amchart,需要确认引入的是ES5兼容版本,或者用Babel转换后再引入。
修复代码
控制器修改
public function genReportPDF(Request $request) { $pdf = \PDF::loadView('report.ReportPDF'); $pdf->setOption('images', true); $pdf->setOption('enable-javascript', true); $pdf->setOption('enable-smart-shrinking', true); // 新增:等待JS执行时间,单位毫秒,可根据图表复杂度调整为1000~5000 $pdf->setOption('javascript-delay', 3000); // 新增:允许加载本地静态资源 $pdf->setOption('enable-local-file-access', true); // 新增:固定页面尺寸避免内容被截断 $pdf->setOption('page-size', 'A4'); return $pdf->download('ReportPDF.pdf'); }
视图修改
<!-- 先定义容器,设置固定宽高,不要使用百分比 --> <div id="chartdiv" style="width: 600px; height: 400px;"></div> <!-- 引入amchart资源用绝对路径 --> <script type="text/javascript" src="{{ public_path('amcharts4/core.js') }}"></script> <script type="text/javascript" src="{{ public_path('amcharts4/charts.js') }}"></script> <script type="text/javascript"> am4core.ready(function() { // 新增:关闭所有amchart动画,避免渲染延迟 am4core.options.animationDuration = 0; am4core.options.hiddenStateDuration = 0; var chart = am4core.create("chartdiv", am4charts.XYChart); // 关闭初始淡入效果 chart.hiddenState.properties.opacity = 1; // 用固定宽高替代百分比设置 chart.width = 600; chart.height = 400; // 此处保留你原有amchart配置代码不变 chart.maskBullets = true; var xAxis = chart.xAxes.push(new am4charts.CategoryAxis()); var yAxis = chart.yAxes.push(new am4charts.CategoryAxis()); // ... 剩余原有配置全部保留 ... // 新增:图表渲染完成后标记状态,配合延迟配置更稳妥 chart.events.on("ready", function() { window.status = "chart_ready"; }); }); </script>
兜底方案
如果上述配置后仍无法正常渲染,可以直接在前端把amchart导出为base64格式的图片,把base64值传给后端后直接插入视图生成PDF,完全不需要依赖wkhtmltopdf的JS渲染能力,成功率100%。
内容的提问来源于stack exchange,提问作者mr kobeng
相关产品推荐
相关产品推荐

