使用pdfkit转换含Chart.js图表的HTML为PDF时图表不显示的解决方法
解决pdfkit转换含Chart.js的HTML文件时图表不显示的问题
我有一段可正常运行的Chart.js图表代码(包含HTML、CSS、JS),但使用pdfkit的from_file方法将HTML转换为PDF时,图表无法显示。转换所用Python代码如下:
import pdfkit # converting html file to pdf file pdfkit.from_file('144474.html', 'output1.pdf')
问题根源
pdfkit依赖的wkhtmltopdf默认不会等待JavaScript完全渲染完成就生成PDF,而Chart.js是通过JS动态绘制canvas图表,导致图表还未渲染完成就被转成PDF,最终显示空白。此外,原Chart.js代码中使用了v2版本的scales配置(xAxes/yAxes数组),但引入的是v3.3.2版本,语法不兼容也会导致图表渲染失败。
解决方案
方案1:添加延迟等待JS渲染完成
在pdfkit配置中增加--javascript-delay参数,给Chart.js足够的渲染时间。修改后的Python代码:
import pdfkit # 若wkhtmltopdf未加入系统环境变量,需指定路径 config = pdfkit.configuration(wkhtmltopdf=r'你的wkhtmltopdf完整路径') options = { 'javascript-delay': '3000', # 等待3秒,可根据实际情况调整 'enable-javascript': '' # 确保启用JavaScript } pdfkit.from_file('144474.html', 'output1.pdf', configuration=config, options=options)
方案2:将Chart.js图表转为图片嵌入HTML
利用Chart.js的toDataURL()方法把图表转为base64图片,替换原canvas元素,pdfkit转换时直接渲染图片,无需等待JS执行。同时修正Chart.js v3版本的语法问题:
const months = [1,2,3] const ndvi_data = [3,4,5] const evi_data = [6,7,8,9] const chart = new Chart(document.getElementById("ndvi_evi_chart"), { type: 'bar', data: { labels: months, datasets: [{ label: "NDVI", type: "bar", stack: "Base", backgroundColor: "#6418C3", data: ndvi_data, }, { label: "EVI", type: "bar", stack: "Sensitivity", backgroundColor: "#B270ED", data: evi_data, }] }, options: { plugins: { legend: { display: true, position: "top", align: "end" } }, scales: { x: { // Chart.js v3+ 改用x/y对象替代xAxes/yAxes数组 stacked: true, ticks: { beginAtZero: true, maxRotation: 0, minRotation: 0 } }, y: { stacked: true, title: { // v3中scaleLabel改为title display: true, text: 'NDVI and EVI' } } } } }); // 图表渲染完成后替换为图片 chart.rendered.then(() => { const canvas = document.getElementById("ndvi_evi_chart"); const img = document.createElement('img'); img.src = canvas.toDataURL('image/png'); img.width = canvas.width; img.height = canvas.height; canvas.parentNode.replaceChild(img, canvas); });
方案3:升级wkhtmltopdf版本
旧版本wkhtmltopdf对ES6+语法支持不佳,建议安装最新稳定版,确保JavaScript能正常执行。
内容的提问来源于stack exchange,提问作者Adarsh Srivastav
相关产品推荐
相关产品推荐

