vue动态表头生成

业务需求

导入excel表单,导入成功后预览表单数据。根据表单首行字段,动态生成预览表单的表头。

excel表单格式:

技术栈

vue,ts,elementUI

实现

页面布局,调用接口获取到excel表格中数据,存入 fields 中。

 

<el-table :data="tableList">    <el-table-column label="行号" width="100">        <template slot-scope="scope">            <div>{{scope.row.index}}</div>        </template>    </el-table-column>    <el-table-column v-for="(item, index) in fields" :key="index" :label="item.label">        <template slot-scope="scope">            <div>{{scope.row[item.field]}}</div>        </template>    </el-table-column></el-table>

逻辑实现

1、上传的表格中数据都是后端返回给前端的,这里是调用了getFileData 接口,返回值中 mapList 是个对象数组。

getFileData(params: any) {    MyForm.getFileData(params).then((res) => {        if (res.status === 0) {            this.setTableList(res.data);        } else {            this.$message({                message: res.data.msg,                type: "error",            });        }    });},

 

2、setTableList 方法就是动态生成表头数据。

但在此之前,需要明白前后端传值中后端需要的参数格式,这里表单的后端实现逻辑中关键的字段有三个:attrNameattrColumnvalue。上图中拿到了attrNamevalue的对应关系:

后端还提供了一个attrNameattrColumn对应关系的接口,在页面加载的时候来调用。

最终生成的表单的数据是attrColumnvalue的对应关系,以这样的数据格式传给后端,那就需要前端处理一下数据格式。

 

interface IField {   label: string;   field: string;}
// methodsgetDetail() {    UserForm.detail(this.id).then((res) => {        if (res.status === 0) {            const list = res.data.formAttrList;            const fields: IField[]   = [];            const fieldMap: {[k: string]: IField } = {};            list.forEach((d: any) => {                const attr = {                        label: d.formAttrName,                        field: d.formAttrColumn,                };                fields.push(attr);                fieldMap[d.formAttrName] = attr;            });            this.fields = fields;            this.fieldMap = fieldMap;        }    });},

先定义空的数组fields,map对象fieldMap。循环返回值列表,把需要的attrNameattrColumn字段拿出来组成数组fields。以attrName为key,fields的Item为value,组成map对象fieldMap

赋值好这两个变量之后,就可以实现setTableList 方法。

3、回到最上边,拿到那个mapList的数据,先做一个校验。当mapList存在的时候,取数组mapList中的第一项,检查表头数据是否存在fieldMap中,如果不存在的话给出提示直接return。

if (mapList && mapList.length > 0) {    const item = mapList[0];    let check = true;    Object.keys(item).forEach((key) => {        if (!this.fieldMap[key]) {            check = false;        }    });    if (!check) {        this.$message({            message: "表单格式已变动,请下载最新模版",            type: "warning",        });        return;    }    // 。。。}

开始组装表单数据。先定义一个数组用来存放最终结果,循环mapList,返回值中的rowNumber数组里的数据是对应着mapList每一项在excel中的行号。

const tableList: any[] = [];mapList.forEach((d: {[k: string]: any}, index: number) => {    const row: {[k: string]: any} = {        index: rowNumber[index],    };    Object.keys(d).forEach((name) => {        const field = this.fieldMap[name].field;        row[field] = d[name];    });    tableList.push(row);});this.tableList = tableList;

整体 setTableList 方法如下:

setTableList(data: any) {this.tableList = [];this.errorColumn = "";const { mapList, rowNumber, errorColumn } = data;if (mapList && mapList.length > 0) {    const item = mapList[0];    let check = true;    Object.keys(item).forEach((key) => {        if (!this.fieldMap[key]) {            check = false;        }    });    if (!check) {        this.$message({            message: "表单格式已变动,请下载最新模版",            type: "warning",        });        return;    }    // 组装表格数据    const tableList: any[] = [];    mapList.forEach((d: {[k: string]: any}, index: number) => {        const row: {[k: string]: any} = {            index: rowNumber[index],        };        Object.keys(d).forEach((name) => {            const field = this.fieldMap[name].field;            row[field] = d[name];        });        tableList.push(row);      });      this.tableList = tableList;  }  // 错误信息  if (errorColumn) {      errorColumn.forEach((el: string) => {          const row = Number(el.split(",")[0]) + 1;          const column = Number(el.split(",")[1]) + 1;          this.errorColumn = `${row}行${column}列`;      });  }},

4、最终效果

关注我吧

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值