之前遇到过一个前端打印页面局部内容的需求,用windos.print
与 vue-print-nb
都存在没有彻底解决包括样式显示异常,缩放比例不对等问题,切需打印内容是之前已经写好的,在做对应修改需要花费的时间更长,最后从网上找到一个htmlToCanvas
与 jsPDF
的方法并结合实际情况用插空白元素的方法解决了分页问题才完成了需求,该方法也存在缺陷,就是文件是图片转化来的不能进行选择,不过客户没有说有这样的需求就可以使用,具体组件及注释如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
|
import html2canvas from 'html2canvas' import JsPDF from 'jspdf'
export function computePrint(ele, wholeNodes, htmlTitle, success = () => {}, fail = () => {}) { const A4_WIDTH = 592.28 const A4_HEIGHT = 841.89 const pageHeight = ele.offsetWidth / A4_WIDTH * A4_HEIGHT const emptyDomHeight = 50 for (let i = 0; i < wholeNodes.length; i++) { const elementOffsetTop = wholeNodes[i].offsetParent === ele ? wholeNodes[i].offsetTop : wholeNodes[i].offsetTop + wholeNodes[i].offsetParent.offsetTop const topPageNum = Math.ceil((elementOffsetTop + 50) / pageHeight) const bottomPageNum = Math.ceil(((elementOffsetTop + 50) + wholeNodes[i].offsetHeight) / pageHeight) if (topPageNum !== bottomPageNum) { const divParent = wholeNodes[i].parentNode const newBlock = document.createElement('div') newBlock.className = 'empty-div' newBlock.style.background = '#fff' const _H = topPageNum * pageHeight - elementOffsetTop newBlock.style.height = emptyDomHeight + _H + 'px' divParent.insertBefore(newBlock, wholeNodes[i]) } } html2canvas(ele, { allowTaint: false, scale: 1, dpi: 300, backgroundColor: '#fff', height: ele.clientHeight + 50, windowHeight: ele.clientHeight + 50 }).then((canvas) => { const emptyDivs = document.querySelectorAll('.empty-div') for (let i = 0; i < emptyDivs.length; i++) { emptyDivs[i].style.height = 0 emptyDivs[i].parentNode.removeChild(emptyDivs[i]) } const contentWidth = canvas.width const contentHeight = canvas.height const pageHeight = (contentWidth / 592.28) * 841.89 let leftHeight = contentHeight let position = 0 const imgWidth = 595.28 const imgHeight = (592.28 / contentWidth) * contentHeight const pageData = canvas.toDataURL('image/jpeg', 0.5) const PDF = new JsPDF('', 'pt', 'a4') if (leftHeight < pageHeight) { PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight) } else { while (leftHeight > 0) { PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight) leftHeight -= pageHeight position -= 841.89 if (leftHeight > 0) { PDF.addPage() } } } PDF.save(htmlTitle + '.pdf') success() }) .catch((error) => { fail(error) }) }
|