rapid-spreadjs 1.0.112 → 1.0.115

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.esm.js CHANGED
@@ -74,7 +74,6 @@ const CommonUtils = {
74
74
  },
75
75
  };
76
76
 
77
- // 导入rapid-utils中的函数(注意:需要在tsconfig.json文件中设置moduleResolution为node,否则会提示:找不到模块“rapid-utils”。你的意思是要将 "moduleResolution" 选项设置为 "nodenext",还是要将别名添加到 "paths" 选项中?ts(2792))
78
77
  /**
79
78
  * SpreadJS工作表工具函数属性
80
79
  */
@@ -663,6 +662,130 @@ const SheetUtils = {
663
662
  });
664
663
  return '=' + cellStrings.join(',');
665
664
  },
665
+ /**
666
+ * 粘贴单元格的值
667
+ * @param sheet 工作表对象
668
+ * @param callFn 粘贴成功或失败的回调函数(该回调函数包含2个参数,第一个参数为是否粘贴成功,第二个参数为提示信息)
669
+ */
670
+ pasteCellValues: (sheet, callFn) => __awaiter(void 0, void 0, void 0, function* () {
671
+ // 检查浏览器是否支持Clipboard API
672
+ if (!navigator.clipboard || !navigator.clipboard.readText) {
673
+ // throw new Error("您的浏览器不支持剪贴板读取功能");
674
+ if (callFn != null && callFn != undefined && typeof callFn == 'function') {
675
+ callFn(false, '您的浏览器不支持剪贴板读取功能!');
676
+ }
677
+ return;
678
+ }
679
+ // 请求剪贴板读取权限
680
+ const permission = yield navigator.permissions.query({
681
+ name: 'clipboard-read',
682
+ });
683
+ if (permission.state === 'denied') {
684
+ // throw new Error("剪贴板读取权限被拒绝");
685
+ if (callFn != null && callFn != undefined && typeof callFn == 'function') {
686
+ callFn(false, '剪贴板读取权限被拒绝!');
687
+ }
688
+ return;
689
+ }
690
+ /**
691
+ * 解析从Excel复制的TSV格式数据,能处理单元格内换行符
692
+ * @param data 剪贴板中的原始TSV数据
693
+ * @returns 二维数组,代表行和列
694
+ */
695
+ function parseExcelData(data) {
696
+ const result = [];
697
+ let currentRow = [];
698
+ let currentCell = '';
699
+ let insideQuotes = false; // 标记是否正在读取一个被引号包裹的单元格
700
+ for (let i = 0; i < data.length; i++) {
701
+ const char = data[i];
702
+ if (char === '"') {
703
+ // 遇到引号,切换状态
704
+ if (insideQuotes && data[i + 1] === '"') {
705
+ // 处理转义的双引号 ("")
706
+ currentCell += '"';
707
+ i++; // 跳过下一个引号
708
+ }
709
+ else {
710
+ insideQuotes = !insideQuotes;
711
+ }
712
+ }
713
+ else if (char === '\t' && !insideQuotes) {
714
+ // 遇到制表符且不在引号内,结束当前单元格
715
+ currentRow.push(currentCell);
716
+ currentCell = '';
717
+ }
718
+ else if ((char === '\n' || char === '\r') && !insideQuotes) {
719
+ // 遇到换行符且不在引号内,结束当前行
720
+ // 处理可能是 \r\n 的情况
721
+ if (char === '\r' && data[i + 1] === '\n') {
722
+ i++; // 跳过 \n
723
+ }
724
+ currentRow.push(currentCell);
725
+ result.push(currentRow);
726
+ currentRow = [];
727
+ currentCell = '';
728
+ }
729
+ else {
730
+ // 普通字符,添加到当前单元格
731
+ currentCell += char;
732
+ }
733
+ }
734
+ // 处理最后一行(如果数据不是以换行符结尾)
735
+ if (currentCell !== '' || currentRow.length > 0) {
736
+ currentRow.push(currentCell);
737
+ result.push(currentRow);
738
+ }
739
+ // 过滤掉可能存在的空行(例如复制内容末尾的空白行)
740
+ return result.filter((row) => row.some((cell) => cell.trim() !== ''));
741
+ }
742
+ const allCells = SheetUtils.getSheetSelectCellObjs(sheet);
743
+ const allCellsGroup = groupByJson(allCells, 'row');
744
+ const allCellsEw = [];
745
+ forEachJson(allCellsGroup, (value, key, source) => {
746
+ allCellsEw.push(value);
747
+ });
748
+ // 读取剪贴板文本内容
749
+ const clipboardText = yield navigator.clipboard.readText();
750
+ // 得到剪贴板中的二维数组值
751
+ const clipboardData = parseExcelData(clipboardText);
752
+ // 验证剪贴板的二维数组内容和框选的单元格二维数组是否一致
753
+ let isRight = true;
754
+ if (allCellsEw.length != clipboardData.length) {
755
+ isRight = false;
756
+ }
757
+ else {
758
+ for (let i = 0; i < allCellsEw.length; i++) {
759
+ const row = allCellsEw[i];
760
+ const clipboardRow = clipboardData[i];
761
+ if (row.length != clipboardRow.length) {
762
+ isRight = false;
763
+ break;
764
+ }
765
+ }
766
+ }
767
+ if (!isRight && callFn != null && callFn != undefined && typeof callFn == 'function') {
768
+ callFn(false, '复制的内容区域和框选的表格区域不一致!');
769
+ return;
770
+ }
771
+ sheet.suspendPaint();
772
+ for (let i = 0; i < allCellsEw.length; i++) {
773
+ const row = allCellsEw[i];
774
+ for (let j = 0; j < row.length; j++) {
775
+ const cell = row[j];
776
+ const cellValue = clipboardData[i][j];
777
+ sheet.setValue(cell.row, cell.col, cellValue);
778
+ // 检查内容是否有换行,有就启用单元格自动换行的配置
779
+ if (cellValue && cellValue.includes('\n')) {
780
+ sheet.getCell(cell.row, cell.col).wordWrap(true);
781
+ }
782
+ }
783
+ }
784
+ sheet.resumePaint();
785
+ if (callFn != null && callFn != undefined && typeof callFn == 'function') {
786
+ callFn(true, '粘贴成功!');
787
+ }
788
+ }),
666
789
  };
667
790
 
668
791
  /**
@@ -942,6 +1065,237 @@ const BusinessUtils = {
942
1065
  created(cyclicCellsRange, allCellsByRow);
943
1066
  }
944
1067
  },
1068
+ /**
1069
+ * 显示超差提醒批注信息
1070
+ * @param cctxConfigs 超差提醒配置集合
1071
+ * @param cellRowIndex 发生改变值的单元格行索引
1072
+ * @param cellColIndex 发生改变值的单元格列索引
1073
+ * @param isValueChgedUse 是否为单元格值发生改变的时候调用
1074
+ * @param commentOptions 批注配置项,默认为:{color: '#E11010', size: 10, defaultTextIsSet: true, defaultText: '无效'}(color:批注颜色,size:批注大小,defaultTextIsSet:是否设置单元格默认值,defaultText:单元格默认值内容)
1075
+ */
1076
+ cctxComments: (spread, cctxConfigs, cellRowIndex, cellColIndex, isValueChgedUse = true, commentOptions = {
1077
+ color: '#E11010',
1078
+ size: 10,
1079
+ defaultTextIsSet: true,
1080
+ defaultText: '无效',
1081
+ }) => {
1082
+ if (!cctxConfigs || cctxConfigs.length == 0) {
1083
+ return;
1084
+ }
1085
+ const sheet = spread.getActiveSheet();
1086
+ spread.suspendPaint();
1087
+ spread.suspendCalcService();
1088
+ spread.suspendEvent();
1089
+ // //批注颜色、大小、是否设置单元格默认值、单元格默认值内容
1090
+ // let commentColor = color,
1091
+ // commentSize = 10,
1092
+ // commentDefaultTextIsSet = true,
1093
+ // commentDefaultText = '无效';
1094
+ let commentColor = commentOptions.color ? commentOptions.color : '#E11010', commentSize = commentOptions.size ? commentOptions.size : 10, commentDefaultTextIsSet = commentOptions.defaultTextIsSet ? commentOptions.defaultTextIsSet : true, commentDefaultText = commentOptions.defaultText ? commentOptions.defaultText : '无效';
1095
+ //将a~f这些字母替换为具体的值
1096
+ const replaceVar = (itemExp, varJsonObjs) => {
1097
+ const letters = ['a', 'b', 'c', 'd', 'e', 'f'];
1098
+ letters.forEach((letter) => {
1099
+ if (itemExp.indexOf(letter) > -1) {
1100
+ itemExp = itemExp.replaceAll(letter, varJsonObjs.find((itemVar) => itemVar.var == letter).value);
1101
+ }
1102
+ });
1103
+ return itemExp;
1104
+ };
1105
+ //将1~20这些数字替换为具体的设置条件
1106
+ const replaceNum = (itemExp, conJsonArr) => {
1107
+ const nums = [];
1108
+ for (let iNum = 1; iNum <= 20; iNum++) {
1109
+ nums.push(iNum);
1110
+ }
1111
+ nums.forEach((num) => {
1112
+ if (itemExp.indexOf(num) > -1 && num <= conJsonArr.length) {
1113
+ //将条件公式【1 || (2 && 3)】中的数组替换为#1#的形式
1114
+ itemExp = itemExp.replaceAll(num, `#${num}#`);
1115
+ }
1116
+ });
1117
+ nums.forEach((num) => {
1118
+ if (itemExp.indexOf(num) > -1 && num <= conJsonArr.length) {
1119
+ //将条件公式中的#1#替换为具体的设置条件
1120
+ itemExp = itemExp.replaceAll(`#${num}#`, `(${conJsonArr[num - 1]})`);
1121
+ }
1122
+ });
1123
+ return itemExp;
1124
+ };
1125
+ //获取新的conJson配置集合
1126
+ const getConJsonArrNew = (conJsonArr, varJsonArr) => {
1127
+ let conJsonArrNew = [];
1128
+ conJsonArr.forEach((element) => {
1129
+ let newElement = element;
1130
+ //将abs替换为[###]
1131
+ newElement = newElement.replaceAll('jd(', '精度开始').replaceAll(')jd', '精度结束').replaceAll('abs', '[###]');
1132
+ //将a~f这些字母替换为具体的值
1133
+ newElement = replaceVar(newElement, varJsonArr);
1134
+ //将[###]替换为Math.abs
1135
+ newElement = newElement.replaceAll('[###]', 'Math.abs').replaceAll('精度开始', 'Number(').replaceAll('精度结束', ').toFixed(8)');
1136
+ //将设置条件添加到新的集合中
1137
+ conJsonArrNew.push(newElement);
1138
+ });
1139
+ return conJsonArrNew;
1140
+ };
1141
+ for (let i = 0; i < cctxConfigs.length; i++) {
1142
+ const item = cctxConfigs[i];
1143
+ //有前置条件
1144
+ if (item.isQz) {
1145
+ //获取所有值单元格集合,格式如:[{"var":"a","value":10,"row":,……}]
1146
+ let varJsonArr = JSON.parse(item.varJson);
1147
+ //获取所有前置条件单元格集合,格式如:[{"var":"a","value":10,"row":,……}]
1148
+ let qzCellJsonArr = JSON.parse(item.qzCellJson);
1149
+ const doEvent = () => {
1150
+ varJsonArr.forEach((element) => {
1151
+ element.value = sheet.getValue(element.row, element.col);
1152
+ });
1153
+ //获取所有设置条件集合
1154
+ let conJsonArr = JSON.parse(item.conJson), conJsonArrNew = getConJsonArrNew(conJsonArr, varJsonArr);
1155
+ qzCellJsonArr.forEach((element) => {
1156
+ element.value = sheet.getValue(element.row, element.col);
1157
+ });
1158
+ //获取所有前置条件公式集合,格式如:[{"var":"a","value":10,"row":,……}]
1159
+ let qzGsJsonArr = JSON.parse(item.qzGsJson);
1160
+ qzGsJsonArr.forEach((element) => {
1161
+ element.value = sheet.getValue(element.row, element.col);
1162
+ });
1163
+ //循环所有前置公式
1164
+ //记录是否所有前置公式对应的条件都没有超差
1165
+ let isAllNotCc = true;
1166
+ for (let j = 0; j < qzGsJsonArr.length; j++) {
1167
+ const itemQzgs = qzGsJsonArr[j];
1168
+ //当前公式中的前置条件
1169
+ let curGsQz = itemQzgs.qzFor.replaceAll('jd(', '精度开始').replaceAll(')jd', '精度结束').replaceAll('abs', '[###]');
1170
+ curGsQz = replaceVar(curGsQz, qzCellJsonArr);
1171
+ curGsQz = curGsQz.replaceAll('[###]', 'Math.abs').replaceAll('精度开始', 'Number(').replaceAll('精度结束', ').toFixed(8)');
1172
+ try {
1173
+ //满足其中一个前置条件时
1174
+ if (eval(curGsQz)) {
1175
+ //获取最终的条件公式
1176
+ const lastFor = replaceNum(itemQzgs.conFor, conJsonArrNew);
1177
+ try {
1178
+ //设置批注
1179
+ if (eval(lastFor)) {
1180
+ isAllNotCc = false;
1181
+ sheet.comments
1182
+ .add(item.row, item.col, itemQzgs.tipMsg)
1183
+ .indicatorColor(commentColor)
1184
+ .indicatorSize(commentSize)
1185
+ .fontSize('10pt')
1186
+ .width(200);
1187
+ if (commentDefaultTextIsSet) {
1188
+ sheet.setValue(item.row, item.col, commentDefaultText);
1189
+ }
1190
+ }
1191
+ //取消批注
1192
+ else {
1193
+ sheet.comments.remove(item.row, item.col);
1194
+ if (commentDefaultTextIsSet) {
1195
+ const cellVal = sheet.getValue(item.row, item.col);
1196
+ if (cellVal == commentDefaultText) {
1197
+ sheet.setValue(item.row, item.col, '');
1198
+ }
1199
+ }
1200
+ }
1201
+ }
1202
+ catch (error) {
1203
+ //取消批注
1204
+ sheet.comments.remove(item.row, item.col);
1205
+ if (commentDefaultTextIsSet) {
1206
+ const cellVal = sheet.getValue(item.row, item.col);
1207
+ if (cellVal == commentDefaultText) {
1208
+ sheet.setValue(item.row, item.col, '');
1209
+ }
1210
+ }
1211
+ }
1212
+ break;
1213
+ }
1214
+ }
1215
+ catch (error) {
1216
+ //
1217
+ }
1218
+ }
1219
+ //当所有公式条件都没有超差的时候,需要取消批注
1220
+ if (isAllNotCc) {
1221
+ //取消批注
1222
+ sheet.comments.remove(item.row, item.col);
1223
+ if (commentDefaultTextIsSet) {
1224
+ const cellVal = sheet.getValue(item.row, item.col);
1225
+ if (cellVal == commentDefaultText) {
1226
+ sheet.setValue(item.row, item.col, '');
1227
+ }
1228
+ }
1229
+ }
1230
+ };
1231
+ //如果当前改变值的单元格在varJsonArr集合中存在,则说明是修改的超差提醒配置的相关单元格
1232
+ if (isValueChgedUse) {
1233
+ if (varJsonArr.some((itemVar) => itemVar.row == cellRowIndex && itemVar.col == cellColIndex) ||
1234
+ qzCellJsonArr.some((itemVar) => itemVar.row == cellRowIndex && itemVar.col == cellColIndex)) {
1235
+ doEvent();
1236
+ }
1237
+ }
1238
+ else {
1239
+ doEvent();
1240
+ }
1241
+ }
1242
+ //无前置条件
1243
+ else {
1244
+ //获取所有值单元格集合,格式如:[{"var":"a","value":10,"row":,……}]
1245
+ let varJsonArr = JSON.parse(item.varJson);
1246
+ const doEvent = () => {
1247
+ varJsonArr.forEach((element) => {
1248
+ element.value = sheet.getValue(element.row, element.col);
1249
+ });
1250
+ //获取所有设置条件集合
1251
+ let conJsonArr = JSON.parse(item.conJson), conJsonArrNew = getConJsonArrNew(conJsonArr, varJsonArr);
1252
+ //获取最终的条件公式
1253
+ const lastFor = replaceNum(item.conFor, conJsonArrNew);
1254
+ try {
1255
+ //设置批注
1256
+ if (eval(lastFor)) {
1257
+ sheet.comments.add(item.row, item.col, item.tipMsg).indicatorColor(commentColor).indicatorSize(commentSize).fontSize('10pt').width(200);
1258
+ if (commentDefaultTextIsSet) {
1259
+ sheet.setValue(item.row, item.col, commentDefaultText);
1260
+ }
1261
+ }
1262
+ //取消批注
1263
+ else {
1264
+ sheet.comments.remove(item.row, item.col);
1265
+ if (commentDefaultTextIsSet) {
1266
+ const cellVal = sheet.getValue(item.row, item.col);
1267
+ if (cellVal == commentDefaultText) {
1268
+ sheet.setValue(item.row, item.col, '');
1269
+ }
1270
+ }
1271
+ }
1272
+ }
1273
+ catch (error) {
1274
+ //取消批注
1275
+ sheet.comments.remove(item.row, item.col);
1276
+ if (commentDefaultTextIsSet) {
1277
+ const cellVal = sheet.getValue(item.row, item.col);
1278
+ if (cellVal == commentDefaultText) {
1279
+ sheet.setValue(item.row, item.col, '');
1280
+ }
1281
+ }
1282
+ }
1283
+ };
1284
+ //如果当前改变值的单元格在varJsonArr集合中存在,则说明是修改的超差提醒配置的相关单元格
1285
+ if (isValueChgedUse) {
1286
+ if (varJsonArr.some((itemVar) => itemVar.row == cellRowIndex && itemVar.col == cellColIndex)) {
1287
+ doEvent();
1288
+ }
1289
+ }
1290
+ else {
1291
+ doEvent();
1292
+ }
1293
+ }
1294
+ }
1295
+ spread.resumeEvent();
1296
+ spread.resumeCalcService();
1297
+ spread.resumePaint();
1298
+ },
945
1299
  };
946
1300
 
947
1301
  /**