版本升级
v9
- 可以放在opitons里作为一个属性设置
v10:
- license必须以
jspreadsheet.setLicense("参数")
形式设置
页面无响应
系统设置/报告自动生成管理,会经过多次无响应弹窗提醒,才能显示页面
原因
- 单元格太多
- 无版本无关
解决办法
给电子表格设置属性tableOverflow: true
解决思路
下拉组件新增数据没有显示
问题原因
对电子表格数据做二次处理时,没有使数据的属性一一对应
- 红色框的数据应该一一对应
- 蓝色框的数据应该一一对应
正确展示的数据
时间组件选择秒
解决办法
- 修改
jsutil
源码,需要引入自定义的jsutil
- 在
feature/jspreadsheet
分支中已经引入,在表格自动生成管理
页面中可以直接使用
项目修改
因为是自定义了jsutil
,避免其它同事知道或者升级等其它风险,所以后续请做以下操作
- 删除
package.json
的中jspreadsheet
和jsuites
,并重新安装依赖 删除其它页面中引用到的代码
import jspreadsheet from "jspreadsheet"; import jSuites from "jsuites"; import "jspreadsheet/dist/jspreadsheet.css"; import "jsuites/dist/jsuites.css";
- 把原
options.license
修改为jspreadsheet.setLicense("参数")
,v10版本后需要这样设置 - 以
public/index.html
中的引用版本中准,jspreadsheet
:v10,jsuites
:v5(以v5的基础上自定义了源码)
修改后的效果
选择时分秒
不选择时分秒
合并表格拖拉复制
已支持操作
暂不支持操作
拖动到的格子与原格子不匹配
超出边界
表格拖拉序号自增
已支持操作
暂不支持的操作
表格中原本有其它内容,导致数字跳转,如下图中跳转了3
应对解决办法
单元格合并及序号自增的代码
单元格合并思路
例如: 要实现拖拉时复制多份合并的单元格
第一步: 找到拖拉前选中的单元格中拥有合并信息的单元格
第二步:找到拖拉后新选中的单元格们
第三步: 在拖拉后根据偏移量,在新选中的单元格中,重新设置合并单元格信息
- 此例子拖拉前的拥有合并信息的格子是A2,拖拉前选中的单元格为纵向格子数为3
- 向下拉,拖拉点是x不变,y变(B3=>B9),所以偏移是6
- 所以要根据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>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。