(本文所有打印方式最终都是调用 window.print() 来打印)

项目需要一个 Web 打印功能,要求也很简单,就是打印一些查询到的表单、表格数据。

最简单的打印方式:

  1. window.print();

window.print() 是原生方法,主流浏览器都可用,调用系统打印功能,打印当前页面。

存在的问题

  1. 会打印当前页面所有内容,而很多都不需要;
  2. 打印没有预览(Chrome 除外),打印前都不知道会打印什么;
  3. 打印页面不好设计、动态填充数据。

使用插件更方便:https://www.yuque.com/kiniroalice/note-front/erzae5

方式一:@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

引入文件时:

  1. <link rel="stylesheet" href="print.css" media="print" />

或者,在通用样式文件中:

  1. /* .css 中 */
  2. @media print {
  3. .print-content {
  4. display: block;
  5. }
  6. .screen-content {
  7. display: none;
  8. }
  9. }
  10. @media print .print-content {
  11. display: block;
  12. }

或者,在 import 时:

  1. /* .css 文件中*/
  2. @import url(print-style.css) print;
  3. @media print {
  4. @import "print-style.css";
  5. body {
  6. font-size:8pt;
  7. }
  8. }
  1. <!-- .html 文件中 -->
  2. <style type="text/css">
  3. @import url(print-style.css) print;
  4. </style>

或者,在 html 文件中:

  1. <style media="print">
  2. .print-content {
  3. display: block;
  4. }
  5. </style>
  6. <p media="print" >网页上看不见,打印时可见</p>

使用 @page 设置打印页面属性,如页眉页脚、纸张大小、方向、页边距、分页等。

  1. /* .css 中*/
  2. @page :pseudo-class {
  3. size: A4 landscape;
  4. margin:2cm;
  5. }
  6. @media print {
  7. @page:right{
  8. @bottom-left {
  9. margin: 10pt 0 30pt 0;
  10. border-top: .25pt solid #666;
  11. content: "Our Cats";
  12. font-size: 9pt;
  13. color: #333;
  14. }
  15. @bottom-right {
  16. margin: 10pt 0 30pt 0;
  17. border-top: .25pt solid #666;
  18. content: counter(page);
  19. font-size: 9pt;
  20. }
  21. @top-right {
  22. content: string(doctitle);
  23. margin: 30pt 0 10pt 0;
  24. font-size: 9pt;
  25. color: #333;
  26. }
  27. }
  28. }

方式二:页面替换

原理:
将页面中不需要打印的部分去掉,替换为需要打印的部分,然后用 window.print() 打印整个页面

参考: https://www.cnblogs.com/30go/p/9788990.html

在 html 中做标记(开始结束点,ID),哪些可以打印

  1. <!-- html -->
  2. <!--startprint-->
  3. <div id="printcontent" style="display:none">
  4. 打印内容
  5. </div>
  6. <!--endprint-->

然后在 js 中找到需要打印的部分,用此替换整个页面

  1. // js
  2. // 用开始结束标记
  3. function doPrint() {
  4. let bdhtml=window.document.body.innerHTML;
  5. let sprnstr="<!--startprint-->"; //开始打印标识字符串有17个字符
  6. let eprnstr="<!--endprint-->"; //结束打印标识字符串
  7. let prnhtml=bdhtml.substr(bdhtml.indexOf(sprnstr)+17); //从开始打印标识之后的内容
  8. prnhtml=prnhtml.substring(0,prnhtml.indexOf(eprnstr)); //截取开始标识和结束标识之间的内容
  9. window.document.body.innerHTML=prnhtml; //把需要打印的指定内容赋给body.innerHTML
  10. window.print(); //调用浏览器的打印功能打印指定区域
  11. window.document.body.innerHTML=bdhtml;//重新给页面内容赋值;
  12. return false;
  13. }
  14. // 用 id 选取
  15. function doPrint2(){
  16. bdhtml=window.document.body.innerHTML;
  17. let jubuData = document.getElementById("printcontent").innerHTML;
  18. window.document.body.innerHTML= jubuData;
  19. window.print();
  20. window.document.body.innerHTML=bdhtml;//重新给页面内容赋值;
  21. return false;
  22. }

存在的问题
执行 doPrint() 方法后,页面显示内容产生了变化,并且在之后 HTML 虽然还原回去了,但样式可能会发生变化,form 表单也会失效,和原先的页面不一样了。

方式三:iframe

  1. // js
  2. function doPrint3(){
  3. //判断iframe是否存在,不存在则创建iframe
  4. var iframe=document.getElementById("print-iframe");
  5. // 或者在创建前,先删除
  6. if(!iframe){
  7. var el = document.getElementById("printcontent");
  8. iframe = document.createElement('IFRAME');
  9. var doc = null;
  10. iframe.setAttribute("id", "print-iframe");
  11. iframe.setAttribute('style', 'position:absolute;width:0px;height:0px;left:-500px;top:-500px;');
  12. document.body.appendChild(iframe);
  13. doc = iframe.contentWindow.document;
  14. //这里可以自定义样式
  15. //doc.write("<LINK rel="stylesheet" type="text/css" href="css/print.css">");
  16. doc.write('<div>' + el.innerHTML + '</div>');
  17. doc.close();
  18. iframe.contentWindow.focus();
  19. }
  20. iframe.contentWindow.print();
  21. if (navigator.userAgent.indexOf("MSIE") > 0){
  22. document.body.removeChild(iframe);
  23. }
  24. }

方式四:onbeforeprint, onafterprint 事件

onbeforeprint, onafterprint 打印前、打印后触发的事件。

HTML 中 :

  1. <!-- html -->
  2. <body onbeforeprint="myScript1" onafterprint="myScript2"></body>
  3. <body>
  4. <div onbeforeprint="myScript1" onafterprint="myScript2"></div>
  5. </body>

JS 中:

  1. // js
  2. window.onbeforeprint=function(){myScript1};
  3. window.onafterprint=function(){myScript2};
  4. // 或者
  5. window.addEventListener("beforeprint", myScript1);
  6. window.addEventListener("onafterprint", myScript2);