[问题记录] html2canvas导出空白PDF(canvas.toDataURL返回data,)
描述:
前端使用pdfjs加载PDF,转换为canvas ,但是当PDF页数过多时,html2canvas 导出空白 PDF。
因为浏览器对canvas大小有限制,所以当canvas超出限制后,canvas.toDataURL就会返回data,. 类似于空数据。
使用pdfjs加载PDF时,是将每一页PDF转换为canvas , 并添加到一个DIV元素下。
而使用html2canvas 生成PDF时,是直接将这个DIV元素转换成PDF,所以会出现空白PDF的问题(如果PDF页数过多)
解决方案:
1.
先将原本的DOM结构改变,原来在DIV下插入PDF画布,如 <div id="pdfArea"><canvas></canvas></div>
改成 <div id="pdfArea"><div><canvas></canvas><div></div> ,也就是加多一层div包裹canvas.
具体操作如下:
// 获取PDF画布元素 let pdfCanvas = document.getElementById("pdfArea"); // 清空元素内容 pdfCanvas.innerHTML=''; pdfjsLib .getDocument({ url: pdfUrl, rangeChunkSize: 65536, disableAutoFetch: false, }) .promise.then((pdfDoc_) => { // 获取PDF文件对象 this.pdfDoc = pdfDoc_; // 获取PDF页数 this.numPages = this.pdfDoc.numPages; // 设置元素边框 $("#pdfCanvas").css("border", "0"); // 循环PDF页码 for (let i = 1; i <= this.numPages; i++) { // 创建画布 let canvas = document.createElement("canvas"); // 设置画布Id canvas.id = "PageNum" + i; // 创建div元素,将画布添加到div,并将div添加到PDF画布元素 let div = document.createElement("div"); div.id="divArea" + i; div.append(canvas); pdfCanvas.append(div); // 后续操作,可百度pdfjs用法,此处省略 } }); },
2.
使用jsPDF, 循环将每一页PDF(canvas) 插入到 新的PDF中。
import jsPDF from 'jspdf'
var pdf = new jsPDF('l','pt','a4'.true); //横向
var pdfWidth = 841.89;
var pdfHeight = 595.28;
var canvasList = document.body.getElementsByTagName("canvas"); // 判断PDF页数大小 // 如果页数太多,不能直接使用html2canvas绘制成一个canvas,浏览器对canvas有大小限制,会导致画布数据为空 // 画布太大,需要分页添加 if(canvasList.length > 20 ){ // 循环画布 for(var i=0; i < canvasList.length; i++){ await html2canvas(document.getElementById('divArea'+ (i+1)),{ useCORS:true, // 开启跨域配置 }).then(function (canvas) { var imgData = canvas.toDataURL('image/jpeg', 0.1); // 添加到PDF pdf.addImage(imgData, 'JPEG', 0, 0,pdfWidth,pdfHeight/canvas.width*canvas.height, undefined,'FAST'); if(i!=canvasList.length-1){ pdf.addPage(); } }); } }
3.最后保存,前端导出或转成base64到后端更新文件
pdf.save(文件名);
pdf.output('datauristring');