浏览器原生 API window.print()
可以用于打印当前窗口(window.document)视图内容。调用此方法会产生一个打印预览弹框,用户可以根据具体设置来得到打印结果。
打印样式
默认情况下,基于页面上的内容,会将元素,布局和样式都进行打印;
如果仅想在打印上设置特殊样式,可以通过以下方式:
F1、使用打印样式表:
<link href=“print.css” media=“print” rel=“stylesheet” />
F2、使用媒介查询:
@media print { div{ font-family: 'SimSun'; } }
F3、使用内联 media 属性:
<style media="print"> div{ font-family: 'SimSun'; } </style>
默认情况下,元素的背景色不会被打印,可通过设置属性来支持:
div{ // Chrome、Safari 等 webkit 浏览器内核 -webkit-print-color-adjust: exact; // 火狐 print-color-adjust: exact; color-adjust: exact; }
打印指定区域内容
F1、通过开始、结束标记(startprint、endprint)来打印
<button onclick="doPrint()">打印</button> <!--startprint--> <div id="printcontent" style="display:none"> ${printContentBody} </div> <!--endprint--> <script type='text/javascript'> function doPrint() { bdhtml=window.document.body.innerHTML; sprnstr="<!--startprint-->"; //开始打印标识字符串有17个字符 eprnstr="<!--endprint-->"; //结束打印标识字符串 prnhtml=bdhtml.substr(bdhtml.indexOf(sprnstr)+17); //从开始打印标识之后的内容 prnhtml=prnhtml.substring(0,prnhtml.indexOf(eprnstr)); //截取开始标识和结束标识之间的内容 window.document.body.innerHTML=prnhtml; //把需要打印的指定内容赋给body.innerHTML window.print(); //调用浏览器的打印功能打印指定区域 window.document.body.innerHTML=bdhtml;//重新给页面内容赋值; return false; } </script>
<button onclick="doPrint2()">打印</button> <div id="printcontent" style="display:none"> ${printContentBody} </div> <script type='text/javascript'>
function doPrint2(){ if(getExplorer() == "IE"){ pagesetup_null(); } //根据div标签ID拿到div中的局部内容 bdhtml=window.document.body.innerHTML; var jubuData = document.getElementById("printcontent").innerHTML; //把获取的 局部div内容赋给body标签, 相当于重置了 body里的内容 window.document.body.innerHTML= jubuData; //调用打印功能 window.print(); window.document.body.innerHTML=bdhtml;//重新给页面内容赋值; return false; } function pagesetup_null(){ var hkey_root,hkey_path,hkey_key; hkey_root="HKEY_CURRENT_USER"; hkey_path="\\Software\\Microsoft\\Internet Explorer\\PageSetup\\"; try{ var RegWsh = new ActiveXObject("WScript.Shell"); hkey_key="header"; RegWsh.RegWrite(hkey_root+hkey_path+hkey_key,""); hkey_key="footer"; RegWsh.RegWrite(hkey_root+hkey_path+hkey_key,""); }catch(e){} } function getExplorer() { var explorer = window.navigator.userAgent ; //ie if (explorer.indexOf("MSIE") >= 0) { return "IE"; } //firefox else if (explorer.indexOf("Firefox") >= 0) { return "Firefox"; } //Chrome else if(explorer.indexOf("Chrome") >= 0){ return "Chrome"; } //Opera else if(explorer.indexOf("Opera") >= 0){ return "Opera"; } //Safari else if(explorer.indexOf("Safari") >= 0){ return "Safari"; } } </script>
监听打印前后事件
通过监听打印前后事件,对不需要进行打印的元素进行隐藏和放开隐藏。
<input type="button" value="打印此页面" onclick="doPrint()" />
<script>
const doPrint= () => { window.print(); }
window.onbeforeprint = function() {
document.getElementById('title').style.display = 'none';
}
window.onafterprint = function() {
document.getElementById('title').style.display = 'block';
}
</script>
上面的方式都在当前窗口进行打印,并且都需要更改 document.body 内容,这会出现视图切换,带来的体验不是太好。
F3、通过动态创建iframe来打印,此方法不影响当前视窗的内容展示。
这里要注意判断iframe是否存在,防止反复使用时,iframe重复创建消耗内存
<button onclick="doPrint3()">打印</button>
<div id="printcontent" style="display:none"> 这里可以自己填充打印内容 </div>
<script type='text/javascript'> function doPrint3(){ //判断iframe是否存在,不存在则创建iframe var iframe=document.getElementById("print-iframe"); if(!iframe){ var el = document.getElementById("printcontent"); 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: 0mm;}</style>'); //解决出现页眉页脚和路径的问题 doc.write('<div>' + el.innerHTML + '</div>'); doc.close(); iframe.contentWindow.focus(); } //解决第一次样式不生效的问题 setTimeout(function(){ iframe.contentWindow.print(); },50) if (navigator.userAgent.indexOf("MSIE") > 0){ document.body.removeChild(iframe); } } </script>
值得注意的是,iframe 是一个新的 window 窗口,不会复用当前窗口的样式,需要为 iframe 注入打印内容所需的样式。
打印设置
设置打印布局
@media print {
@page {
/* 纵向展示(高度展示内容更多) */
/* size: portrait; */
/* 横向(宽度展示内容更大) */
size: landscape;
/* 打印的边距 上右下左 */
margin: 1cm 2cm 1cm 2cm;
}
}
注意,一旦设置为 size: landscape,在打印时将不能切换展示模式,包括纸张类的设置。
更改分页
强行插入分页
page-break-before( after ) 用于设置元素前( 后 )的分页行为,可取值:
* auto默认值。如果必要则在元素前插入分页符。
* always在元素前插入分页符。
* avoid避免在元素前插入分页符。
* left在元素之前足够的分页符,一直到一张空白的左页为止。
* right在元素之前足够的分页符,一直到一张空白的右页为止。
* inherit规定应该从父元素继承 page-break-before 属性的设置。
page-break-inside设置元素内部的分页行为。取值如下:
* auto默认。如果必要则在元素内部插入分页符。
* avoid避免在元素内部插入分页符。
* inherit规定应该从父元素继承 page-break-inside 属性的设置。
orphans设置当元素内部发生分页时必须在页面底部保留的最少行数。
widows设置当元素内部发生分页时必须在页面顶部保留的最少行数。
@page
@page 规则用于在打印文档时修改某些CSS属性。你不能用@page规则来修改所有的CSS属性,而是只能修改margin,orphans,widow 和 page breaks of the document。对其他属性的修改是无效的。
@page {
/* auto (浏览器控制)、landscape (横向)、portrait(竖向)*/
size:A4 portrait;
margin: 0; // 可以控制打印布局(四周边距)
margin-top:0; //去除页眉
margin-bottom:0; //去除页脚
}
/*
需要双面打印的时候,通常会用到,对左页和右页设置不同的样式
通过分别设置左页和右页不同的左右页面距,为装订边留出更多的空间
*/
@page :left {
margin-left: 2.5cm;
margin-right: 2.7cm;
}
@page :right{
margin-left: 2.7cm;
margin-right: 2.5cm;
}
end.