You can control whether to show the table's header or footer, whether to display an alternating row style or column style, and whether to highlight the first column or the last column. For example:
SpreadJS supports built-in table styles or you can customize the table style. For example:
SpreadJS supports customize the style of the table header, data or footer, the table column header, data or footer. Using code such as the following:
<template>
<div class="sample-tutorial">
<gc-spread-sheets class="sample-spreadsheets" @workbookInitialized="initSpread"></gc-spread-sheets>
<panel v-bind:tableStylesList="tableStylesList" @onShowHeader="onShowHeader"
@onHighlightFirstColumn="onHighlightFirstColumn" @onShowFooter="onShowFooter"
@onHighlightLastColumn="onHighlightLastColumn" @onBandColumns="onBandColumns" @onBandRows="onBandRows"
@onStyleTypeChange="onStyleTypeChange"></panel>
</div>
</template>
<script setup>
import '@mescius/spread-sheets-vue';
import { ref } from "vue";
import Panel from "./panel.vue";
import GC from "@mescius/spread-sheets";
const spreadNS = GC.Spread.Sheets;
let spreadRef;
const tableStylesList = ref({
0: "Light1",
1: "Light2",
2: "Light3",
3: "Light4",
4: "Light5",
5: "Light6",
6: "Light7",
7: "Light8",
8: "Light9",
9: "Light10",
10: "Light11",
11: "Light12",
12: "Light13",
13: "Light14",
14: "Light15",
15: "Light16",
16: "Light17",
17: "Light18",
18: "Light19",
19: "Light20",
20: "Light21",
21: "Medium1",
22: "Medium2",
23: "Medium3",
24: "Medium4",
25: "Medium5",
26: "Medium6",
27: "Medium7",
28: "Medium8",
29: "Medium9",
30: "Medium10",
31: "Medium11",
32: "Medium12",
33: "Medium13",
34: "Medium14",
35: "Medium15",
36: "Medium16",
37: "Medium17",
38: "Medium18",
39: "Medium19",
40: "Medium20",
41: "Medium21",
42: "Medium22",
43: "Medium23",
44: "Medium24",
45: "Medium25",
46: "Medium26",
47: "Medium27",
48: "Medium28",
49: "Dark1",
50: "Dark2",
51: "Dark3",
52: "Dark4",
53: "Dark5",
54: "Dark6",
55: "Dark7",
56: "Dark8",
57: "Dark9",
58: "Dark10",
59: "Dark11",
60: "None",
61: "Custom1",
62: "Custom2"
});
function setStyles(sheet) {
let table = sheet.tables.all()[0];
sheet.suspendPaint();
let tableHeaderStyle = new GC.Spread.Sheets.Style();
tableHeaderStyle.backColor = "Accent 1 80";
let tableDataStyle = new GC.Spread.Sheets.Style();
tableDataStyle.backColor = "Accent 4 80";
let tableFooterStyle = new GC.Spread.Sheets.Style();
tableFooterStyle.backColor = "Accent 6 80";
table.layoutStyle({
header: tableHeaderStyle,
data: tableDataStyle,
footer: tableFooterStyle
});
let tableColumnHeaderStyle = new GC.Spread.Sheets.Style();
tableColumnHeaderStyle.backColor = "Accent 1 40";
let tableColumnDataStyle = new GC.Spread.Sheets.Style();
tableColumnDataStyle.backColor = "Accent 4 40";
let tableColumnFooterStyle = new GC.Spread.Sheets.Style();
tableColumnFooterStyle.backColor = "Accent 6 40";
table.columnLayoutStyle(1, {
header: tableColumnHeaderStyle,
data: tableColumnDataStyle,
footer: tableColumnFooterStyle
});
let tableColumn3DataStyle = new GC.Spread.Sheets.Style();
tableColumn3DataStyle.formatter = "0%";
table.columnLayoutStyle(3, {
data: tableColumn3DataStyle
});
sheet.resumePaint();
}
function initCustomThemes(spread) {
const theme1 = new GC.Spread.Sheets.Tables.TableTheme();
theme1.name('custom1');
theme1.wholeTableStyle(new GC.Spread.Sheets.Tables.TableStyle('#e0f2f1'));
theme1.headerRowStyle(new GC.Spread.Sheets.Tables.TableStyle('#26a69a', '#fff'));
theme1.firstRowStripStyle(new GC.Spread.Sheets.Tables.TableStyle('#b2dfdb'));
theme1.firstColumnStripStyle(new GC.Spread.Sheets.Tables.TableStyle('#b2dfdb'));
theme1.footerRowStyle(new GC.Spread.Sheets.Tables.TableStyle('#26a69a', '#fff'));
theme1.highlightFirstColumnStyle(new GC.Spread.Sheets.Tables.TableStyle('#26a69a', '#fff'));
theme1.highlightLastColumnStyle(new GC.Spread.Sheets.Tables.TableStyle('#26a69a', '#fff'));
const theme2 = new GC.Spread.Sheets.Tables.TableTheme();
theme2.name('custom2');
theme2.wholeTableStyle(new GC.Spread.Sheets.Tables.TableStyle('#ede7f6'));
theme2.headerRowStyle(new GC.Spread.Sheets.Tables.TableStyle('#ede7f6', '#000'));
theme2.firstRowStripStyle(new GC.Spread.Sheets.Tables.TableStyle('#e1bee7'));
theme2.firstColumnStripStyle(new GC.Spread.Sheets.Tables.TableStyle('#e1bee7'));
theme2.footerRowStyle(new GC.Spread.Sheets.Tables.TableStyle('#ede7f6', '#000'));
spread.customTableThemes.add(theme1);
spread.customTableThemes.add(theme2);
}
const initSpread = (spread) => {
spreadRef = spread;
spread.fromJSON(jsonData);
initCustomThemes(spread);
let sheet = spread.getActiveSheet();
setStyles(sheet);
spread.bind(GC.Spread.Sheets.Events.EnterCell, (eventType, data) => {
if (data) {
let activeSheet = spread.getActiveSheet();
let activeTable = activeSheet.tables.find(activeSheet.getActiveRowIndex(), activeSheet.getActiveColumnIndex());
if (activeTable) {
let style = activeTable.style(), name = 'None';
if (style) {
name = style.name();
}
self.styleType = name;
}
}
});
}
const getActiveSheetTable = () => {
let sheet = spreadRef.getActiveSheet();
let table = sheet.tables.find(
sheet.getActiveRowIndex(),
sheet.getActiveColumnIndex()
) || sheet.tables.all()[0];
return { sheet, table };
}
const onShowHeader = (value) => {
let { sheet, table } = getActiveSheetTable();
if (table) {
table.showHeader(value);
sheet.invalidateLayout();
sheet.repaint();
}
}
const onShowFooter = (value) => {
let { sheet, table } = getActiveSheetTable();
if (table) {
table.showFooter(value);
sheet.invalidateLayout();
sheet.repaint();
}
}
const onHighlightFirstColumn = (value) => {
let { sheet, table } = getActiveSheetTable();
if (table) {
table.highlightFirstColumn(value);
sheet.invalidateLayout();
sheet.repaint();
}
}
const onHighlightLastColumn = (value) => {
let { sheet, table } = getActiveSheetTable();
if (table) {
table.highlightLastColumn(value);
sheet.invalidateLayout();
sheet.repaint();
}
}
const onBandRows = (value) => {
let { sheet, table } = getActiveSheetTable();
if (table) {
table.bandRows(value);
sheet.invalidateLayout();
sheet.repaint();
}
}
const onBandColumns = (value) => {
let { sheet, table } = getActiveSheetTable();
if (table) {
table.bandColumns(value);
sheet.invalidateLayout();
sheet.repaint();
}
}
const onStyleTypeChange = (value) => {
let { sheet, table } = getActiveSheetTable();
if (table) {
table.style(value);
sheet.repaint();
}
}
</script>
<style scoped>
#app {
height: 100%;
}
.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;
}
.option-group {
margin-bottom: 6px;
}
label {
display: inline-block;
min-width: 90px;
margin-bottom: 6px;
}
select {
padding: 4px 6px;
}
p {
padding: 0 0 12px;
margin: 0;
}
body {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
</style>
<template>
<div class="options-container">
<p>Select the table in the Spread instance and change the style and properties using the checkboxes and drop-down menu.</p>
<div class="option-group">
<input type="checkbox" id="showHeader" v-model="isShowHeader" v-on:change="onShowHeader" />
<label for="showHeader">Header Row</label>
</div>
<div class="option-group">
<input type="checkbox" id="highlightFirstColumn" v-model="isHighlightFirstColumn" v-on:change="onHighlightFirstColumn" />
<label for="highlightFirstColumn">First Column</label>
</div>
<div class="option-group">
<input type="checkbox" id="showFooter" v-model="isShowFooter" v-on:change="onShowFooter" />
<label for="showFooter">Total Row</label>
</div>
<div class="option-group">
<input type="checkbox" id="highlightLastColumn" v-model="isHighlightLastColumn" v-on:change="onHighlightLastColumn" />
<label for="highlightLastColumn">Last Column</label>
</div>
<div class="option-group">
<input type="checkbox" id="bandColumns" v-model="isBandColumns" v-on:change="onBandColumns" />
<label for="bandColumns">Banded Column</label>
</div>
<div class="option-group">
<input type="checkbox" id="bandRows" v-model="isBandRows" v-on:change="onBandRows" />
<label for="bandRows">Banded Row</label>
</div>
<div class="option-group">
<label for="tableStyles">Styles:</label>
<select id="tableStyles" v-model="styleType" v-on:change="onStyleTypeChange">
<option v-bind:value="item" v-for="(item, index) in tableStylesList" :key="index">{{ item }}</option>
</select>
</div>
</div>
</template>
<script>
export default {
props: [
"tableStylesList"
],
data: function () {
return {
isShowHeader: true,
isHighlightFirstColumn: false,
isShowFooter: false,
isHighlightLastColumn: false,
isBandColumns: false,
isBandRows: true,
styleType: 'None'
};
},
methods: {
onShowHeader() {
this.$emit("onShowHeader", this.isShowHeader);
},
onHighlightFirstColumn() {
this.$emit("onHighlightFirstColumn", this.isHighlightFirstColumn);
},
onShowFooter() {
this.$emit("onShowFooter", this.isShowFooter);
},
onHighlightLastColumn() {
this.$emit("onHighlightLastColumn", this.isHighlightLastColumn);
},
onBandColumns() {
this.$emit("onBandColumns", this.isBandColumns);
},
onBandRows() {
this.$emit("onBandRows", this.isBandRows);
},
onStyleTypeChange(event) {
this.$emit("onStyleTypeChange", this.styleType);
}
}
}
</script>
<style>
</style>
<!DOCTYPE html>
<html style="height:100%;font-size:14px;">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>SpreadJS VUE</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" type="text/css"
href="$DEMOROOT$/en/vue3/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css">
<script src="$DEMOROOT$/en/vue3/node_modules/systemjs/dist/system.src.js"></script>
<script src="data.js" type="text/javascript"></script>
<script src="./systemjs.config.js"></script>
<script src="./compiler.js" type="module"></script>
<script>
var System = SystemJS;
System.import("./src/app.js");
System.import('$DEMOROOT$/en/lib/vue3/license.js');
</script>
</head>
<body>
<div id="app"></div>
</body>
</html>
var jsonData = {
version: "16.0.0",
name: "",
sheetCount: 2,
customList: [],
activeSheetIndex: 1,
sheets: {
Table: {
name: "Table",
isSelected: false,
activeRow: 38,
activeCol: 2,
visible: 1,
theme: {
name: "Office",
themeColor: {
name: "Office",
background1: { a: 255, r: 255, g: 255, b: 255 },
background2: { a: 255, r: 231, g: 230, b: 230 },
text1: { a: 255, r: 0, g: 0, b: 0 },
text2: { a: 255, r: 68, g: 84, b: 106 },
accent1: { a: 255, r: 91, g: 155, b: 213 },
accent2: { a: 255, r: 237, g: 125, b: 49 },
accent3: { a: 255, r: 165, g: 165, b: 165 },
accent4: { a: 255, r: 255, g: 192, b: 0 },
accent5: { a: 255, r: 68, g: 114, b: 196 },
accent6: { a: 255, r: 112, g: 173, b: 71 },
hyperlink: { a: 255, r: 5, g: 99, b: 193 },
followedHyperlink: { a: 255, r: 149, g: 79, b: 114 },
},
headingFont: "'Calibri Light'",
bodyFont: "Calibri",
font: { headerFont: "'Calibri Light'", bodyFont: "Calibri" },
},
data: {
dataTable: {
0: {
0: { value: "SalesPers" },
1: { value: "Region" },
2: { value: "SaleAmt" },
3: { value: "ComPct" },
4: { value: "ComAmt" },
},
1: {
0: { value: "Joe" },
1: { value: "North" },
2: { value: 260 },
3: { value: 0.1 },
4: { value: 26, formula: { si: 0 } },
},
2: {
0: { value: "Robert" },
1: { value: "South" },
2: { value: 660 },
3: { value: 0.15 },
4: { value: 99, formula: { si: 0 } },
},
3: {
0: { value: "Michelle" },
1: { value: "East" },
2: { value: 940 },
3: { value: 0.15 },
4: { value: 141, formula: { si: 0 } },
},
4: {
0: { value: "Erich" },
1: { value: "West" },
2: { value: 410 },
3: { value: 0.12 },
4: { value: 49.2, formula: { si: 0 } },
},
5: {
0: { value: "Dafna" },
1: { value: "North" },
2: { value: 800 },
3: { value: 0.15 },
4: { value: 120, formula: { si: 0 } },
},
6: {
0: { value: "Robert" },
1: { value: "South" },
2: { value: 900 },
3: { value: 0.15 },
4: { value: 135, formula: { si: 0 } },
}
},
defaultDataNode: {
style: {
backColor: null,
foreColor: "Text 1 0",
vAlign: 2,
font: "normal normal 14.6667px Calibri",
themeFont: "Body",
borderLeft: null,
borderTop: null,
borderRight: null,
borderBottom: null,
locked: true,
textIndent: 0,
wordWrap: false,
shrinkToFit: false,
textDecoration: 0,
isVerticalText: false,
textOrientation: 0,
fontStyle: "normal",
fontWeight: "normal",
fontSize: "14.6667px",
fontFamily: "Calibri",
},
},
},
rowHeaderData: { defaultDataNode: { style: { themeFont: "Body" } } },
colHeaderData: { defaultDataNode: { style: { themeFont: "Body" } } },
columns: [
{ size: 81 },
{ size: 65 },
{ size: 74 },
{ size: 69 },
{ size: 76 },
],
defaultData: {},
leftCellIndex: 0,
topCellIndex: 0,
selections: {
0: { row: 38, col: 2, rowCount: 1, colCount: 1 },
length: 1,
},
defaults: {
colHeaderRowHeight: 20,
colWidth: 64,
rowHeaderColWidth: 40,
rowHeight: 20,
_isExcelDefaultColumnWidth: true,
},
rowOutlines: { items: [] },
columnOutlines: { items: [] },
cellStates: {},
states: {},
outlineColumnOptions: {},
autoMergeRangeInfos: [],
tables: [
{
name: "Table1",
row: 0,
col: 0,
rowCount: 7,
colCount: 5,
rowFilter: {
range: { row: 1, col: 0, rowCount: 6, colCount: 5 },
typeName: "HideRowFilter",
dialogVisibleInfo: {},
filterButtonVisibleInfo: {
0: true,
1: true,
2: true,
3: true,
4: true,
},
showFilterButton: true,
filteredOutRows: [],
tableName: "Table1",
},
columns: [
{ id: 1, name: "SalesPers", footerValue: "Total" },
{ id: 2, name: "Region" },
{ id: 3, name: "SaleAmt" },
{ id: 4, name: "ComPct" },
{
id: 5,
name: "ComAmt",
footerFormula: "SUBTOTAL(109,Table1[ComAmt])",
dataAreaFormula: "C2*D2",
},
],
},
],
shapeCollectionOption: { snapMode: 0 },
sharedFormulas: {
0: {
formula: "C2*D2",
baseRow: 1,
baseColumn: 4,
lastRow: 6,
lastColumn: 4,
},
nextIndex: 1,
},
printInfo: {
showColumnHeader: 1,
showRowHeader: 1,
paperSize: { width: 850, height: 1100, kind: 1 },
},
index: 0,
order: 0,
},
TableWithLayoutStyle: {
name: "TableWithLayoutStyle",
isSelected: true,
activeRow: 5,
activeCol: 7,
visible: 1,
theme: {
name: "Office",
themeColor: {
name: "Office",
background1: { a: 255, r: 255, g: 255, b: 255 },
background2: { a: 255, r: 231, g: 230, b: 230 },
text1: { a: 255, r: 0, g: 0, b: 0 },
text2: { a: 255, r: 68, g: 84, b: 106 },
accent1: { a: 255, r: 91, g: 155, b: 213 },
accent2: { a: 255, r: 237, g: 125, b: 49 },
accent3: { a: 255, r: 165, g: 165, b: 165 },
accent4: { a: 255, r: 255, g: 192, b: 0 },
accent5: { a: 255, r: 68, g: 114, b: 196 },
accent6: { a: 255, r: 112, g: 173, b: 71 },
hyperlink: { a: 255, r: 5, g: 99, b: 193 },
followedHyperlink: { a: 255, r: 149, g: 79, b: 114 },
},
headingFont: "'Calibri Light'",
bodyFont: "Calibri",
font: { headerFont: "'Calibri Light'", bodyFont: "Calibri" },
},
data: {
dataTable: {
0: {
0: { value: "SalesPers" },
1: { value: "Region" },
2: { value: "SaleAmt" },
3: { value: "ComPct" },
4: { value: "ComAmt" },
8: {
value:
"Add record to the table, see the auto-expanded table layout style",
},
},
1: {
0: { value: "Joe" },
1: { value: "North" },
2: { value: 260 },
3: { value: 0.1 },
4: { value: 26, formula: { si: 0 } },
8: {
value: "The table layout style‘s priority is higher than the table theme",
},
},
2: {
0: { value: "Robert" },
1: { value: "South" },
2: { value: 660 },
3: { value: 0.15 },
4: { value: 99, formula: { si: 0 } },
8: {
value: "Usually 'Banded Row' and 'Banded Column' only have backColor setting, so check these two options may take no effect",
},
},
3: {
0: { value: "Michelle" },
1: { value: "East" },
2: { value: 940 },
3: { value: 0.15 },
4: { value: 141, formula: { si: 0 } },
},
4: {
0: { value: "Erich" },
1: { value: "West" },
2: { value: 410 },
3: { value: 0.12 },
4: { value: 49.2, formula: { si: 0 } },
},
5: {
0: { value: "Dafna" },
1: { value: "North" },
2: { value: 800 },
3: { value: 0.15 },
4: { value: 120, formula: { si: 0 } },
},
6: {
0: { value: "Robert" },
1: { value: "South" },
2: { value: 900 },
3: { value: 0.15 },
4: { value: 135, formula: { si: 0 } },
},
},
defaultDataNode: {
style: {
backColor: null,
foreColor: "Text 1 0",
vAlign: 2,
font: "normal normal 14.6667px Calibri",
themeFont: "Body",
borderLeft: null,
borderTop: null,
borderRight: null,
borderBottom: null,
locked: true,
textIndent: 0,
wordWrap: false,
shrinkToFit: false,
textDecoration: 0,
isVerticalText: false,
textOrientation: 0,
fontStyle: "normal",
fontWeight: "normal",
fontSize: "14.6667px",
fontFamily: "Calibri",
},
},
},
rowHeaderData: { defaultDataNode: { style: { themeFont: "Body" } } },
colHeaderData: { defaultDataNode: { style: { themeFont: "Body" } } },
columns: [
{ size: 81 },
{ size: 65 },
{ size: 74 },
{ size: 69 },
{ size: 76 },
],
defaultData: {},
leftCellIndex: 0,
topCellIndex: 0,
selections: {
0: { row: 5, col: 7, rowCount: 1, colCount: 1 },
length: 1,
},
defaults: {
colHeaderRowHeight: 20,
colWidth: 64,
rowHeaderColWidth: 40,
rowHeight: 20,
_isExcelDefaultColumnWidth: true,
},
rowOutlines: { items: [] },
columnOutlines: { items: [] },
cellStates: {},
states: {},
outlineColumnOptions: {},
autoMergeRangeInfos: [],
tables: [
{
name: "Table2",
row: 0,
col: 0,
rowCount: 7,
colCount: 5,
rowFilter: {
range: { row: 1, col: 0, rowCount: 6, colCount: 5 },
typeName: "HideRowFilter",
dialogVisibleInfo: {},
filterButtonVisibleInfo: {
0: true,
1: true,
2: true,
3: true,
4: true,
},
showFilterButton: true,
filteredOutRows: [],
tableName: "Table2",
},
columns: [
{ id: 1, name: "SalesPers", footerValue: "Total" },
{ id: 2, name: "Region" },
{ id: 3, name: "SaleAmt" },
{ id: 4, name: "ComPct" },
{
id: 5,
name: "ComAmt",
footerFormula: "SUBTOTAL(109,Table2[ComAmt])",
dataAreaFormula: "C2*D2",
},
],
},
],
shapeCollectionOption: { snapMode: 0 },
sharedFormulas: {
0: {
formula: "C2*D2",
baseRow: 1,
baseColumn: 4,
lastRow: 6,
lastColumn: 4,
},
nextIndex: 1,
},
printInfo: {
showColumnHeader: 1,
showRowHeader: 1,
paperSize: { width: 850, height: 1100, kind: 1 },
},
index: 1,
order: 1,
},
},
sheetTabCount: 0,
namedPatterns: {},
pivotCaches: {},
};
(function (global) {
SystemJS.config({
transpiler: 'plugin-babel',
babelOptions: {
es2015: true
},
paths: {
// paths serve as alias
'npm:': 'node_modules/'
},
packageConfigPaths: [
'./node_modules/*/package.json',
"./node_modules/@mescius/*/package.json",
"./node_modules/@babel/*/package.json",
"./node_modules/@vue/*/package.json"
],
map: {
'vue': "npm:vue/dist/vue.esm-browser.js",
'tiny-emitter': 'npm:tiny-emitter/index.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-vue': 'npm:@mescius/spread-sheets-vue/index.js'
},
meta: {
'*.css': { loader: 'systemjs-plugin-css' },
'*.vue': { loader: "../plugin-vue/index.js" }
}
});
})(this);