Getting Started with Jspreadsheet CE v5
Overview
Jspreadsheet CE, formerly jExcel, is a free, lightweight JavaScript spreadsheet library to help developers bring Excel-like data grids and spreadsheet features to their applications. The library enables developers to build robust data management interfaces using React, Angular or pure JavaScript.
Why Choose Jspreadsheet CE?
- Create rich, interactive data grid interfaces
- Handle complex data inputs with Excel-like functionality
- Direct Excel compatibility: Copy and paste using standard shortcuts
- Proven success across thousands of implementations
- Lightweight, fast, and intuitive
- Easy integration with third-party plugins
- Built for collaboration and sharing
Installation
Choose one of the following installation options:
NPM
Install jspreadsheet using NPM:
npm install jspreadsheet-ce@5
CDN
Include jspreadsheet directly from JSDelivr CDN:
<script src="https://cdn.jsdelivr.net/npm/jspreadsheet-ce@5/dist/index.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/jspreadsheet-ce@5/dist/jspreadsheet.min.css" type="text/css" />
<script src="https://cdn.jsdelivr.net/npm/jsuites@5/dist/jsuites.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/jsuites@5/dist/jsuites.min.css" type="text/css" />
Download
Download and run jspreadsheet on your server or local machine:
https://bossanova.uk/jspreadsheet/v5/jspreadsheet.zip
License
This software is distributed under the MIT license.
Documentation
Global methods and properties
| Method Description |
|---|
Create a new spreadsheet.jspreadsheet(element: HTMLDivElement | HTMLTableElement, options: SpreadsheetOptions): WorksheetInstance[]; |
Destroy a given spreadsheet.jspreadsheet.destroy(element: JspreadsheetInstanceElement, destroyEventHandlers?: boolean): void; |
Destroy all spreadsheets in all namespaces.jspreadsheet.destroyAll(): void; |
Translate Jspreadsheet components and extensions.jspreadsheet.setDictionary(translations: Record<string, string>): void; |
Get a worksheet instance by name and namespace.jspreadsheet.getWorksheetInstanceByName(worksheetName: string | null | undefined, namespace: string): WorksheetInstance | Record<string, WorksheetInstance>; |
Examples
Create a new data grid
You can create a new data grid with spreadsheet-like controls from an HTML table element, a JS array, a CSV, a JSON file or an Excel XLSX file.
<html>
<script src="https://bossanova.uk/jspreadsheet/v5/jspreadsheet.js"></script>
<script src="https://jsuites.net/v5/jsuites.js"></script>
<link rel="stylesheet" href="https://bossanova.uk/jspreadsheet/v5/jspreadsheet.css" type="text/css" />
<link rel="stylesheet" href="https://jsuites.net/v5/jsuites.css" type="text/css" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Material+Icons" />
<div id='spreadsheet'></div>
<script>
// Create a new spreadsheet
jspreadsheet(document.getElementById('spreadsheet'), {
worksheets: [{
minDimensions: [6,6],
}]
});
</script>
</html>
import React, { useRef } from "react";
import { Spreadsheet, Worksheet } from "@jspreadsheet-ce/react";
import "jsuites/dist/jsuites.css";
import "jspreadsheet-ce/style.css";
export default function App() {
// Spreadsheet array of worksheets
const spreadsheet = useRef();
// Render component
return (
<>
<Spreadsheet ref={spreadsheet}>
<Worksheet minDimensions={[6,6]} />
</Spreadsheet>
</>
);
}
<template>
<Spreadsheet ref="spreadsheet">
<Worksheet :minDimensions="[6,6]" />
</Spreadsheet>
</template>
<script>
import { Spreadsheet, Worksheet } from "@jspreadsheet-ce/vue";
import "jsuites/dist/jsuites.css";
import "jspreadsheet-ce/dist/jspreadsheet.css";
export default {
components: {
Spreadsheet,
Worksheet,
}
};
</script>
import { Component, ViewChild, ElementRef } from "@angular/core";
import jspreadsheet from "jspreadsheet-ce";
import "jspreadsheet-ce/dist/jspreadsheet.css";
import "jsuites/dist/jsuites.css";
@Component({
standalone: true,
selector: "app-root",
template: `<div #spreadsheet></div>`
})
export class AppComponent {
@ViewChild("spreadsheet") spreadsheet: ElementRef;
// Worksheets
worksheets: jspreadsheet.worksheetInstance[];
// Create a new data grid
ngAfterViewInit() {
// Create spreadsheet
this.worksheets = jspreadsheet(this.spreadsheet.nativeElement, {
worksheets: [
minDimensions: [6,6]
}]
});
}
}
Destroying The Data Grid
The following example shows how to dynamically destroy and recreate a new data grid.
<html>
<script src="https://bossanova.uk/jspreadsheet/v5/jspreadsheet.js"></script>
<script src="https://jsuites.net/v5/jsuites.js"></script>
<link rel="stylesheet" href="https://bossanova.uk/jspreadsheet/v5/jspreadsheet.css" type="text/css" />
<link rel="stylesheet" href="https://jsuites.net/v5/jsuites.css" type="text/css" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Material+Icons" />
<div id='jspreadsheet'></div>
<p><input type='button' value='Destroy' id="btn1" /> <input type='button' value='Create' id="btn2" /></p>
<script>
// Create a new spreadsheet
let create = function() {
if (document.getElementById('jspreadsheet').spreadsheet) {
destroy();
}
jspreadsheet(document.getElementById('jspreadsheet'), {
worksheets: [ { minDimensions:[5,5] } ]
});
}
// Destroy the spreadsheet
let destroy = function() {
jspreadsheet.destroy(document.getElementById('jspreadsheet'));
}
// Create the spreadsheet
jspreadsheet(document.getElementById('jspreadsheet'), {
worksheets: [{
minDimensions: [5,5],
}]
});
document.getElementById("btn1").onclick = () => destroy()
document.getElementById("btn2").onclick = () => create()
</script>
</html>
import React, { useRef, useEffect } from "react";
import { jspreadsheet } from "@jspreadsheet-ce/react";
import "jsuites/dist/jsuites.css";
import "jspreadsheet-ce/dist/jspreadsheet.css";
export default function App() {
// Spreadsheet array of worksheets
const spreadsheet = useRef();
const instance = useRef();
const destroy = function() {
jspreadsheet.destroy(spreadsheet.current);
}
const create = function() {
if (instance.current) {
destroy();
}
jspreadsheet(spreadsheet.current, {
worksheets: [ { minDimensions:[5,5] } ]
});
}
useEffect(() => {
if (!instance.current && spreadsheet.current) {
instance.current = jspreadsheet(spreadsheet.current, {
worksheets: [ { minDimensions:[5,5] } ]
})
}
}, [])
// Render component
return (
<>
<div ref={spreadsheet}></div>
<button onClick={destroy}>Destroy</button>
<button onClick={create}>Create</button>
</>
);
}
<template>
<div>
<div ref="spreadsheet"></div>
<button @click="destroy">Destroy</button>
<button @click="create">Create</button>
</div>
</template>
<script>
import { ref, onMounted } from "vue";
import { jspreadsheet } from "@jspreadsheet-ce/vue";
import "jsuites/dist/jsuites.css";
import "jspreadsheet-ce/dist/jspreadsheet.css";
export default {
name: "App",
setup() {
const spreadsheet = ref(null);
let instance = null;
const destroy = () => {
if (instance) {
jspreadsheet.destroy(spreadsheet.value);
instance = null;
}
};
const create = () => {
if (instance) {
destroy();
}
instance = jspreadsheet(spreadsheet.value, {
worksheets: [{ minDimensions: [5, 5] }],
});
};
onMounted(() => {
if (!instance && spreadsheet.value) {
instance = jspreadsheet(spreadsheet.value, {
worksheets: [{ minDimensions: [5, 5] }],
});
}
});
return {
spreadsheet,
destroy,
create,
};
},
};
</script>
import { Component, ViewChild, ElementRef } from "@angular/core";
import jspreadsheet from "jspreadsheet-ce";
import "jspreadsheet-ce/dist/jspreadsheet.css";
import "jsuites/dist/jsuites.css";
@Component({
standalone: true,
selector: "app-spreadsheet",
template: `
<div #spreadsheet id="jspreadsheet"></div>
<p>
<button (click)="destroy()">Destroy</button>
<button (click)="create()">Create</button>
</p>
`,
})
export class SpreadsheetComponent {
@ViewChild("spreadsheet") spreadsheetRef: ElementRef;
worksheets: jspreadsheet.worksheetInstance[];
ngAfterViewInit() {
this.initialCreate();
}
initialCreate() {
this.worksheets = jspreadsheet(this.spreadsheetRef.nativeElement, {
worksheets: [{
minDimensions: [5, 5]
}]
});
}
create() {
if (this.spreadsheetRef.nativeElement.spreadsheet) {
this.destroy();
}
this.worksheets = jspreadsheet(this.spreadsheetRef.nativeElement, {
worksheets: [{
minDimensions: [5, 5]
}]
});
}
destroy() {
jspreadsheet.destroy(this.spreadsheetRef.nativeElement);
}
}
Importing Spreadsheet Files
Using TabularJS for File Import
TabularJS imports spreadsheet files into Jspreadsheet. It supports 16+ file formats including Excel, OpenDocument, CSV, and converts them to JSON format compatible with Jspreadsheet.
Features
- Supports .xlsx, .xls, .ods, .csv, .tsv, HTML tables, and legacy formats
- Extracts data, formulas, styles, and merged cells
- Pure JavaScript implementation with no external dependencies
- Compatible with Vanilla JS, React, Vue, and Angular
Installation
npm install tabularjs
Basic Usage
The library provides an async function that accepts a file and returns Jspreadsheet-compatible data:
<html>
<script src="https://bossanova.uk/jspreadsheet/v5/jspreadsheet.js"></script>
<link rel="stylesheet" href="https://bossanova.uk/jspreadsheet/v5/jspreadsheet.css" type="text/css" />
<script src="https://jsuites.net/v5/jsuites.js"></script>
<link rel="stylesheet" href="https://jsuites.net/v5/jsuites.css" type="text/css" />
<script src="https://cdn.jsdelivr.net/npm/tabularjs/dist/tabularjs.min.js"></script>
<div id="spreadsheet"></div>
<input type="file" id="fileInput" accept=".xlsx,.xls,.ods,.csv" />
<script>
let root = document.getElementById('spreadsheet');
document.getElementById('fileInput').addEventListener('change', async (e) => {
const file = e.target.files[0];
if (file) {
const result = await tabularjs(file);
// Destroy
jspreadsheet.destroy(root);
// Create
jspreadsheet(root, result);
}
});
</script>
</html>
import React, { useRef } from "react";
import jspreadsheet from "jspreadsheet-ce";
import tabularjs from "tabularjs";
import "jsuites/dist/jsuites.css";
import "jspreadsheet-ce/dist/jspreadsheet.css";
export default function App() {
const spreadsheet = useRef(null);
const inputRef = useRef(null);
const handleFileLoad = async (e) => {
const file = e.target.files[0];
if (file) {
const result = await tabularjs(file);
jspreadsheet(spreadsheet.current, result);
}
};
return (
<div>
<div ref={spreadsheet}></div>
<input
ref={inputRef}
type="file"
onChange={handleFileLoad}
accept=".xlsx,.xls,.ods,.csv"
style={{ display: 'none' }}
/>
<button onClick={() => inputRef.current.click()}>
Import Spreadsheet
</button>
</div>
);
}
<template>
<div>
<div ref="spreadsheet"></div>
<input
ref="fileInput"
type="file"
@change="handleFileLoad"
accept=".xlsx,.xls,.ods,.csv"
style="display: none"
/>
<button @click="$refs.fileInput.click()">Import Spreadsheet</button>
</div>
</template>
<script>
import jspreadsheet from "jspreadsheet-ce";
import tabularjs from "tabularjs";
import "jsuites/dist/jsuites.css";
import "jspreadsheet-ce/dist/jspreadsheet.css";
export default {
methods: {
async handleFileLoad(e) {
const file = e.target.files[0];
if (file) {
const result = await tabularjs(file);
jspreadsheet(this.$refs.spreadsheet, result);
}
}
}
}
</script>
import { Component, ViewChild, ElementRef } from "@angular/core";
import jspreadsheet from "jspreadsheet-ce";
import tabularjs from "tabularjs";
import "jsuites/dist/jsuites.css";
import "jspreadsheet-ce/dist/jspreadsheet.css";
@Component({
selector: "app-root",
template: `
<div>
<div #spreadsheet></div>
<input
#fileInput
type="file"
(change)="handleFileLoad($event)"
accept=".xlsx,.xls,.ods,.csv"
style="display: none"
/>
<button (click)="fileInput.click()">Import Spreadsheet</button>
</div>
`
})
export class AppComponent {
@ViewChild("spreadsheet") spreadsheet: ElementRef;
async handleFileLoad(event: Event) {
const input = event.target as HTMLInputElement;
const file = input.files?.[0];
if (file) {
const result = await tabularjs(file);
jspreadsheet(this.spreadsheet.nativeElement, result);
}
}
}