Overview

You can use tags to store private data. SpreadJS supports tags for cells, rows, columns, and sheets.

Sheet.tag(value?): Gets or sets the tag for the sheet. Sheet.getTag(row, col, sheetArea?) or Sheet.setTag(row, col, tag, sheetArea?): Get or set tag for: sheet: when row is -1 and col is -1 row: when col is -1 and row >= 0 column: when row is -1 and col >= 0 cell: when row >=0 and col >= 0 CellRange.tag(value?): Gets or sets the tag for the cell. When a tag is set, the following events will occur: CellChanged event for CellRange.tag(value) RowChanged event for CellRange.tag(value) ColumnChanged event for CellRange.tag(value) You can clear the tag by setting the tag to null or undefined or by using Sheet.clear(row, column, rowCount, columnCount, sheetArea, StorageType.tag). For example:
import * as React from 'react'; import * as ReactDOM from 'react-dom'; import './styles.css'; import { AppFunc } from './app-func'; import { App } from './app-class'; // 1. Functional Component sample ReactDOM.render(<AppFunc />, document.getElementById('app')); // 2. Class Component sample // ReactDOM.render(<App />, document.getElementById('app'));
import * as React from 'react'; import * as ReactDOM from 'react-dom'; import GC from '@mescius/spread-sheets'; import { SpreadSheets, Worksheet, Column } from '@mescius/spread-sheets-react'; import './styles.css'; const Component = React.Component; function _getElementById(id) { return document.getElementById(id); } export function AppFunc() { const [spread,setSpread] = React.useState(null); const [state,setState]=React.useState(""); let autoGenerateColumns = false; let initSpread = function(value) { setSpread(value); let sheet = value.sheets[0]; // sheet tag sheet.tag("Sheet tag"); // row tag sheet.setTag(3, -1, "Row 4 tag"); sheet.getRange(5, -1, 1, -1).tag("Row 6 tag"); sheet.getCell(5, -1, GC.Spread.Sheets.SheetArea.rowHeader).backColor('#82BC00'); // column tag sheet.getRange(-1, 4, -1, 3).tag("Column E-G tag"); sheet.getCell(-1, 4, GC.Spread.Sheets.SheetArea.colHeader).backColor('#82BC00'); // cell tag sheet.getCell(0, 0).tag("A1 tag"); sheet.getCell(0, 0).backColor("#E3E3E3"); sheet.getRange(6, 0, 4, 3).tag("Cells tag (A7:C10)"); sheet.getRange(6, 0, 4, 3).backColor("#E3E3E3"); bindEvents(sheet); } let bindEvents = function(sheet) { sheet.bind(GC.Spread.Sheets.Events.SelectionChanged, function () { setState(()=>({ tagText: "" })) getTag(sheet); }); } let handelTagText = function(e) { setState({ tagText: e.target.value }) } let handelSetTag = function(e) { let sheet = spread.getActiveSheet(); let tag = state.tagText; let selections = sheet.getSelections(); if (!selections || selections.length === 0) { return; } sheet.suspendPaint(); let length = selections.length; for (let i = 0; i < length; i++) { let sel = selections[i], rowIndex = sel.row, colIndex = sel.col, rowCount = sel.rowCount, colCount = sel.colCount, maxRow = rowIndex + rowCount, maxColumn = colIndex + colCount, r, c; if (rowIndex === -1 && colIndex === -1) { sheet.tag(tag); } else if (rowIndex === -1) { for (c = colIndex; c < maxColumn; c++) { sheet.setTag(-1, c, tag); } } else if (colIndex === -1) { for (r = rowIndex; r < maxRow; r++) { sheet.setTag(r, -1, tag); } } else { for (r = rowIndex; r < maxRow; r++) { for (c = colIndex; c < maxColumn; c++) { sheet.setTag(r, c, tag); } } } } sheet.resumePaint(); getTag(sheet); } let handelClearTag = function() { let sheet = spread.getActiveSheet(); let selections = sheet.getSelections(); if (!selections || selections.length === 0) { return; } sheet.suspendPaint(); let length = selections.length; for (let i = 0; i < length; i++) { let sel = selections[i], row = sel.row, col = sel.col; if (row === -1 && col === -1) { sheet.tag(null); } else { sheet.clear(row, col, sel.rowCount, sel.colCount, GC.Spread.Sheets.SheetArea.viewport, GC.Spread.Sheets.StorageType.tag); } } sheet.resumePaint(); getTag(sheet); } let getTag = function(sheet) { let selections = sheet.getSelections(); if (!selections || selections.length === 0) { return; } let sel = selections[0], row = sel.row, col = sel.col; if (row === -1 && col === -1) { setState({ tagText: sheet.tag() !== null ? sheet.tag() : "" }) } else { setState({ tagText: sheet.getTag(row, col) !== null ? sheet.getTag(row, col) : "" }) } }; return (<div class="sample-tutorial"> <div class="sample-spreadsheets"> <SpreadSheets workbookInitialized={spread => initSpread(spread)}> <Worksheet></Worksheet> </SpreadSheets> </div> <Panel panelInfo={state} handelSetTag={(e) => { handelSetTag(e) }} handelClearTag={(e) => { handelClearTag(e) }} handelTagText={(e)=>{handelTagText(e)}} /> </div>); } const Panel = React.memo((props)=>{ let state = props.tagText; const {panelInfo, handelTagText, handelSetTag, handelClearTag} = props; return ( <div class="options-container"> <div class="option-row"> <p> <span>You can set, get or clear tag of selected items.</span> <span>Tags are provided in this demo: sheet, Row 4, Row 6, Column E-G, A1, A7:C10.</span> </p> </div> <div class="option-row"> <label for="txtTag">Tag: </label> <input id="txtTag" value={panelInfo.tagText} onChange = {(e)=>{handelTagText(e)}} /> </div> <div class="option-row"> <input type="button" id="btnSetTag" value="Set tag" title="Set tag to selected item(s)" onClick={(e) => { handelSetTag(state) }} /> <input type="button" id="btnClearTag" value="Clear tag" title="Clear tag of selected items" onClick={(e) => { handelClearTag(e) }} /> </div> </div> ) })
import * as React from 'react'; import * as ReactDOM from 'react-dom'; import GC from '@mescius/spread-sheets'; import { SpreadSheets, Worksheet, Column } from '@mescius/spread-sheets-react'; import './styles.css'; const Component = React.Component; function _getElementById(id) { return document.getElementById(id); } export class App extends Component { constructor(props) { super(props); this.spread = null; this.state = { tagText: '' } this.autoGenerateColumns = false; this.handelTagText = this.handelTagText.bind(this); } render() { return (<div class="sample-tutorial"> <div class="sample-spreadsheets"> <SpreadSheets workbookInitialized={spread => this.initSpread(spread)}> <Worksheet></Worksheet> </SpreadSheets> </div> <Panel panelInfo={this.state} handelSetTag={(e) => { this.handelSetTag(e) }} handelClearTag={(e) => { this.handelClearTag(e) }} handelTagText={(e)=>{this.handelTagText(e)}} /> </div>); } initSpread(spread) { this.spread = spread; let sheet = spread.sheets[0]; // sheet tag sheet.tag("Sheet tag"); // row tag sheet.setTag(3, -1, "Row 4 tag"); sheet.getRange(5, -1, 1, -1).tag("Row 6 tag"); sheet.getCell(5, -1, GC.Spread.Sheets.SheetArea.rowHeader).backColor('#82BC00'); // column tag sheet.getRange(-1, 4, -1, 3).tag("Column E-G tag"); sheet.getCell(-1, 4, GC.Spread.Sheets.SheetArea.colHeader).backColor('#82BC00'); // cell tag sheet.getCell(0, 0).tag("A1 tag"); sheet.getCell(0, 0).backColor("#E3E3E3"); sheet.getRange(6, 0, 4, 3).tag("Cells tag (A7:C10)"); sheet.getRange(6, 0, 4, 3).backColor("#E3E3E3"); this.bindEvents(sheet); } bindEvents(sheet) { let self = this; sheet.bind(GC.Spread.Sheets.Events.SelectionChanged, function () { self.setState(()=>({ tagText: "" })) self.getTag(sheet); }); } handelTagText(e){ this.setState({ tagText: e.target.value }) } handelSetTag(e) { let sheet = this.spread.getActiveSheet(); let tag = this.state.tagText; let selections = sheet.getSelections(); if (!selections || selections.length === 0) { return; } sheet.suspendPaint(); let length = selections.length; for (let i = 0; i < length; i++) { let sel = selections[i], rowIndex = sel.row, colIndex = sel.col, rowCount = sel.rowCount, colCount = sel.colCount, maxRow = rowIndex + rowCount, maxColumn = colIndex + colCount, r, c; if (rowIndex === -1 && colIndex === -1) { sheet.tag(tag); } else if (rowIndex === -1) { for (c = colIndex; c < maxColumn; c++) { sheet.setTag(-1, c, tag); } } else if (colIndex === -1) { for (r = rowIndex; r < maxRow; r++) { sheet.setTag(r, -1, tag); } } else { for (r = rowIndex; r < maxRow; r++) { for (c = colIndex; c < maxColumn; c++) { sheet.setTag(r, c, tag); } } } } sheet.resumePaint(); this.getTag(sheet); } handelClearTag() { let sheet = this.spread.getActiveSheet(); let selections = sheet.getSelections(); if (!selections || selections.length === 0) { return; } sheet.suspendPaint(); let length = selections.length; for (let i = 0; i < length; i++) { let sel = selections[i], row = sel.row, col = sel.col; if (row === -1 && col === -1) { sheet.tag(null); } else { sheet.clear(row, col, sel.rowCount, sel.colCount, GC.Spread.Sheets.SheetArea.viewport, GC.Spread.Sheets.StorageType.tag); } } sheet.resumePaint(); this.getTag(sheet); } getTag(sheet) { let selections = sheet.getSelections(); if (!selections || selections.length === 0) { return; } let sel = selections[0], row = sel.row, col = sel.col; if (row === -1 && col === -1) { this.setState({ tagText: sheet.tag() !== null ? sheet.tag() : "" }) } else { this.setState({ tagText: sheet.getTag(row, col) !== null ? sheet.getTag(row, col) : "" }) } }; } class Panel extends Component { constructor(props) { super(props); this.state = this.props.tagText; } // componentWillReceiveProps(nextProps) { // this.setState(nextProps.tagText); // } render() { const {panelInfo, handelTagText, handelSetTag, handelClearTag} = this.props; return ( <div class="options-container"> <div class="option-row"> <p> <span>You can set, get or clear tag of selected items.</span> <span>Tags are provided in this demo: sheet, Row 4, Row 6, Column E-G, A1, A7:C10.</span> </p> </div> <div class="option-row"> <label for="txtTag">Tag: </label> <input id="txtTag" value={panelInfo.tagText} onChange = {(e)=>{handelTagText(e)}} /> </div> <div class="option-row"> <input type="button" id="btnSetTag" value="Set tag" title="Set tag to selected item(s)" onClick={(e) => { handelSetTag(this.state) }} /> <input type="button" id="btnClearTag" value="Clear tag" title="Clear tag of selected items" onClick={(e) => { handelClearTag(e) }} /> </div> </div> ) } }
<!doctype html> <html 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/react/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <!-- SystemJS --> <script src="$DEMOROOT$/en/react/node_modules/systemjs/dist/system.src.js"></script> <script src="systemjs.config.js"></script> <script> System.import('$DEMOROOT$/en/lib/react/license.js').then(function () { System.import('./src/app'); }); </script> </head> <body> <div id="app"></div> </body> </html>
.sample { position: relative; height: 100%; overflow: auto; } .sample::after { display: block; content: ""; clear: both; } .sample-tutorial { position: relative; height: 100%; overflow: hidden; } .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; } label { display: inline-block; margin-bottom: 6px; } input { padding: 4px; width: 100%; margin: 0 4px 4px 0; box-sizing: border-box; } input[type=button] { width: 30%; } p { background-color: #F4F8EB; padding: 4px; } p span { display: block; } body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } #app { height: 100%; }
(function (global) { System.config({ transpiler: 'plugin-babel', babelOptions: { es2015: true, react: true }, meta: { '*.css': { loader: 'css' } }, paths: { // paths serve as alias 'npm:': 'node_modules/' }, // map tells the System loader where to look for things map: { '@mescius/spread-sheets': 'npm:@mescius/spread-sheets/index.js', '@mescius/spread-sheets-react': 'npm:@mescius/spread-sheets-react/index.js', '@grapecity/jsob-test-dependency-package/react-components': 'npm:@grapecity/jsob-test-dependency-package/react-components/index.js', 'react': 'npm:react/umd/react.production.min.js', 'react-dom': 'npm:react-dom/umd/react-dom.production.min.js', 'css': 'npm:systemjs-plugin-css/css.js', 'plugin-babel': 'npm:systemjs-plugin-babel/plugin-babel.js', 'systemjs-babel-build':'npm:systemjs-plugin-babel/systemjs-babel-browser.js' }, // packages tells the System loader how to load when no filename and/or no extension packages: { src: { defaultExtension: 'jsx' }, "node_modules": { defaultExtension: 'js' }, } }); })(this);