表格破事多

397 阅读5分钟

先说明一下,凳凳在这使用的是Vue-cli3 + Element-UI哦,要是React、Angular那就非常抱歉啊,等我先学习了,再来重新修改。
为啥要写这篇文章呢,就是因为最近项目遇到了很多使用表格的功能。要是说只要表格看看,那还有啥要整理的啊,little case!
关键需求不是这个亚子的呀!!!
有需求的宝宝可以看看啊。

表格合并

打开Element-UI官网,你就会发现。哎呀,这不是我想要的啊,我要根据某个字段名相同的进行合并啊,怎么就是普普通通的两行合并呢??
原来合并还可以这么干。

<el-table
 :data="tableData"
 stripe
 border
 :span-method="objectSpanMethod"
 :header-cell-style="{'background-color':'#ccc','color':'#333'}"
 style="width: 100%"
>
    <el-table-column prop="type" label="类型" min-width="30%"></el-table-column>
    <el-table-column prop="name" label="姓名" min-width="30%"></el-table-column>
    <el-table-column prop="date" label="日期" min-width="30%"></el-table-column>
    <el-table-column prop="address" label="地址"></el-table-column>
 </el-table>
getSpan(data) {
  for (var i = 0; i < data.length; i++) {
    if (i === 0) {
      this.span.push(1);
      this.index = 0;
    } else {
      // 判断当前元素某一属性与上一个元素的某一属性是否相同
      if (data[i].type === data[i - 1].type) {
        this.span[this.index] += 1;
        this.span.push(0);
      } else {
        this.span.push(1);
        this.index = i;
      }
    }
  }
},

objectSpanMethod({ rowIndex, columnIndex }) {
  if (columnIndex === 0) {
    const _row = this.span[rowIndex];
    const _col = _row > 0 ? 1 : 0;
    return {
      rowspan: _row,
      colspan: _col
    };
  }
}

表格下载

表格下载其实有两种方法,一是传入数据,将数据以表格形式导出,下面会讲到。
我现在讲的是另一种方法:将excel表格放在前端文件夹中,点击超链接下载excel。
excel需要放在public文件目录下:

使用代码如下:

<div class="buttom">
     <a href="/resource/template.xlsx" target="模板.xlsx">下载模板</a>
</div>

往下不论是单表格、多表格导入导出,需要先安装相关的依赖。

npm install -S file-saver xlsx

npm install -D script-loader

安装完成后,才能继续以下步骤:

单表格

单表格导入

<input
      class="input-file"
      type="file"
      @change="exportData"
      accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
    />
<div class="buttom" @click="importExcel">导入表格</div>
<!--input需要隐藏起来-->
<!--.input-file {display: none;}-->
//在此需要引入需要的xlsx文件:
import XLSX from "xlsx";
//导入表格
importExcel() {
  document.querySelector(".input-file").click();
  console.log("导入表格!");
},
 exportData(event) {
   if (!event.currentTarget.files.length) {
     return;
   }
   const that = this;
   that.allExcelData = [];
   // 拿取文件对象
   let f = event.currentTarget.files[0];
   this.fileName = f.name;
   console.log("上传的文件名", this.fileName);
   //这里已经拿到了excel的file文件,若是项目需求,可直接$emit丢出文件
   that.$emit("getMyExcelData", f);
   // 用FileReader来读取
   let reader = new FileReader();
   // 重写FileReader上的readAsBinaryString方法
   FileReader.prototype.readAsBinaryString = function(f) {
     let binary = "";
     let wb; // 读取完成的数据
     let outdata; // 你需要的数据
     let reader = new FileReader();
     reader.onload = function() {
       // 读取成Uint8Array,再转换为Unicode编码(Unicode占两个字节)
       let bytes = new Uint8Array(reader.result);
       let length = bytes.byteLength;
       for (let i = 0; i < length; i++) {
         binary += String.fromCharCode(bytes[i]);
       }
       // 接下来就是xlsx
       wb = XLSX.read(binary, {
         cellDates: true //有日期必须要写,表格没有日期可不写
         type: "binary",
       });
       outdata = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]);
       //处理数据
       console.log("outdata", outdata);
       that.allExcelData = that.handleData(outdata);
     };
     reader.readAsArrayBuffer(f);
   };
   reader.readAsBinaryString(f);
},
//将中文字段转为英文字段
handleData(data) {
  for (let item in data) {
    for (let key in data[item]) {
      if (key == "类型") {
        data[item]["type"] = data[item][key];
      } else if (key == "日期") {
        data[item]["date"] = data[item][key];
      } else if (key == "姓名") {
        data[item]["name"] = data[item][key];
      } else if (key == "地址") {
        data[item]["address"] = data[item][key];
      }
    }
  }
  return data;
},

在此我是将表格与整个页面是分离,表格为一个组件,在表格显示的这一块需要处理一下日期格式,当时浪费了我不少时间。。。。
:formatter="dateFormat" 这一段便是格式化表格日期。

<div class="form">
  <el-table
    v-loading="loading"
    :data="list"
    stripe
    border
    :header-cell-style="{'background-color':'#ccc','color':'#333'}"
    style="width: 100%"
  >
    <el-table-column prop="type" label="类型" min-width="30%"></el-table-column>
    <el-table-column prop="name" label="姓名" min-width="30%"></el-table-column>
    <el-table-column prop="date" :formatter="dateFormat" label="日期" min-width="30%"></el-table-column>
    <el-table-column prop="address" label="地址"></el-table-column>
  </el-table>
</div>
//一定要安装moment.js
import moment from "moment";

dateFormat(row, column) {
  var date = row[column.property];
  if (date === undefined) {
    return "";
  }
  return moment(date).format("YYYY-MM-DD");
}
单表格导出

<div class="footer">
    <div class="buttom" @click="ExportExcel">导出</div>
</div>
 //导出表格
ExportExcel() {
 console.log("导出表格!");
 const { columns } = this;
 require.ensure([], () => {
   const { export_json_to_excel } = require("@/vendor/Export2Excel");
   //  ---require 括号里面是相对路径其实是引用  Export2Excel.js
   const tHeader = ["类型", "姓名", "日期", "地址"];
   //  ----tHeader 数组里面放的是字段的对应名
   const filterVal = ["type", "name", "date", "address"];
   //filterVal  字段对应的值
   columns &&
     columns.map(data => {
       tHeader.push(data.value);
       filterVal.push(data.key);
     });
   const list = this.allExcelData;
   // 对应的json数组
   const data = this.formatJson(filterVal, list);
   export_json_to_excel(tHeader, data, "人员状况");
 });
},
formatJson(filterVal, jsonData) {
 return jsonData.map(v => filterVal.map(j => v[j]));
}

多表格

多表格导出

这里的多表格我是使用的是多个sheet导出,也可以使用一个sheet多个表格,凳凳暂时没时间去研究。。
有时间一定回更^-^!

//HTML写一个按钮绑定exportExcel即可
exportExcel() {
  console.log("导出");
  const list = [];
  let _this = this;
  this.allExcelData.forEach(item => {
    list.push({
      tHeader: ["类型", "姓名", "日期", "地址"],
      filterVal: ["type", "name", "date", "address"],
      tableDatas: item.formList,
      sheetName: item.formName
    });
  });
  // console.log(list);
  require.ensure([], () => {
    const { export_json_to_excel } = require("@/vendor/Export2Excel2");
    //  ---require 括号里面是相对路径其实是引用  Export2Excel.js

    let tHeader = [];
    let dataArr = [];
    let sheetnames = [];
    for (var i in list) {
      tHeader.push(list[i].tHeader);
      dataArr.push(_this.formatJson(list[i].filterVal, list[i].tableDatas));
      sheetnames.push(list[i].sheetName);
    }
    export_json_to_excel({
      header: tHeader,
      data: dataArr,
      sheetname: sheetnames,
      filename: "人员明细表" + this.getDay(0)
    });
  });
},
formatJson(filterVal, jsonData) {
  return jsonData.map(v => filterVal.map(j => v[j]));
},
//获取哪天的日期,当天 day = 0;昨天 day = -1;明天 day = 1;
getDay(day) {
  var today = new Date();
  var targetday_milliseconds = today.getTime() + 1000 * 60 * 60 * 24 * day;
  today.setTime(targetday_milliseconds); //注意,这行是关键代码
  var tYear = today.getFullYear();
  var tMonth = today.getMonth();
  var tDate = today.getDate();
  tMonth = this.doHandleMonth(tMonth + 1);
  tDate = this.doHandleMonth(tDate);
  return tYear + "-" + tMonth + "-" + tDate;
},
doHandleMonth(month) {
  var m = month;
  if (month.toString().length == 1) {
    m = "0" + month;
  }
  return m;
}

显示多表格的组件:

<div class="form" v-for="(item,index) in list" :key="index">
  <p>{{item.formName}}</p>
  <el-table
    :data="item.formList"
    stripe
    border
    :header-cell-style="{'background-color':'#ccc','color':'#333'}"
    style="width: 100%"
  >
    <el-table-column prop="type" label="类型" min-width="30%"></el-table-column>
    <el-table-column prop="name" label="姓名" min-width="30%"></el-table-column>
    <el-table-column prop="date" label="日期" min-width="30%"></el-table-column>
    <el-table-column prop="address" label="地址"></el-table-column>
  </el-table>
</div>

父子组件传参::list="allExcelData"

还想看点啥啊
噢!
源码看过来:点击这里,可以直接下载使用的哦。