公司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>
<!-- 打印终 -->
最终实现的效果如下