vue+eleui+xlsx实现表格的导出

2022-03-06 10:06:59 浏览数 (2)

安装xlsx插件

代码语言:javascript复制
npm install --save xlsx file-saver

开始实现步骤

引入xlsx
代码语言:javascript复制
  import FileSaver from 'file-saver'
  import XLSX from 'xlsx'
封装导出表格组件
代码语言:javascript复制
<template>
  <transition name="fadeIn" >
    <div v-show='false'>
      <el-table
      :id="exportExcelInfo.excelId"
      :data="tableDatas"
      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 {
    name: 'ExportExcelCommon',
    props: {
      exportExcelInfo: {
        type: Object,
        default: {}
      },
      exportExcelArry: {
        type: Array,
        default: []
      },
      tableData: {
        type: Array,
        default: []
      },
    },
    data(){
        return {
          dataItem:{},
          tableDatas:this.tableData  //通过data, 定义新变量currentSearch, 这样currentSearch的值变更时,不会影响父组件传来的search的值
        }
      },
    watch:{
    			tableData:function(newList){
    				this.tableDatas = newList;
    			}
    		},
    methods: {
      //excel导出全部 合并sheet
      exportOutAllByOrder(row) {
        var xlsxParam = {
          raw: true
        } // 导出的内容只做解析,不进行格式转换
         var workbook = XLSX.utils.book_new();

         const allData2 = [];
         for (var i = 0; i < row.length; i  ) {
           for (var j = 0; j < row[i].detaildata.length; j  ) {
             this.dataItem = row[i].detaildata[j];
             delete this.dataItem.orderid;
             this.dataItem.username = row[i].username
             allData2.push(this.dataItem);
           }
         }

         //展示的顺序,把data中对象的属性按照你想要的顺序排放就可以了,我这里把id移到了第一列展示
         const header3 = ["username", "datetime", "ordername", "product", "linename", "procedureid","procedurename","number","price","s_total"];
         //展示的名称
         const headerDisplay3 = {username:"员工", datetime:"日期", ordername:"订单", product:"产品", linename:"线别", procedureid:"工序号", procedurename:"工序名", number:"数量", price:"单价", s_total:"总金额"};
         //将表头放到原始数据里面去,要保证表头在数组的最前面
         const newData3 = [headerDisplay3, ...allData2];
         //加了一句skipHeader:true,这样就会忽略原来的表头
         // let ws = XLSX.utils.table_to_sheet(document.querySelector('#'   this.exportExcelInfo.excelId), xlsxParam);
         let ws = XLSX.utils.json_to_sheet(newData3, {header:header3, skipHeader:true});
         // 这里可以添加多个sheet页
         XLSX.utils.book_append_sheet(workbook, ws, "总表");
        for (var i = 0; i < row.length; i  ) {
          this.tableDatas = row[i].detaildata;
          for (var j = 0; j < this.tableDatas.length; j  ) {
            delete this.tableDatas[j].username;
          }
          if(this.tableDatas != null){
            //展示的顺序,把data中对象的属性按照你想要的顺序排放就可以了,我这里把id移到了第一列展示
            const header = ["datetime", "ordername", "product", "linename", "procedureid","procedurename","number","price","s_total"];
            //展示的名称
            const headerDisplay = {datetime:"日期", ordername:"订单", product:"产品", linename:"线别", procedureid:"工序号", procedurename:"工序名", number:"数量", price:"单价", s_total:"总金额"};
            //将表头放到原始数据里面去,要保证表头在数组的最前面
            const newData = [headerDisplay, ...this.tableDatas];
            //加了一句skipHeader:true,这样就会忽略原来的表头
            // let ws = XLSX.utils.table_to_sheet(document.querySelector('#'   this.exportExcelInfo.excelId), xlsxParam);
            let ws = XLSX.utils.json_to_sheet(newData, {header:header, skipHeader:true});
                // 这里可以添加多个sheet页
                XLSX.utils.book_append_sheet(workbook, ws, row[i].username);
          }
         }
         var wbout = XLSX.write(workbook, {
           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
      },
      //excel导出全部 合并sheet
      exportOutAll(row) {
        var xlsxParam = {
          raw: true
        } // 导出的内容只做解析,不进行格式转换
        var workbook = XLSX.utils.book_new();
        // 拼接总表需要的数据
        const allData = [];
        for (var i = 0; i < row.length; i  ) {
          for (var j = 0; j < row[i].detaildata.length; j  ) {
            this.dataItem = row[i].detaildata[j];
            delete this.dataItem.orderid;
            this.dataItem.username = row[i].username
            allData.push(this.dataItem);
          }
        }

        //展示的顺序,把data中对象的属性按照你想要的顺序排放就可以了,我这里把id移到了第一列展示
        const header2 = ["username", "datetime", "ordername", "product", "linename", "procedureid","procedurename","number","price","s_total"];
        //展示的名称
        const headerDisplay2 = {username:"员工", datetime:"日期", ordername:"订单", product:"产品", linename:"线别", procedureid:"工序号", procedurename:"工序名", number:"数量", price:"单价", s_total:"总金额"};
        //将表头放到原始数据里面去,要保证表头在数组的最前面
        const newData2 = [headerDisplay2, ...allData];
        //加了一句skipHeader:true,这样就会忽略原来的表头
        // let ws = XLSX.utils.table_to_sheet(document.querySelector('#'   this.exportExcelInfo.excelId), xlsxParam);
        let ws = XLSX.utils.json_to_sheet(newData2, {header:header2, skipHeader:true});
        // 这里可以添加多个sheet页
        XLSX.utils.book_append_sheet(workbook, ws, "总表");
        for (var i = 0; i < row.length; i  ) {
          this.tableDatas = row[i].detaildata;
          for (var j = 0; j < this.tableDatas.length; j  ) {
            delete this.tableDatas[j].username;
          }
          if(this.tableDatas != null){
            //展示的顺序,把data中对象的属性按照你想要的顺序排放就可以了,我这里把id移到了第一列展示
            const header = ["datetime", "ordername", "product", "linename", "procedureid","procedurename","number","price","s_total"];
            //展示的名称
            const headerDisplay = {datetime:"日期", ordername:"订单", product:"产品", linename:"线别", procedureid:"工序号", procedurename:"工序名", number:"数量", price:"单价", s_total:"总金额"};
            //将表头放到原始数据里面去,要保证表头在数组的最前面
            const newData = [headerDisplay, ...this.tableDatas];
            //加了一句skipHeader:true,这样就会忽略原来的表头
            // let ws = XLSX.utils.table_to_sheet(document.querySelector('#'   this.exportExcelInfo.excelId), xlsxParam);
            let ws = XLSX.utils.json_to_sheet(newData, {header:header, skipHeader:true});
            // 这里可以添加多个sheet页
            XLSX.utils.book_append_sheet(workbook, ws, row[i].username);
          }
         }
         var wbout = XLSX.write(workbook, {
           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
      },
      //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') { //时间标准格式化
              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') { //时间标准格式化
            return value
          } else if (item.formatterType == 'amount-type') { //金额转换
            return value
          }
        }
      },
    }
  };
</script>

其实就是在页面创建了一个隐藏的表格,将需要导出的数据放进这个表格然后实现导出

在页面使用上述组件
代码语言:javascript复制
import ExportExcelCommon from "../../../components/ExportExcelCommonOrigin";
components: {
  ExportExcelCommon
},
导出方法
代码语言:javascript复制
exportExcelAll () {
        this.exportExcelInfo.excelName = '用户收入表.xlsx';
        this.$confirm('导出列表数据到Excel', '提示', {
            type: 'warning',
            confirmButtonText: '确认',
            cancelButtonText: '取消'
        }).then( async () => {
            this.tableAllData = this.incomeList;
              setTimeout(()=>{
                this.$refs.myChild.exportOutAll(this.incomeList);
              },500)
        }).catch(() => {
            this.$message({message: '导出Excel失败!', type: 'warning'})
        });
        //获取到表格数据的值并赋给this.tableAllData
        //同样延时调导出方法,需在initData('export-excel')方法执行成功后调this.$refs.myChild.exportExcel();方法
      },

这样就可以实现将el_table中的数据导出并保存到本地excel了

0 人点赞