vue

vue实战(11)——vue+element UI实现表格数据导

2019-03-27  本文已影响1142人  wayne1125

一、应用场景

按照需求导出功能分为勾选批量导出及按照查询结果导出,考虑到接口操作导出的复杂性,因此实现了js控制导出的功能


导出功能截图

二、安装相关依赖

cnpm install --save xlsx file-saver

具体插件使用参考https://github.com/SheetJS/js-xlsxhttps://github.com/eligrey/FileSaver.js

三、实现代码

考虑到多处使用导出功能,所以封装成公用组件形式
1、列表页

<template>
<div class="add-button">
      <span @click="exportExcelSelect">按勾选导出</span>
      <span @click="exportExcel">按查询结果导出</span>
 </div>
  <export-excel-common ref="myChild" :exportExcelInfo="exportExcelInfo" :tableData="tableAllData" :exportExcelArry="exportExcelArry"></export-excel-common>
</template>
<script>
  export default {
    components: {
      exportExcelCommon
    },
    data() {
      return {
        //导出表格字段及formatter信息
        exportExcelArry: [{
          prop: 'phoneNumber',
          label: '用户手机号',
          formatterFlag: false
        },{
          prop: 'userFundRedEnvelopRecord.status',
          label: '状态',
          formatterFlag: true,
          formatterType: 'common-type',
          formatterInfo: [{value: 0,label: '未完成'},{value: 1,label: '已完成'}]
        },{
          prop: 'userFundRedEnvelopRecord.name',
          label: '任务名称',
          formatterFlag: false
        }],
        //导出excel表格id及excel名称
        exportExcelInfo: {
          excelId: 'record-table',
          excelName: '红包获取记录.xlsx'
        },
        //需要导出的table数据
        tableAllData: [],
  },
  methods {
    exportExcelSelect () {
        if(this.selectListArry.length == 0){
          global.message('请勾选操作项')
          return;
        }
        //将选中项传给this. tableAllData
        this.tableAllData = this.selectListArry
        //需要延时调导出方法,为了等待数据初始化到列表中
        setTimeout(()=>{
          this.$refs.myChild.exportExcel();
        },500)
      },
      exportExcel () {
        this.initData('export-excel')
        //获取到表格数据的值并赋给this.tableAllData
        //同样延时调导出方法,需在initData('export-excel')方法执行成功后调this.$refs.myChild.exportExcel();方法
      }
  }
}

2、通用组件ExportExcelCommon.vue

<template>
   <transition name="fadeIn">
       <div v-show='false'>
           <el-table :id="exportExcelInfo.excelId" :data="tableData" highlight-current-row style="width: 100%">
             <template v-for="(item,index) in exportExcelArry">
         <el-table-column v-if="!item.formatterFlag" :prop="item.prop" :label="item.label">
         </el-table-column>
         <el-table-column v-else :prop="item.prop" :label="item.label">
             <template slot-scope="scope">
               <span>{{formatter(scope.row[item.prop],item,scope.row,item.prop)}}</span>
           </template>
         </el-table-column>
       </template>
     </el-table>
       </div>
   </transition>
</template>
<script>
 import FileSaver from 'file-saver'
 import XLSX from 'xlsx'
   export default {
       props: {
           exportExcelInfo: {
               type: Object,
               default: {}
           },
           exportExcelArry: {
       type: Array,
       default: []
     },
           tableData: {
       type: Array,
       default: []
     },
       },
       methods: {
         //excel导出
         exportExcel () {
       var xlsxParam = { raw: true } // 导出的内容只做解析,不进行格式转换
        var wb = XLSX.utils.table_to_book(document.querySelector('#'+this.exportExcelInfo.excelId),xlsxParam)
        var wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: true, type: 'array' })
        try {
           FileSaver.saveAs(new Blob([wbout], { type: 'application/octet-stream' }), this.exportExcelInfo.excelName)
        } catch (e) { 
          if (typeof console !== 'undefined') console.log(e, wbout) 
        }
        return wbout
     },
     //表格formatter数据格式化
         formatter (value,item,row,prop) {
           //针对table中item多层对象层级的情况
           if(prop.indexOf('.') > 0){
         let temp = prop.split('.')
         //item中嵌套两层
         if(temp.length == 2){
           let temp = prop.split('.')
           if(item.formatterType == 'common-type'){  //通用类型转换
             let arry = item.formatterInfo
             for(let i in arry){
               if(arry[i].value == row[temp[0]][temp[1]]){
                 return arry[i].label
               }
             }
           } else if(item.formatterType == 'time-type'){ //时间标准格式化
             if(!global.isNull(row[temp[0]][temp[1]])){
               return row[temp[0]][temp[1]].substring(0,row[temp[0]][temp[1]].length - 2)
             }
           } else if(item.formatterType == 'amount-type'){ //金额转换
             return (row[temp[0]][temp[1]] / 100).toFixed(2)
           }
         }
       } else{ //item中无嵌套对象
         let temp = prop.split('.')
           if(item.formatterType == 'common-type'){  //通用类型转换
             let arry = item.formatterInfo
             for(let i in arry){
               if(arry[i].value == value){
                 return arry[i].label
               }
             }
           } else if(item.formatterType == 'time-type'){ //时间标准格式化
             if(!global.isNull(row[temp[0]][temp[1]])){
               return value.substring(0,value.length - 2)
             }
           } else if(item.formatterType == 'amount-type'){ //金额转换
             return (value / 100).toFixed(2)
           }
       }
     },
 }
};
</script>

说明:
1、通常情况下列表中的字段不需要formatter,把exportExcelArry 对象中formatterFlag设成false;
2、需要formatter的数据主要有code对应label的转换(type='common-type'),金额的单位转换等,需要根据自己项目的需求封装成通用的组件;
3、针对后端返回的数据data多层的情况,需要对exportExcelArry中的prop字段进行分割来获取row中对应的值,一般情况下两层足够了。

上一篇 下一篇

猜你喜欢

热点阅读