背景
原生方式打印网页只需执行window.print()
即可,但会打印整个页面
一般需要打印的只是网页的一部分,这里使用创建iframe
的思路实现局部打印
该打印方法只适用于pc端
,移动端的应用实现打印需要支持window.print()
才能使用该方式,一般是蓝牙连接打印机,像安卓原生app调用蓝牙方法
方式等
window.print局部打印
案例使用vue
写法
打印已加载内容
页面中的一部分,如
<div id="printTag">
<div>katsuki</div>
</div>
给一个元素添加点击事件,触发doPrint
doPrint() {
if(this.isPrinting) return
this.isPrinting = true;
let iframe = document.getElementById("print-iframe");
if (!iframe) {
// 初始化
let el = document.getElementById("printTag");
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("<div>" + el.innerHTML + "</div>");
doc.close();
iframe.contentWindow.print();
this.isPrinting = false;
} else {
// 已存在iframe
iframe.contentWindow.print();
this.isPrinting = false;
}
if (navigator.userAgent.indexOf("MSIE") > 0) {
document.body.removeChild(iframe);
}
}
打印请求返回或动态生成内容
若打印内容是请求回来的图片或者动态生成的标签内容,需要延迟等待iframe
加载再执行打印
isReloadImg
为图片重新写入iframe
判断值,解决同名称但内容不同图片的不更新显示问题
若每次返回图片路径不同,则直接替换img
的src
属性即可
<div id="printTag"></div>
给一个元素添加点击事件,触发getPrintImg
getPrintImg() {
// 通过请求获得
this.printImgUrl = data.url;
// 生成img
let el = document.getElementById("printTag");
el.innerHTML = "";
let img = document.createElement("IMG");
img.setAttribute("src", this.printImgUrl);
img.setAttribute("alt", "图片");
el.appendChild(img);
this.isReloadImg = true;
this.doPrint()
},
doPrint() {
if(this.isPrinting) return
this.isPrinting = true;
let iframe = document.getElementById("print-iframe");
if (!iframe) {
// 初始化
let el = document.getElementById("printTag");
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("<div>" + el.innerHTML + "</div>");
doc.close();
// 设置延迟,等iframe加载内容
this.timeout = setTimeout(() => {
iframe.contentWindow.print();
this.isPrinting = false;
this.isReloadImg = false;
clearTimeout(this.timeout);
}, 1000)
} else {
// 已存在iframe,判断是否更新iframe内容
if(this.isReloadImg) {
let el = document.getElementById("printTag");
let doc = iframe.contentWindow.document
doc.write("<div>" + el.innerHTML + "</div>");
doc.close();
this.timeout = setTimeout(() => {
iframe.contentWindow.print();
this.isPrinting = false;
this.isReloadImg = false;
clearTimeout(this.timeout);
}, 1000)
} else {
// 没有重新获取图片时,不需要更新iframe内容
iframe.contentWindow.print();
this.isPrinting = false;
}
}
if (navigator.userAgent.indexOf("MSIE") > 0) {
document.body.removeChild(iframe);
}
}