1

版本升级

v9

  1. 可以放在opitons里作为一个属性设置

v10:

  1. license必须以jspreadsheet.setLicense("参数")形式设置

页面无响应

系统设置/报告自动生成管理,会经过多次无响应弹窗提醒,才能显示页面

b5de0ba56eeb2754cd031cd095a1c1c7.png

原因

  1. 单元格太多
  2. 无版本无关

解决办法

给电子表格设置属性tableOverflow: true

电子表格性能链接

解决思路

image.png

下拉组件新增数据没有显示

问题原因

对电子表格数据做二次处理时,没有使数据的属性一一对应

  1. 红色框的数据应该一一对应
  2. 蓝色框的数据应该一一对应
    QQ截图20230810173319.png

正确展示的数据

freemarker生成代码.gif

image.png

时间组件选择秒

解决办法

  1. 修改jsutil源码,需要引入自定义的jsutil
  2. feature/jspreadsheet分支中已经引入,在表格自动生成管理页面中可以直接使用

项目修改

因为是自定义了jsutil,避免其它同事知道或者升级等其它风险,所以后续请做以下操作

  1. 删除package.json的中jspreadsheetjsuites,并重新安装依赖
  2. 删除其它页面中引用到的代码

      import jspreadsheet from "jspreadsheet";
      import jSuites from "jsuites";
      import "jspreadsheet/dist/jspreadsheet.css";
      import "jsuites/dist/jsuites.css";
  3. 把原options.license修改为jspreadsheet.setLicense("参数"),v10版本后需要这样设置
  4. public/index.html中的引用版本中准,jspreadsheet:v10,jsuites:v5(以v5的基础上自定义了源码)

image.png

修改后的效果

选择时分秒

QQ截图20230810175211.png

不选择时分秒

QQ截图20230810175045.png

合并表格拖拉复制

已支持操作

444.gif

暂不支持操作

拖动到的格子与原格子不匹配

freemarker生成代码.gif

freemarker生成代码.gif

超出边界

111.gif

表格拖拉序号自增

已支持操作

555.gif

暂不支持的操作

表格中原本有其它内容,导致数字跳转,如下图中跳转了3

666.gif

应对解决办法

777.gif

单元格合并及序号自增的代码

单元格合并思路

例如: 要实现拖拉时复制多份合并的单元格

888.gif

第一步: 找到拖拉前选中的单元格中拥有合并信息的单元格

FB534A51-3F49-40f2-8BCC-99F1D4B03F46.png

第二步:找到拖拉后新选中的单元格们

image.png

第三步: 在拖拉后根据偏移量,在新选中的单元格中,重新设置合并单元格信息
  1. 此例子拖拉前的拥有合并信息的格子是A2,拖拉前选中的单元格为纵向格子数为3
  2. 向下拉,拖拉点是x不变,y变(B3=>B9),所以偏移是6
  3. 所以要根据2(6/3=2)份单元格,即给A5,A8的单元格更新合并信息(2+3=5,5+3=8,...)

序号自增思路

第一步: 找到内容为纯数字字符加数字的单元格
第二步: 拖拉后新的单元格会更新单元格的内容(在jspreadsheet中的onafterchanges事件中能监听到)
第三步: 给纯数字+1,或给字符加数字+1

代码

<template>
  <div>
    <p>运行前注意license是否有效,无效请到官网demo中复制一个</p>
    <div ref="jspreadsheet" />
  </div>
</template>
<script>
export default {
  name: "Jspreadsheet",
  data() {
    return {
      jspreadsheet: "", //电子表格dom实例

      selectCellsName: [], //拖拉前选中的单元格们的name
      selectCellsMerge: [], //拖拉前选中的单元格们的合并信息
      isStartDraging: false, //是否在拖拉中
      isAfterchanges: false, //是否完成拖拉后修改单元格
      afterchangesRecords: [], //拖拉后修改的单元格们

      beforeDragSelectedStartPosition: {
        //拖拉前选中的单元格们的起始坐标
        x: -1,
        y: -1,
      },
      beforeDragSelectedEndPosition: {
        //拖拉前选中的单元格们的终止坐标
        x: -1,
        y: -1,
      },
      beforeDragSelectedOffset: {
        //拖拉前选中的单元格们的x轴和y轴的偏移
        x: -1,
        y: -1,
      },

      afterDragNewSelectedStartPosition: {
        //拖拉后选中的单元格们的起始坐标
        x: -1,
        y: -1,
      },
      afterDragNewSelectedEndPosition: {
        //拖拉后选中的单元格们的终止坐标
        x: -1,
        y: -1,
      },
      afterDragSelectedOffset: {
        //拖拉后选中的单元格们的x轴和y轴的偏移
        x: -1,
        y: -1,
      },
    };
  },
  mounted() {
    this.initSheet();
  },
  methods: {
    //初始化电子表格
    initSheet() {
      jspreadsheet.setLicense(
        "OGM5YjI1NjY3NzdiNGQxOWU1NWIwNDUzYWQyYjQxOWQwOTc2MzVjMjNjMjRjODBhZGFiZDU5ZTE3YjNhYTE4NGNkYTM2ODUxMmQxM2UwNmY3ZWQxMjJmYjBhMTJjYzhkMWJkNjUzYWMyNGQ4ZGU4MDk3NjY3MWMwNWQxMzRhMjcsZXlKdVlXMWxJam9pU25Od2NtVmhaSE5vWldWMElpd2laR0YwWlNJNk1UWTVNakkxTmpZeE9Dd2laRzl0WVdsdUlqcGJJbXB6Y0hKbFlXUnphR1ZsZEM1amIyMGlMQ0pqYjJSbGMyRnVaR0p2ZUM1cGJ5SXNJbXB6YUdWc2JDNXVaWFFpTENKamMySXVZWEJ3SWl3aWQyVmlJaXdpYkc5allXeG9iM04wSWwwc0luQnNZVzRpT2lJek5DSXNJbk5qYjNCbElqcGJJblkzSWl3aWRqZ2lMQ0oyT1NJc0luWXhNQ0lzSW1Ob1lYSjBjeUlzSW1admNtMXpJaXdpWm05eWJYVnNZU0lzSW5CaGNuTmxjaUlzSW5KbGJtUmxjaUlzSW1OdmJXMWxiblJ6SWl3aWFXMXdiM0owSWl3aVltRnlJaXdpZG1Gc2FXUmhkR2x2Ym5NaUxDSnpaV0Z5WTJnaUxDSndjbWx1ZENJc0luTm9aV1YwY3lKZExDSmtaVzF2SWpwMGNuVmxmUT09"
      );

      this.jspreadsheet = jspreadsheet(this.$refs.jspreadsheet, {
        data: [
          ["aaa", "AA", "2000", "2000", "2000", "2000"],
          ["bbbb", "BB", "5000", "2000", "2000", "2000"],
          ["cccc", "CC", "3000", "2000", "2000", "2000"],
          ["a", "1", "a9", "aa1", "我我1", "我我  a我1"],
          // ["ddddd", "DD", "我1", "我我11", "aa1", "a1"],
          // ["cccc", "CC", "3000", "2000", "2000", "2000"],
          // ["a", "1", "a9", "aa1", "我我1", "我我  a我1"],
          // ["ddddd", "DD", "我1", "我我11", "aa1", "a1"],
          // ["cccc", "CC", "3000", "2000", "2000", "2000"],
          // ["a", "1", "a9", "aa1", "我我1", "我我  a我1"],
          // ["ddddd", "DD", "我1", "我我11", "aa1", "a1"],
        ],
        columns: [
          {
            type: "text",
            width: "300px",
          },
          {
            type: "text",
            width: "80px",
          },
          {
            type: "text",
            width: "100px",
          },
        ],
        mergeCells: {
          A2: [2, 2],
          // A5: [2, 2],
        },
        minDimensions: [10, 20],
        //监听已经选中的表格cells
        onselection: (worksheet, px, py, ux, uy, origin) => {
          this.onCornerEvents({
            eventName: "onselection",
            params: {
              px,
              py,
              ux,
              uy,
            },
          });
          //开始拖拉
          if (this.isStartDraging) {
            // 获取拖拉后选中的起始坐标
            this.afterDragNewSelectedStartPosition = {
              x: this.beforeDragSelectedEndPosition.x + 1,
              y: this.beforeDragSelectedEndPosition.y + 1,
            };
            // 获取拖拉后选中的终止坐标
            this.afterDragNewSelectedEndPosition = {
              x: ux + 1,
              y: uy + 1,
            };
          }
        },
        // 拖拉后改变的cells数据
        onafterchanges: (worksheet, afterchangesRecords) => {
          this.isAfterchanges = true;
          this.afterchangesRecords = afterchangesRecords;
        },
      });
    },
    //获取选中的cells中的合并的信息及其名字
    getMergeCellsNameAndMerge(px, py, ux, uy) {
      this.selectCellsName = [];
      this.beforeDragSelectedStartPosition = {
        x: px,
        y: py,
      };
      this.beforeDragSelectedEndPosition = {
        x: ux,
        y: uy,
      };
      //获取拖拉前选中的单元格中的有合并的单元格name
      for (let i = this.beforeDragSelectedStartPosition.x; i <= this.beforeDragSelectedEndPosition.x; i++) {
        for (let j = this.beforeDragSelectedStartPosition.y; j <= this.beforeDragSelectedEndPosition.y; j++) {
          const res = this.numberConvertToLetter(i + 1) + (j + 1);
          if (!this.selectCellsName.includes(res)) {
            this.selectCellsName.push(res);
          }
        }
      }
      // 拖拉前选中的单元格x,y和偏移
      this.beforeDragSelectedOffset = {
        x: ux - px + 1,
        y: uy - py + 1,
      };
      this.getCellsMerge();
    },
    // 根据cell的name获取多个cell的合并信息
    getCellsMerge() {
      this.selectCellsMerge = [];
      this.selectCellsName.forEach((item) => {
        if (this.jspreadsheet.getMerge(item))
          this.selectCellsMerge.push({
            [item]: this.jspreadsheet.getMerge(item),
          });
      });
    },
    //数字转字母,如1=>A,2=>B,... 27=>AA,28=>AB
    numberConvertToLetter(columnNumber) {
      let ans = [];
      while (columnNumber > 0) {
        const a0 = ((columnNumber - 1) % 26) + 1;
        ans.push(String.fromCharCode(a0 - 1 + "A".charCodeAt()));
        columnNumber = Math.floor((columnNumber - a0) / 26);
      }
      ans.reverse();
      return ans.join("");
    },
    //字母转数字,如A=>1,B=>2,... AA=>27,AB=>28
    letterConvertToNumber(str) {
      let count = 0;
      const strArray = str.toUpperCase().split("");
      strArray.forEach(function (item, index) {
        count += item.charCodeAt() - 64 + index * 25;
      });
      return count;
    },
    // 监听拖拉点(选中时的下拉时的十字架)
    onCornerEvents({ eventName, params }) {
      const { px, py, ux, uy } = params;
      const jssCorner = document.getElementsByClassName("jss_corner")[0];
      //鼠标按下
      jssCorner.onmousedown = (mousedownEvent) => {
        if (eventName === "onselection") {
          this.isStartDraging = true;
          this.getMergeCellsNameAndMerge(px, py, ux, uy);
        }
        //鼠标移开
        document.onmouseup = (mouseupEvent) => {
          if (eventName === "onselection") {
            this.isStartDraging = false;
            this.setNewSelectionCells();
          }
          this.updateCellValue();

          document.onmouseup = null;
          document.onmousemove = null;
        };
      };
    },
    //更新cell的value
    updateCellValue() {
      if (this.afterchangesRecords.length) {
        const firstItem = this.afterchangesRecords[0];
        // 判断字符是否是字符加数字,并且是1个或多个字符串开头,1个或多个数字结尾
        const reg = new RegExp(/^(\W|\w)+\d+$/);
        const isStrsNumber = reg.test(firstItem.value);

        if (isStrsNumber) {
          let tempIndexValue = 1;
          this.afterchangesRecords.forEach((item) => {
            let { value } = item;
            value = String(value);
            const prevStrs = value.replace(/^(.*?)\d*$/, (str, match, index) => match || "0"); //找到字符串中前面的所有字符(汉字或英文)
            let nextNumbers = value.replace(/^.*?(\d*)$/, (str, match, index) => match || "0"); //找到字符串中后面的所有数字
            nextNumbers = Number(nextNumbers) + tempIndexValue; //字符串中后面的所有数字+1
            const newValue = prevStrs + nextNumbers; //合并成为新的value
            this.jspreadsheet.updateCell(item.x, item.y, newValue); //更新单元格的value,格式如: updateCell(x,y,value),x,y为坐标
            tempIndexValue++;
          });
        }
      }
    },
    // 下拉时,设置新选中的cell的value
    setNewSelectionCells() {
      //下拉的偏移值
      this.afterDragSelectedOffset = {
        x: this.afterDragNewSelectedEndPosition.x - this.afterDragNewSelectedStartPosition.x,
        y: this.afterDragNewSelectedEndPosition.y - this.afterDragNewSelectedStartPosition.y,
      };
      // 往下拉,即x不变,y变
      if (this.afterDragNewSelectedStartPosition.x === this.afterDragNewSelectedEndPosition.x) {
        this.selectCellsMerge.forEach((item) => {
          const itemKey = Object.keys(item)[0]; //获取到有合并信息的单元格的name,如A1
          const cellNameX = itemKey.replace(/[^a-zA-Z]/gi, ""); //获取数字前的字符串(汉字和英文字符)
          const cellNameY = Number(itemKey.replace(/[^0-9]/gi, "")); //获取最后的一串数字(单个或多个)

          const offsetArr = []; //往下拉时,有多少个偏移,如选中的单元格为2*2,下拉了7个格子,则复制3份
          for (let i = cellNameY; i < this.afterDragNewSelectedEndPosition.y; i += this.beforeDragSelectedOffset.y) {
            if (i > cellNameY) {
              offsetArr.push(i);
            }
          }
          offsetArr.forEach((offsetItem) => {
            let newCellMergeName = cellNameX + offsetItem;
            let cellMergeColspan = Object.values(item)[0][0];
            let cellMergeRowspan = Object.values(item)[0][1];
            //重新设置格子合并,如setMerge("A2",2,2),等同于数据初始化时的 A2: [2, 2],
            this.jspreadsheet.setMerge(newCellMergeName, cellMergeColspan, cellMergeRowspan);
          });
        });
      }

      // 往右拉,即x变,y不变
      if (this.afterDragNewSelectedStartPosition.y === this.afterDragNewSelectedEndPosition.y) {
        this.selectCellsMerge.forEach((item) => {
          const itemKey = Object.keys(item)[0];
          const cellNameX = itemKey.replace(/[^a-zA-Z]/gi, "");
          const cellNameY = Number(itemKey.replace(/[^0-9]/gi, ""));

          const offsetArr = [];
          for (
            let i = this.letterConvertToNumber(cellNameX);
            i < this.afterDragNewSelectedEndPosition.x;
            i += this.beforeDragSelectedOffset.x
          ) {
            if (i > this.letterConvertToNumber(cellNameX)) {
              offsetArr.push(i);
            }
          }
          offsetArr.forEach((offsetItem) => {
            let newCellMergeName = this.numberConvertToLetter(offsetItem) + cellNameY;
            let cellMergeColspan = Object.values(item)[0][0];
            let cellMergeRowspan = Object.values(item)[0][1];
            this.jspreadsheet.setMerge(newCellMergeName, cellMergeColspan, cellMergeRowspan);
          });
        });
      }
    },
  },
};
</script>



aaaa
5 声望0 粉丝

下一篇 »
njs