页面局部打印

window 对象下有一个 print 方法可以实现整个页面的打印,但无法选择指定内容的打印。iframewindow 属性也具有 print 方法,利用 iframe 可以实现页面的局部打印:创建 __iframe__,引入css样式文件,克隆需要打印的元素添加到 iframe 里,将创建的 iframe 添加到页面上,调用 iframe.contentWindowprint 方法,进行打印。

打印方法

  • 获取要打印的 dom 并克隆(递归)

    1
    2
    3
    let printElement = document.getElementById('print_view')
    // 递归克隆元素
    let clonePrintElement = cloneElement(printElement)
  • 创建 iframe ,设置 style 和 srcdoc(用于引入 css 样式)

    1
    2
    3
    4
    5
    6
    7
    let iframe = document.createElement('iframe')
    // 设置 iframe 为隐藏元素(根据实际情况,设置 style 属性)
    iframe.setAttribute('style', 'visibility: hidden')
    // 在这里可以通过【link】引入 css 文件,设置打印样式(非必须)
    iframe.setAttribute('srcdoc', '<html><head><title></title></head><body></body></html>')
    // 在添加到 body 后,才能使用 iframe.contentWindow 和 iframe.contentDocument
    document.body.appendChild(iframe)
  • 将 dom 的克隆元素添加到 iframe(延迟添加)

    1
    2
    // 在上一步中使用【srcdoc】属性时,这里需要使用 setTimeout 来保证 iframe.contentDocument.body 可以正常使用
    iframe.contentDocument.body.appendChild(clonePrintElement)
  • 调用 iframe.contentWindow.print 方法打印

    1
    iframe.contentWindow.print()

多次打印(修改内容)

  • 创建 iframe 时,添加一个标识属性

    1
    iframe.setAttribute('id', 'print_iframe')
  • 第二次打印时,根据上一步添加的标识属性,判断 iframe 是否存在

    • 不包含图片:清空 iframe 的 body
    1
    2
    3
    4
    5
    6
    7
    let iframe = document.getElementById('print_iframe')
    if (!iframe) {
    // iframe 不存在,创建 iframe
    } else {
    // 清空 iframe 的 body
    iframe.contentDocument.body.innerText = ''
    }
    • 包含图片:在内容改变后,需要先移除 removeIFrame
    1
    2
    3
    4
    5
    6
    7
    let iframe = document.getElementById('print_iframe')
    if (!iframe) {
    // iframe 不存在,创建 iframe
    } else {
    // iframe 存在时,数据没有改变,直接调用打印
    iframe.contentWindow.print()
    }

相关函数

  • createIFrame

    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
    // 不包含图片
    function createIFrame () {
    return new Promise ((resolve, reject) => {
    let iframe = document.getElementById('print_iframe')
    if (!iframe) {
    iframe.setAttribute('style', 'visibility: hidden')
    iframe.setAttribute('srcdoc', '<html><head><title></title></head><body></body></html>')
    document.body.appendChild(iframe)
    } else {
    iframe.contentDocument.body.innerText = ''
    }

    setTimeout(() => resolve(iframe), 50)
    })
    }

    // 包含图片
    function createIFrame () {
    return new Promise ((resolve, reject) => {
    let iframe = document.getElementById('print_iframe')
    if (!iframe) {
    iframe.setAttribute('style', 'visibility: hidden')
    iframe.setAttribute('srcdoc', '<html><head><title></title></head><body></body></html>')
    document.body.appendChild(iframe)

    setTimeout(() => resolve(iframe), 50)
    } else {
    iframe.contentWindow.print()
    }
    })
    }
  • print

    1
    2
    3
    4
    5
    6
    7
    function print (element) {
    createPrintIFrame().then(iframe => {
    const printElement = cloneElement(element)
    iframe.contentDocument.body.appendChild(printElement)
    iframe.contentWindow.print()
    }).catch(error => { console.log(`print:${error}`) })
    }
  • cloneElement

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function cloneElement (element) {
    const clone = element.cloneNode()

    const childElements = Array.prototype.slice.call(element.childNodes)
    for (let index = 0; index < childElements.length; index++) {
    clone.appendChild(cloneElement(childElements[index]))
    }

    return clone
    }
  • removeIFrame

    1
    2
    3
    4
    function removeIFrame () {
    let iframe = document.getElementById('print_iframe')
    if(iframe) iframe.remove()
    }
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!

扫一扫,分享到微信

微信分享二维码

~