js前端打印

1.js原生打印

不借助辅助工具,把css样式和内容直接带入到打印页面,但是会存在部分样式浏览器无法成功转换成pdf,也会存在样式紊乱问题,具体原因在代码注释中

function printTO() {
	let printHtml = ''
            
     // 下列获取会存在有样式紊乱问题,在不清楚css引用的顺序情况下,会存在有样式覆盖问题
     // 建议确定样式的引入顺序,或样式只存在一种标签内

     // 获取styles标签样式
     const styles = document.querySelectorAll('style')
     styles.forEach(el => {
         printHtml += el.outerHTML
     })

     // 获取link标签样式
     const links =document.querySelectorAll('link')
     links.forEach(el => {
         el.outerHTML.indexOf('.css') > -1 ? printHtml += el.outerHTML : void(0)
     })

     // 转换打印区域内容为String
     let div = document.createElement('div')
     // 需要复制打印区域节点,不能直接把区域append到div元素中,会把打印区域全部移入到div中
     div.appendChild(document.getElementById('打印区域id').cloneNode(true))
     printHtml += div.innerHTML
     
     const newWinDow = window.open('', '打印', "height=600, width=1200, top=50, left=100, toolbar=no, menubar=no, scrollbars=yes, resizable=yes, location=no, status=no")
     newWinDow.document.write(contentHTML)
     // newWinDow.print()
     // 延迟一定时间调用打印事件,因为页面可能还未完全渲染完毕,导致打印预览的内容为空或者不全
     setTimeout(() => {
         newWinDow.print()
     }, 300)
}

2.借助插件

把打印区域内容转为图片,然后在进行打印,这里需要注意,可能会存在图片不清晰问题,解决方案,放大图片的倍数,然后在缩小,可以很大程度解决不清晰程度。
借助插件:html2canvas

function printTO() {
	// 前端转为图片,浏览器在转为pdf
	// 但还是会存在部分样式问题,建议查阅浏览器转pdf不兼容样式,避免使用这些样式
    try {
        const canvasID = document.getElementById('打印内容id')
        html2canvas(canvasID, {
         	// 放大图片倍数,然后下面控制缩小
            // 建议配合width,height参数一起使用
            scale: 5
        }).then(canvas => {
            const imgUrl = canvas.toDataURL("image/png")
            // 转为图片后,需要控制打印区域大小
            const html = `<div style="width: 820px; margin: 0 auto;"><img src="${imgUrl}" width="100%" /></div>`
            const newWinDow = window.open('', '打印', "height=600, width=1200, top=50, left=100, toolbar=no, menubar=no, scrollbars=yes, resizable=yes, location=no, status=no")
            newWinDow.document.write(html)
            
            // 延迟一定时间调用打印事件,因为页面可能还未完全渲染完毕,导致打印预览的内容为空
            setTimeout(() => {
                newWinDow.print()
            }, 300)
        })
    } catch (error) {
        throw Error(error)
    }
}