批量打印 :
1.用到print.js 自行安装 安装完成后 引用 import printJS from 'print-js';
2.用到深拷贝
深拷贝代码:(可以将此代码放在一个页面中,对此进行引用即可,例如:放在until文件中,引用代码 import { deepClone } from '@/utils/index')
export function deepClone(source) {
if (!source && typeof source !== 'object') {
throw new Error('error arguments', 'deepClone')
}
const targetObj = source.constructor === Array ? [] : {}
Object.keys(source).forEach(keys => {
if (source[keys] && typeof source[keys] === 'object') {
targetObj[keys] = deepClone(source[keys])
} else {
targetObj[keys] = source[keys]
}
})
return targetObj
}
数据源:
dataSource:[//原数据
{
company:'报表A',
datas:[
{
name:'张三1',
age:10,
money:100
},{
name:'张三2',
age:10,
money:100
},{
name:'张三3',
age:10,
money:100
},{
name:'张三4',
age:10,
money:100
},{
name:'张三5',
age:10,
money:100
}
],
money:10000
},{
company:'报表B',
datas:[
{
name:'李四1',
age:10,
money:100
},{
name:'李四2',
age:11,
money:12010
},{
name:'李四3',
age:11,
money:12010
},{
name:'李四4',
age:11,
money:12010
},{
name:'李四5',
age:11,
money:12010
},{
name:'李四6',
age:11,
money:12010
}
],
money:10000
}
],
转换数据:
[
{
"currentPage": 1,
"datas": [
{
"name": "张三1",
"age": 10,
"money": 100
},
{
"name": "张三2",
"age": 10,
"money": 100
},
{
"name": "张三3",
"age": 10,
"money": 100
},
{
"name": "张三4",
"age": 10,
"money": 100
},
{
"name": "张三5",
"age": 10,
"money": 100
}
],
"company": "报表A",
"money": 10000,
"totalPage": 1
},
{
"currentPage": 1,
"datas": [
{
"name": "李四1",
"age": 10,
"money": 100
},
{
"name": "李四2",
"age": 11,
"money": 12010
},
{
"name": "李四3",
"age": 11,
"money": 12010
},
{
"name": "李四4",
"age": 11,
"money": 12010
},
{
"name": "李四5",
"age": 11,
"money": 12010
}
],
"company": "报表B",
"money": 10000,
"totalPage": 2
},
{
"currentPage": 2,
"datas": [
{
"name": "李四6",
"age": 11,
"money": 12010
}
],
"company": "报表B",
"money": 10000,
"totalPage": 2
}
]
注释:需要数据源转换成为 需要打印的数据,原因是,在打印中,不知道分页的页码,所以,此时是需要通过计算,将页码放入到需要打印的数据中的,
代码展示:
html的代码:
<template> <div class="modalContainer printAsset" ref="modalContainer" id="container" > <table border="1" cellspacing="0" width="1080" height="300" class="printTable" v-for="(items,index) in resultArray" :key="index"> <tr class="tr-box title"> <td colspan="7" align="center" >{{ items.corpName }}</td> </tr> <tr class="title"> <td >参考信息:</td> <td align="center" colspan="4" rowspan="2" class="bigTitle" style="font-family:fangsong; font-weight: bold; font-size:28px;" >记账凭证</td> <td align="right" colspan="2">业务日期:{{ items.singTime }}</td> </tr> <tr class="title"> <td >序号:</td> <td align="right" colspan="4" >附件数:{{ items.attCount}}</td> </tr> <tr class="title" > <td>{{items.year}}年第{{items.period}}期</td> <td align="center" colspan="4">日期:{{ items.singTime }}</td> <td align="right" colspan="2">凭证号:{{ items.voucherGroup }}-{{ items.nos }} ({{ items.currentPage }} / {{items.totalPage}}) </td> </tr> <tr border class="headTitle titleInfo"> <td width="220px" height="30px" class="voucherDesc" align="center" style="width:220px;">摘要</td> <td width="311px" height="30px" class="accountName" align="center">科目</td> <td width="80px" height="30px" class="currency" align="center" >币别</td> <td width="80px" height="30px" class="toRate" align="center" >汇率</td> <td width="115px" height="30px" class="oAmt" align="center" >原币金额</td> <td width="120px" height="30px" class="dAmt" align="center" >借方</td> <td width="120px" height="30px" class="cAmt" align="center" >贷方</td> </tr> <tr v-for="(item,i) in items.datas" :key="i" class="headTitle"> <td width="220px" height="40px" class="voucherDesc" style="width:220px;">{{ item.voucherDesc }}</td> <td width="311px" height="40px" class="accountName">{{ item.accountName }}</td> <td width="80px" height="40px" class="currency">{{ item.currency }}</td> <td width="80px" height="40px" class="toRate">{{ item.toRate }}</td> <td width="115px" height="40px" class="oAmt" align="right">{{ item.oAmt }}</td> <td width="120px" height="40px" class="dAmt" align="right">{{ item.dAmt }}</td> <td width="120px" height="40px" class="cAmt" align="right">{{ item.cAmt }}</td> </tr> <tr class="footerTitle"> <td colspan="5">合计: {{items.sumAmount}}</td> <td align="right"> <span v-if="items.currentPage == items.totalPage" > {{items.sumDAmount}} </span></td> <td align="right"> <span v-if="items.currentPage == items.totalPage" > {{items.sumCAmount}} </span></td> </tr> <tr class="title"> <td height="40px">经办:Kiki</td> <td height="40px">审核:Hedy</td> <td height="40px" colspan="2">过账:{{items.creator}}</td> <td height="40px" colspan="2">出纳:Lena</td> <td height="40px" align="right">制单:{{items.creator }}</td> </tr> </table> </div> </template>脚本代码:
export default { props: { tableDataPrint:{ type:Array, default:[] } } , data(){ return { resultArray:[],//用来打印的数据 } }, created() { }, mounted() { }, methods:{printInt(){ this.tableDataPrint.forEach((item)=>{ item.financeVoucherDetailPrint.forEach((val)=>{ if(/\/$/.test(val.voucherDesc)){ val.voucherDesc = val.voucherDesc.slice(0,-1); } val.voucherDesc = val.voucherDesc.replace(/\/[^\/]*$/, ''); }) }) this.$nextTick(()=>{ this.handleDeal() setTimeout(()=>{ let id = document.getElementById('container'); printJS({ printable:id, type:'html', style: 'table{font-size:12px; width:1080px; font-family:宋体} .titleInfo td{border-top: 2px solid #000; font-size:16px} .titleInfo .voucherDesc{ border-left: 2px solid #000;} .titleInfo .cAmt{border-right: 2px solid #000;} .headTitle .voucherDesc{ border-left: 2px solid #000;} .headTitle .cAmt{border-right: 2px solid #000;} .footerTitle td:nth-of-type(1){border-left: 2px solid #000; border-bottom:2px solid #000} .footerTitle td:nth-of-type(2){border-bottom:2px solid #000} .footerTitle td:nth-of-type(1){font-weight:900} .footerTitle td:nth-of-type(3){border-bottom:2px solid #000;border-right: 2px solid #000;} .printTable{page-break-before:always; border:none;} .bigTitle{font-size:28px;} .tr-box td{ padding-right:24px} .footerTitle td{ height:40px} .title td{ border:none;} .item{height:1120px;margin:0;padding:0;page-break-before:always}', //设置打印时候的样式 scanStyles:false //此处很重要,因为如果此处忽略了,将打印的样式和预览时候的样式将会有出入,比如 预览的宽度和展示的宽度不一致,还有就是设置的样式不生效等问题,所以此处必要
}); },500) }) }, handleDeal(){ let resultArray = []; let dataSource = []; //复制数据源 dataSource = deepClone(this.tableDataPrint); for(var i=0;i<dataSource.length;i++){ let item = {}; for(var j=0;j<dataSource[i].financeVoucherDetailPrint.length;j++){
let lists = []; let multiple = 0; let totalPage = 0;
multiple = parseInt(dataSource[i].financeVoucherDetailPrint.length/5); //dataSource[i].financeVoucherDetailPrint 指向的是最终的数据列 ,展示列数据长度/5 是因为 要求展示每页5条数据,可以根据自己的需求进行调整即可, 将此文档为5 的地方都换成需要自己展示的条数即可 let remainder = dataSource[i].financeVoucherDetailPrint.length%5; if(multiple>0){ for(var k=0;k<multiple;k++){ for(var x=k*5+0;x<k*5+5;x++){ lists.push(dataSource[i].financeVoucherDetailPrint[x]); } totalPage++; item.currentPage = k+1; item.datas = deepClone(lists); item.attCount = dataSource[i].attCount; item.corpName = dataSource[i].corpName; item.creator = dataSource[i].creator; item.nos = dataSource[i].nos; item.period = dataSource[i].period; item.singTime = dataSource[i].singTime; item.sumAmount = dataSource[i].sumAmount; item.sumCAmount = dataSource[i].sumCAmount; item.sumDAmount = dataSource[i].sumDAmount; item.voucherGroup = dataSource[i].voucherGroup; item.year = dataSource[i].year; item.totalPage = totalPage; let itemClone = deepClone(item); resultArray.push(itemClone); lists = []; } if(remainder>0){ item.currentPage = item.currentPage + 1; totalPage++;
let index = multiple*5; for(var y=index;y<index+remainder;y++){ lists.push(dataSource[i].financeVoucherDetailPrint[y]); }
let diff = 5 - remainder; //当不足5条的时候,进行自动补充到5条,有数据的地方是自动展示,剩下的空白 for(let k=0;k<diff;k++){ lists.push({}); } item.datas = deepClone(lists) item.attCount = dataSource[i].attCount; item.corpName = dataSource[i].corpName; item.creator = dataSource[i].creator; item.nos = dataSource[i].nos; item.period = dataSource[i].period; item.singTime = dataSource[i].singTime; item.sumAmount = dataSource[i].sumAmount; item.sumCAmount = dataSource[i].sumCAmount; item.sumDAmount = dataSource[i].sumDAmount; item.voucherGroup = dataSource[i].voucherGroup; item.year = dataSource[i].year; item.totalPage = totalPage; resultArray.push(deepClone(item)); lists = [];
} //在这里更新totalPage if(multiple>0&&remainder>0){ totalPage = multiple+1; let total_ = multiple+1; for(var m = resultArray.length-total_;m<resultArray.length;m++){ resultArray[m].totalPage = totalPage; } } if(multiple>0&&remainder==0){ totalPage = multiple; let total_ = multiple;
for(var m=resultArray.length-total_;m<resultArray.length;m++){ resultArray[m].totalPage = totalPage; }
} totalPage = 0; }else{ if(remainder>0){ item.currentPage = item.currentPage + 1; let index = multiple*5; for(var y=index;y<index+remainder;y++){ lists.push(dataSource[i].financeVoucherDetailPrint[y]); }
let diff = 5 - remainder; for(let k=0;k<diff;k++){ lists.push({}); }
item.datas = deepClone(lists); item.currentPage = 1; item.totalPage = 1;
item.attCount = dataSource[i].attCount; item.corpName = dataSource[i].corpName; item.creator = dataSource[i].creator; item.nos = dataSource[i].nos; item.period = dataSource[i].period; item.singTime = dataSource[i].singTime; item.sumAmount = dataSource[i].sumAmount; item.sumCAmount = dataSource[i].sumCAmount; item.sumDAmount = dataSource[i].sumDAmount; item.voucherGroup = dataSource[i].voucherGroup; item.year = dataSource[i].year; resultArray.push(deepClone(item)); lists = []; } } break; } } this.resultArray = resultArray;//要用来打印的数据 // console.log("原来的数据不用动dataSource",this.dataSource); // console.log("用来打印的数据resultArray",this.resultArray); } } } 样式“: .tr-box{ border-color: transparent; }
.title{ border:none; td{ border:none;} } ::v-deep .printTable { border:none !important; }
::v-deep .headTitle{ td{ &:nth-of-type(1){ width: 220px !important; } } } .titleInfo{ td{ border-top: 2px solid #000; } .voucherDesc{ border-left: 2px solid #000;} .cAmt{border-right: 2px solid #000;} } .headTitle{ .voucherDesc{ border-left: 2px solid #000;} .cAmt{border-right: 2px solid #000;} } .footerTitle{ td{ &:nth-of-type(1){ border-left: 2px solid #000; border-bottom: 2px solid #000; } &:nth-of-type(2){ border-bottom: 2px solid #000; } &:nth-of-type(3){ border-bottom: 2px solid #000; border-right: 2px solid #000; } } } @media print{ ::v-deep .headTitle{ td{ &:nth-of-type(1){ width: 220px !important; } } } // 控制页面自动分页 .page-break{ page-break-after: always; page-break-inside: avoid; } .printAsset { width: 100%; // 表格基本样式 ::v-deep .printTable { width: 100%; border-collapse: collapse; border-spacing: 0; border:none !important; // 实现分页,行不撕裂的关键 tr { page-break-inside: avoid; } // 单元格样式 } }
*{ margin:0; padding:0; } table { counter-reset: section; } .page-number::before{ counter-increment: section; content: "Section " counter(section) ". "; } } @page{ size:auto; margin:0mm; } 标签:vue,name,money,age,js,item,2px,print,border From: https://www.cnblogs.com/rockyjs/p/17984380