记录在table中实现热键自动录入格式内容

128 阅读3分钟
本次分享只做日常记录,具体实现方法可能不是很友好,各位如果有啥好的见解欢迎反馈!
首先需求是根据热键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;
};
上述方法是我针对本次需求所做的应对方案,有些地方可能写的不是很妥当,欢迎各位提出宝贵意见,感谢!