html2canvas捕获Chart.js图表生成PDF不受窗口大小影响的解决方法
问题:html2canvas生成PDF时图表尺寸无法固定
我需要使用html2canvas生成的图片制作PDF,网站上的基础组件如下图所示:
全屏浏览器下生成的PDF效果如下图:
调整窗口大小后,基础组件的显示效果如下图:
此时生成的PDF效果如下图:
我的需求是无论当前窗口尺寸是多少,生成的PDF中的两张图表显示效果完全一致。我已经在html2canvas的配置项中添加了windowHeight: "1080px", windowWidth: "1920px",现在文本渲染已经可以正常适配,但图表尺寸却没有按照配置的窗口参数调整,相关代码如下:
let dataURL; await html2canvas(document.getElementById(id), { windowHeight: "1080px", windowWidth: "1920px", }).then(canvas => dataURL = canvas.toDataURL() ) return dataURL
请问我该如何解决这个问题?
问题原因
你设置的windowHeight和windowWidth只是html2canvas模拟的视口参数,并不会触发页面内图表的重绘逻辑。绝大多数可视化图表库都会基于DOM节点的实际渲染尺寸、当前真实窗口的视口尺寸来绘制内容,不会自动适配html2canvas的模拟视口参数,所以才会出现文本适配但图表尺寸错位的问题。
解决方案
你可以在调用html2canvas截图前,临时强制固定目标节点的尺寸,触发图表重绘到指定大小,截图完成后再还原原有样式即可,具体实现代码如下:
let dataURL; const targetDom = document.getElementById(id); // 先保存原有的样式,后续恢复用 const originalStyle = { width: targetDom.style.width, height: targetDom.style.height, position: targetDom.style.position, left: targetDom.style.left, top: targetDom.style.top, zIndex: targetDom.style.zIndex }; // 临时固定目标节点尺寸为你需要的1920*1080,移出可视区避免影响用户当前页面 targetDom.style.width = '1920px'; targetDom.style.height = '1080px'; targetDom.style.position = 'fixed'; targetDom.style.left = '-9999px'; targetDom.style.top = '0'; targetDom.style.zIndex = '-999'; // 如果是ECharts/Highcharts等图表,这里要手动调用重绘方法,等待重绘完成 // 以ECharts为例: // const chartInst = echarts.getInstanceByDom(targetDom.querySelector('.chart-class')); // chartInst.resize({width: 1920, height: 对应图表高度}); // await new Promise(resolve => setTimeout(resolve, 300)); // 等待重绘完成,时长可根据实际情况调整 await html2canvas(targetDom, { windowHeight: 1080, // 注意这里不用加px,传数字即可 windowWidth: 1920, scrollX: 0, scrollY: 0, scale: 2, // 提高生成图片的清晰度,可按需调整 useCORS: true // 如果有跨域资源可以开启 }).then(canvas => dataURL = canvas.toDataURL('image/png', 1.0) ) // 恢复原有样式 Object.assign(targetDom.style, originalStyle); // 如果手动调用了图表resize,这里要再调用一次resize恢复成当前窗口尺寸 // chartInst.resize(); return dataURL
其他注意事项
- 如果你的图表是响应式布局、绑定了窗口
resize事件,可以在临时修改尺寸前临时移除事件监听,恢复样式后再重新绑定,避免冲突。 - 如果生成的图表有模糊问题,可以调整
scale参数到2~3之间,平衡清晰度和生成文件大小。
内容的提问来源于stack exchange,提问作者flotho
相关产品推荐
相关产品推荐

