vue print.js 批量打印功能 [需要打印页面页码张数的] (打印方法一)

批量打印  :

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;
   }
posted @ 2024-01-24 12:03  一封未寄出的信  阅读(2756)  评论(2编辑  收藏  举报