Codeigniter 3.x使用mPDF导出PDF时Google Chart不显示问题咨询
问题根本原因
mPDF 本身不支持执行页面内的 JavaScript 代码,你前端代码里通过 Google Chart JS 生成图表、再转成图片的逻辑,在服务器端调用 $this->load->view() 拉取HTML内容的时候完全不会执行,拿到的只有空的 piechart 容器,所以导出的PDF对应位置是空白。
可行解决方案
方案1:前端预生成图表图片传给后端生成PDF(适配现有代码改动最小)
你现有JS已经实现了图表加载完成后转成图片的逻辑,只要把生成的base64图片内容传给后端,后端直接写到HTML里给mPDF渲染即可:
- 拆分页面逻辑:不要直接把带JS的视图传给mPDF加载,先做一个预览页,用户在浏览器打开预览页时JS已经执行完成,把生成的图表base64存入隐藏表单,用户点击导出按钮时把base64一并提交到后端导出接口。
- 调整预览页JS代码:
google.charts.load('current', { 'packages': ['corechart'] }); google.charts.setOnLoadCallback(drawChart); function drawChart() { var data = google.visualization.arrayToDataTable([ ['Questions', 'Result'], ['Correct Answers', <?= !empty($student_result[0]['correct_ans_count']) ? $student_result[0]['correct_ans_count'] : '0'; ?>], ['Wrong Answers', <?= !empty($student_result[0]['wrong_ans_count']) ? $student_result[0]['wrong_ans_count'] : '0'; ?>], ['Skipped Questions', <?= !empty($student_result[0]['skiped_que_count']) ? $student_result[0]['skiped_que_count'] : '0'; ?>], ]); var options = { title: 'Test Result Piechart', pieHole: 0.4, chartArea: { left: 100, top: 70, width: '100%', height: '80%' } }; var chart_area = document.getElementById('piechart'); var chart = new google.visualization.PieChart(chart_area); google.visualization.events.addListener(chart, 'ready', function() { const imgBase64 = chart.getImageURI(); // 把base64存入隐藏表单 document.getElementById('chart_base64').value = imgBase64; chart_area.innerHTML = '<img src="' + imgBase64 + '" class="img-responsive">'; }); chart.draw(data, options); }
- 预览页新增隐藏表单和导出按钮:
<form action="/你的控制器名/导出方法名" method="post"> <input type="hidden" name="chart_base64" id="chart_base64"> <!-- 其他导出需要的参数也可以放到这里,比如学生ID、考试ID等 --> <button type="submit">导出PDF</button> </form> <div id="piechart" style="width: 100%; max-width:900px; height: 500px;"></div>
- 调整后端导出逻辑:
public function 导出方法名() { // 接收前端传过来的图表base64 $chartBase64 = $this->input->post('chart_base64'); $data = [ 'name' => 'abc', 'chart_base64' => $chartBase64 ]; // 导出专用视图不需要带Google Chart相关JS,直接渲染图片即可 $html = $this->load->view('export_result',$data,true); $this->load->library('M_pdf'); $mpdf = new mPDF(); $mpdf->AddPage( 'P', // L - landscape, P - portrait '', '', '', '', 4, // margin_left 4, // margin right 4, // margin top 4, // margin bottom 4, // margin header 4 ); ob_clean(); $mpdf->allow_charset_conversion = true; $mpdf->SetDisplayMode('fullpage'); $mpdf->WriteHTML($html); // 注意原代码输出文件名后缀写错了,应该是pdf不是php $mpdf->Output('test.pdf', 'D'); }
- 新建导出专用视图
export_result.php:
<div style="width: 100%; max-width:900px; height: 500px;"> <img src="<?= $chart_base64 ?>" class="img-responsive"> <!-- 其他需要导出的页面内容 --> </div>
方案2:服务端直接生成图表
如果不想走前端提交的逻辑,可以直接在服务端使用PHP图表库生成图片,比如用JpGraph直接生成饼图PNG,写到HTML后直接传给mPDF渲染,完全不需要依赖JS,稳定性更高。
内容的提问来源于stack exchange,提问作者w.Daya
相关产品推荐
相关产品推荐

