本帖最后由 Richard.Ma 于 2025-3-5 10:07 编辑
在电子表格的使用过程中,脏单元格是指单元格值被修改过。SpreadJS 提供了 getDirtyCells 方法,可以标记和管理脏数据。然而,SpreadJS 仅在当前工作簿的会话期间跟踪脏数据,并不会在保存到文件时存储这些标记,这意味着下次加载文件时,所有脏数据都会清空。
对于一些用户来说,他们希望能在保存文件时保留脏数据标记,并在下次加载时恢复这些标记,以便继续追踪哪些单元格被修改过。本文将介绍如何通过 tag 属性存储和加载脏数据,从而实现这一需求。
实现思路 SpreadJS 提供了 sheet.tag() 方法,可以为工作表存储额外的元数据,我们可以利用这一特性存储脏数据的列表,并在下次加载时恢复状态。.
代码实现 1.在保存文件前,遍历所有工作表,并将 getDirtyCells() 获取的脏数据存储到 tag 中。 - function saveDirtyCells(spread) {
- spread.sheets.forEach((sheet) => {
- sheet.tag({ "dirtyCells": sheet.getDirtyCells() }); // 将脏数据存入 tag
- });
- }
复制代码
2.在加载 SpreadJS 文件后,读取 tag 并恢复单元格状态,使其重新被标记为脏数据。 - function loadDirtyCells(spread) {
- spread.suspendPaint(); // 暂停绘制,提高性能
- spread.suspendCalcService(); // 暂停计算,提高加载效率
- for (var i = 0; i < spread.getSheetCount(); i++) {
- let sheet = spread.getSheet(i);
- var tag = sheet.tag();
-
- if (tag && tag["dirtyCells"] && tag["dirtyCells"].length > 0) {
- let dirtyCells = tag["dirtyCells"];
- // 先还原旧值
- dirtyCells.forEach((dirtyCell) => {
- sheet.setValue(dirtyCell.row, dirtyCell.col, dirtyCell.oldValue ? dirtyCell.oldValue : null);
- });
- // 清除 Pending Changes 以重新标脏
- sheet.clearPendingChanges();
- // 再设置新值,SpreadJS 会重新标记为脏数据
- dirtyCells.forEach((dirtyCell) => {
- sheet.setValue(dirtyCell.row, dirtyCell.col, dirtyCell.newValue);
- });
- console.log(sheet.getDirtyCells()); // 验证脏数据恢复是否成功
- }
- // 额外:为所有脏数据单元格添加单元格状态以可视化跟踪,方便用户识别哪些数据被修改过。(可选)
- sheet.cellStates.clear(new GC.Spread.Sheets.Range(1, 2, 3, 3), GC.Spread.Sheets.SheetArea.viewport);
- var style = new GC.Spread.Sheets.Style();
- style.backColor = 'yellow';
- var range = new GC.Spread.Sheets.Range(-1, -1, -1, -1);
- sheet.cellStates.add(range, GC.Spread.Sheets.CellStatesType.dirty, style);
- }
- spread.resumeCalcService(); // 恢复计算
- spread.resumePaint(); // 恢复绘制
- }
复制代码
该方案适用于需要长期跟踪数据变化的场景,例如:
- 需要在多个会话中跟踪用户的修改情况。
- 需要为用户提供数据修改的历史记录。
- 需要在二次加载时,维持对未提交修改的追踪。
完整的演示demo请参考附件
history_record.zip
(2.03 KB, 下载次数: 1)
|