html2canvas + jspdf 导出pdf失败?看我就对了
前言
作为一名优秀的咸鱼,我本着能不做就不做的原则下"集沙成石",昨天出现了一个不得不解决的bug。
我负责的其中一款项目是面向C端的。通过各种图、文、视频来展示宣传C端的优势,但是有的时候需要通过纸质的内容向C端的领导进行汇报,所以这里就用需要把页面元素转为PDF了。
之前通过`html2canvas`和`jspdf`已经实现了的,但是昨天突然有的人导出就不行了。。。,而且C端还急需向领导汇报。🙀🙀🙀🙀🙀🙀
问题
那能行吗? 作为一名优秀的咸鱼,怎么可以让客户着急呢。 打开客户端调试器一看,错误不就已经出现了吗,那肯定是jsPdf
的问题了,更新插件总该行了吧,聪明如我😃😃😃
js
Uncaught (in promise) Error: Supplied data is not a JPEG
at getJpegSizeFromBytes (jsPdf.debug.js:4753:43)
at jsPDFAPI.processJPEG (jsPdf.debug.js:4801:24)
at jsPDFAPI.addImage (jsPdf.debug.js:4697:66)
呐~ 你肯定猜到了,更新之后没解决。。。
搞半天才发现这眼睛不好使啊,都明明白白的告诉我Supplied data is not a JPEG
数据不是JPEG格式的
继续往上排查结果发现canvas
画布在渲染dom页面的时候竟然都是空白的,我emo了...
js
html2canvas(this.dom, {
backgroundColor: '#fff',
canvas: c,
useCORS: true,
}).then((canvas) => {
// canvas 竟然没有画面。。。。
document.body.appendChild(canvas)
})
方案
- 排查之后发现之所以导致
canvas
画布空白,竟然是因为页面过长导致的。- 在掘金、stackoverflow都查看了一下都没有查到我需要的答案
- 解决方案
最后,我只想到了一个办法,那就是使用canvas.scale
方法根据可渲染的最大高度来对canvas
进行缩放,降低画面的清晰度。
这里需要注意一下在设置canvas的width和height的时候需要考虑当前像素比,不然会出现画面拉伸的问题。
js
/**
* 创建并配置canvas的参数
*/
configCanvas = function (h) {
// 画板dom
const canvasDom = document.createElement('canvas')
canvasDom.style.backgroundColor = '#fff'
canvasDom.style.width = this.fileW + 'px'
canvasDom.style.height = h + 'px'
const defaultSize = { // html2canvas的width和height默认需要设置为style.width .height的window.devicePixelRatio倍
w: this.fileW * window.devicePixelRatio,
h: h * window.devicePixelRatio
}
canvasDom.width = defaultSize.w
canvasDom.height = defaultSize.h
if (this.maxHeight < h) {
// 根据实际高度和最大渲染高度来计算缩放
domScale.h = Math.min(this.maxHeight / h, 1)
canvasDom.height = domScale.h * defaultSize.h
}
// 画板
const ctx = canvasDom.getContext('2d')
ctx.scale(1, domScale.h)
this.domRenderToCanvas(canvasDom)
}
传送门:dom2pdf