ElementUI中el-table表格实现类似Excel复制黏贴功能

html:

<el-table :data="tableList" :cell-class-name="getCellIndex" @paste.native="pasteInfo($event)"
@cell-click="cellClick">
	<el-table-column label="No." width="80">
		<template slot-scope="scope">
			<span>
				{{ scope.$index + 1 }}
			</span>
		</template>
	</el-table-column>
	<el-table-column prop="seriesName" label="NEX/G08">
		<template slot-scope="scope">
			{{ scope.row.seriesName }}
		</template>
	</el-table-column>
	<el-table-column prop="mmDate" label="Date" width="">
		<template slot-scope="scope">
			{{ scope.row.mmDate }}
		</template>
	</el-table-column>
	<el-table-column prop="attHours" label="Att hours" width="">
		<template slot-scope="scope">
			<span v-if="!isEdit">
				{{ scope.row.attHours }}
			</span>
			<el-input placeholder="" :style="{ '--inputColor':checkValue(scope.row.attHours)?'#F93920':'','--inputColor2':checkValue(scope.row.attHours)?'#FA664C4D':''}"
			v-else @change="updatedValue('Att hours',scope.row.attHours,scope.row)"
			v-model="scope.row.attHours" style="width: 98%">
			</el-input>
		</template>
	</el-table-column>
	<el-table-column label="Volume" style="text-align: center;">
		<template slot-scope="scope">
			<span v-if="!isEdit">
				{{ scope.row.volume }}
			</span>
			<el-input placeholder="" :style="{ '--inputColor':checkValue(scope.row.volume)?'#F93920':'','--inputColor2':checkValue(scope.row.volume)?'#FA664C4D':''}"
			v-else @change="updatedValue('Volume',scope.row.volume,scope.row)" v-model="scope.row.volume"
			style="width: 98%">
			</el-input>
		</template>
	</el-table-column>
</el-table>

js:

/** 设置行、列索引 */
getCellIndex: function({
	row,
	column,
	rowIndex,
	columnIndex
}) {
	row.index = rowIndex;
	column.index = columnIndex;
},
/** 点击单元格 */
cellClick(row, column, cell, event) {
	this.rowIndex = row.index;
	this.columnIndex = column.index
},
/** 复制粘贴 */
pasteInfo(e) {
	if (!this.isEdit) {
		return
	}
	try {
		e.preventDefault(); //阻止默认粘贴事件
		e.stopPropagation(); //阻止事件冒泡
		var data = null;
		var clipboardData = e.clipboardData || window.clipboardData; // IE
		if (!clipboardData) {
			//chrome
			clipboardData = e.originalEvent.clipboardData;
		}
		data = clipboardData.getData("Text"); //复制过来的内容
		if (data.indexOf("\r\n") == -1) {
			data = data + "\r\n"
		}
		//首先对源头进行解析
		var rowStrArray = data.split("\r\n"); //拆成多行
		let rows = [];
		for (var i = 0; i < rowStrArray.length - 1; i++) {
			var row = [];
			var tdStrArray = rowStrArray[i].split("\t"); //按列拆分
			for (var j = 0; j < tdStrArray.length; j++) {
				row.push(tdStrArray[j]);
			}
			rows.push(row);
		}
		this.pasteRowLength = rows.length;
		let emptyObj = { //需要复制粘贴的key值列
			index: undefined,
			seriesName: undefined,
			mmDate: undefined,
			attHours: undefined,
			volume: undefined
		}
		for (var j = 0; j < rows.length; j++) {
			if (this.rowIndex + j > this.tableList.length - 1) {//黏贴行的index大于表格行数不处理
				break
			};
			let item = {};
			item = JSON.parse(JSON.stringify(this.tableList[this.rowIndex + j]));
			let num = 0;
			let numFlag = 0; //从哪一列开始粘贴:全部列都可以粘贴(即从第0列可以粘贴)
			for (var key in emptyObj) {
				if (rows[j][num] === undefined) {
					break
				}
				if (!rows[j][num]) {
					rows[j][num] = null;
				}
				if (this.columnIndex <= numFlag) {
					// 针对不能修改的列字段做处理,可以复制粘贴的列才做赋值。根据需求加下面的if判断
					if (key !== 'index' && key !== 'seriesName' && key !== 'mmDate') {
						item[key] = rows[j][num]
					}
					num = num + 1
				}
				numFlag = numFlag + 1
			}
			this.$set(this.tableList, this.rowIndex + j, item)
		}
        //To Do 后台交互,table中更新的列
		this.handlePasteUpdate(this.tableList.slice(this.rowIndex, this.pasteRowLength + this.rowIndex))
	} catch(err) {
		this.$message.error('请选择粘贴位置')
	}
},
/** 检验输入的值 */
checkValue(value) {
	let reg = /^[0-9]+$/;
	if (value && value.trim() !== "" && !reg.test(value.trim())) {
		return true
	} else {
		return false
	}
},
/** 单个输入保存逻辑 */
updatedValue(lineName, value, row) {
	let reg = /^[+-]?(\d|([1-9]\d+))(\.\d+)?$/;
	if (row.attHours && row.attHours.trim() !== "" && !reg.test(row.attHours.trim()) || row.volume && row.volume.trim() !== "" && !reg.test(row.volume.trim())) { //一行中有错误单个保存
		if (value.trim() !== "" && !reg.test(value.trim())) {
			this.$message({
				type: "warning",
				dangerouslyUseHTMLString: true,
				message: "只能是一个数字,请重新输入</br></br>The target can only be a number, please re-enter",
			});
			return;
		}
	}
	//To Do 后台交互
} else { //一行中无错误整行保存
	let passList = [];
	passList.push(row)
	//To Do 后台交互
}
},

tips:记录黏贴时点击单元格的rowIndex和columnIndex,处理好复制过来的数据,用记录的rowIndex和columnIndex判断处理table数据,定义复制行的key,过滤不需要复制的字段,用this.$set动态更新table数组更新视图。(逻辑完善,对输入的字段进行校验,整行无问题保存整行数据或保存单个数据)

实现效果如下:

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值