Skip to content

打印前端页面 #9

Description

@Kaviilee

前端打印局部PDF

  1. window.print()

    利用 iframe 局部生成 pdf,但是利用 iframe 来生成会有一个问题,那就是需要自己编写样式带入iframe内。

    /*
     * 因为使用的 webpack ,所以会有生产和开发环境
     * 在开发环境中,所有的样式都将以 <style> 的形式展示
     * 而在生成环境中,则将样式分类到不同的 <link> 中
     * 并且需要用到 window.onload
     * 这是因为需要等待 link 的样式文件下载完成后才可以去执行 window.print,不然没有打印样式
     * window.print 能阻塞页面其他操作
     * 点击 取消/打印,关闭该页面,返回原页面
     */
    function createPrintHtml(domStr) {
        // domStr 就是要打印的部分
        let str
        if (process.env.NODE_ENV === '"development"') {
            // 获取全部 <style>
            str = "<!DOCTYPE html><head><meta charset='utf-8'>"
            + '<script>window.onload=function(){window.print();window.close()}</script>'
            + '<style>'
            + Array.from(window.document.querySelectorAll('style')).map(n => n.innerText).join('')
            + '</style></head><body>'
            + domStr
            + '</body></html>'
        } else {
            // 获取全部 <link>
            str = "<!DOCTYPE html><head><meta charset='utf-8'>"
            + '<script>window.onload=function(){window.print();window.close()}</script>'
            + window.document.head.innerHTML.match(/href="(.*?)"/gi).filter(_ => _.endsWith('css"')).map(n => n.slice(6)).map(n => n.slice(0, -1)).map(_ => `<link rel="stylesheet" type="text/css" href="${location.origin + _}" >`).join('')
            + '</head><body>'
            + domStr
            + '</body></html>'
        }
        return str
    }

    在得到打印内容之后

    const str = createPrintHtml(newStr)
    // 判断iframe是否存在,不存在则创建iframe
    let iframe = document.getElementById('print-iframe')
    if (!iframe) {
        iframe = document.createElement('IFRAME')
        let doc = null
        iframe.setAttribute('id', 'print-iframe')
        iframe.setAttribute('style', 'position:absolute;width:0px;height:0px;left:-500px;top:-500px;')
        document.body.appendChild(iframe)
        doc = iframe.contentWindow.document
    
        doc.write(str)
        doc.close()
        iframe.contentWindow.focus()
    }
    iframe.contentWindow.print()
    if (navigator.userAgent.indexOf('MSIE') > 0) {
        document.body.removeChild(iframe)
    }
  2. html2canvas + jsPDF

    利用 html2canvas 先将 html DOM 转换成 canvas,然后 toDataURL 之后再利用 jsPDF 生成 pdf

    import html2canvas from 'html2canvas'
    import { jsPDF } from 'jspdf'
    
    const generatePdf = (dom) => {
        // 要打印的 dom
        console.log(dom)
        
        html2canvas(dom, { useCORS: false, allowTaint: true })
            .then(canvas => {
                let img = canvas.toDataURL('image/png', 1.0)
                let pdf = new jsPDF({ format: 'a4' })
                pdf.addImage(img, 'PNG', 15, 20, 180, 180)
                pdf.save('yourpdfname.pdf')
            })
    }

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions