一、表格的合并
由于一般具有打印功能的表格都具有只读功能,所以这是我这边添加的一个原始表格,通过循环展示每一列的数据:
<template>
<div style="margin-top: 100px">
<el-table
:data="tableData"
border
:cell-style="globalConsts.cellStyle"
:header-cell-style="globalConsts.headerCellStyle"
>
<el-table-column
v-for="item in formTheadOptions"
:key="item.prop"
:prop="item.prop"
:label="item.label"
align="center"
/></el-table>
</div>
</template>
<script>
export default {
data() {
return {
formTheadOptions: [
{ prop: "A", label: "A" },
{ prop: "B", label: "B" },
{ prop: "C", label: "C" },
{ prop: "D", label: "D" },
{ prop: "E", label: "E" },
],
tableData: [
{
A: "A1",
B: "B1",
C: "C1",
D: "D1",
E: "E1",
},
{
A: "A2",
B: "B2",
C: "C2",
D: "D2",
E: "E2",
},
{
A: "A3",
B: "B3",
C: "C3",
D: "D3",
E: "E3",
},
],
};
},
};
</script>
关于表格的合并,组件给我们提供了一个方法span-method来合并我们的表格,他需要返回一个包含两个元素的数组[rowspan,colspan],或者一个对象:{ rowspan:rowspan, colspan:colspan},默认都是[1,1]:
el-table
:data="tableData"
border
:cell-style="globalConsts.cellStyle"
:header-cell-style="globalConsts.headerCellStyle"
:span-method="spanMethod"//表格使用组件提供的方法
>
<el-table-column
v-for="item in formTheadOptions"
:key="item.prop"
:prop="item.prop"
:label="item.label"
align="center"
/></el-table>
//methods中创建一个合并方法
spanMethod({ row, column, rowIndex, columnIndex }) {
console.log("row:");
console.log(row);
console.log("column:");
console.log(column);
console.log("rowIndex:" + rowIndex);
console.log("columnIndex:" + columnIndex);
return [1, 1];
}
打印的结果可以看出来每一格都循环调用了该方法,其中row表示当前行数据,column表示当前列数据:
1.1表格行合并
现在我们来进行表格的行合并,数据作如下修改:
tableData: [
{
A: "A1",
B: "B1",
C: "C1",
D: "D1",
E: "E1",
mergeACount: 2,//假设我们需要合并第一列A,mergeACount表示当前行需要合并数量
},
{
A: "A2",
B: "B2",
C: "C2",
D: "D2",
E: "E2",
mergeACount: 3,
},
{
A: "A3",
B: "B3",
C: "C3",
D: "D3",
E: "E3"
},
],
方法作如下修改:
spanMethod({ row, column, rowIndex, columnIndex }) {
if (column.property === "A") {
if (row.mergeCount) {
return {
rowspan: 1,
colspan: row.mergeCount,
};
} else {
return {
rowspan: 1,
colspan: 1,
};
}
} else {
if (row.mergeCount && columnIndex <= row.mergeCount - 1) {
//这里需要解释一下,需要根据当前行A列合并个数,计算后边的单元格占位,已合并的需要返回[0,0]
return {
rowspan: 0,
colspan: 0,
};
} else {
return {
rowspan: 1,
colspan: 1,
};
}
}
},
结果:
至于表格标题的合并,网上也有一大堆解决办法,我这边常用的方法是隐藏表格标题,使用数据展示作为标题。
1.2表格列合并
表格列的合并无非就是多条数据使用同一个名字,修改一下数据:
tableData: [
{
A: "A1",
B: "B1",
C: "C1",
D: "D1",
E: "E1",
isNeedMerge: true,
mergeCount: 2,
},
{
A: "A2",
B: "B2",
C: "C2",
D: "D2",
E: "E2",
isNeedMerge: false,
mergeCount: 0,
},
{
A: "A3",
B: "B3",
C: "C3",
D: "D3",
E: "E3",
isNeedMerge: true,
mergeCount: 1,
},
],
修改方法:
spanMethod({ row, column, rowIndex, columnIndex }) {
if (column.property === "B" || column.property === "C") {
//多条的话可以封装
if (row.isNeedMerge) {
return {
rowspan: row.mergeCount,
colspan: 1,
};
} else {
return {
rowspan: 0,
colspan: 0,
};
}
} else {
return {
rowspan: 1,
colspan: 1,
};
}
},
这里只是使用了比较基础的表格合并,至于比较复杂的表格合并,大家可以找到合适的方法,针对固定的表格比如xxx单,xxx配方,这些有一个共性就是结构比较确定,没有太大的变化,针对这种表格,最最最简单的方法 可以通过每一行去计算当前行需要的合并方式,贴一个最近做的表格:
二、表格的导出/上传
表格的导出主要使用了js.xlsx,这里有一个已经写好的基本表格样式,可以下载直接用:
使用方法:
exportFile(type) {
this.$refs.exportFilePopover.doClose();
import("@/dependences/Export2Excel").then((excel) => {
//表格标题,没有可以为空
const tHeader = this.formTheadOptions.map((item) => item.label);
//表格prop,他需要把每一行读成一个数组
const filterVal = this.formTheadOptions.map((item) => item.prop);
const list = this.tableData;
const data = this.formatJson(filterVal, list);
const merges = this.mergesJson();//需要合并的单元格
excel.export_json_to_excel({
header: tHeader,
data,
merges,
filename: this.tableTitle,
autoWidth: true,
bookType: type,
});
});
},
formatJson(filterVal, jsonData) {
return jsonData.map((v) =>
filterVal.map((j) => {
return v[j];
})
);
},
mergesJson(){
//这里的合并信息和表格展示时完全不一样!他需要返回一个数组["A1:B1","C1:D1"]
//其中A代表第一列,1代表第一行,"A1:B1"可以在表格中看到就是左上角两个,他们两个进行合并;
//这个不同的表格数据合并可以找到合适的方法去计算出合并的单元格;
return [];
}
上传同样是使用了js.xlsx,我这有个封装好的组件可以拿去用:
使用方法:
<upload-excel
:on-success="handleSuccess"
:before-upload="beforeUpload"
ref="uploadExcel"
></upload-excel>
handleSuccess({ results, header }) {
//results:数组,每一行的数据对象
//header 表格每一列标题构成的数组,实际使用可以输出看看
}
//上传文件前校验
beforeUpload(file) {
const isLt1M = file.size / 1024 / 1024 < 5;
if (isLt1M) {
return true;
}
this.$message({
message: "请不要上传超过5M的文件!",
type: "warning",
});
return false;
},
文章内容就是这些了,主要做个记录,方便下次使用,如果对大家有什么帮助或者又问题欢迎提问~