Overview

Cell States provide information about how a cell will respond to different actions from the user, such as when editing, hovering, read-only. and others by applying different styles to the specified range(s) depending on the cell state. The following simple example automatically changes the background color to white when hovering over a cell using a predefined style.

SpreadJS supports the following cell states: Type Comments hover Mouse hovers over the cell. invalid Data-validation failed. readonly Cell is locked. edit Cell is being edited. active Cell has focus. selected Cell(s) is in the selection range. dirty Cell value has changed. invalid formula Cell value is invalid formula string. Here is an example of setting the style:
import { Component, NgModule, enableProdMode } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { SpreadSheetsModule } from '@mescius/spread-sheets-angular'; import GC from '@mescius/spread-sheets'; import './styles.css'; @Component({ selector: 'app-component', templateUrl: 'src/app.component.html' }) export class AppComponent { autoGenerateColumns = true; dataSource: any[]; spread: GC.Spread.Sheets.Workbook; hostStyle = { width: '100%', height: '100%', overflow: 'hidden', float: 'left' }; constructor() { } initSpread($event: any) { this.spread = $event.spread; let spread = this.spread; spread.suspendPaint(); let sheet = spread.getSheet(0); spread.options.backColor = "#fefce3"; spread.options.grayAreaBackColor = "#fefce3"; sheet.options.gridline.showHorizontalGridline = false; sheet.options.gridline.showVerticalGridline = false; sheet.options.selectionBorderColor = "transparent"; sheet.defaults.rowHeight = 60; sheet.defaults.colWidth = 90; sheet.setColumnCount(10); sheet.options.rowHeaderVisible = false; sheet.options.colHeaderVisible = false; let style = sheet.getDefaultStyle(); style.font = "20px Segoe UI"; style.vAlign = GC.Spread.Sheets.VerticalAlign.top; style.labelOptions = { alignment: GC.Spread.Sheets.LabelAlignment.leftTop, visibility: GC.Spread.Sheets.LabelVisibility.visible, font: 'normal 14px/normal "nimbus-sans"', foreColor: "#333333", margin: "3px 0px 0px 10px" }; style.cellPadding = "25px 0px 0px 0px"; sheet.setValue(0, 0, "Add to inventory"); sheet.getCell(0, 0).font("bold normal 25px normal"); sheet.getRange(0, 0, 1, 10).setBorder(new GC.Spread.Sheets.LineBorder('black', GC.Spread.Sheets.LineStyle.thick), { bottom: true }); sheet.getRange(1, 0, 5, 10).borderBottom(new GC.Spread.Sheets.LineBorder('black', GC.Spread.Sheets.LineStyle.thin)); sheet.getCell(1, 0).watermark("PRODUCT NAME"); sheet.getRange(1, 0, 1, 7).borderRight(new GC.Spread.Sheets.LineBorder('black', GC.Spread.Sheets.LineStyle.thin)); sheet.addSpan(1, 0, 1, 7); sheet.addSpan(1, 7, 1, 3); sheet.getCell(1, 7).watermark("TAGS"); sheet.getRange(2, 0, 1, 5).borderRight(new GC.Spread.Sheets.LineBorder('black', GC.Spread.Sheets.LineStyle.thin)); let vendorCombo = new GC.Spread.Sheets.CellTypes.ComboBox(); let vendorList = ["Select a vendor", "ted", "Magna Phasellus Dolor Incorporated", "Fames Ac Turpis Inc.", "Eu Eros Institute", "Suspendisse Sagittis Associates", "Tempor Lorem PC", "Nulla Facilisi Sed PC", "Dignissim Corp.", "Blandit Ltd", "Dapibus Gravida Aliquam LLP", "Cursus A Inc.", "Tellus PC", "Fusce Mi Foundation", "Dictum Sapien Aenean Associates", "In Tincidunt PC", "Sapien Aenean Ltd", "Libero Foundation", "Egestas Rhoncus Proin Corp.", "Feugiat Nec Diam Institute", "Turpis Foundation", "Pede Malesuada Vel Associates", "Eget Venenatis A PC", "Mollis Vitae Corporation", "Gravida Mauris Incorporated", "Tortor Consulting", "Habitant Morbi Tristique Corporation", "Enim Corp.", "Sed Turpis Nec LLC", "Enim Foundation", "Tincidunt Orci Quis Institute", "Lectus Pede LLC", "Class Corporation", "Erat Volutpat Nulla LLP", "Sed LLC", "Justo Faucibus Associates", "Vel Turpis Foundation", "Tellus Aenean Limited", "Tempus Scelerisque Corporation", "Eleifend LLP", "A Felis Ullamcorper Company", "Neque Non LLC", "Nibh Donec Est PC"]; vendorCombo.items(vendorList); vendorCombo.maxDropDownItems(10); vendorCombo.editorValueType(GC.Spread.Sheets.CellTypes.EditorValueType.text); sheet.getCell(2, 0, GC.Spread.Sheets.SheetArea.viewport).watermark("VENDOR").cellType(vendorCombo).value("Select a vendor").font("15px Segoe UI").textIndent(1.25); sheet.addSpan(2, 0, 1, 5); let productList = ["Select a product type", "et magnis", "Vivamus rhoncus.", "egestas ligula.", "nulla. Cras", "Proin mi.", "turpis non", "ante ipsum", "arcu. Curabitur", "ante. Maecenas", "magna. Phasellus", "Suspendisse aliquet,", "purus gravida", "ac risus.", "mollis non,"] let productCombo = new GC.Spread.Sheets.CellTypes.ComboBox(); productCombo.items(productList); productCombo.editorValueType(GC.Spread.Sheets.CellTypes.EditorValueType.text); sheet.getCell(2, 5).watermark("PRODUCT TYPE").cellType(vendorCombo).value("Select a vendor").font("15px Segoe UI").textIndent(1.25); sheet.addSpan(2, 5, 1, 5); sheet.addSpan(3, 0, 1, 10); sheet.getCell(3, 0).watermark("PRODUCT DESCRIPTION"); sheet.getRange(4, 0, 1, 8).borderRight(new GC.Spread.Sheets.LineBorder('black', GC.Spread.Sheets.LineStyle.thin)); sheet.getCell(4, 0).watermark("SKU"); sheet.addSpan(4, 0, 1, 2); sheet.getCell(4, 2).watermark("INITIAL STOCK LEVEL"); sheet.addSpan(4, 2, 1, 2); sheet.addSpan(4, 4, 1, 2); sheet.addSpan(4, 6, 1, 2); sheet.addSpan(4, 8, 1, 2); sheet.getCell(4, 4).watermark("COST PRICE"); sheet.getCell(4, 6).watermark("WHOLESALE PRICE"); sheet.getCell(4, 8).watermark("RETAIL PRICE"); sheet.getRange(5, 0, 1, 5).borderRight(new GC.Spread.Sheets.LineBorder('black', GC.Spread.Sheets.LineStyle.thin)); sheet.getCell(5, 0).watermark("COUNTRY"); sheet.addSpan(5, 0, 1, 5); sheet.getCell(5, 5).watermark("CITY"); sheet.addSpan(5, 5, 1, 5); let hoverStyle = new GC.Spread.Sheets.Style(); hoverStyle.backColor = 'white'; let range = new GC.Spread.Sheets.Range(1, 0, 5, 10); sheet.cellStates.add(range, GC.Spread.Sheets.CellStatesType.hover, hoverStyle) spread.resumePaint(); } } @NgModule({ imports: [BrowserModule, SpreadSheetsModule], declarations: [AppComponent], exports: [AppComponent], bootstrap: [AppComponent] }) export class AppModule {} enableProdMode(); // Bootstrap application with hash style navigation and global services. platformBrowserDynamic().bootstrapModule(AppModule);
<!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/angular/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <!-- Polyfills --> <script src="$DEMOROOT$/en/angular/node_modules/zone.js/fesm2015/zone.min.js"></script> <!-- SystemJS --> <script src="$DEMOROOT$/en/angular/node_modules/systemjs/dist/system.js"></script> <script src="systemjs.config.js"></script> <script> // workaround to load 'rxjs/operators' from the rxjs bundle System.import('rxjs').then(function (m) { System.import('@angular/compiler'); System.set(SystemJS.resolveSync('rxjs/operators'), System.newModule(m.operators)); System.import('$DEMOROOT$/en/lib/angular/license.ts'); System.import('./src/app.component'); }); </script> </head> <body> <app-component></app-component> </body> </html>
<div class="sample-tutorial"> <gc-spread-sheets [hostStyle]="hostStyle" (workbookInitialized)="initSpread($event)"> <gc-worksheet [autoGenerateColumns]='autoGenerateColumns'></gc-worksheet> <gc-worksheet [autoGenerateColumns]='autoGenerateColumns'></gc-worksheet> </gc-spread-sheets> </div>
.sample-tutorial { position: relative; height: 100%; overflow: hidden; } .sample-spreadsheets { width: 100%; height: 100%; overflow: hidden; float: left; } .options-container legend { text-align: center; } .option-row { font-size: 14px; padding: 5px; } input { display:block; width: 100%; margin: 8px 0; box-sizing: border-box; } label, input { padding: 4px 6px; } body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } #app { height: 100%; } #drawUnderline { display: inline-block; width: 30px; } #drawUnderlineLabel { display: inline-block; } #allowAutoCreateHyperlink { display: inline-block; width: 30px; } #setHyperlinkButton { font-weight: bold; background-color: #ecf3ff; width: 200px; height: 35px; border-radius: 4px; border-color: #0b93d5; border-width: thin; } #settingsDiv { margin-top: "10px" } #settingString { padding:"2px 10px } #allowAutoCreateHyperlinkDiv { margin-top: "10px" }
(function (global) { System.config({ transpiler: 'ts', typescriptOptions: { tsconfig: true }, meta: { 'typescript': { "exports": "ts" }, '*.css': { loader: 'css' } }, paths: { // paths serve as alias 'npm:': 'node_modules/', 'cdn:': 'https://cdn.mescius.io/demoapps/packages/spreadjs/19.2.2-master-2026-09-02-2133/' }, // map tells the System loader where to look for things map: { 'zone': 'npm:zone.js/fesm2015/zone.min.js', 'rxjs': 'npm:rxjs/dist/bundles/rxjs.umd.min.js', '@angular/core': 'npm:@angular/core/fesm2022', '@angular/common': 'npm:@angular/common/fesm2022/common.mjs', '@angular/compiler': 'npm:@angular/compiler/fesm2022/compiler.mjs', '@angular/platform-browser': 'npm:@angular/platform-browser/fesm2022/platform-browser.mjs', '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/fesm2022/platform-browser-dynamic.mjs', '@angular/common/http': 'npm:@angular/common/fesm2022/http.mjs', '@angular/router': 'npm:@angular/router/fesm2022/router.mjs', '@angular/forms': 'npm:@angular/forms/fesm2022/forms.mjs', 'jszip': 'npm:jszip/dist/jszip.min.js', 'typescript': 'npm:typescript/lib/typescript.js', 'ts': './plugin.js', 'tslib':'npm:tslib/tslib.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', '@mescius/spread-sheets': 'cdn:@mescius/spread-sheets/index.js', '@mescius/spread-sheets-angular': 'cdn:@mescius/spread-sheets-angular/fesm2020/mescius-spread-sheets-angular.mjs', '@grapecity/jsob-test-dependency-package/react-components': 'npm:@grapecity/jsob-test-dependency-package/react-components/index.js' }, // packages tells the System loader how to load when no filename and/or no extension packages: { src: { defaultExtension: 'ts' }, rxjs: { defaultExtension: 'js' }, "node_modules": { defaultExtension: 'js' }, "node_modules/@angular": { defaultExtension: 'mjs' }, "@mescius/spread-sheets-angular": { defaultExtension: 'mjs' }, '@angular/core': { defaultExtension: 'mjs', main: 'core.mjs' } } }); })(this);