记一次原生实现浏览器打印功能
记一次实现浏览器打印功能
刚好遇到项目需要实现浏览器原生打印需求,浏览器原生API window.print()
方法可以满足基础打印需求,同时也会遇到各种各样的问题
打印问题汇总
- 调用
window.print()
打印会打印整个document页面 - 当然也可以用
document.body.innerHTML
来置换页面内容,但是使用框架的小伙伴们就得用window.location.reload()
来刷新页面,用户体验上不是很好,这个问题下方有更优化的打印方案
doPrint() {
const html = document.getElementById('XXX').innerHTML
// 赋值打印的区域,进行打印
window.document.body.innerHTML = html
// 防止样式丢失,添加样式文件
document.body.appendChild(this.getStyle())
// 调用window打印方法
window.print()
// 打印完成后重新加载页面
window.location.reload()
},
getStyle() {
// 获取样式
let linkTag = document.createElement('link')
linkTag.id = 'commonstyle'
linkTag.href = `/XXX/doPrint.css`
linkTag.setAttribute('rel', 'stylesheet')
linkTag.setAttribute('type', 'text/css')
return linkTag
}
- 打印样式添加方式
- 引入css样式:一定要添加
media="print"
<link href="XXX.css" media="print" rel="stylesheet" />
- style使用内联
media
属性
<style media="print">
@page {
// 可以设置打印的css样式
margin: 0;
}
</style>
- 使用
@media print
媒体查询
@media print {
// 内容同上style
}
有没有一种更贴近用户体验的打印方式?
优化打印效果
- 不使用 document.body.innerHTML 来置换页面内容,改为生成
iframe
打印
doPrint() {
try {
// 获取需要打印区域的id
const oldStr = document.getElementById('需要打印区域Id')
let newStr = document.createElement('IFRAME')
document.body.appendChild(newStr)
let doc = newStr.contentWindow.document
// 这里可以自定义样式
doc.write(
`<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
<link rel="stylesheet" href="/XXX/doPrint.css" type="text/css">
</head>
<!--zoom缩放页面适配打印纸张大小的效果-->
<body style="zoom: 0.7;">
<div id="printchart">
${oldStr.innerHTML}
</div>
</body>
</html>`
)
doc.close()
// 为iframe添加Id方便后续操作
newStr.setAttribute('id', 'printIframe')
newStr.setAttribute('frameborder', '0')
newStr.setAttribute(
'style',
'position:absolute;width:0;height:0;left:-500px;top:-500px;'
)
newStr.contentWindow.focus()
newStr.contentWindow.onload = function () {
newStr.contentWindow.print()
// 去除iframe元素
document.body.removeChild(newStr)
}
} catch (error) {
console.log(error)
}
}
总结
无论是 document.body.innerHTML
置换页面内容,还是生成 iframe
实现打印,满足项目和业务需求才是最终目标,不满足的情况下调用一些现有的js库实现打印功能也可以,本文更多的是记录
如果大家有更好的方案,欢迎留言交流!!!
转载自:https://juejin.cn/post/7231015741453402149