vue2 实现打印功能

公司erp系统的打印功能是前后端未分离的,由php写的。经常会出现打印很慢很慢,或者卡死导致页面崩溃的问题。所有我优化了一下,改为前端打印。

1.这次打印使用的第三方插件是 print.min.js,print.min.css同学们引入即可

首先我是先将要打印的HTML+css模板写好。分页的地方要加<div class="paging"></div>

const template = `<div class="print-template">
   <div class="printBox" v-for="(item,index) in printArr" :key='index'>
      <div v-for="(m,n) in item.page" :key='n'>
      <!-- 表格 -->
      <table class="assetPrintTable">
        <!-- 表格标题 -->
        <thead>
          <tr class="printBox-title">
            <th>{{item.contactRemark}}</th>
            <th>{{item.system.companyName}}销售单 <br/> <p style="font-size:14px;font- 
                weight:400 !important;"></p></th>
            <th>(页码:{{n+1}}/{{Math.ceil(item.goods.length/16)}})</th>
          </tr>
          <!-- 订单信息 -->
          <tr class="printBox-info">
            <th class="printBox-info-item">
              <span>订单号:</span>
              <span>{{item.billNo}}</span>
            </th>
            <th class="printBox-info-item" style="width: 200px;">
              <span>业务员:</span>
              <span>{{item.salesperson_name}}</span>
            </th>
          </tr>
          <!-- 表头 -->
            <tr class="m-order-list-header-wrap" style="border-top: 1px solid black;">
              <th class="m-order-list-header-item" style="width: 42px;border-left: 1px 
                       solid black;">序号</th>
              <th class="m-order-list-header-item-width" style="width: 150px;">条码</th>
              <th class="m-order-list-header-item-width" style="width: 240px;">商品名称 
              </th>
              <th class="m-order-list-header-item-width" style="width: 59px;">规格</th>
              <th class="m-order-list-header-item-width" style="width: 50px;">单位</th>
              <th class="m-order-list-header-item-width" style="width: 60px;">下单数</th>
              <th class="m-order-list-header-item-width" style="width: 60px;">单价</th>
              <th class="m-order-list-header-item-width" style="width: 70px;">总价</th>
              <th class="m-order-list-header-item-width" style="width: 150px;">备注</th>
            </tr>
        </thead>
        <!-- 列表内容 -->
        <tbody style="border-top: 1px solid black;">
          <tr class="m-order-list-content-item" v-for="(k,num) in m.goods" :key="num">
            <!-- 列表单元格 -->
            <!-- 序号 -->
            <td class="m-order-list-col" style="width:42px;border-left: 1px solid black;">
              {{n*16+num+1}}
            </td>
            <!-- 条码 -->
            <td class="m-order-list-col-width" style="width: 150px;word-break: break-all;">{{k.barCode?k.barCode:k.invNumber}}
            </td>
            <!-- 商品名称 -->
            <td class="m-order-list-col-width" style="width: 240px;text-align: left;">{{k.good_name}}
            </td>
            <!-- 规格 -->
              <td class="m-order-list-col-width" style="width: 59px;">{{k.gs_num}}{{k.mainUnit}}/{{k.spec_unit_name}}
              </td>
            <!-- 单位 -->
            <td class="m-order-list-col-width" style="width: 50px;">{{k.spec_unit_name}}
            </td>
            <!-- 下单数 -->
            <td class="m-order-list-col-width" style="width: 60px;">{{k.qty}}
            </td>
            <!-- 单价 -->
            <td class="m-order-list-col-width" style="width: 60px;">{{k.real_price}}
            </td>
            <!-- 总价 -->
            <td class="m-order-list-col-width" style="width: 70px;">{{k.amount}}
            </td>
{{k.out_change_num}} 
            </td> -->
            <!-- 备注 -->
            <td class="m-order-list-col-width" style="width: 150px;text-align: left;">{{k.description}}
            </td>
          </tr>
        </tbody>
      </table>
      </div>
      <!-- 每个订单渲染分页 -->
      <div class="paging"></div>
    </div>
</div>`;

2.接下来获取打印数据,以及数据处理

    printRender() {
      return new Promise(resolve => {
        const api = "/index.php/scm/test/toPdfMulti_new";
        let obj = {
          id: this.ruturnId,
        };
        zinJSON(api, obj, res => {
          if (res.status == 200) {
            var list = getFirstAvailableValue(ObjectValue("data.order_mains", res), []);
            list.forEach((item, index) => {

             //在这里我对数据做了一下处理,把数据按16条为一个数组,然后打印每个页面就是16条数据
               //这样就不会出现有些时候一条数据分了两页,表格被切断了一样,不美观。

              item.page = [];
              if (item.goods && item.goods.length) {
                for (var k = 0; k < Math.ceil(item.goods.length / 16); k++) {
                  item.page.push({ goods: [] });
                  for (var i = 0; i < 16; i++) {
                    if ((k * 16 + i) >= item.goods.length) {
                      break;
                    }
                    item.page[k].goods.push(item.goods[k * 16 + i]);
                  }
                }
              }
            })
            this.printArr = list;
            resolve();
          } else {
            this.$message.warning(res.msg);
          }
        }, null, 'post')
      })

    },



//数据获取完后,就开始渲染模板

printBox() {
      var that = this;
      if (this.checkTableIdArr.length > 0) {
        this.printRender().then(resolve => {

          //先设置模板为可见状态

          document.querySelector('#printJS-HTML').style.display = 'block';

          //这个focus事件为啥忘记了,好像是和打印的窗口有关,需要添加一下

          const focuser = setInterval(() => window.dispatchEvent(new Event('focus')), 500);
          setTimeout(function () {
            printJS({
              printable: 'printJS-HTML',
              type: 'html',
              css: '/statics/components/printTemplate/printTemplate.css',//这里是模板的css样式引入即可
              style: '@page { size: auto;} .paging{page-break-after: always;}',//这里是分页的关键,渲染到类名为paging时则强制分页。
              scanStyles: false,
              onPrintDialogClose: function () {
                //清除focus事件
                clearInterval(focuser);
                const api = "/index.php/scm/invSo/updatePrintStatus";
              }
            });
            //最后清除dom,不然你的页面会多了这个模板
            document.querySelector('#printJS-HTML').style.display = 'none'
          }, 500)
        });
      } else {
        return this.$message.warning('请选择需要打印的订单!');
      }
    },

3.我们将处理好的数据,传到模板组件中即可

<!-- 打印始 -->
    <div id="printJS-HTML" style="display:none;">
      <print-template :print-arr="printArr"></print-template>
    </div>
    <!-- 打印终 -->

最终实现的效果如下

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值