先说明一下,凳凳在这使用的是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"
噢!
源码看过来:点击这里,可以直接下载使用的哦。