前言
当某些甲方爸爸有浏览器打印需求时,项目中可以使用iframe标签来实现此功能。
打印
总所周知 window.print
可以打印整个页面,但此方法想局部打印会很麻烦,先是重新设置body内容,打印完之后还得还原页面,导致页面需要重新渲染,用户体验不好。
iframe的特点是不影响页面布局,它能够将另一个 HTML 页面嵌入到当前页面中。但是局部打印所使用到的css样式需要另外写一份到iframe里。
<div id="printer-content">
<table border="1" cellpadding="0" cellspacing="0">
<tr>
<th>表头</th>
<th>表头</th>
</tr>
<tr>
<td>内容</td>
<td>内容</td>
</tr>
<tr>
<td>内容</td>
<td>内容</td>
</tr>
</table>
<button onclick="toPrint()">打印</button>
</div>
<script>
function toPrint() {
if (!(window).ActiveXObject || "ActiveXObject" in window) { //是否ie
removeIeHeaderFooter();
}
//局部打印的内容
let printHtml = document.getElementById('printer-content').outerHTML;
let iframe = document.createElement("iframe"); //创建iframe节点
iframe.setAttribute('style', 'position:absolute;width:0px;height:0px;left:-500px;top:-500px;'); //给节点添加属性
document.getElementsByTagName("body")[0].appendChild(iframe); //把iframe节点挂载到body下
let doc = iframe.contentDocument || iframe.contentWindow.document;
// 样式不能忘!
let css = `<style>
th{padding: 8px 10px;font-size: 600;font-size: 16px;}
td {padding: 8px 10px;font-size: 600;color: black;font-size: 16px;}
#printer-content{ padding-top:30px;}
@media print {@page {size: auto;margin: 0;}}
</style>`
let str = css + printHtml
doc.write(str); //往iframe节点里加内容
iframe.contentWindow.focus();
iframe.contentWindow.print(); //打印
doc.close();
document.body.removeChild(iframe); //删除iframe节点
}
//去除ie页眉页脚
function removeIeHeaderFooter() {
let hkey_path;
hkey_path = "HKEY_CURRENT_USER\\Software\\Microsoft\\Internet Explorer\\PageSetup\\";
try {
let RegWsh = new ActiveXObject("WScript.Shell");
RegWsh.RegWrite(hkey_path + "header", "");
RegWsh.RegWrite(hkey_path + "footer", "");
} catch (e) { }
}
</script>
扩展
还有一种打印方法是通过canvas把dom转换为图片添加入iframe里,本人浅试了一下是可以实现打印需求的,需要注意canvas打印图片的大小,如果图片大小控制不当,打印出来的内容可能会模糊。