前端实现浏览器打印、打印预览功能

11,772 阅读1分钟

原生H5场景

  1. 方法一:window.print()

    window.print();会弹出打印对话框,打印的是window.document.body.innerHTML中的内容,如果想要打印局部页面内容,则得先隐藏不必打印的内容,或截取需要打印的内容覆盖整个页面。

    • 隐藏不必打印的内容:
    <body>
    <p class="non-print">no print1</p>
    
    <h1>打印标题</h1>
    <p>打印内容~~</p>
    
    <button class="non-print" type="button" onclick="doPrint()">打印</button>
    <p class="non-print">no print2</p>
    </body>
    
    <script>
    function doPrint() {
        let nonPrints = document.getElementsByClassName('non-print');
        for(let i = 0; i < nonPrints.length; i++){
            nonPrints[i].style.display = 'none'
        }
        window.print();
    }
    </script>
    
    • 截取需要打印的内容覆盖整个页面:
      <body>
      <p>no print1</p>
      
      <!--startprint-->
      <h1>打印标题</h1>
      <p>打印内容~~</p>
      <!--endprint-->
      
      <button type="button" onclick="doPrint()">打印</button>
      <p>no print2</p>
      </body>
      
      <script>
          function doPrint() {
              bodyhtml=window.document.body.innerHTML;
              startprint="<!--startprint-->";
              endprint="<!--endprint-->";
              printhtml=bodyhtml.substr(bodyhtml.indexOf(startprint)+17);
              printhtml=printhtml.substring(0,printhtml.indexOf(endprint));
              window.document.body.innerHTML=printhtml;
              window.print();
          }
      </script>
      
  • 方法二:采用JQuery插件:能快捷地选择打印的选择器,或从打印中排除不需要的选择器
    • 插件1:jQuery.print.js

      • 能快速根据选择器进行相应打印
      • 示例代码: 在vue中使用
      // 在/public的index.html中引入print插件
      <script src="/js/jQuery.print.min.js"></script>
      // Print.vue
      <template>
              <div id="print-details">
                      <div id="prints" >
                              // 打印内容
                      /div>
                      <div @click="printBtn" >打印</div>
              </div>
      </template>
      <script>
      // ……
      methods: {
              printBtn(){
                      let _this = this;
                      setTimeout(()=>{
                              $("#prints").print({
                                      /*options*/
                                      globalStyles: true,
                                      mediaPrint: false,
                                      stylesheet: null,
                                      noPrintSelector: ".no-print",
                                      iframe: true,
                                      append: null,
                                      prepend: null,
                                      manuallyCopyFormValues: true,
                                      timeout: 750,
                                      title: null,
                                      doctype: '<!doctype html>',
                                      deferred: $.Deferred().done(function(){
                                              // window.onbeforeprint();
                                              // window.onafterprint();
                                              // 打印弹框关闭后自动返回订单列表
                                              _this.goBack();
                                      })//回调函数
                               });
                      }, 300)
              },
      }
      // ……
      </script>
      <style lang="scss">
      /* 样式将只应用于打印 */  
      @media print {   
              .content-title{
                      width: 100%;
                      display: flex;
                      justify-content: space-between;
                      padding: 0 8px;
              }
              .content-bar-name{
                      display: flex;
                      justify-content: space-between;
                      background: #FFF;
                      padding: 0 10px;
                      font-size: 16px;
              } 
      }
      </style>
      
    • 插件2:jquery.print-preview.js

      • 能快速根据选择器进行相应打印
      • 提供打印前预览功能
      • 注意:浏览器打印事件无法监听是否执行的是打印确定还是取消事件

        以下onbeforeprint与onafterprint 并不能实现所要事件区别效果,无论是否打印,两个事件都会执行

      var beforePrint = function() {
          console.log('Functionality to run before printing.');
      };
      
      var afterPrint = function() {
          console.log('Functionality to run after printing');
      };
      
      if (window.matchMedia) {
          var mediaQueryList = window.matchMedia('print');
          mediaQueryList.addListener(function(mql) {
              if (mql.matches) {
                  beforePrint();
              } else {
                  afterPrint();
              }
          });
      }
      
      window.onbeforeprint = beforePrint;
      window.onafterprint = afterPrint;
      

Vue场景

批量打印

原理:与单一打印并没有不同,同样是将打印单遍历显示在打印区域中,需要注意的地方是打印样式,借助@media print 进行微调处理