赞
踩
之前有需求,一键生成pdf,下载到本地,详见;http://t.csdn.cn/5GzSx。
本次的需求基于上次有升级,上次是直接生成pdf,只是为了看。这次的需求是预览账单并保存为pdf,保存的pdf是可以选中复制的,那么之前的方案就不能用了。
网上有很多方法,但是都或多或少存在问题,大部分的都是先生成图片,然后再生成pdf文件。不可复制,还容易失真。后面尝试了多种方式后,发现了一个宝藏,直接利用浏览器的打印功能。一语点醒梦中人呀,不仅可以预览,还可以保存为pdf,还可以选中复制。
后面尝试了写一写,发现存在一些兼容问题和样式问题,而且需要处理选定固定的dom去保存。基于此,去调研了一下,找到一个比较好用的库,兼容性挺好,样式也能保留。— print-js:https://printjs.crabbly.com/
const print = () => {
let printHtml = printRef.value.innerHTML
let oldHtml = window.document.body.innerHTML
window.document.body.innerHTML = printHtml
// 调用打印功能
window.print()
window.document.body.innerHTML = oldHtml
return false
}
const print = () => { let iframe = document.getElementById('print-iframe') // 防止多次重建iframe if (!iframe) { var el = document.getElementById('print-content') iframe = document.createElement('IFRAME') var 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('<style media="print">@page {size: auto; margin: 0 mm;}</style>') // 解决出现页眉页脚和路径的问题 doc.write('<div style="margin: 40px auto;">' + printHtml + '</div>') doc.close() iframe.contentWindow.focus() } setTimeout(function () { iframe.contentWindow.print() }, 50) // 解决第一次样式不生效的问题 if (navigator.userAgent.indexOf('MSIE') > 0) { document.body.removeChild(iframe) } }
看了一下源码,实际使用的还是iframe方式,里面做了很多兼容
import print from 'print-js' print({ printable: 'print-content', // header: '账单', type: 'html', // maxWidth: 800, // headerStyle: 'font-size:6px;font-weight:600;text-align:center;padding:15px 0 10px 0;',// 标题设置 // properties: [],// json数据元 // gridHeaderStyle: 'font-size:6px;font-weight:400;height:40px;line-height:40px;border: 1px solid #ccc;padding:3px 5px 3px 5px;text-align:center;',// json格式表头样式 // gridStyle: 'font-size:1px;font-weight:200;border: 1px solid #ccc;padding:3px 5px 3px 5px;text-align:center;',// json各式表哥央视 // scanStyles: false,// 不适用默认样式 // repeatTableHeader: false,// 打印json表头只显示在第一页 // style: '@page{size:auto;margin: 0cm 1cm 0cm 1cm;}',// 去除页眉页脚 // font_size: 30, targetStyles: ['*'], // 使用dom的所有样式,很重要 ignoreElements: ['no-print','bc','gb'] })
因为我的页面最开始对账单是不显示的,状态是’display: none’,预览打印出来的就是空白,解决办法:在打印前后处理dom状态
const dom = document.getElementById('print-content')
dom?.setAttribute('style', 'display: block')
// ... 调用打印
dom?.setAttribute('style', 'display: none')
完整代码
import print from 'print-js' const handlePrint = () => { const dom = document.getElementById('print-content') dom?.setAttribute('style', 'display: block') print({ printable: 'print-content', // header: '账单', type: 'html', // maxWidth: 800, // headerStyle: 'font-size:6px;font-weight:600;text-align:center;padding:15px 0 10px 0;',// 标题设置 // properties: [],// json数据元 // gridHeaderStyle: 'font-size:6px;font-weight:400;height:40px;line-height:40px;border: 1px solid #ccc;padding:3px 5px 3px 5px;text-align:center;',// json格式表头样式 // gridStyle: 'font-size:1px;font-weight:200;border: 1px solid #ccc;padding:3px 5px 3px 5px;text-align:center;',// json各式表哥央视 // scanStyles: false,// 不适用默认样式 // repeatTableHeader: false,// 打印json表头只显示在第一页 // style: '@page{size:auto;margin: 0cm 1cm 0cm 1cm;}',// 去除页眉页脚 font_size: '', // 解决本来的font-size 不生效问题 targetStyles: ['*'], // 使用dom的所有样式,很重要 ignoreElements: ['no-print','bc','gb'] }) dom?.setAttribute('style', 'display: none') }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。