我的另一篇文章写了autoTable+jsPdf生成PDF
参考这里
1、将html转成图片canvas(
scrollY: refDom.top, // 关键代码,截取长度
height: refDom.height // 加高度,避免截取不全
)上面两个属性是截取长图的关键
const refDom = this.$refs.htmlDom.getBoundingClientRect()//就是 #pdfDom 这个divhtml2Canvas(document.querySelector('#pdfDom'), {allowTaint: true,taintTest: false,useCORS: true,async: true,scale: '1', // 放大倍数dpi: '192', // 精度,清晰度设置scrollY: refDom.top, // 关键代码,截取长度height: refDom.height // 加高度,避免截取不全}).then(canvas => {// 将canvas的裁剪到PDF中})
2、canvas的的宽和A4纸(pageWidth,pageHeight)的宽要一致,缩放canvas ,得到缩放后的canvas的高(imgHeight),canavs的实际高leftHeight
3、每次裁剪A4纸高度的canvas ,
const pageData = canvas.toDataURL('image/jpeg/png', 1) //html2Canvas获取到的canvasPDF.addImage(pageData,0,position,pageWidth,imgHeight)leftHeight -= pageHeight // 剩余高度position -= pageWidth// 新加一页if (leftHeight > 0) {PDF.addPage()}
完整代码
html
<template><div> <div id="pdfDom" style="border: 1px solid red;width: 1000px;margin: 0 auto;" ref="htmlDom"><!--自己加内容--></div><button @click="textHtml2Canvas">测试结果img</button></div></template>
js
// 生成PDFtextHtml2Canvas () {const refDom = this.$refs.htmlDom.getBoundingClientRect()const pageWidth = 595.28 - 40 // A4纸的宽高 减去左右边距const pageHeight = 841.89// a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高html2Canvas(document.querySelector('#pdfDom'), {allowTaint: true,taintTest: false,useCORS: true,async: true,scale: '1', // 放大倍数dpi: '192', // 精度scrollY: refDom.top, // 关键代码height: refDom.height + 50 // 加高度,避免截取不全}).then(canvas => {const contentWidth = canvas.widthconst contentHeight = canvas.heightconst pageData = canvas.toDataURL('image/jpeg/png', 1)const PDF = new JsPDF('', 'pt', 'a4') // , true// canvas图片的高const imgHeight = pageWidth / contentWidth * contentHeight // canvas的宽与PDF的宽比列一样的时候,canvas的高缩放后的值let leftHeight = imgHeight let position = 0// 如果图片的高小于A4纸的高,不分页if (leftHeight < pageHeight) {PDF.addImage(pageData, 'JPEG', 20, 0, pageWidth, imgHeight)} else {// 分页// let index = 0while (leftHeight > 0) {// console.log(leftHeight, '每一页的高度', imgHeight, index)// index++// addImage(stream, startX, startY, width, height)// stream:图片流// (startX,startY)图片的放置的开始点PDF.addImage(pageData, 'JPEG', 20, position, pageWidth, imgHeight)leftHeight = leftHeight - pageHeightposition -= pageHeightif (leftHeight > 0) {PDF.addPage()}}}PDF.save('html变pdf.pdf') // 保存PDFreturn PDF.output('datauristring')})},
另外,如果要设置上下边距,每次分页的时候,新建一个canvas来承接裁剪的部分,在新的canvas中留出边距。然后将新的canvas传给jsPDF。但是我发现这样做之后,生成的PDF清晰度不够了。
弊端
1、内容会被截断(一行字有时候会被裁成两页显示)
2、如果裁到最后一页的时候,canvas的高只剩下一点点,而且是空白的,就多了一空白页
我有一个猜想。可不可以这样
1、按模块区分,当一个模块占了大半张PDF的时候,第二个模块就要另开一页。
2、先生成几张canvas图片,预估他们会不会被分页裁断