Vue.js Spreadsheet Integration
Build powerful, Excel-like data grids in your Vue.js applications. This guide covers both the official Vue wrapper and direct integration approaches, giving you the flexibility to choose the best method for your project requirements.
Quick Setup
Don't forget to import the required CSS files:
import "jsuites/dist/jsuites.css";
import "jspreadsheet/dist/jspreadsheet.css";
Documentation
Using the Official Vue Wrapper
The @jspreadsheet/vue
wrapper simplifies setup and provides Vue-specific features for building interactive spreadsheets.
Important Note:
The wrapper usesstyles
instead ofstyle
to avoid conflicts with Vue's built-in style attribute. This ensures proper CSS handling within Vue components.
Installation
Install the Vue wrapper using npm:
npm install @jspreadsheet/vue
Quick Start Example
Create a web-based spreadsheet using the Vue wrapper.
<template>
<Spreadsheet ref="spreadsheet">
<Worksheet :data="data" :columns="columns" />
</Spreadsheet>
<input type="button" value="getData" @click="getData()" />
</template>
<script>
import { Spreadsheet, Worksheet, jspreadsheet } from "@jspreadsheet/vue";
import "jsuites/dist/jsuites.css";
import "jspreadsheet/dist/jspreadsheet.css";
// Set the license for both plugin and the spreadsheet
jspreadsheet.setLicense('YTRmYTJiNDQ0NDk5Mzc5MDUwNjc0ZDQ3NDAyYjZkY2NiYTFkZmFmZGI2NTk1ZDhiNTIwY2E0Njk0MTlmOTg5MzBiYWFmOGNlMWYwZDNjOGRjOGMzOTJhNGMwZWEyOGZjZDllODA0MWQxZTg0ZjE3N2UyY2ZlOTY5ZDkxOWYxNmEsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpVNU56azJOell5TENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0p6ZEdGamEySnNhWFI2TG1sdklpd2lkMlZpWTI5dWRHRnBibVZ5TG1sdklpd2lkMlZpSWl3aWJHOWpZV3hvYjNOMElsMHNJbkJzWVc0aU9pSXpOQ0lzSW5OamIzQmxJanBiSW5ZM0lpd2lkamdpTENKMk9TSXNJbll4TUNJc0luWXhNU0lzSW1Ob1lYSjBjeUlzSW1admNtMXpJaXdpWm05eWJYVnNZU0lzSW5CaGNuTmxjaUlzSW5KbGJtUmxjaUlzSW1OdmJXMWxiblJ6SWl3aWFXMXdiM0owWlhJaUxDSmlZWElpTENKMllXeHBaR0YwYVc5dWN5SXNJbk5sWVhKamFDSXNJbkJ5YVc1MElpd2ljMmhsWlhSeklpd2lZMnhwWlc1MElpd2ljMlZ5ZG1WeUlpd2ljMmhoY0dWeklpd2labTl5YldGMElsMHNJbVJsYlc4aU9uUnlkV1Y5');
export default {
components: {
Spreadsheet,
Worksheet,
},
methods: {
getData() {
console.log(this.$refs.spreadsheet.current[0].getData());
}
},
data() {
// Worksheet data
const data = [
["US", "Cheese", "2019-02-12"],
["CA", "Apples", "2019-03-01"],
["CA", "Carrots", "2018-11-10"],
["BR", "Oranges", "2019-01-12"],
]
// Columns
const columns = [
{ width: "300px" },
{ width: "200px" },
{ width: "200px" }
]
return {
data,
columns
}
}
}
</script>
Using the library
The following example demonstrates how to use JSpreadsheet without a dedicated wrapper. By leveraging the library directly, developers gain greater flexibility and control, enabling highly customized implementations tailored to their specific needs.
Integration with Vue 3
<template>
<div ref="spreadsheetRef"></div>
</template>
<script setup>
import jspreadsheet from 'jspreadsheet';
import "jsuites/dist/jsuites.css";
import "jspreadsheet/dist/jspreadsheet.css";
import { onMounted, ref } from 'vue'
// Set the license for both plugin and the spreadsheet
jspreadsheet.setLicense('YTRmYTJiNDQ0NDk5Mzc5MDUwNjc0ZDQ3NDAyYjZkY2NiYTFkZmFmZGI2NTk1ZDhiNTIwY2E0Njk0MTlmOTg5MzBiYWFmOGNlMWYwZDNjOGRjOGMzOTJhNGMwZWEyOGZjZDllODA0MWQxZTg0ZjE3N2UyY2ZlOTY5ZDkxOWYxNmEsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpVNU56azJOell5TENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0p6ZEdGamEySnNhWFI2TG1sdklpd2lkMlZpWTI5dWRHRnBibVZ5TG1sdklpd2lkMlZpSWl3aWJHOWpZV3hvYjNOMElsMHNJbkJzWVc0aU9pSXpOQ0lzSW5OamIzQmxJanBiSW5ZM0lpd2lkamdpTENKMk9TSXNJbll4TUNJc0luWXhNU0lzSW1Ob1lYSjBjeUlzSW1admNtMXpJaXdpWm05eWJYVnNZU0lzSW5CaGNuTmxjaUlzSW5KbGJtUmxjaUlzSW1OdmJXMWxiblJ6SWl3aWFXMXdiM0owWlhJaUxDSmlZWElpTENKMllXeHBaR0YwYVc5dWN5SXNJbk5sWVhKamFDSXNJbkJ5YVc1MElpd2ljMmhsWlhSeklpd2lZMnhwWlc1MElpd2ljMlZ5ZG1WeUlpd2ljMmhoY0dWeklpd2labTl5YldGMElsMHNJbVJsYlc4aU9uUnlkV1Y5');
const options = {
worksheets: [
{
search: true,
data: [
[42, 42, 42, 42],
[42, 42, 42, 42],
],
columns: [
{ title: "First Column", width: 100 },
{ title: "Second Column", width: 150 },
{ title: "Third Column", width: 200 },
{ title: "Fourth Column", width: 250 },
],
},
],
};
const spreadsheetRef = ref(null)
onMounted(() => {
jspreadsheet(spreadsheetRef.value, options)
})
</script>
Creating a Custom Editor with a Vue 3 Component
The following example demonstrates how to integrate a Vue 3 component as a custom editor in JSpreadsheet, enabling advanced interactivity and tailored functionality within spreadsheet cells.
See this example on stackblitz
<template>
<Spreadsheet ref="spreadsheet">
<Worksheet :data="data" :columns="columns" /> </Spreadsheet
><br />
<input type="button" value="getData" @click="getData()" />
<input type="button" value="setValue('A1', false)" @click="setValue()" />
</template>
<script>
import { h, createApp, ref } from 'vue';
import { Spreadsheet, Worksheet, jspreadsheet } from '@jspreadsheet/vue';
import InputSwitch from 'primevue/inputswitch';
// Set the license for both plugin and the spreadsheet
jspreadsheet.setLicense('YTRmYTJiNDQ0NDk5Mzc5MDUwNjc0ZDQ3NDAyYjZkY2NiYTFkZmFmZGI2NTk1ZDhiNTIwY2E0Njk0MTlmOTg5MzBiYWFmOGNlMWYwZDNjOGRjOGMzOTJhNGMwZWEyOGZjZDllODA0MWQxZTg0ZjE3N2UyY2ZlOTY5ZDkxOWYxNmEsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpVNU56azJOell5TENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0p6ZEdGamEySnNhWFI2TG1sdklpd2lkMlZpWTI5dWRHRnBibVZ5TG1sdklpd2lkMlZpSWl3aWJHOWpZV3hvYjNOMElsMHNJbkJzWVc0aU9pSXpOQ0lzSW5OamIzQmxJanBiSW5ZM0lpd2lkamdpTENKMk9TSXNJbll4TUNJc0luWXhNU0lzSW1Ob1lYSjBjeUlzSW1admNtMXpJaXdpWm05eWJYVnNZU0lzSW5CaGNuTmxjaUlzSW5KbGJtUmxjaUlzSW1OdmJXMWxiblJ6SWl3aWFXMXdiM0owWlhJaUxDSmlZWElpTENKMllXeHBaR0YwYVc5dWN5SXNJbk5sWVhKamFDSXNJbkJ5YVc1MElpd2ljMmhsWlhSeklpd2lZMnhwWlc1MElpd2ljMlZ5ZG1WeUlpd2ljMmhoY0dWeklpd2labTl5YldGMElsMHNJbVJsYlc4aU9uUnlkV1Y5');
const Editor = {
createCell(cell, value, x, y, instance) {
// Create reactive state for the cell
const isChecked = ref(value === 'true' || value === true);
// Create Vue app for the cell
createApp({
setup() {
return () =>
h(InputSwitch, {
modelValue: isChecked.value,
'onUpdate:modelValue': (newValue) => {
isChecked.value = newValue; // Update reactive state
instance.setValueFromCoords(x, y, newValue, true); // Force update
},
});
},
}).mount(cell);
cell.vueState = isChecked;
},
updateCell(cell, value, x, y, instance) {
if (cell.vueState) {
const newValue = !!(value === 'true' || value === true || value === 1);
if (cell.vueState.value !== newValue) {
cell.vueState.value = newValue;
}
}
},
openEditor(cell) {
cell.vueState.value = !cell.vueState.value;
return false; // No separate editor
},
closeEditor() {
return false; // Not used
},
destroyCell(cell) {
// Cleanup Vue app
if (cell.vueApp) {
cell.vueApp.unmount();
cell.vueState = null;
}
},
};
export default {
components: {
Spreadsheet,
Worksheet,
},
methods: {
getData() {
console.log(this.$refs.spreadsheet.current[0].getData());
},
setValue() {
console.log(this.$refs.spreadsheet.current[0].setValue('A1', false));
},
},
data() {
// Worksheet data
const data = [
[true, 'Cheese', ''],
[true, 'Apples', ''],
[true, 'Carrots', ''],
[false, 'Oranges', ''],
];
// Columns
const columns = [{ type: Editor }];
return {
data,
columns
};
},
};
</script>
Integration with Vue2
<html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
<script src="https://jspreadsheet.com/v11/jspreadsheet.js"></script>
<script src="https://jsuites.net/v6/jsuites.js"></script>
<link rel="stylesheet" href="https://jspreadsheet.com/v11/jspreadsheet.css" type="text/css" />
<link rel="stylesheet" href="https://jsuites.net/v6/jsuites.css" type="text/css" />
<div id="spreadsheet"></div>
<br>
<input type="button" value="Add new row" onclick="vm.insertRow()" />
<script>
// Set the license for both plugin and the spreadsheet
jspreadsheet.setLicense('YTRmYTJiNDQ0NDk5Mzc5MDUwNjc0ZDQ3NDAyYjZkY2NiYTFkZmFmZGI2NTk1ZDhiNTIwY2E0Njk0MTlmOTg5MzBiYWFmOGNlMWYwZDNjOGRjOGMzOTJhNGMwZWEyOGZjZDllODA0MWQxZTg0ZjE3N2UyY2ZlOTY5ZDkxOWYxNmEsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpVNU56azJOell5TENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0p6ZEdGamEySnNhWFI2TG1sdklpd2lkMlZpWTI5dWRHRnBibVZ5TG1sdklpd2lkMlZpSWl3aWJHOWpZV3hvYjNOMElsMHNJbkJzWVc0aU9pSXpOQ0lzSW5OamIzQmxJanBiSW5ZM0lpd2lkamdpTENKMk9TSXNJbll4TUNJc0luWXhNU0lzSW1Ob1lYSjBjeUlzSW1admNtMXpJaXdpWm05eWJYVnNZU0lzSW5CaGNuTmxjaUlzSW5KbGJtUmxjaUlzSW1OdmJXMWxiblJ6SWl3aWFXMXdiM0owWlhJaUxDSmlZWElpTENKMllXeHBaR0YwYVc5dWN5SXNJbk5sWVhKamFDSXNJbkJ5YVc1MElpd2ljMmhsWlhSeklpd2lZMnhwWlc1MElpd2ljMlZ5ZG1WeUlpd2ljMmhoY0dWeklpd2labTl5YldGMElsMHNJbVJsYlc4aU9uUnlkV1Y5');
let options = {
worksheets: [{
data:[[]],
minDimensions:[8,10],
}],
}
let vm = new Vue({
el: '#spreadsheet',
mounted: function() {
let spreadsheet = jspreadsheet(this.$el, options);
Object.assign(this, spreadsheet);
}
});
</script>