(本文所有打印方式最终都是调用 window.print() 来打印)
项目需要一个 Web 打印功能,要求也很简单,就是打印一些查询到的表单、表格数据。
最简单的打印方式:
window.print();
window.print() 是原生方法,主流浏览器都可用,调用系统打印功能,打印当前页面。
存在的问题:
- 会打印当前页面所有内容,而很多都不需要;
- 打印没有预览(Chrome 除外),打印前都不知道会打印什么;
- 打印页面不好设计、动态填充数据。
方式一:@media print
CSS 样式默认是显示器 @media screen ,而显示器(screen)和打印机(printer)是两种设备,在显示器中看到的样式,打印出来可能会完全不同。
显示器使用像素 px,而打印机使用毫米 mm、厘米 cm、英寸 in、磅 pt(1/72 英寸)。
可以专门设计一套样式,作为打印样式。
参考: https://www.html.cn/archives/4731 https://www.cnblogs.com/ylz-blog/p/5260894.html
引入文件时:
<link rel="stylesheet" href="print.css" media="print" />
或者,在通用样式文件中:
/* .css 中 */@media print {.print-content {display: block;}.screen-content {display: none;}}@media print .print-content {display: block;}
或者,在 import 时:
/* .css 文件中*/@import url(print-style.css) print;@media print {@import "print-style.css";body {font-size:8pt;}}
<!-- .html 文件中 --><style type="text/css">@import url(print-style.css) print;</style>
或者,在 html 文件中:
<style media="print">.print-content {display: block;}</style><p media="print" >网页上看不见,打印时可见</p>
使用 @page 设置打印页面属性,如页眉页脚、纸张大小、方向、页边距、分页等。
/* .css 中*/@page :pseudo-class {size: A4 landscape;margin:2cm;}@media print {@page:right{@bottom-left {margin: 10pt 0 30pt 0;border-top: .25pt solid #666;content: "Our Cats";font-size: 9pt;color: #333;}@bottom-right {margin: 10pt 0 30pt 0;border-top: .25pt solid #666;content: counter(page);font-size: 9pt;}@top-right {content: string(doctitle);margin: 30pt 0 10pt 0;font-size: 9pt;color: #333;}}}
方式二:页面替换
原理:
将页面中不需要打印的部分去掉,替换为需要打印的部分,然后用 window.print() 打印整个页面
在 html 中做标记(开始结束点,ID),哪些可以打印
<!-- html --><!--startprint--><div id="printcontent" style="display:none">打印内容</div><!--endprint-->
然后在 js 中找到需要打印的部分,用此替换整个页面
// js// 用开始结束标记function doPrint() {let bdhtml=window.document.body.innerHTML;let sprnstr="<!--startprint-->"; //开始打印标识字符串有17个字符let eprnstr="<!--endprint-->"; //结束打印标识字符串let prnhtml=bdhtml.substr(bdhtml.indexOf(sprnstr)+17); //从开始打印标识之后的内容prnhtml=prnhtml.substring(0,prnhtml.indexOf(eprnstr)); //截取开始标识和结束标识之间的内容window.document.body.innerHTML=prnhtml; //把需要打印的指定内容赋给body.innerHTMLwindow.print(); //调用浏览器的打印功能打印指定区域window.document.body.innerHTML=bdhtml;//重新给页面内容赋值;return false;}// 用 id 选取function doPrint2(){bdhtml=window.document.body.innerHTML;let jubuData = document.getElementById("printcontent").innerHTML;window.document.body.innerHTML= jubuData;window.print();window.document.body.innerHTML=bdhtml;//重新给页面内容赋值;return false;}
存在的问题:
执行 doPrint() 方法后,页面显示内容产生了变化,并且在之后 HTML 虽然还原回去了,但样式可能会发生变化,form 表单也会失效,和原先的页面不一样了。
方式三:iframe
// jsfunction doPrint3(){//判断iframe是否存在,不存在则创建iframevar 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("<LINK rel="stylesheet" type="text/css" href="css/print.css">");doc.write('<div>' + el.innerHTML + '</div>');doc.close();iframe.contentWindow.focus();}iframe.contentWindow.print();if (navigator.userAgent.indexOf("MSIE") > 0){document.body.removeChild(iframe);}}
方式四:onbeforeprint, onafterprint 事件
onbeforeprint, onafterprint 打印前、打印后触发的事件。
HTML 中 :
<!-- html --><body onbeforeprint="myScript1" onafterprint="myScript2"></body><body><div onbeforeprint="myScript1" onafterprint="myScript2"></div></body>
JS 中:
// jswindow.onbeforeprint=function(){myScript1};window.onafterprint=function(){myScript2};// 或者window.addEventListener("beforeprint", myScript1);window.addEventListener("onafterprint", myScript2);
