Joestar.Xu 发表于 2024-11-18 15:11:36

给单元格的指定位置插入字符

本帖最后由 Joestar.Xu 于 2024-11-25 11:35 编辑

当表格中有许多需要引用的参数时,我们会倾向于将其作为一个外部的表格引入来使用,但是在SpreadJS中想要给单元格的指定位置插入引用却不是那么的简单。


在点击外部表格时会由于焦点的变化,会导致单元格退出编辑状态,进而无法顺利将我们想要插入的引用插入到单元格的指定位置。

如下图:



进入编辑状态后,点击右侧的加号,打开外部表格进行引入操作。



在点击了外部的表格后,编辑状态就会退出。

此时,如果我们还想要实现插入的效果,就只能使用浏览器原生的光标API来实现这个需求。

整体的实现思路是:记录下插入的索引位置=》弹出外部表格并且获取要插入的值(或其他的数据,结合自己的业务场景来选择)=》通过API重新进入编辑状态=》根据之前记录下的索引位置插入需要插入的值。

最终的实现效果为下图:



实现源码:

window.onload = async () => {
let designer, spread, sheet;

let designerConfig = JSON.parse(
    JSON.stringify(GC.Spread.Sheets.Designer.DefaultConfig)
);

designer = new GC.Spread.Sheets.Designer.Designer(
    "gc-designer-container",
    designerConfig
);

spread = designer.getWorkbook();

sheet = spread.getActiveSheet();

let cursorPos = -1;
sheet.bind(GC.Spread.Sheets.Events.EditStarting, (e, info) => {
    let editor = document.querySelector("div");
    editor.addEventListener("click", () => {
      getCursorIndex(editor);
    });
});

let style = new GC.Spread.Sheets.Style();
style.cellButtons = [
    {
      imageType: GC.Spread.Sheets.ButtonImageType.plus,
      command: (sheet, row, col, option) => {
      let div = document.createElement("div");
      div.className = "testDiv";
      div.style.border = "3px solid red";
      div.style.x = "300px";
      div.style.y = "300px";
      div.style.display = "block";
      div.style.position = "absolute";
      div.style.width = "500px";
      div.style.height = "500px";
      div.setAttribute("gcUIElement", "gcEditingInput");

      let button = document.createElement("button");
      button.innerText = "确定";
      button.style.position = "absolute";
      button.style.right = "0";
      button.style.top = "0";
      button.style.width = "100px";
      button.style.height = "30px";

      div.appendChild(button);

      sheet.getParent().getHost().appendChild(div);

      let newSpread = new GC.Spread.Sheets.Workbook(
          document.querySelector(".testDiv"),
          { sheetCount: 1 }
      );

      let newSheet = newSpread.getActiveSheet();

      button.addEventListener("click", () => {
          if (cursorPos == -1) {
            cursorPos = sheet.getValue(
            sheet.getActiveRowIndex(),
            sheet.getActiveColumnIndex()
            ).length;
            console.log("cursorPos == -1", cursorPos);
          }

          let selection = newSheet.getSelections();
          console.log(selection);

          sheet.getParent().getHost().removeChild(div);
          newSpread.destroy();

          sheet.startEdit();
          let gcEditingInput = document.querySelector(
            "div"
          );
          moveCursorToIndex(gcEditingInput, cursorPos);
          insertAtCursorInDiv("INSERT");
      });
      },
    },
];
sheet.setStyle(0, 0, style);
sheet.setValue(0, 0, "Test");

function getCursorIndex(editor) {
    const selection = window.getSelection();
    const range = selection.getRangeAt(0);
    const preCaretRange = range.cloneRange();
    preCaretRange.selectNodeContents(editor);
    preCaretRange.setEnd(range.endContainer, range.endOffset);
    cursorPos = preCaretRange.toString().length;
    console.log(`光标位置: ${cursorPos}`);
}

function moveCursorToIndex(div, index) {
    let currentIndex = 0;
    let targetNode = div.firstChild.childNodes.firstChild;

    if (targetNode.textContent == "=") {
      for (let i = 0; i < div.firstChild.childNodes.length; i++) {
      let node = div.firstChild.childNodes;
      let nodeTextLength = node.textContent.length;

      if (currentIndex + nodeTextLength > index) {
          targetNode = node;
          break;
      }
      currentIndex += nodeTextLength;
      }
    }

    let range = document.createRange();
    let offset = index - currentIndex;
    range.setStart(targetNode, offset);
    range.setEnd(targetNode, offset);
    let selection = document.getSelection();
    selection.removeAllRanges();
    selection.addRange(range);
}

function insertAtCursorInDiv(string) {
    let selection = document.getSelection();
    let textNode = document.createTextNode(string);
    selection.getRangeAt(0).insertNode(textNode);
    selection.collapseToEnd();
}
};
页: [1]
查看完整版本: 给单元格的指定位置插入字符