Undo Manager

SpreadJS allows you to have better control over the undo/redo stack, including setting the maximum size of actions to record. Make any changes below such as editing text or resizing row and cols then undo or redo your actions using the buttons.

You can get the redoStack of spreadJS according to getRedoStack method. You can get the undoStack of spreadJS according to getUndoStack method. You can get or set the max size of redoStack/undoStack according to maxSize method.
window.onload = function () { var spread = new GC.Spread.Sheets.Workbook(_getElementById('ss')); initSpread(spread); } function initSpread(spread) { spread.fromJSON(data[0]); var sheet = spread.getActiveSheet(); attachEvent(spread); executeCommand(spread); updateInfo(spread); } function attachEvent(spread) { var events = GC.Spread.Sheets.Events; spread.bind(events.ValueChanged, updateInfoHandle); spread.bind(events.ViewZoomed, updateInfoHandle); spread.bind(events.ColumnChanged, updateInfoHandle); spread.bind(events.ColumnWidthChanged, updateInfoHandle); spread.bind(events.RowChanged, updateInfoHandle); spread.bind(events.RowHeightChanged, updateInfoHandle); let setButton = _getElementById("gc-max-size-set"); let maxSizeDom = _getElementById("gc-max-size"); let redoButton = _getElementById("gc-redo-button"); let undoButton = _getElementById("gc-undo-button"); let undoManager = spread.undoManager(); setButton.addEventListener("click", () => { let value = Number(maxSizeDom.value); if (!isNaN(value)) { spread.undoManager().maxSize(value); } }) redoButton.addEventListener("click", () => { undoManager.redo(); updateInfo(spread); }) undoButton.addEventListener("click", () => { undoManager.undo(); updateInfo(spread); }) } function executeCommand(spread) { var commandManager = spread.commandManager(); let sheet = spread.getActiveSheet(); let sheetName = sheet.name(); spread.suspendPaint() commandManager.execute({ cmd: "resizeColumn", sheetName: sheetName, size: 70, rowHeader: false, columns: [{ firstCol: 0, lastCol: 5 }], }); commandManager.execute({ cmd: "editCell", sheetName: sheetName, row: 0, col: 0, newValue: "Edit Cell", autoFormat: true, }); commandManager.execute({ cmd: "resizeRow", sheetName: sheetName, rows: [{ firstRow: 0, lastRow: 5, }], size: 30, columnHeader: false, }) spread.undoManager().undo(); spread.resumePaint(); } function updateInfoHandle(sender, info) { var sheet = info.sheet; var spread = sheet.parent; updateInfo(spread); } function updateInfo(spread) { var undoManager = spread.undoManager(); setTimeout(() => { updateUndoInfo(undoManager); updateRedoInfo(undoManager); }, 0); } function updateUndoInfo(undoManager) { var undoStack = undoManager.getUndoStack(); var description = getDescription(undoStack); let undoContainer = _getElementById("gc-undo-stack-container"); undoContainer.value = description; } function updateRedoInfo(undoManager) { var redoStack = undoManager.getRedoStack(); let description = getDescription(redoStack); let redoContainer = _getElementById("gc-redo-stack-container"); redoContainer.value = description; } function getDescription(actionStack) { let description = ""; for (var i = 0; i < actionStack.length; i++) { description = description + (i + 1) + '.' + actionStack[i].cmd + "\r\n"; } return description; } function _getElementById(id) { return document.getElementById(id); }
<!doctype html> <html lang="en" style="height:100%;font-size:14px;"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/en/purejs/node_modules/@grapecity/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <link rel="stylesheet" type="text/css" href="styles.css"> <script src="$DEMOROOT$/en/purejs/node_modules/@grapecity/spread-sheets/dist/gc.spread.sheets.all.min.js" type="text/javascript"></script> <script src="app.js" type="text/javascript"></script> <script src="data.js" type="text/javascript"></script> <script src="$DEMOROOT$/spread/source/js/license.js" type="text/javascript"></script> </head> <body> <div class="sample-tutorial"> <!-- Workbook host element --> <div id="ss" class="sample-spreadsheets"></div> <div class="options-container"> <div class="option-row"> <input type="button" value="Redo" class="gc-stack-button" id="gc-redo-button"> <input type="button" value="Undo" class="gc-stack-button" id="gc-undo-button"> </div> <div class="gc-undo-stack-container option-row"> <label>The undoStack includes the following command:</label> <textarea type="text" class="gc-stack-list" id="gc-undo-stack-container" cols="30"></textarea> </div> <div class="gc-redo-stack-container option-row"> <label>The redoStack includes the following command:</label> <textarea type="text" class="gc-stack-list" id="gc-redo-stack-container" cols="30"></textarea> </div> <div class="option-row"> <label>Undo/Redo Stack Max Size</label> <input type="number" min="0" max="2147483647" id="gc-max-size" class="gc-max-size" value="10"> <input type="button" id="gc-max-size-set" value="set"> </div> </div> </div> </body> </html>
var data = [{ "version":"12.0.0", "tabStripRatio":0.6, "sheetCount":1, "sheets":{ "Sheet1":{ "name":"Sheet1", "rowCount":114, "columnCount":21, "activeRow":2, "activeCol":2, "data":{ "dataTable":{ "2":{ "2":{ "value":"Student", "style": { "foreColor" : "#FFFFFF", "backColor" : "#82BC00", "hAlign" : 1 } }, "3":{ "value":"Language", "style": { "foreColor" : "#FFFFFF", "backColor" : "#82BC00", "hAlign" : 1 } }, "4":{ "value":"Math", "style": { "foreColor" : "#FFFFFF", "backColor" : "#82BC00", "hAlign" : 1 } }, "5":{ "value":"Science", "style": { "foreColor" : "#FFFFFF", "backColor" : "#82BC00", "hAlign" : 1 } }, "6":{ "value":"Music", "style": { "foreColor" : "#FFFFFF", "backColor" : "#82BC00", "hAlign" : 1 } }, "7":{ "value":"History", "style": { "foreColor" : "#FFFFFF", "backColor" : "#82BC00", "hAlign" : 1 } } }, "3":{ "2":{ "value":"Ally", "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "3":{ "value":95.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "4":{ "value":65.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "5":{ "value":75.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "6":{ "value":95.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "7":{ "value":91.8, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} } }, "4":{ "2":{ "value":"Tom", "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "3":{ "value":81.8, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "4":{ "value":95.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "5":{ "value":95, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "6":{ "value":75.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "7":{ "value":88, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} } }, "5":{ "2":{ "value":"Jack", "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "3":{ "value":95.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "4":{ "value":68.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "5":{ "value":65.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "6":{ "value":88, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "7":{ "value":79, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} } }, "6":{ "2":{ "value":"John", "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "3":{ "value":68.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "4":{ "value":81.8, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "5":{ "value":86, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "6":{ "value":75, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "7":{ "value":86, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} } }, "7":{ "2":{ "value":"Lily", "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "3":{ "value":95.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "4":{ "value":65.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "5":{ "value":95.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "6":{ "value":95.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "7":{ "value":91.8, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} } }, "8":{ "2":{ "value":"Linda", "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "3":{ "value":75.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "4":{ "value":95.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "5":{ "value":88, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "6":{ "value":65.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "7":{ "value":65.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} } }, "9":{ "2":{ "value":"Will", "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "3":{ "value":95.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "4":{ "value":94.8, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "5":{ "value":94, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "6":{ "value":55.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "7":{ "value":88, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} } } } }, } } }]
.sample-tutorial { position: relative; height: 100%; overflow: hidden; } body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } .sample-spreadsheets { width: calc(100% - 280px); height: 100%; overflow: hidden; float: left; } .options-container{ float: right; width: 280px; padding: 12px; height: 100%; box-sizing: border-box; background: #fbfbfb; overflow: auto; } .option-row { font-size: 14px; padding: 5px; margin-top: 10px; } .gc-stack-list{ width: 100%; height: 150px; margin-top: 10px; } .gc-stack-button{ margin: 0 5px; }