批量打印 :
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.$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.data);
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].datas.length/5); //dataSource[i].datas指向的是最终的数据列 ,展示列数据长度/5 是因为 要求展示每页5条数据,可以根据自己的需求进行调整即可, 将此文档为5 的地方都换成需要自己展示的条数即可
let remainder = dataSource[i].datas.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].datas[x]);
}
totalPage++;
item.currentPage = k+1;
item.datas = deepClone(lists);
item.money= dataSource[i].money;
item.name= dataSource[i].name;
item.age= dataSource[i].age;
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].datas[y]);
}
let diff = 5 - remainder; //当不足5条的时候,进行自动补充到5条,有数据的地方是自动展示,剩下的空白
for(let k=0;k<diff;k++){
lists.push({});
}
item.datas = deepClone(lists)
item.money= dataSource[i].money;
item.name= dataSource[i].name;
item.age= dataSource[i].age;
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].datas[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.money= dataSource[i].money;
item.name= dataSource[i].name;
item.age= dataSource[i].age;
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;
}