Data Grid Footers
Footers allow you to display information, summaries, or calculations at the bottom of a data grid. This section provides instructions for implementing footers during initialization or runtime using programmatic techniques.
Documentation
Methods
Methods providing programmatic interaction with the footers of the Jspreadsheet data grid.
Method | Description |
---|---|
getFooter |
Get the current footer settings.getFooter() : Array |
setFooter |
Set the footer settings.setFooter(newValue: Array) : void |
resetFooter |
Reset and remove the footers.resetFooter() : void |
getFooterValue |
Get the current footer cell value from the coordinates x, y.getFooterValue(x: Number, y: Number) : void |
setFooterValue |
Set the value of a footer cell. In v12, accepts array of values.setFooterValue(records: FooterRecord[]) : void |
interface FooterRecord {
value: string | number | boolean | undefined;
x: number;
y: number;
}
Events
Events allowing you to intercept user interactions with the Jspreadsheet data grid.
Event | Description |
---|---|
onchangefooter |
Triggered when the footers undergo modification in the Jspreadsheet data grid.onchangefooter(worksheet: Object, newValue: String, oldValue: String) : null |
onchangefootervalue |
Triggered when the values of the footers in the Jspreadsheet data grid are modified.onchangefootervalue(worksheet: Object, records: FooterRecord[]) : null |
onrenderfootercell |
Triggered when a footer cell is rendered.onrenderfootercell(worksheet: Object, footer: object) : null |
Initial Settings
Properties available during the initialization of the Jspreadsheet online spreadsheet.
Property | Description |
---|---|
footers?: string[] |
Footer definitions |
applyMaskOnFooters?: boolean |
Apply a mask defined in a column to the related footer |
Examples
Basic footer usage
The following example shows how to implement footers with basic formulas and formatting:
<html>
<script src="https://jspreadsheet.com/v12/jspreadsheet.js"></script>
<script src="https://jsuites.net/v6/jsuites.js"></script>
<link rel="stylesheet" href="https://jsuites.net/v6/jsuites.css" type="text/css" />
<link rel="stylesheet" href="https://jspreadsheet.com/v12/jspreadsheet.css" type="text/css" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Material+Icons" />
<div id="spreadsheet"></div>
<script>
// Set your JSS license key (The following key only works for one day)
jspreadsheet.setLicense('OTVjNDU1NTIzNmM3NWZhYjRjNjQ2YjVhMzNmODJmODljZDhkY2QwYjEzZmU1OGZlZGFlYmRjODVlODc0Y2VlZjJlOGZmMzhjNGE5ZDNmMDczNjI3MDlhMzRlNzg2NjVjY2YxYmVjZjgzNjBkZWQ2Njc1Y2NiODdjNjg5MzBjZjYsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpVNU56azJORFl6TENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0p6ZEdGamEySnNhWFI2TG1sdklpd2lkMlZpWTI5dWRHRnBibVZ5TG1sdklpd2lkMlZpSWl3aWJHOWpZV3hvYjNOMElsMHNJbkJzWVc0aU9pSXpOQ0lzSW5OamIzQmxJanBiSW5ZM0lpd2lkamdpTENKMk9TSXNJbll4TUNJc0luWXhNU0lzSW1Ob1lYSjBjeUlzSW1admNtMXpJaXdpWm05eWJYVnNZU0lzSW5CaGNuTmxjaUlzSW5KbGJtUmxjaUlzSW1OdmJXMWxiblJ6SWl3aWFXMXdiM0owWlhJaUxDSmlZWElpTENKMllXeHBaR0YwYVc5dWN5SXNJbk5sWVhKamFDSXNJbkJ5YVc1MElpd2ljMmhsWlhSeklpd2lZMnhwWlc1MElpd2ljMlZ5ZG1WeUlpd2ljMmhoY0dWeklpd2labTl5YldGMElsMHNJbVJsYlc4aU9uUnlkV1Y5');
// Custom SUMCOL formula to consider only visible rows
const SUMCOL = function(column) {
let sum = 0;
const worksheet = this;
const data = worksheet.getData(true); // Get only visible rows
for (let i = 0; i < data.length; i++) {
const value = parseFloat(data[i][column]) || 0;
sum += value;
}
return sum;
}
// Register custom formula
jspreadsheet.setFormula('SUMCOL', SUMCOL);
// Create the spreadsheet
let worksheets = jspreadsheet(document.getElementById('spreadsheet'), {
worksheets: [{
data: [
['Cheese', 10, 6.00],
['Apples', 5, 4.00],
['Carrots', 5, 1.00],
['Oranges', 6, 2.00],
],
footers: [
[
'Visible Total',
'=SUMCOL(1)',
'=SUMCOL(2)',
]
],
columns: [
{ width: '400px' }
]
}],
onrenderfootercell: function(worksheet, footer) {
if (footer.v && footer.x > 0) {
// Applying a mask to the footer value
footer.element.innerText = jSuites.mask.render(footer.v, { mask: '$ #,##0.00'}, true);
}
}
});
</script>
</html>
Programmatic updates
Change the formulas in the footers after initialization.
<html>
<script src="https://jspreadsheet.com/v12/jspreadsheet.js"></script>
<script src="https://jsuites.net/v6/jsuites.js"></script>
<link rel="stylesheet" href="https://jsuites.net/v6/jsuites.css" type="text/css" />
<link rel="stylesheet" href="https://jspreadsheet.com/v12/jspreadsheet.css" type="text/css" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Material+Icons" />
<div id="spreadsheet"></div>
<p><input type='button' value='Change to AVERAGE' id="btn1"></p>
<script>
// Set your JSS license key (The following key only works for one day)
jspreadsheet.setLicense('OTVjNDU1NTIzNmM3NWZhYjRjNjQ2YjVhMzNmODJmODljZDhkY2QwYjEzZmU1OGZlZGFlYmRjODVlODc0Y2VlZjJlOGZmMzhjNGE5ZDNmMDczNjI3MDlhMzRlNzg2NjVjY2YxYmVjZjgzNjBkZWQ2Njc1Y2NiODdjNjg5MzBjZjYsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpVNU56azJORFl6TENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0p6ZEdGamEySnNhWFI2TG1sdklpd2lkMlZpWTI5dWRHRnBibVZ5TG1sdklpd2lkMlZpSWl3aWJHOWpZV3hvYjNOMElsMHNJbkJzWVc0aU9pSXpOQ0lzSW5OamIzQmxJanBiSW5ZM0lpd2lkamdpTENKMk9TSXNJbll4TUNJc0luWXhNU0lzSW1Ob1lYSjBjeUlzSW1admNtMXpJaXdpWm05eWJYVnNZU0lzSW5CaGNuTmxjaUlzSW5KbGJtUmxjaUlzSW1OdmJXMWxiblJ6SWl3aWFXMXdiM0owWlhJaUxDSmlZWElpTENKMllXeHBaR0YwYVc5dWN5SXNJbk5sWVhKamFDSXNJbkJ5YVc1MElpd2ljMmhsWlhSeklpd2lZMnhwWlc1MElpd2ljMlZ5ZG1WeUlpd2ljMmhoY0dWeklpd2labTl5YldGMElsMHNJbVJsYlc4aU9uUnlkV1Y5');
// Create the spreadsheet
let worksheets = jspreadsheet(document.getElementById('spreadsheet'), {
worksheets: [{
data: [
['Cheese', 10, 6.00],
['Apples', 5, 4.00],
['Carrots', 5, 1.00],
['Oranges', 6, 2.00],
],
footers: [
[
'Total',
'=SUM(B:B)',
'=SUM(C:C)',
]
],
columns: [
{ width: '400px' }
]
}],
onrenderfootercell: function(worksheet, footer) {
if (footer.v && footer.x > 0) {
// Applying a mask to the footer value
footer.element.innerText = jSuites.mask.render(footer.v, { mask: '$ #,##0.00'}, true);
}
}
});
let update = function() {
worksheets[0].setFooterValue([
{ x: 0, y: 0, value: 'Average' },
{ x: 1, y: 0, value: '=AVERAGE(B:B)' },
{ x: 2, y: 0, value: '=AVERAGE(C:C)' }
]);
}
document.getElementById("btn1").onclick = update
</script>
</html>
import React, {useRef} from "react";
import {Spreadsheet, Worksheet, jspreadsheet} from "@jspreadsheet/react";
import jSuites from "jsuites";
import formula from "@jspreadsheet/formula";
import "jsuites/dist/jsuites.css";
import "jspreadsheet/dist/jspreadsheet.css";
// License
jspreadsheet.setLicense('OTVjNDU1NTIzNmM3NWZhYjRjNjQ2YjVhMzNmODJmODljZDhkY2QwYjEzZmU1OGZlZGFlYmRjODVlODc0Y2VlZjJlOGZmMzhjNGE5ZDNmMDczNjI3MDlhMzRlNzg2NjVjY2YxYmVjZjgzNjBkZWQ2Njc1Y2NiODdjNjg5MzBjZjYsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpVNU56azJORFl6TENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0p6ZEdGamEySnNhWFI2TG1sdklpd2lkMlZpWTI5dWRHRnBibVZ5TG1sdklpd2lkMlZpSWl3aWJHOWpZV3hvYjNOMElsMHNJbkJzWVc0aU9pSXpOQ0lzSW5OamIzQmxJanBiSW5ZM0lpd2lkamdpTENKMk9TSXNJbll4TUNJc0luWXhNU0lzSW1Ob1lYSjBjeUlzSW1admNtMXpJaXdpWm05eWJYVnNZU0lzSW5CaGNuTmxjaUlzSW5KbGJtUmxjaUlzSW1OdmJXMWxiblJ6SWl3aWFXMXdiM0owWlhJaUxDSmlZWElpTENKMllXeHBaR0YwYVc5dWN5SXNJbk5sWVhKamFDSXNJbkJ5YVc1MElpd2ljMmhsWlhSeklpd2lZMnhwWlc1MElpd2ljMlZ5ZG1WeUlpd2ljMmhoY0dWeklpd2labTl5YldGMElsMHNJbVJsYlc4aU9uUnlkV1Y5');
// Load the formula pro extension
jspreadsheet.setExtensions({formula});
// Create a new data grid
export default function App() {
// Spreadsheet array of worksheets
const spreadsheet = useRef();
// Data
const data = [
['Cheese', 10, 6.00],
['Apples', 5, 4.00],
['Carrots', 5, 1.00],
['Oranges', 6, 2.00],
];
// Columns
const columns = [
{width: '400px'}
];
// Data grid cell definitions
const footers = [
[
'Total',
'=SUM(B:B)',
'=SUM(C:C)',
]
];
// Event
const onrenderfootercell = (worksheet, footer) => {
if (footer.v && footer.x > 0) {
// Applying a mask to the footer value
footer.element.innerText = jSuites.mask.render(footer.v, {mask: '$ #,##0.00'}, true);
}
}
// Update
const update = () => {
spreadsheet.current[0].setFooterValue([
{ x: 0, y: 0, value: 'Average' },
{ x: 1, y: 0, value: '=AVERAGE(B:B)' },
{ x: 2, y: 0, value: '=AVERAGE(C:C)' }
]);
}
// Render data grid component
return (<>
<Spreadsheet ref={spreadsheet} onrenderfootercell={onrenderfootercell}>
<Worksheet data={data} columns={columns} footers={footers}/>
</Spreadsheet>
<input type="button" value="Change to AVERAGE" onClick={() => update()}/>
</>);
}
<template>
<Spreadsheet ref="spreadsheet" :onrenderfootercell="onrenderfootercell">
<Worksheet :data="data" :columns="columns" :footers="footers" />
</Spreadsheet>
<button type="button" @click="update">Update</button>
</template>
<script>
import { Spreadsheet, Worksheet, jspreadsheet } from '@jspreadsheet/vue';
import formula from '@jspreadsheet/formula';
import jSuites from 'jsuites';
import 'jsuites/dist/jsuites.css';
import 'jspreadsheet/dist/jspreadsheet.css';
// License
jspreadsheet.setLicense('OTVjNDU1NTIzNmM3NWZhYjRjNjQ2YjVhMzNmODJmODljZDhkY2QwYjEzZmU1OGZlZGFlYmRjODVlODc0Y2VlZjJlOGZmMzhjNGE5ZDNmMDczNjI3MDlhMzRlNzg2NjVjY2YxYmVjZjgzNjBkZWQ2Njc1Y2NiODdjNjg5MzBjZjYsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpVNU56azJORFl6TENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0p6ZEdGamEySnNhWFI2TG1sdklpd2lkMlZpWTI5dWRHRnBibVZ5TG1sdklpd2lkMlZpSWl3aWJHOWpZV3hvYjNOMElsMHNJbkJzWVc0aU9pSXpOQ0lzSW5OamIzQmxJanBiSW5ZM0lpd2lkamdpTENKMk9TSXNJbll4TUNJc0luWXhNU0lzSW1Ob1lYSjBjeUlzSW1admNtMXpJaXdpWm05eWJYVnNZU0lzSW5CaGNuTmxjaUlzSW5KbGJtUmxjaUlzSW1OdmJXMWxiblJ6SWl3aWFXMXdiM0owWlhJaUxDSmlZWElpTENKMllXeHBaR0YwYVc5dWN5SXNJbk5sWVhKamFDSXNJbkJ5YVc1MElpd2ljMmhsWlhSeklpd2lZMnhwWlc1MElpd2ljMlZ5ZG1WeUlpd2ljMmhoY0dWeklpd2labTl5YldGMElsMHNJbVJsYlc4aU9uUnlkV1Y5');
// Load the formula pro extension
jspreadsheet.setExtensions({ formula });
export default {
components: {
Spreadsheet,
Worksheet,
},
methods: {
update() {
this.$refs.spreadsheet.current[0].setFooterValue([
{ x: 0, y: 0, value: 'Average' },
{ x: 1, y: 0, value: '=AVERAGE(B:B)' },
{ x: 2, y: 0, value: '=AVERAGE(C:C)' }
]);
},
// Event
onrenderfootercell(worksheet, footer) {
if (footer.v && footer.x > 0) {
// Applying a mask to the footer value
footer.element.innerText = jSuites.mask.render(footer.v, { mask: '$ #,##0.00' }, true);
}
},
},
data() {
// Data
const data = [
['Cheese', 10, 6.0],
['Apples', 5, 4.0],
['Carrots', 5, 1.0],
['Oranges', 6, 2.0],
];
// Columns
const columns = [{ width: '400px' }];
// Data grid cell definitions
const footers = [['Total', '=SUM(B:B)', '=SUM(C:C)']];
return {
data,
columns,
footers,
};
},
};
</script>
import { Component, ViewChild, ElementRef, AfterViewInit } from "@angular/core";
import jspreadsheet from "jspreadsheet";
import formula from '@jspreadsheet/formula';
import jSuites from 'jsuites';
import 'jsuites/dist/jsuites.css';
import 'jspreadsheet/dist/jspreadsheet.css';
// Set your JSS license key (The following key only works for one day)
jspreadsheet.setLicense('OTVjNDU1NTIzNmM3NWZhYjRjNjQ2YjVhMzNmODJmODljZDhkY2QwYjEzZmU1OGZlZGFlYmRjODVlODc0Y2VlZjJlOGZmMzhjNGE5ZDNmMDczNjI3MDlhMzRlNzg2NjVjY2YxYmVjZjgzNjBkZWQ2Njc1Y2NiODdjNjg5MzBjZjYsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpVNU56azJORFl6TENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0p6ZEdGamEySnNhWFI2TG1sdklpd2lkMlZpWTI5dWRHRnBibVZ5TG1sdklpd2lkMlZpSWl3aWJHOWpZV3hvYjNOMElsMHNJbkJzWVc0aU9pSXpOQ0lzSW5OamIzQmxJanBiSW5ZM0lpd2lkamdpTENKMk9TSXNJbll4TUNJc0luWXhNU0lzSW1Ob1lYSjBjeUlzSW1admNtMXpJaXdpWm05eWJYVnNZU0lzSW5CaGNuTmxjaUlzSW5KbGJtUmxjaUlzSW1OdmJXMWxiblJ6SWl3aWFXMXdiM0owWlhJaUxDSmlZWElpTENKMllXeHBaR0YwYVc5dWN5SXNJbk5sWVhKamFDSXNJbkJ5YVc1MElpd2ljMmhsWlhSeklpd2lZMnhwWlc1MElpd2ljMlZ5ZG1WeUlpd2ljMmhoY0dWeklpd2labTl5YldGMElsMHNJbVJsYlc4aU9uUnlkV1Y5');
// Load the formula pro extension
jspreadsheet.setExtensions({ formula });
// Create component
@Component({
standalone: true,
selector: "app-root",
template: `<div #spreadsheet></div>
<button type="button" (click)="update()">Update</button>`
})
export class AppComponent implements AfterViewInit {
@ViewChild("spreadsheet") spreadsheet: ElementRef;
// Worksheets
worksheets: jspreadsheet.worksheetInstance[];
// Create a new data grid
ngAfterViewInit() {
// Create spreadsheet
this.worksheets = jspreadsheet(this.spreadsheet.nativeElement, {
worksheets: [{
data: [
['Cheese', 10, 6.00],
['Apples', 5, 4.00],
['Carrots', 5, 1.00],
['Oranges', 6, 2.00],
],
footers: [
[
'Total',
'=SUM(B:B)',
'=SUM(C:C)',
]
],
columns: [
{ width: '400px' }
]
}],
onrenderfootercell: function(worksheet, footer) {
if (footer.v && footer.x > 0) {
// Applying a mask to the footer value
footer.element.innerText = jSuites.mask.render(footer.v, { mask: '$ #,##0.00'}, true);
}
}
});
}
update() {
this.worksheets[0].setFooterValue([
{ x: 0, y: 0, value: 'Average' },
{ x: 1, y: 0, value: '=AVERAGE(B:B)' },
{ x: 2, y: 0, value: '=AVERAGE(C:C)' }
]);
}
}
Cross-footer Calculations
Footers are used to hold static information, but the following example creates a complete cross-footer calculation with realtime updates using onafterchanges. See our cross spreadsheet footer calculations on jsfiddle
<html>
<script src="https://jspreadsheet.com/v12/jspreadsheet.js"></script>
<script src="https://jsuites.net/v6/jsuites.js"></script>
<link rel="stylesheet" href="https://jsuites.net/v6/jsuites.css" type="text/css" />
<link rel="stylesheet" href="https://jspreadsheet.com/v12/jspreadsheet.css" type="text/css" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Material+Icons" />
<div id="spreadsheet1"></div><br>
<div id="spreadsheet2"></div><br>
<div id="spreadsheet3"></div><br>
<script>
// Set your JSS license key (The following key only works for one day)
jspreadsheet.setLicense('OTVjNDU1NTIzNmM3NWZhYjRjNjQ2YjVhMzNmODJmODljZDhkY2QwYjEzZmU1OGZlZGFlYmRjODVlODc0Y2VlZjJlOGZmMzhjNGE5ZDNmMDczNjI3MDlhMzRlNzg2NjVjY2YxYmVjZjgzNjBkZWQ2Njc1Y2NiODdjNjg5MzBjZjYsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpVNU56azJORFl6TENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0p6ZEdGamEySnNhWFI2TG1sdklpd2lkMlZpWTI5dWRHRnBibVZ5TG1sdklpd2lkMlZpSWl3aWJHOWpZV3hvYjNOMElsMHNJbkJzWVc0aU9pSXpOQ0lzSW5OamIzQmxJanBiSW5ZM0lpd2lkamdpTENKMk9TSXNJbll4TUNJc0luWXhNU0lzSW1Ob1lYSjBjeUlzSW1admNtMXpJaXdpWm05eWJYVnNZU0lzSW5CaGNuTmxjaUlzSW5KbGJtUmxjaUlzSW1OdmJXMWxiblJ6SWl3aWFXMXdiM0owWlhJaUxDSmlZWElpTENKMllXeHBaR0YwYVc5dWN5SXNJbk5sWVhKamFDSXNJbkJ5YVc1MElpd2ljMmhsWlhSeklpd2lZMnhwWlc1MElpd2ljMlZ5ZG1WeUlpd2ljMmhoY0dWeklpd2labTl5YldGMElsMHNJbVJsYlc4aU9uUnlkV1Y5');
// Load the formula pro extension
jspreadsheet.setExtensions({ formula });
// Create the spreadsheet
let s1 = jspreadsheet(document.getElementById('spreadsheet1'), {
worksheets: [{
worksheetName: 'JSS1',
data: [
[43, 64],
[51, 46],
],
footers: [
['=SUM(A:A)']
],
}],
});
// Create the spreadsheet
let s2 = jspreadsheet(document.getElementById('spreadsheet2'), {
worksheets: [{
worksheetName: 'JSS2',
data: [
[34, 53],
[51, 35],
],
footers: [
['=SUM(A:A)']
],
}],
});
// Create the spreadsheet
let s3 = jspreadsheet(document.getElementById('spreadsheet3'), {
worksheets: [{
worksheetName: 'JSS3',
data: [
[34, 53],
[51, 35],
],
footers: [
['=SUM(JSS1!A:A,JSS2!A:A,JSS3!A:A)']
],
}],
});
</script>
</html>
import React, { useRef } from "react";
import { Spreadsheet, Worksheet, jspreadsheet } from "@jspreadsheet/react";
import formula from "@jspreadsheet/formula";
import "jsuites/dist/jsuites.css";
import "jspreadsheet/dist/jspreadsheet.css";
// License
jspreadsheet.setLicense('OTVjNDU1NTIzNmM3NWZhYjRjNjQ2YjVhMzNmODJmODljZDhkY2QwYjEzZmU1OGZlZGFlYmRjODVlODc0Y2VlZjJlOGZmMzhjNGE5ZDNmMDczNjI3MDlhMzRlNzg2NjVjY2YxYmVjZjgzNjBkZWQ2Njc1Y2NiODdjNjg5MzBjZjYsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpVNU56azJORFl6TENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0p6ZEdGamEySnNhWFI2TG1sdklpd2lkMlZpWTI5dWRHRnBibVZ5TG1sdklpd2lkMlZpSWl3aWJHOWpZV3hvYjNOMElsMHNJbkJzWVc0aU9pSXpOQ0lzSW5OamIzQmxJanBiSW5ZM0lpd2lkamdpTENKMk9TSXNJbll4TUNJc0luWXhNU0lzSW1Ob1lYSjBjeUlzSW1admNtMXpJaXdpWm05eWJYVnNZU0lzSW5CaGNuTmxjaUlzSW5KbGJtUmxjaUlzSW1OdmJXMWxiblJ6SWl3aWFXMXdiM0owWlhJaUxDSmlZWElpTENKMllXeHBaR0YwYVc5dWN5SXNJbk5sWVhKamFDSXNJbkJ5YVc1MElpd2ljMmhsWlhSeklpd2lZMnhwWlc1MElpd2ljMlZ5ZG1WeUlpd2ljMmhoY0dWeklpd2labTl5YldGMElsMHNJbVJsYlc4aU9uUnlkV1Y5');
// Load the formula pro extension
jspreadsheet.setExtensions({ formula });
// Create a new data grid
export default function App() {
// Spreadsheet array of worksheets
const spreadsheet1 = useRef();
const spreadsheet2 = useRef();
const spreadsheet3 = useRef();
// Update footers from the last data grid
const onafterchanges = function () {
if (spreadsheet3.current) {
spreadsheet3.current[0].setFooter();
}
}
const s1 = [{
worksheetName: 'JSS1',
data: [
[43, 64],
[51, 46],
],
footers: [
['=SUM(A:A)']
],
}]
const s2 = [{
worksheetName: 'JSS2',
data: [
[34, 53],
[51, 35],
],
footers: [
['=SUM(A:A)']
],
}]
const s3 = [{
worksheetName: 'JSS3',
data: [
[34, 53],
[51, 35],
],
footers: [
['=SUM(JSS1!A:A,JSS2!A:A,JSS3!A:A)']
],
}]
// Render data grid component
return (
<p>
<Spreadsheet ref={spreadsheet1} worksheets={s1} onafterchanges={onafterchanges} />
<Spreadsheet ref={spreadsheet2} worksheets={s2} onafterchanges={onafterchanges} />
<Spreadsheet ref={spreadsheet3} worksheets={s3} onafterchanges={onafterchanges} />
</p>
);
}
<template>
<Spreadsheet ref="spreadsheet1" :worksheets="s1" :onafterchanges="onafterchanges" />
<Spreadsheet ref="spreadsheet2" :worksheets="s2" :onafterchanges="onafterchanges" />
<Spreadsheet ref="spreadsheet3" :worksheets="s3" :onafterchanges="onafterchanges" />
</template>
<script>
import { Spreadsheet, Worksheet, jspreadsheet } from "@jspreadsheet/vue";
import formula from "@jspreadsheet/formula";
import "jsuites/dist/jsuites.css";
import "jspreadsheet/dist/jspreadsheet.css";
// License
jspreadsheet.setLicense('OTVjNDU1NTIzNmM3NWZhYjRjNjQ2YjVhMzNmODJmODljZDhkY2QwYjEzZmU1OGZlZGFlYmRjODVlODc0Y2VlZjJlOGZmMzhjNGE5ZDNmMDczNjI3MDlhMzRlNzg2NjVjY2YxYmVjZjgzNjBkZWQ2Njc1Y2NiODdjNjg5MzBjZjYsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpVNU56azJORFl6TENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0p6ZEdGamEySnNhWFI2TG1sdklpd2lkMlZpWTI5dWRHRnBibVZ5TG1sdklpd2lkMlZpSWl3aWJHOWpZV3hvYjNOMElsMHNJbkJzWVc0aU9pSXpOQ0lzSW5OamIzQmxJanBiSW5ZM0lpd2lkamdpTENKMk9TSXNJbll4TUNJc0luWXhNU0lzSW1Ob1lYSjBjeUlzSW1admNtMXpJaXdpWm05eWJYVnNZU0lzSW5CaGNuTmxjaUlzSW5KbGJtUmxjaUlzSW1OdmJXMWxiblJ6SWl3aWFXMXdiM0owWlhJaUxDSmlZWElpTENKMllXeHBaR0YwYVc5dWN5SXNJbk5sWVhKamFDSXNJbkJ5YVc1MElpd2ljMmhsWlhSeklpd2lZMnhwWlc1MElpd2ljMlZ5ZG1WeUlpd2ljMmhoY0dWeklpd2labTl5YldGMElsMHNJbVJsYlc4aU9uUnlkV1Y5');
// Load the formula pro-extension
jspreadsheet.setExtensions({ formula });
export default {
components: {
Spreadsheet,
Worksheet,
},
methods: {
// Update footers from the last data grid
onafterchanges() {
if (this.$refs.spreadsheet3) {
this.$refs.spreadsheet3.current[0].setFooter();
}
}
},
data() {
const s1 = [{
worksheetName: 'JSS1',
data: [
[43, 64],
[51, 46],
],
footers: [
['=SUM(A:A)']
],
}]
const s2 = [{
worksheetName: 'JSS2',
data: [
[34, 53],
[51, 35],
],
footers: [
['=SUM(A:A)']
],
}]
const s3 = [{
worksheetName: 'JSS3',
data: [
[34, 53],
[51, 35],
],
footers: [
['=SUM(JSS1!A:A,JSS2!A:A,JSS3!A:A)']
],
}]
return {
s1,
s2,
s3,
};
}
}
</script>
import { Component, ViewChild, ElementRef, AfterViewInit } from "@angular/core";
import jspreadsheet from "jspreadsheet";
import formula from "@jspreadsheet/formula";
import "jspreadsheet/dist/jspreadsheet.css";
import "jsuites/dist/jsuites.css";
// Set your JSS license key (The following key only works for one day)
jspreadsheet.setLicense('OTVjNDU1NTIzNmM3NWZhYjRjNjQ2YjVhMzNmODJmODljZDhkY2QwYjEzZmU1OGZlZGFlYmRjODVlODc0Y2VlZjJlOGZmMzhjNGE5ZDNmMDczNjI3MDlhMzRlNzg2NjVjY2YxYmVjZjgzNjBkZWQ2Njc1Y2NiODdjNjg5MzBjZjYsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpVNU56azJORFl6TENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0p6ZEdGamEySnNhWFI2TG1sdklpd2lkMlZpWTI5dWRHRnBibVZ5TG1sdklpd2lkMlZpSWl3aWJHOWpZV3hvYjNOMElsMHNJbkJzWVc0aU9pSXpOQ0lzSW5OamIzQmxJanBiSW5ZM0lpd2lkamdpTENKMk9TSXNJbll4TUNJc0luWXhNU0lzSW1Ob1lYSjBjeUlzSW1admNtMXpJaXdpWm05eWJYVnNZU0lzSW5CaGNuTmxjaUlzSW5KbGJtUmxjaUlzSW1OdmJXMWxiblJ6SWl3aWFXMXdiM0owWlhJaUxDSmlZWElpTENKMllXeHBaR0YwYVc5dWN5SXNJbk5sWVhKamFDSXNJbkJ5YVc1MElpd2ljMmhsWlhSeklpd2lZMnhwWlc1MElpd2ljMlZ5ZG1WeUlpd2ljMmhoY0dWeklpd2labTl5YldGMElsMHNJbVJsYlc4aU9uUnlkV1Y5');
// Load the formula pro extension
jspreadsheet.setExtensions({ formula });
// Create component
@Component({
standalone: true,
selector: "app-root",
template: `
<div #spreadsheet1></div>
<div #spreadsheet2></div>
<div #spreadsheet3></div>
`
})
export class AppComponent implements AfterViewInit {
@ViewChild("spreadsheet1") spreadsheet1: ElementRef;
@ViewChild("spreadsheet2") spreadsheet2: ElementRef;
@ViewChild("spreadsheet3") spreadsheet3: ElementRef;
// Worksheets
s1: jspreadsheet.worksheetInstance[];
s2: jspreadsheet.worksheetInstance[];
s3: jspreadsheet.worksheetInstance[];
// Create a new data grid
ngAfterViewInit() {
// Create the spreadsheet
this.s1 = jspreadsheet(this.spreadsheet1.nativeElement, {
worksheets: [{
worksheetName: 'JSS1',
data: [
[43, 64],
[51, 46],
],
footers: [
['=SUM(A:A)']
],
}],
onafterchanges: () => {
this.s3[0].setFooter();
}
});
// Create the spreadsheet
this.s2 = jspreadsheet(this.spreadsheet2.nativeElement, {
worksheets: [{
worksheetName: 'JSS2',
data: [
[34, 53],
[51, 35],
],
footers: [
['=SUM(A:A)']
],
}],
onafterchanges: () => {
this.s3[0].setFooter();
}
});
// Create the spreadsheet
this.s3 = jspreadsheet(this.spreadsheet3.nativeElement, {
worksheets: [{
worksheetName: 'JSS3',
data: [
[34, 53],
[51, 35],
],
footers: [
['=SUM(JSS1!A:A,JSS2!A:A,JSS3!A:A)']
],
}],
onafterchanges: () => {
this.s3[0].setFooter();
}
});
}
}
What are the differences from Version 11
- Footer is now automatically updated when formulas are executed.
- refreshFooter method is dropped
- Method signature updated: setFooterValue now receives an array of values
- Event signature updated for onupdatefootervalue
- Event signature updated for onrenderfootercell