rapid-spreadjs 1.0.144 → 1.0.145
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.cjs.js +285 -20
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.cjs.min.js +1 -1
- package/dist/index.cjs.min.js.map +1 -1
- package/dist/index.esm.js +285 -20
- package/dist/index.esm.js.map +1 -1
- package/dist/index.esm.min.js +1 -1
- package/dist/index.esm.min.js.map +1 -1
- package/dist/utils/business.d.ts +16 -0
- package/dist/utils/formula.d.ts +90 -1
- package/package.json +1 -1
package/dist/index.cjs.js
CHANGED
|
@@ -1377,6 +1377,231 @@ const BusinessUtils = {
|
|
|
1377
1377
|
* @returns 返回所有需要显示和隐藏的行索引结果对象,格式如:{hasValueIndex: [1, 2, 3], noValueIndex: [4, 5, 6]},hasValueIndex代表所有显示的行索引,noValueIndex代表所有隐藏的行索引
|
|
1378
1378
|
*/
|
|
1379
1379
|
dynamicLoadRows: (GC, spread, dynamicLoadRangeJson, headerRangeHeight, footerRangeHeight, remainingHeight = 500, pageDir = 1, blankRowCellValue = '空白') => {
|
|
1380
|
+
const sheet = spread.getActiveSheet();
|
|
1381
|
+
// 暂停绘制
|
|
1382
|
+
sheet.suspendPaint();
|
|
1383
|
+
// 获取所有单元格对象
|
|
1384
|
+
const cells = SheetUtils.getAllCellObjsByRanges(sheet, dynamicLoadRangeJson);
|
|
1385
|
+
// 设置所有行可见,原因是:如果再次执行的时候,第一次隐藏的行没有还原
|
|
1386
|
+
cells.forEach((item, index) => {
|
|
1387
|
+
sheet.setRowVisible(item.row, true);
|
|
1388
|
+
});
|
|
1389
|
+
// 获取按照row分组后的数据,格式如:{"1":[{row: 1, col: 43, rowCount: 1, colCount: 24}]}
|
|
1390
|
+
const cellsGroupByRow = rapidUtils.groupByJson(cells, 'row');
|
|
1391
|
+
// 获取序号列的跨列数
|
|
1392
|
+
let seqColSpanCount = null;
|
|
1393
|
+
// 最终行索引Key对应的单元格对象集合(跨行的索引)
|
|
1394
|
+
let rowCells = [];
|
|
1395
|
+
rapidUtils.forEachJson(cellsGroupByRow, (cellItems, rowIndexKey, source) => {
|
|
1396
|
+
if (seqColSpanCount == null) {
|
|
1397
|
+
const seqSpans = sheet.getSpans(sheet.getCell(parseInt(rowIndexKey), 1));
|
|
1398
|
+
seqColSpanCount = seqSpans[0].colCount;
|
|
1399
|
+
}
|
|
1400
|
+
// 得到序号列的跨行单元格对象
|
|
1401
|
+
const seqColSpanObj = sheet.getSpans({ row: parseInt(rowIndexKey), col: 1, rowCount: cellItems[0].rowCount, colCount: seqColSpanCount })[0];
|
|
1402
|
+
// 当前序号跨行单元格对应的所有单元格中是否有值
|
|
1403
|
+
let curRowHasValue = false;
|
|
1404
|
+
// 当前所有行索引
|
|
1405
|
+
let curRowIndexs = [];
|
|
1406
|
+
for (let i = 0; i < cellItems.length; i++) {
|
|
1407
|
+
// 获取当前单元格对象
|
|
1408
|
+
const cell = cellItems[i];
|
|
1409
|
+
for (let j = cell.row; j < cell.row + cell.rowCount; j++) {
|
|
1410
|
+
if (!curRowIndexs.some((x) => x == j)) {
|
|
1411
|
+
curRowIndexs.push(j);
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
// 获取当前单元格的值
|
|
1415
|
+
const cellValue = sheet.getValue(cell.row, cell.col);
|
|
1416
|
+
// 验证是否有值
|
|
1417
|
+
if (cellValue !== null &&
|
|
1418
|
+
cellValue !== undefined &&
|
|
1419
|
+
cellValue !== '' &&
|
|
1420
|
+
cellValue !== '/' &&
|
|
1421
|
+
!(cellValue instanceof GC.Spread.CalcEngine.CalcError)) {
|
|
1422
|
+
curRowHasValue = true;
|
|
1423
|
+
break;
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
let rowObjs = { row: parseInt(rowIndexKey), rows: curRowIndexs, cells: cellItems, hasValue: curRowHasValue };
|
|
1427
|
+
if (!rowCells.some((x) => x.rowSpan == seqColSpanObj.row)) {
|
|
1428
|
+
let rowIndexs = [];
|
|
1429
|
+
const seqColSpanRowSpan = sheet.getSpans({ row: seqColSpanObj.row, col: 1, rowCount: 1, colCount: 1 })[0];
|
|
1430
|
+
for (let i = 0; i < seqColSpanRowSpan.rowCount; i++) {
|
|
1431
|
+
rowIndexs.push(seqColSpanObj.row + i);
|
|
1432
|
+
}
|
|
1433
|
+
rowCells.push({
|
|
1434
|
+
rowSpan: seqColSpanObj.row,
|
|
1435
|
+
rowIndexs: rowIndexs,
|
|
1436
|
+
rows: [rowObjs],
|
|
1437
|
+
});
|
|
1438
|
+
}
|
|
1439
|
+
else {
|
|
1440
|
+
let curRow = rowCells.find((x) => x.rowSpan == seqColSpanObj.row);
|
|
1441
|
+
curRow.rows.push(rowObjs);
|
|
1442
|
+
}
|
|
1443
|
+
});
|
|
1444
|
+
// 有值和没有值的行索引集合
|
|
1445
|
+
let hasValueRows = [], noValueRows = [];
|
|
1446
|
+
// 有值的行索引(序号列使用)
|
|
1447
|
+
let hasValueRowsSer = [];
|
|
1448
|
+
rowCells.forEach((rowObj, index) => {
|
|
1449
|
+
if (rowObj.rows.some((x) => x.hasValue) && !hasValueRowsSer.some((x) => x == rowObj.rowSpan)) {
|
|
1450
|
+
hasValueRowsSer.push(rowObj.rowSpan);
|
|
1451
|
+
}
|
|
1452
|
+
if (rowObj.rows.some((x) => x.hasValue)) {
|
|
1453
|
+
// rowObj.rows.forEach(x => {
|
|
1454
|
+
// x.rows.forEach(rowIndex => {
|
|
1455
|
+
// if (!hasValueRows.some(hItem => hItem == rowIndex)) {
|
|
1456
|
+
// hasValueRows.push(rowIndex);
|
|
1457
|
+
// }
|
|
1458
|
+
// });
|
|
1459
|
+
// });
|
|
1460
|
+
rowObj.rowIndexs.forEach((rowIndex) => {
|
|
1461
|
+
if (!hasValueRows.some((hItem) => hItem == rowIndex)) {
|
|
1462
|
+
hasValueRows.push(rowIndex);
|
|
1463
|
+
}
|
|
1464
|
+
});
|
|
1465
|
+
}
|
|
1466
|
+
else {
|
|
1467
|
+
// rowObj.rows.forEach(x => {
|
|
1468
|
+
// x.rows.forEach(rowIndex => {
|
|
1469
|
+
// if (!noValueRows.some(hItem => hItem == rowIndex)) {
|
|
1470
|
+
// noValueRows.push(rowIndex);
|
|
1471
|
+
// }
|
|
1472
|
+
// });
|
|
1473
|
+
// });
|
|
1474
|
+
rowObj.rowIndexs.forEach((rowIndex) => {
|
|
1475
|
+
if (!noValueRows.some((hItem) => hItem == rowIndex)) {
|
|
1476
|
+
noValueRows.push(rowIndex);
|
|
1477
|
+
}
|
|
1478
|
+
});
|
|
1479
|
+
}
|
|
1480
|
+
});
|
|
1481
|
+
let serNum = 0;
|
|
1482
|
+
hasValueRowsSer.forEach((rowIndex, index) => {
|
|
1483
|
+
const curVal = sheet.getValue(rowIndex, 1);
|
|
1484
|
+
// 检查第一个单元格的值是否包含非数字字符,有非数字字符的时候代表不填充序号
|
|
1485
|
+
if (!/^(?!\d+$)[\u4e00-\u9fa5a-zA-Z0-9!@#$%^&*()_+[\]{};':",.\/?\\|-]+$/.test(curVal)) {
|
|
1486
|
+
serNum++;
|
|
1487
|
+
// 设置序号列单元格的值(1、2、3...的格式)
|
|
1488
|
+
sheet.setValue(rowIndex, 1, serNum);
|
|
1489
|
+
}
|
|
1490
|
+
});
|
|
1491
|
+
hasValueRows.forEach((rowIndex, index) => {
|
|
1492
|
+
// 设置行可见
|
|
1493
|
+
sheet.setRowVisible(rowIndex, true);
|
|
1494
|
+
});
|
|
1495
|
+
noValueRows.forEach((rowIndex) => {
|
|
1496
|
+
// 设置行不可见
|
|
1497
|
+
sheet.setRowVisible(rowIndex, false);
|
|
1498
|
+
});
|
|
1499
|
+
/** 创建空白行单元格 */
|
|
1500
|
+
const createBlackRowCell = () => {
|
|
1501
|
+
// 工作表总高度
|
|
1502
|
+
const sheetTotalHeight = pageDir == 1 ? 1055 : 615;
|
|
1503
|
+
// 之前已经创建的空白行索引
|
|
1504
|
+
let createBlackRowIndex = -1;
|
|
1505
|
+
// 获取所有可见行的总高度
|
|
1506
|
+
let allRowHeight = 0;
|
|
1507
|
+
for (let i = 0; i < sheet.getRowCount(); i++) {
|
|
1508
|
+
const curRowVisible = sheet.getRowVisible(i);
|
|
1509
|
+
const blankRowCell = sheet.getTag(i, 1);
|
|
1510
|
+
if (curRowVisible && (blankRowCell == null || blankRowCell == undefined || blankRowCell != 'BlankCell')) {
|
|
1511
|
+
allRowHeight += sheet.getRowHeight(i);
|
|
1512
|
+
}
|
|
1513
|
+
// 设置已创建的空白行索引
|
|
1514
|
+
if (blankRowCell == 'BlankCell') {
|
|
1515
|
+
createBlackRowIndex = i;
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
// 针对纵表情况,工作表总高度-表头和表尾总高度>=remainingHeight,空白行不显示;<remainingHeight,空白行显示
|
|
1519
|
+
// 是否显示空白行
|
|
1520
|
+
let isShowBlankRow = true;
|
|
1521
|
+
if (pageDir == 1 && allRowHeight - headerRangeHeight - footerRangeHeight >= remainingHeight) {
|
|
1522
|
+
isShowBlankRow = false;
|
|
1523
|
+
}
|
|
1524
|
+
if (!isShowBlankRow) {
|
|
1525
|
+
// 设置行不可见
|
|
1526
|
+
if (createBlackRowIndex != -1) {
|
|
1527
|
+
sheet.setRowVisible(createBlackRowIndex, false);
|
|
1528
|
+
}
|
|
1529
|
+
return;
|
|
1530
|
+
}
|
|
1531
|
+
// 获取到最后一行动态加载区域的行索引
|
|
1532
|
+
const lastRowIndex = rowCells[rowCells.length - 1].rowSpan +
|
|
1533
|
+
sheet.getSpans({ row: rowCells[rowCells.length - 1].rowSpan, col: 1, rowCount: 1, colCount: 1 })[0].rowCount -
|
|
1534
|
+
1; // dynamicLoadRangeJson[0].row + dynamicLoadRangeJson[0].rowCount - 1;
|
|
1535
|
+
// 创建空白行
|
|
1536
|
+
if (allRowHeight < sheetTotalHeight) {
|
|
1537
|
+
// 获取空白行单元格的标签
|
|
1538
|
+
const blankRowCell = sheet.getTag(lastRowIndex + 1, 1);
|
|
1539
|
+
if (!blankRowCell || blankRowCell !== 'BlankCell') {
|
|
1540
|
+
// 添加一行、合并单元格
|
|
1541
|
+
sheet.addRows(lastRowIndex + 1, 1);
|
|
1542
|
+
sheet.addSpan(lastRowIndex + 1, 1, 1, 77);
|
|
1543
|
+
// 设置添加这一行的行高
|
|
1544
|
+
sheet.setRowHeight(lastRowIndex + 1, sheetTotalHeight - allRowHeight);
|
|
1545
|
+
// 获取添加这一行的区域范围
|
|
1546
|
+
const addRowRange = sheet.getRange(lastRowIndex + 1, 1, 1, 77);
|
|
1547
|
+
// 设置边框线
|
|
1548
|
+
addRowRange.setBorder(new GC.Spread.Sheets.LineBorder('#000', GC.Spread.Sheets.LineStyle.thin), { all: true });
|
|
1549
|
+
addRowRange.setBorder(new GC.Spread.Sheets.LineBorder('#000', GC.Spread.Sheets.LineStyle.medium), {
|
|
1550
|
+
left: true,
|
|
1551
|
+
right: true,
|
|
1552
|
+
top: false,
|
|
1553
|
+
bottom: false,
|
|
1554
|
+
});
|
|
1555
|
+
// 设置单元格水平和垂直居中
|
|
1556
|
+
addRowRange.hAlign(GC.Spread.Sheets.HorizontalAlign.center);
|
|
1557
|
+
addRowRange.vAlign(GC.Spread.Sheets.HorizontalAlign.center);
|
|
1558
|
+
sheet.setValue(lastRowIndex + 1, 1, blankRowCellValue);
|
|
1559
|
+
sheet.setTag(lastRowIndex + 1, 1, 'BlankCell');
|
|
1560
|
+
}
|
|
1561
|
+
else {
|
|
1562
|
+
// 设置添加这一行的行高
|
|
1563
|
+
sheet.setRowHeight(lastRowIndex + 1, sheetTotalHeight - allRowHeight);
|
|
1564
|
+
// 显示空白行单元格
|
|
1565
|
+
sheet.setRowVisible(lastRowIndex + 1, true);
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
// 隐藏空白行单元格
|
|
1569
|
+
else {
|
|
1570
|
+
const blankRowCell = sheet.getTag(lastRowIndex + 1, 1);
|
|
1571
|
+
// 如果空白行单元格标签存在,则隐藏
|
|
1572
|
+
if (blankRowCell && blankRowCell == 'BlankCell') {
|
|
1573
|
+
sheet.setRowVisible(lastRowIndex + 1, false);
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1576
|
+
};
|
|
1577
|
+
createBlackRowCell();
|
|
1578
|
+
// // 处理单元格边框线的问题
|
|
1579
|
+
// const allRowIndex = orderByJson(unionJson(hasValueRows, noValueRows));
|
|
1580
|
+
// const rowRange = sheet.getRange(allRowIndex[0], 1, allRowIndex.length, 77);
|
|
1581
|
+
// rowRange.setBorder(new GC.Spread.Sheets.LineBorder('#000', GC.Spread.Sheets.LineStyle.thin), { all: true });
|
|
1582
|
+
// rowRange.setBorder(new GC.Spread.Sheets.LineBorder('#000', GC.Spread.Sheets.LineStyle.medium), {
|
|
1583
|
+
// left: true,
|
|
1584
|
+
// right: true,
|
|
1585
|
+
// top: false,
|
|
1586
|
+
// bottom: false,
|
|
1587
|
+
// });
|
|
1588
|
+
// 恢复绘制
|
|
1589
|
+
sheet.resumePaint();
|
|
1590
|
+
return { hasValueIndex: hasValueRows, noValueIndex: noValueRows };
|
|
1591
|
+
},
|
|
1592
|
+
/**
|
|
1593
|
+
* 动态加载行(动态显示数据行和序号值)
|
|
1594
|
+
* @param GC GC对象
|
|
1595
|
+
* @param spread 工作簿实例
|
|
1596
|
+
* @param dynamicLoadRangeJson 动态加载的“试验结果”JSON数组范围,格式如:[{row: 1, col: 1, rowCount: 1, colCount: 1}]
|
|
1597
|
+
* @param headerRangeHeight 表头区域总高度
|
|
1598
|
+
* @param footerRangeHeight 表尾区域总高度
|
|
1599
|
+
* @param remainingHeight 剩余高度(针对纵表情况,工作表总高度-表头和表尾总高度>=remainingHeight,空白行不显示;<remainingHeight,空白行显示)
|
|
1600
|
+
* @param pageDir 页面方向(1:纵向、2:横向)
|
|
1601
|
+
* @param blankRowCellValue 空白行单元格值,默认为:空白
|
|
1602
|
+
* @returns 返回所有需要显示和隐藏的行索引结果对象,格式如:{hasValueIndex: [1, 2, 3], noValueIndex: [4, 5, 6]},hasValueIndex代表所有显示的行索引,noValueIndex代表所有隐藏的行索引
|
|
1603
|
+
*/
|
|
1604
|
+
dynamicLoadRows_Backup: (GC, spread, dynamicLoadRangeJson, headerRangeHeight, footerRangeHeight, remainingHeight = 500, pageDir = 1, blankRowCellValue = '空白') => {
|
|
1380
1605
|
const sheet = spread.getActiveSheet();
|
|
1381
1606
|
// 暂停绘制
|
|
1382
1607
|
sheet.suspendPaint();
|
|
@@ -15889,37 +16114,77 @@ const FormulaUtils = {
|
|
|
15889
16114
|
return retData.allCellVals.length;
|
|
15890
16115
|
},
|
|
15891
16116
|
},
|
|
16117
|
+
// {
|
|
16118
|
+
// funName: 'YjMid',
|
|
16119
|
+
// funDesc: '获取所有选择的单元格中的中间值',
|
|
16120
|
+
// funDefaultVal: null,
|
|
16121
|
+
// funParams: [
|
|
16122
|
+
// {
|
|
16123
|
+
// name: '数值1',
|
|
16124
|
+
// repeatable: false,
|
|
16125
|
+
// optional: false,
|
|
16126
|
+
// },
|
|
16127
|
+
// {
|
|
16128
|
+
// name: '数值2',
|
|
16129
|
+
// repeatable: false,
|
|
16130
|
+
// optional: false,
|
|
16131
|
+
// },
|
|
16132
|
+
// {
|
|
16133
|
+
// name: '数值3',
|
|
16134
|
+
// repeatable: false,
|
|
16135
|
+
// optional: false,
|
|
16136
|
+
// },
|
|
16137
|
+
// ],
|
|
16138
|
+
// funCallback: (spread, sheet, retData) => {
|
|
16139
|
+
// //得到所有参数中为数字的集合,即:数字参数才参与计算
|
|
16140
|
+
// retData.allCellVals = retData.allCellVals.filter((item) => FormulaUtils.commFun.isNumber(item));
|
|
16141
|
+
// //如果传递的参数小于3个,则返回0
|
|
16142
|
+
// if (retData.allCellVals.length < 3) {
|
|
16143
|
+
// return 0;
|
|
16144
|
+
// }
|
|
16145
|
+
// let retArrVals: Array<number> = FormulaUtils.commFun.convertToInt(retData.allCellVals);
|
|
16146
|
+
// const maxVal = Math.max(...retArrVals),
|
|
16147
|
+
// minVal = Math.min(...retArrVals);
|
|
16148
|
+
// return retArrVals[0] * 1 + retArrVals[1] * 1 + retArrVals[2] * 1 - maxVal * 1 - minVal * 1;
|
|
16149
|
+
// },
|
|
16150
|
+
// },
|
|
15892
16151
|
{
|
|
15893
|
-
funName: '
|
|
16152
|
+
funName: 'YJMID',
|
|
15894
16153
|
funDesc: '获取所有选择的单元格中的中间值',
|
|
15895
16154
|
funDefaultVal: null,
|
|
15896
16155
|
funParams: [
|
|
15897
16156
|
{
|
|
15898
|
-
name: '
|
|
15899
|
-
repeatable: false,
|
|
15900
|
-
optional: false,
|
|
15901
|
-
},
|
|
15902
|
-
{
|
|
15903
|
-
name: '数值2',
|
|
15904
|
-
repeatable: false,
|
|
15905
|
-
optional: false,
|
|
15906
|
-
},
|
|
15907
|
-
{
|
|
15908
|
-
name: '数值3',
|
|
16157
|
+
name: '单元格范围',
|
|
15909
16158
|
repeatable: false,
|
|
15910
16159
|
optional: false,
|
|
15911
16160
|
},
|
|
15912
16161
|
],
|
|
15913
16162
|
funCallback: (spread, sheet, retData) => {
|
|
15914
|
-
|
|
15915
|
-
|
|
15916
|
-
|
|
15917
|
-
|
|
15918
|
-
|
|
16163
|
+
// 步骤1:过滤有效数字(包括数字字符串,如'8'),排除null、undefined、空字符串、'/'、0
|
|
16164
|
+
const validNumbers = retData.allCellVals
|
|
16165
|
+
.filter((item) => {
|
|
16166
|
+
// 将项转换为数字
|
|
16167
|
+
const num = Number(item);
|
|
16168
|
+
// 检查是否为有效数字:非NaN、非0、非无穷大,且原始项不是空字符串或'/'
|
|
16169
|
+
return !isNaN(num) && num !== 0 && isFinite(num) && item !== '' && item !== '/';
|
|
16170
|
+
})
|
|
16171
|
+
.map((item) => Number(item)); // 确保所有项都是数字类型
|
|
16172
|
+
// 如果没有有效数字,返回'/'
|
|
16173
|
+
if (validNumbers.length === 0) {
|
|
16174
|
+
return '/';
|
|
16175
|
+
}
|
|
16176
|
+
// 步骤2:对数字进行升序排序
|
|
16177
|
+
validNumbers.sort((a, b) => a - b);
|
|
16178
|
+
// 步骤3:计算中位数
|
|
16179
|
+
const midIndex = Math.floor(validNumbers.length / 2);
|
|
16180
|
+
// 数组长度为奇数:返回中间值
|
|
16181
|
+
if (validNumbers.length % 2 === 1) {
|
|
16182
|
+
return validNumbers[midIndex];
|
|
16183
|
+
}
|
|
16184
|
+
// 数组长度为偶数:返回中间两个值的平均值
|
|
16185
|
+
else {
|
|
16186
|
+
return (validNumbers[midIndex - 1] + validNumbers[midIndex]) / 2;
|
|
15919
16187
|
}
|
|
15920
|
-
let retArrVals = FormulaUtils.commFun.convertToInt(retData.allCellVals);
|
|
15921
|
-
const maxVal = Math.max(...retArrVals), minVal = Math.min(...retArrVals);
|
|
15922
|
-
return retArrVals[0] * 1 + retArrVals[1] * 1 + retArrVals[2] * 1 - maxVal * 1 - minVal * 1;
|
|
15923
16188
|
},
|
|
15924
16189
|
},
|
|
15925
16190
|
{
|