Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

打印前端页面 #9

Open
Kaviilee opened this issue May 13, 2021 · 0 comments
Open

打印前端页面 #9

Kaviilee opened this issue May 13, 2021 · 0 comments

Comments

@Kaviilee
Copy link
Owner

前端打印局部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')
            })
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant