Format String

Format String is an update to the style formatter in SpreadJS. Cells in the workbook can have both formulas and text as a part of text value templates. These can be combined with other spreadsheet features like sparkline formulas to create custom formats inside worksheet cells. The developer can write JavaScript code to set the format string as the formatter for a style.

The formatter is divided into the following three cases normal cell formatter: Standard formatter syntax format. formula format string: Standard formula syntax format text template format string: Text string where formula is contained by "{{" and "}}". In the past, you could not set values and formulas in one cell at the same time, but now you can set the formula to the formatter of Style. This template is a string of text values and formula, use "{{" and "}}" to wrap the formula in the string, in the formula you still can reference the current cell. We provide the '@' symbol, this symbol represents the current cell reference. you can use it directly in the formula or text value template We provide an option called saveAsView for workbook JSON serialization, which helps you save the format string result to excel.
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: 'calc(100% - 280px)', height: '100%', overflow: 'hidden', float: 'left' }; constructor() { } initSpread($event: any) { this.spread = $event.spread; let spread = this.spread; spread.suspendPaint(); let gcns = GC.Spread.Sheets; let sheet = spread.getActiveSheet(); let data = [ [, "FY 2019"], [, "Sales"], [, "Monthly", "Cumulative"], ["Apr", 188897, 188897], ["May", 208146, 397043], ["Jun", 226196, 623239], ["Jul", 277318, 900557], ["Aug", 263273, 1163830], ["Sep", 259845, 1423675], ["Oct", 241047, 1664722], ["Nov", 256306, 1921028], ["Dec", 195845, 2116873], ["Jan", 204934, 2321808], ["Feb", 257852, 2579660], ["Mar", 227779, 2807439] ]; sheet.setArray(3, 1, data); sheet.setColumnWidth(2, 110); sheet.setColumnWidth(3, 110); sheet.setRowCount(20); sheet.setColumnCount(9); sheet.options.gridline.showHorizontalGridline = false; sheet.options.gridline.showVerticalGridline = false; sheet.getRange(3, 1, 15, 3).setBorder( new gcns.LineBorder("black", gcns.LineStyle.medium), { all: true }); sheet.addSpan(3, 2, 1, 2); sheet.addSpan(4, 2, 1, 2); sheet.getRange(3, 2, 3, 2).backColor('#CFE1F3').hAlign(gcns.HorizontalAlign.center); sheet.getRange(6, 1, 12, 1).backColor('#CCC1DA'); let cMapSource = [ { "Currency": "USD", "Value": 1, "Symbol": "$" }, { "Currency": "CNY", "Value": 7.02, "Symbol": "¥" }, { "Currency": "JPY", "Value": 108.8, "Symbol": "¥" }, { "Currency": "EURO", "Value": 0.91, "Symbol": "€" }, ]; sheet.tables.addFromDataSource('cT', 3, 5, cMapSource); [5, 6, 7].forEach((col) => { sheet.setColumnWidth(col, 80); }); sheet.getCell(1, 2).value("Unit:").hAlign(gcns.HorizontalAlign.right); sheet.getRange(1, 3, 1, 1).backColor("yellow").setBorder( new gcns.LineBorder("blue", gcns.LineStyle.medium), { all: true }); let dv1 = gcns.DataValidation.createFormulaListValidator('=cT[[#Data], [Currency]]'); sheet.setDataValidator(1, 3, dv1); sheet.getCell(1, 3).hAlign(gcns.HorizontalAlign.center).value("USD"); sheet.getRange(6, 2, 12, 2) .hAlign(gcns.HorizontalAlign.center) .formatter('=VLOOKUP($D$2,cT[#Data],3,FALSE)&" "&TEXT(@*VLOOKUP($D$2,cT[#Data],2,FALSE),"###,###")'); 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/core-js/client/shim.min.js"></script> <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-spread-sheets> <div class="options-container"> <div class="option-row" style="padding:2px 10px"> <p> By changing the value of D2 to select the currency calculation strategy, you will notice that the table on the left has changed. </p> </div>     </div>  </div>
.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; } body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; }
(function (global) { System.config({ transpiler: 'ts', typescriptOptions: { tsconfig: true }, meta: { 'typescript': { "exports": "ts" }, '*.css': { loader: 'css' } }, paths: { // paths serve as alias 'npm:': 'node_modules/' }, // map tells the System loader where to look for things map: { 'core-js': 'npm:core-js/client/shim.min.js', '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': 'npm:@mescius/spread-sheets/index.js', '@mescius/spread-sheets-angular': 'npm:@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);