请选择 进入手机版 | 继续访问电脑版
 找回密码
 立即注册

QQ登录

只需一步,快速开始

Richard.Ma 讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2025-3-5 10:04  /   查看:60  /  回复:0
本帖最后由 Richard.Ma 于 2025-3-5 10:07 编辑

       在电子表格的使用过程中,脏单元格是指单元格值被修改过。SpreadJS 提供了 getDirtyCells 方法,可以标记和管理脏数据。然而,SpreadJS 仅在当前工作簿的会话期间跟踪脏数据,并不会在保存到文件时存储这些标记,这意味着下次加载文件时,所有脏数据都会清空。

       对于一些用户来说,他们希望能在保存文件时保留脏数据标记,并在下次加载时恢复这些标记,以便继续追踪哪些单元格被修改过。本文将介绍如何通过 tag 属性存储和加载脏数据,从而实现这一需求。

实现思路
SpreadJS 提供了 sheet.tag() 方法,可以为工作表存储额外的元数据,我们可以利用这一特性存储脏数据的列表,并在下次加载时恢复状态。.

代码实现
1.在保存文件前,遍历所有工作表,并将 getDirtyCells() 获取的脏数据存储到 tag 中。
  1. function saveDirtyCells(spread) {
  2.     spread.sheets.forEach((sheet) => {
  3.         sheet.tag({ "dirtyCells": sheet.getDirtyCells() }); // 将脏数据存入 tag
  4.     });
  5. }
复制代码

2.在加载 SpreadJS 文件后,读取 tag 并恢复单元格状态,使其重新被标记为脏数据。
  1. function loadDirtyCells(spread) {
  2.     spread.suspendPaint(); // 暂停绘制,提高性能
  3.     spread.suspendCalcService(); // 暂停计算,提高加载效率

  4.     for (var i = 0; i < spread.getSheetCount(); i++) {
  5.         let sheet = spread.getSheet(i);
  6.         var tag = sheet.tag();
  7.         
  8.         if (tag && tag["dirtyCells"] && tag["dirtyCells"].length > 0) {
  9.             let dirtyCells = tag["dirtyCells"];

  10.             // 先还原旧值
  11.             dirtyCells.forEach((dirtyCell) => {
  12.                 sheet.setValue(dirtyCell.row, dirtyCell.col, dirtyCell.oldValue ? dirtyCell.oldValue : null);
  13.             });

  14.             // 清除 Pending Changes 以重新标脏
  15.             sheet.clearPendingChanges();

  16.             // 再设置新值,SpreadJS 会重新标记为脏数据
  17.             dirtyCells.forEach((dirtyCell) => {
  18.                 sheet.setValue(dirtyCell.row, dirtyCell.col, dirtyCell.newValue);
  19.             });

  20.             console.log(sheet.getDirtyCells()); // 验证脏数据恢复是否成功
  21.         }

  22.         // 额外:为所有脏数据单元格添加单元格状态以可视化跟踪,方便用户识别哪些数据被修改过。(可选)
  23.         sheet.cellStates.clear(new GC.Spread.Sheets.Range(1, 2, 3, 3), GC.Spread.Sheets.SheetArea.viewport);
  24.         var style = new GC.Spread.Sheets.Style();
  25.         style.backColor = 'yellow';
  26.         var range = new GC.Spread.Sheets.Range(-1, -1, -1, -1);
  27.         sheet.cellStates.add(range, GC.Spread.Sheets.CellStatesType.dirty, style);
  28.     }

  29.     spread.resumeCalcService(); // 恢复计算
  30.     spread.resumePaint(); // 恢复绘制
  31. }
复制代码


该方案适用于需要长期跟踪数据变化的场景,例如:

  • 需要在多个会话中跟踪用户的修改情况。
  • 需要为用户提供数据修改的历史记录。
  • 需要在二次加载时,维持对未提交修改的追踪。



完整的演示demo请参考附件
history_record.zip (2.03 KB, 下载次数: 1)

0 个回复

您需要登录后才可以回帖 登录 | 立即注册
返回顶部