本次分享只做日常记录,具体实现方法可能不是很友好,各位如果有啥好的见解欢迎反馈!
首先需求是根据热键F1自动录入表格单元格内容,其实也就是通过服务去开一个webscoket获取数据,相当于复制粘贴的功能
前端的话是直接监听webscoket返回数据,因为数据格式取决于你选择的内容,目前分为两种格式,一种是横向多个,另一种是竖向多个,当然还有单个数据的录入,这边分成两个变量存储
// 这里根据返回的数据先做首尾空格处理,然后横向的话是根据\t去分割,纵向的话根据正则/\r?\n/去匹配,最后做空值处理
lineSplitArr.value = newVal.data.trim()
.split("\t")
.map((item:string) => item.replace(/[\r\n\t]/g, ""))
.filter(Boolean);
// 列分割后的数组
columnSplitArr.value = newVal.data
.trim()
.split(/\r?\n/)
.map((item:string) => item.replace(/[\r\n\t]/g, ""))
.filter(Boolean);
单个填充
根据上面提到的两个变量是否都为空去做单个数据处理
// 循环表格columns处理过后的key数组
for (let i = 0; i < keyArr.value.length; i++) {
// 记录每次填充的key下标值
let fInx = String(areValidateInx.value) ? areValidateInx.value : i;
// 主要为了找到要填充的表格index,方法贴下面
let fillInx = handleTableToIndex(
keyArr.value[fInx],
lineSplitArr.value[0]
);
let linkFindCur = linkKeyArr.find(
(fItem) => fItem.key === keyArr.value[fInx]
);
let curKey = keyArr.value[fInx];
if (String(fillInx) && linkFindCur) {
//判断当前录入数据是否是可分割的,方法在下
let isBreak = commonFun(lineSplitArr.value[0],curKey,fillInx)
if (isBreak) break;
} else {
if (String(fillInx)) {
// 填充下拉选项时验证
let isCheck = autoEntryCheck(
fillInx,
keyArr.value[fInx],
lineSplitArr.value[0]
);
// 如果自动录入找到 并且是select类型
if (isCheck && selectKeyList.value.includes(keyArr.value[fInx])) {
break;
}
// 如果没找到 做提示
else if (
!isCheck &&
selectKeyList.value.includes(keyArr.value[fInx])
) {
errorKeyHint(keyArr.value[fInx]);
break;
} else if (!selectKeyList.value.includes(keyArr.value[fInx])) {
let fillValue = lineSplitArr.value[0];
tableData.value[fillInx][curKey] = fillValue;
break;
}
} else {
// 单元格填充满得情况重置下标值
if (fInx == keyArr.value.length - 1) {
areValidateInx.value = "";
break;
}
areValidateInx.value = String(areValidateInx.value)
? areValidateInx.value + 1
: i + 1;
continue;
}
}
}
// 处理填充table下标
const handleTableToIndex = (key: string, val: string) => {
let fillInx = "";
for (let i = 0; i < tableData.value.length; i++) {
if (!tableData.value[i][key]) {
fillInx = i;
break;
}
}
return fillInx;
};
//判断当前录入数据是否是可分割的
const commonFun = (fillValue:string,key:string,fillIndex:string) => {
let linkFindCur = linkKeyArr.find((fItem) => fItem.key === key);
if (linkFindCur) {
//判断是否是连续的数字和其他字符组成
if (checkConsecutiveCharacters(fillValue)) {
// 将字符串数字和其他字符分割
let { isJump, resultObj } = enterCurValueFill(linkFindCur, fillValue);
if (isJump) {
tableData.value[fillIndex] = {
...tableData.value[fillIndex],
...resultObj,
};
return true
}
} else {
tableData.value[fillIndex][key] = fillValue;
// 这里只为做单个字段的验证以及联动处理
checkUnitRankInputLink(key, fillIndex);
return true
}
} else {
tableData.value[fillIndex][key] = fillValue;
}
};
行多个填充
主要逻辑在于下面这个方法,取出要填充的table的index和对应key,后续根据返回的结果去做遍历填充
// 行填充取出对应开始索引以及key
/**
*
* @param array 表格数据
* @param keyArr columns key数组
* @param fillArr 要填充的数据arr
* @returns
*/
export const countAdjacentEmptyValues = (array:any, keyArr:string[], fillArr:string[]) => {
const result = [];
for (let i = 0; i < array.length; i++) {
for (let j = 0; j < keyArr.length - fillArr.length + 1; j++) {
let valid = true;
for (let f = 0; f < fillArr.length; f++) {
if (array[i][keyArr[j + f]]) {
valid = false;
break;
}
}
if (valid) {
result.push({
key: keyArr[j],
index: i
});
}
}
}
return result;
};
列多个填充
列多个填充也是大同小异,需要去处理要填充的下标以及key,处理完之后可能存在两种情况,分别为当前列第一项有值或者无值,根据这两种情况还需做下对应处理,代码如下
// 处理需要填充的key以及对应索引列表
const canNeedFillKey = (arr: String[]) => {
let tableValue = tableData.value;
let keyValue = keyArr.value;
let returnVal;
outer: for (let i = 0; i < tableValue.length; i++) {
for (let j = 0; j < keyValue.length; j++) {
// 如果当前key表格中某项已经存在
if (tableValue[i][keyValue[j]]) {
// 处理当前key存在的情况判断表格剩余key的值
let handleArr = reduceFun(keyValue[j]);
if (handleArr.length && handleArr.length < arr.length) {
MessagePlugin.warning(
`欲填入列数量不足,剩余[${handleArr.length}],导入数量[${arr.length}]!`
);
break outer;
} else if (handleArr.length && handleArr.length >= arr.length) {
returnVal = [...handleArr];
break outer;
}
continue;
// 如果表格某一项的key全都不存在,获取到当前key赋值
} else if (tableValue.every((item: any) => !item[keyValue[j]])) {
if (tableData.value.length < arr.length) {
MessagePlugin.warning(
`欲填入列数量不足,剩余[${tableData.value.length}],导入数量[${arr.length}]!`
);
break outer;
} else {
returnVal = [
{
key: keyValue[j],
},
];
}
break outer;
}
}
}
return returnVal;
};
// 分离表格对应单元格没数据key和索引
const reduceFun = (key: string) => {
let arr: { key: string; index: number }[] = [];
tableData.value.forEach((item: any, i: number) => {
if (!item[key]) {
arr.push({
key,
index: i,
});
}
});
return arr;
};