Products

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