Apply Free Header Area
TableSheet provides the applyFreeHeaderArea method to configure the free header area for the column header.
Generate Free Header Area JSON
If you want to refer to formulas with sheet names (like "TableSheet1![ColumnName]", "OtherSheet!A1" or "AVERAGE(TableSheet1[ColumnName])") when you generate the free header area JSON, you should enable this sheet option:
This is the sample code:
Formula Text Box in Header Area Support
You can double click cells in the header area to start editing, or press the "=" key to enter formula editing.
Then you can select TableSheet columns or any range in the free header area.
import * as React from 'react';
import { createRoot } from 'react-dom/client';
import './styles.css';
import { AppFunc } from './app-func';
import { App } from './app-class';
// 1. Functional Component sample
createRoot(document.getElementById('app')).render(<AppFunc />);
// 2. Class Component sample
// createRoot(document.getElementById('app')).render(<App />);
/*REPLACE_MARKER*/
/*DO NOT DELETE THESE COMMENTS*/
import * as React from 'react';
import GC from '@mescius/spread-sheets';
import "@mescius/spread-sheets-tablesheet";
import { SpreadSheets } from '@mescius/spread-sheets-react';
import './styles.css';
export function AppFunc() {
const initSpread = (spread) => {
spread.clearSheets();
spread.suspendPaint();
var dataManager = spread.dataManager();
var myTable = dataManager.addTable("myTable", {
data: [
{ id: 1, item: "Airfare", description: "Tickets", cost: 300, quantity: 1 },
{ id: 2, item: "Hotel", description: "Room", cost: 125, quantity: 3 },
{ id: 3, item: "Car rental", description: "Cost per day", cost: 52, quantity: 6 },
{ id: 4, item: "Gas", description: "Cost per gallon", cost: 1.74, quantity: 14 },
{ id: 5, item: "Entertainment", description: "Amount", cost: 130, quantity: 1 },
{ id: 6, item: "Gifts", description: "Amount", cost: 85, quantity: 1 },
{ id: 7, item: "Miscellaneous", description: "Amount", cost: 55, quantity: 1 },
{ id: 8, item: "Food", description: "Cost per day", cost: 48, quantity: 6 },
]
});
//init a table sheet
var sheet = spread.addSheetTab(0, "TableSheet1", GC.Spread.Sheets.SheetType.tableSheet);
sheet.applyTableTheme(GC.Spread.Sheets.Tables.TableThemes.professional7);
//bind a view to the table sheet
myTable.fetch().then(function () {
var Colors = {
lightGreen: "rgb(227,239,218)",
middleGreen: "rgb(115,150,61)",
darkGreen: "rgb(115,150,61)",
lightGray: "rgb(191,191,191)",
white: "rgb(255,255,255)",
gray: "rgb(225,225,225)",
black: "rgb(0,0,0)"
};
var formatter = "$#,##0.00_);($#,##0.00)";
var currencyFormatter = { formatter: formatter };
var headerStyle = {
backColor: Colors.darkGreen,
foreColor: Colors.white,
font: "bold 12pt Calibri",
hAlign: "left"
};
var dataBarRule1 = {
ruleType: "dataBarRule",
color: Colors.darkGreen,
gradient: true
};
var dataBarRule2 = {
ruleType: "dataBarRule",
color: Colors.lightGray,
gradient: true,
barDirection: "rightToLeft"
};
var view = myTable.addView("myView", [
{ value: "item", caption: "Item", width: 180, headerStyle },
{ value: "description", caption: "Description", width: 120, headerStyle },
{ value: "quantity", caption: "Qty", width: 90, headerStyle },
{ value: "cost", caption: "Cost", width: 100, style: currencyFormatter, headerStyle, conditionalFormats: [dataBarRule1] },
{ value: "=[@cost]*[@quantity]", caption: "Amount", width: 120, style: currencyFormatter, headerStyle, conditionalFormats: [dataBarRule2] }
]);
// create template sheet for free header area json
var templateSheet = new GC.Spread.Sheets.Worksheet();
templateSheet.options.keepUnknownFormulas = true;
var currencyFormatterStyle = new GC.Spread.Sheets.Style();
currencyFormatterStyle.formatter = formatter;
currencyFormatterStyle.hAlign = GC.Spread.Sheets.HorizontalAlign.left;
templateSheet.setRowCount(6);
var freeHeaderAreaStyle = new GC.Spread.Sheets.Style();
freeHeaderAreaStyle.backColor = Colors.white;
templateSheet.setValue(0, 0, "Business Trip Budget");
templateSheet.getCell(0, 0).hAlign(GC.Spread.Sheets.HorizontalAlign.left).font("bold 30px \"Microsoft Sans Serif\"");
templateSheet.addSpan(0, 0, 1, 5);
var titleStyle = new GC.Spread.Sheets.Style();
titleStyle.backColor = Colors.lightGreen;
titleStyle.foreColor = Colors.black;
templateSheet.setStyle(0, -1, titleStyle);
templateSheet.setRowHeight(0, 80);
templateSheet.getCell(1, 0)
.value("Enter Target trip budget below. Total trip cost and under or over budget are automatically calculated.")
.font("italic 12px \"Microsoft Sans Serif\"")
.foreColor("rgb(120,120,120)")
.textIndent(2);
templateSheet.setStyle(1, -1, titleStyle);
templateSheet.addSpan(1, 0, 1, 5);
var headerDescriptionStyle = new GC.Spread.Sheets.Style();
headerDescriptionStyle.backColor = Colors.lightGreen;
headerDescriptionStyle.borderBottom = new GC.Spread.Sheets.LineBorder(Colors.middleGreen, GC.Spread.Sheets.LineStyle.thick);
templateSheet.setStyle(2, -1, headerDescriptionStyle);
templateSheet.addSpan(2, 0, 1, 5);
templateSheet.setRowHeight(2, 16);
templateSheet.setValue(3, 0, "Target trip budget");
templateSheet.getCell(3, 0).hAlign(GC.Spread.Sheets.HorizontalAlign.left).font("bold 14px \"Trebuchet MS\"").foreColor(Colors.darkGreen);
templateSheet.addSpan(3, 0, 1, 2);
templateSheet.setValue(3, 2, 1000);
templateSheet.getCell(3, 2).hAlign(GC.Spread.Sheets.HorizontalAlign.left).font("bold 14px \"Trebuchet MS\"").foreColor(Colors.darkGreen).formatter(formatter);
templateSheet.setFormula(3, 3, '=HBARSPARKLINE(ROUND(C4/MAX(C4,C5),2),"' + Colors.darkGreen + '",false)');
templateSheet.setStyle(3, 3, new GC.Spread.Sheets.Style(undefined, Colors.black));
templateSheet.addSpan(3, 3, 1, 2);
templateSheet.setStyle(3, -1, freeHeaderAreaStyle);
templateSheet.setValue(4, 0, "Total cost of the trip");
templateSheet.getCell(4, 0).hAlign(GC.Spread.Sheets.HorizontalAlign.left).font("bold 14px \"Trebuchet MS\"").foreColor(Colors.lightGray);
templateSheet.addSpan(4, 0, 1, 2);
templateSheet.setFormula(4, 2, '=SUM(TableSheet1[Amount])');
templateSheet.getCell(4, 2).hAlign(GC.Spread.Sheets.HorizontalAlign.left).font("bold 14px \"Trebuchet MS\"").foreColor(Colors.lightGray).formatter(formatter);
var contentBorderStyle = new GC.Spread.Sheets.Style();
contentBorderStyle.backColor = Colors.white;
contentBorderStyle.borderBottom = new GC.Spread.Sheets.LineBorder(Colors.lightGray, GC.Spread.Sheets.LineStyle.thick);
templateSheet.setStyle(4, -1, contentBorderStyle);
templateSheet.setFormula(4, 3, '=HBARSPARKLINE(ROUND(C5/MAX(C4,C5),2),"' + Colors.lightGray + '",false)');
templateSheet.setStyle(4, 3, new GC.Spread.Sheets.Style(undefined, Colors.black));
templateSheet.addSpan(4, 3, 1, 2);
templateSheet.setFormula(5, 0, '=IF(C4>C5,"You\'re under budget by","You\'re over budget by")');
templateSheet.getCell(5, 0).hAlign(GC.Spread.Sheets.HorizontalAlign.left).font("bold 14px \"Trebuchet MS\"").foreColor(Colors.black);
templateSheet.addSpan(5, 0, 1, 2);
templateSheet.setFormula(5, 2, '=C4-C5');
templateSheet.getCell(5, 2).hAlign(GC.Spread.Sheets.HorizontalAlign.left).font("bold 14px \"Trebuchet MS\"").formatter(formatter).foreColor(Colors.black);
templateSheet.setStyle(5, -1, freeHeaderAreaStyle);
templateSheet.addSpan(5, 2, 1, 3);
let template = templateSheet.toJSON();
sheet.applyFreeHeaderArea(template);
sheet.setDataView(view);
});
spread.resumePaint();
}
return (
<div class="sample-tutorial">
<div class="sample-spreadsheets">
<SpreadSheets workbookInitialized={spread => initSpread(spread)}>
</SpreadSheets>
</div>
</div>
);
}
/*REPLACE_MARKER*/
/*DO NOT DELETE THESE COMMENTS*/
import * as React from 'react';
import GC from '@mescius/spread-sheets';
import "@mescius/spread-sheets-tablesheet";
import { SpreadSheets } from '@mescius/spread-sheets-react';
import './styles.css';
const Component = React.Component;
export class App extends Component {
render() {
return (
<div class="sample-tutorial">
<div class="sample-spreadsheets">
<SpreadSheets workbookInitialized={spread => this.initSpread(spread)}>
</SpreadSheets>
</div>
</div>
);
}
initSpread(spread) {
spread.clearSheets();
spread.suspendPaint();
var dataManager = spread.dataManager();
var myTable = dataManager.addTable("myTable", {
data: [
{ id: 1, item: "Airfare", description: "Tickets", cost: 300, quantity: 1 },
{ id: 2, item: "Hotel", description: "Room", cost: 125, quantity: 3 },
{ id: 3, item: "Car rental", description: "Cost per day", cost: 52, quantity: 6 },
{ id: 4, item: "Gas", description: "Cost per gallon", cost: 1.74, quantity: 14 },
{ id: 5, item: "Entertainment", description: "Amount", cost: 130, quantity: 1 },
{ id: 6, item: "Gifts", description: "Amount", cost: 85, quantity: 1 },
{ id: 7, item: "Miscellaneous", description: "Amount", cost: 55, quantity: 1 },
{ id: 8, item: "Food", description: "Cost per day", cost: 48, quantity: 6 },
]
});
//init a table sheet
var sheet = spread.addSheetTab(0, "TableSheet1", GC.Spread.Sheets.SheetType.tableSheet);
sheet.applyTableTheme(GC.Spread.Sheets.Tables.TableThemes.professional7);
//bind a view to the table sheet
myTable.fetch().then(function() {
var Colors = {
lightGreen: "rgb(227,239,218)",
middleGreen: "rgb(115,150,61)",
darkGreen: "rgb(115,150,61)",
lightGray: "rgb(191,191,191)",
white: "rgb(255,255,255)",
gray: "rgb(225,225,225)",
black: "rgb(0,0,0)"
};
var formatter = "$#,##0.00_);($#,##0.00)";
var currencyFormatter = { formatter: formatter };
var headerStyle = {
backColor: Colors.darkGreen,
foreColor: Colors.white,
font: "bold 12pt Calibri",
hAlign: "left"
};
var dataBarRule1 = {
ruleType: "dataBarRule",
color: Colors.darkGreen,
gradient: true
};
var dataBarRule2 = {
ruleType: "dataBarRule",
color: Colors.lightGray,
gradient: true,
barDirection: "rightToLeft"
};
var view = myTable.addView("myView", [
{ value: "item", caption: "Item", width: 180, headerStyle },
{ value: "description", caption: "Description", width: 120, headerStyle },
{ value: "quantity", caption: "Qty", width: 90, headerStyle },
{ value: "cost", caption: "Cost", width: 100, style: currencyFormatter, headerStyle, conditionalFormats: [dataBarRule1] },
{ value: "=[@cost]*[@quantity]", caption: "Amount", width: 120, style: currencyFormatter, headerStyle, conditionalFormats: [dataBarRule2] }
]);
// create template sheet for free header area json
var templateSheet = new GC.Spread.Sheets.Worksheet();
templateSheet.options.keepUnknownFormulas = true;
var currencyFormatterStyle = new GC.Spread.Sheets.Style();
currencyFormatterStyle.formatter = formatter;
currencyFormatterStyle.hAlign = GC.Spread.Sheets.HorizontalAlign.left;
templateSheet.setRowCount(6);
var freeHeaderAreaStyle = new GC.Spread.Sheets.Style();
freeHeaderAreaStyle.backColor = Colors.white;
templateSheet.setValue(0, 0, "Business Trip Budget");
templateSheet.getCell(0, 0).hAlign(GC.Spread.Sheets.HorizontalAlign.left).font("bold 30px \"Microsoft Sans Serif\"");
templateSheet.addSpan(0, 0, 1, 5);
var titleStyle = new GC.Spread.Sheets.Style();
titleStyle.backColor = Colors.lightGreen;
titleStyle.foreColor = Colors.black;
templateSheet.setStyle(0, -1, titleStyle);
templateSheet.setRowHeight(0, 80);
templateSheet.getCell(1, 0)
.value("Enter Target trip budget below. Total trip cost and under or over budget are automatically calculated.")
.font("italic 12px \"Microsoft Sans Serif\"")
.foreColor("rgb(120,120,120)")
.textIndent(2);
templateSheet.setStyle(1, -1, titleStyle);
templateSheet.addSpan(1, 0, 1, 5);
var headerDescriptionStyle = new GC.Spread.Sheets.Style();
headerDescriptionStyle.backColor = Colors.lightGreen;
headerDescriptionStyle.borderBottom = new GC.Spread.Sheets.LineBorder(Colors.middleGreen, GC.Spread.Sheets.LineStyle.thick);
templateSheet.setStyle(2, -1, headerDescriptionStyle);
templateSheet.addSpan(2, 0, 1, 5);
templateSheet.setRowHeight(2, 16);
templateSheet.setValue(3, 0, "Target trip budget");
templateSheet.getCell(3, 0).hAlign(GC.Spread.Sheets.HorizontalAlign.left).font("bold 14px \"Trebuchet MS\"").foreColor(Colors.darkGreen);
templateSheet.addSpan(3, 0, 1, 2);
templateSheet.setValue(3, 2, 1000);
templateSheet.getCell(3, 2).hAlign(GC.Spread.Sheets.HorizontalAlign.left).font("bold 14px \"Trebuchet MS\"").foreColor(Colors.darkGreen).formatter(formatter);
templateSheet.setFormula(3, 3, '=HBARSPARKLINE(ROUND(C4/MAX(C4,C5),2),"'+ Colors.darkGreen +'",false)');
templateSheet.setStyle(3, 3, new GC.Spread.Sheets.Style(undefined, Colors.black));
templateSheet.addSpan(3, 3, 1, 2);
templateSheet.setStyle(3, -1, freeHeaderAreaStyle);
templateSheet.setValue(4, 0, "Total cost of the trip");
templateSheet.getCell(4, 0).hAlign(GC.Spread.Sheets.HorizontalAlign.left).font("bold 14px \"Trebuchet MS\"").foreColor(Colors.lightGray);
templateSheet.addSpan(4, 0, 1, 2);
templateSheet.setFormula(4, 2, '=SUM(TableSheet1[Amount])');
templateSheet.getCell(4, 2).hAlign(GC.Spread.Sheets.HorizontalAlign.left).font("bold 14px \"Trebuchet MS\"").foreColor(Colors.lightGray).formatter(formatter);
var contentBorderStyle = new GC.Spread.Sheets.Style();
contentBorderStyle.backColor = Colors.white;
contentBorderStyle.borderBottom = new GC.Spread.Sheets.LineBorder(Colors.lightGray, GC.Spread.Sheets.LineStyle.thick);
templateSheet.setStyle(4, -1, contentBorderStyle);
templateSheet.setFormula(4, 3, '=HBARSPARKLINE(ROUND(C5/MAX(C4,C5),2),"'+ Colors.lightGray +'",false)');
templateSheet.setStyle(4, 3, new GC.Spread.Sheets.Style(undefined, Colors.black));
templateSheet.addSpan(4, 3, 1, 2);
templateSheet.setFormula(5, 0, '=IF(C4>C5,"You\'re under budget by","You\'re over budget by")');
templateSheet.getCell(5, 0).hAlign(GC.Spread.Sheets.HorizontalAlign.left).font("bold 14px \"Trebuchet MS\"").foreColor(Colors.black);
templateSheet.addSpan(5, 0, 1, 2);
templateSheet.setFormula(5, 2, '=C4-C5');
templateSheet.getCell(5, 2).hAlign(GC.Spread.Sheets.HorizontalAlign.left).font("bold 14px \"Trebuchet MS\"").formatter(formatter).foreColor(Colors.black);
templateSheet.setStyle(5, -1, freeHeaderAreaStyle);
templateSheet.addSpan(5, 2, 1, 3);
let template = templateSheet.toJSON();
sheet.applyFreeHeaderArea(template);
sheet.setDataView(view);
});
spread.resumePaint();
}
}
<!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" style="height: 100%;"></div>
</body>
</html>
.sample-tutorial {
position: relative;
height: 100%;
overflow: hidden;
}
.sample-spreadsheets {
width: 100%;
height: 100%;
overflow: hidden;
float: left;
}
body {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.gc-columnHeader-selected, .gc-columnHeader-highlight, .gc-columnHeader-hover {
background-color: rgba(115,150,61,0.8);
color: white;
border-bottom-color: white !important;
}
(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-tablesheet': 'npm:@mescius/spread-sheets-tablesheet/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/cjs/react.production.js',
'react-dom': 'npm:react-dom/cjs/react-dom.production.js',
'react-dom/client': 'npm:react-dom/cjs/react-dom-client.production.js',
'scheduler': 'npm:scheduler/cjs/scheduler.production.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);