Importing Spreadsheet Files
Using TabularJS for File Import
TabularJS is a powerful JavaScript library that 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 16+ file formats including .xlsx, .xls, .ods, .csv, .tsv, .wks, .sylk, .dif, .dbf, HTML tables, and XML spreadsheets
- Extracts data, formulas, styles, and merged cells
- Pure JavaScript library compatible with Node.js and browser environments
- Works with Vanilla JS, React, Vue, and Angular
- Handles large spreadsheets efficiently
- Preserves formatting and cell properties
- TypeScript support included
- MIT licensed
Resources
- NPM Package: https://www.npmjs.com/package/tabularjs
- GitHub Repository: https://github.com/jspreadsheet/tabularjs
Installation
Install TabularJS via NPM:
npm install tabularjs
Or include via CDN:
<script src="https://cdn.jsdelivr.net/npm/tabularjs/dist/index.min.js"></script>
Documentation
Method
The TabularJS library exports a single async function that processes files and returns Jspreadsheet-compatible configuration:
tabularjs(file: File): Promise<object>
Parameters:
file: A File object from an input element or drag-and-drop
Returns:
- A Promise that resolves to a Jspreadsheet configuration object with
worksheetsarray containing data, formulas, styles, and merged cells
Examples
Drag and Drop Import
This example demonstrates importing files via drag and drop.
<html>
<script src="https://jspreadsheet.com/v12/jspreadsheet.js"></script>
<script src="https://jsuites.net/v6/jsuites.js"></script>
<link rel="stylesheet" href="https://jspreadsheet.com/v12/jspreadsheet.css" type="text/css" />
<link rel="stylesheet" href="https://jsuites.net/v6/jsuites.css" type="text/css" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Material+Icons" />
<script src="https://cdn.jsdelivr.net/npm/tabularjs/dist/index.min.js"></script>
<style>
#dropzone {
border: 2px dashed #ccc;
padding: 40px;
text-align: center;
margin-bottom: 20px;
}
#dropzone.dragover {
border-color: #000;
background-color: #f0f0f0;
}
</style>
<div id="dropzone">Drag and drop a spreadsheet file here</div>
<div id='spreadsheet'></div>
<script>
// Set your JSS license key (The following key only works for one day)
jspreadsheet.setLicense('ZTE3OTMxMTU3N2Y2MWQ1N2Y4MjgyMWEzYzkyZWI3ZWJlMzk1OGZiNjY0NzQyZGE0MDg3YzgxMjg5YzgxMjNjYzY4ODk3Nzk0MTgyNjNmMGQ5MTY2NDk4NWE1NjBlYzU2NTE4Y2JjYTIxMDQ4NDE0YjgyZjM0NjIyMTQ1MmUzZTMsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpZMU5ETTFOamsyTENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0p6ZEdGamEySnNhWFI2TG1sdklpd2lkMlZpWTI5dWRHRnBibVZ5TG1sdklpd2liRzlqWVd4b2IzTjBJbDBzSW5Cc1lXNGlPaUl6TkNJc0luTmpiM0JsSWpwYkluWTNJaXdpZGpnaUxDSjJPU0lzSW5ZeE1DSXNJbll4TVNJc0luWXhNaUlzSW1Ob1lYSjBjeUlzSW1admNtMXpJaXdpWm05eWJYVnNZU0lzSW5CaGNuTmxjaUlzSW5KbGJtUmxjaUlzSW1OdmJXMWxiblJ6SWl3aWFXMXdiM0owWlhJaUxDSmlZWElpTENKMllXeHBaR0YwYVc5dWN5SXNJbk5sWVhKamFDSXNJbkJ5YVc1MElpd2ljMmhsWlhSeklpd2lZMnhwWlc1MElpd2ljMlZ5ZG1WeUlpd2ljMmhoY0dWeklpd2labTl5YldGMElsMHNJbVJsYlc4aU9uUnlkV1Y5');
const root = document.getElementById('spreadsheet');
const dropzone = document.getElementById('dropzone');
// Handle file import
async function importFile(file) {
const result = await tabularjs(file);
result.tableOverflow = true;
jspreadsheet(root, result);
}
// Drag and drop events
dropzone.addEventListener('dragover', (e) => {
e.preventDefault();
dropzone.classList.add('dragover');
});
dropzone.addEventListener('dragleave', () => {
dropzone.classList.remove('dragover');
});
dropzone.addEventListener('drop', async (e) => {
e.preventDefault();
dropzone.classList.remove('dragover');
const file = e.dataTransfer.files[0];
if (file) {
await importFile(file);
}
});
</script>
</html>
import React, { useRef, useState } from "react";
import { jspreadsheet } from "@jspreadsheet/react";
import tabularjs from "tabularjs";
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('ZTE3OTMxMTU3N2Y2MWQ1N2Y4MjgyMWEzYzkyZWI3ZWJlMzk1OGZiNjY0NzQyZGE0MDg3YzgxMjg5YzgxMjNjYzY4ODk3Nzk0MTgyNjNmMGQ5MTY2NDk4NWE1NjBlYzU2NTE4Y2JjYTIxMDQ4NDE0YjgyZjM0NjIyMTQ1MmUzZTMsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpZMU5ETTFOamsyTENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0p6ZEdGamEySnNhWFI2TG1sdklpd2lkMlZpWTI5dWRHRnBibVZ5TG1sdklpd2liRzlqWVd4b2IzTjBJbDBzSW5Cc1lXNGlPaUl6TkNJc0luTmpiM0JsSWpwYkluWTNJaXdpZGpnaUxDSjJPU0lzSW5ZeE1DSXNJbll4TVNJc0luWXhNaUlzSW1Ob1lYSjBjeUlzSW1admNtMXpJaXdpWm05eWJYVnNZU0lzSW5CaGNuTmxjaUlzSW5KbGJtUmxjaUlzSW1OdmJXMWxiblJ6SWl3aWFXMXdiM0owWlhJaUxDSmlZWElpTENKMllXeHBaR0YwYVc5dWN5SXNJbk5sWVhKamFDSXNJbkJ5YVc1MElpd2ljMmhsWlhSeklpd2lZMnhwWlc1MElpd2ljMlZ5ZG1WeUlpd2ljMmhoY0dWeklpd2labTl5YldGMElsMHNJbVJsYlc4aU9uUnlkV1Y5');
export default function App() {
const spreadsheet = useRef();
const [dragOver, setDragOver] = useState(false);
const importFile = async (file) => {
const result = await tabularjs(file);
result.tableOverflow = true;
if (spreadsheet.current) {
jspreadsheet.destroy(spreadsheet.current);
jspreadsheet(spreadsheet.current, result);
}
};
const handleDrop = async (e) => {
e.preventDefault();
setDragOver(false);
const file = e.dataTransfer.files[0];
if (file) {
await importFile(file);
}
};
const handleDragOver = (e) => {
e.preventDefault();
setDragOver(true);
};
const handleDragLeave = () => {
setDragOver(false);
};
return (
<>
<div
onDrop={handleDrop}
onDragOver={handleDragOver}
onDragLeave={handleDragLeave}
style={{
border: '2px dashed #ccc',
padding: '40px',
textAlign: 'center',
marginBottom: '20px',
backgroundColor: dragOver ? '#f0f0f0' : 'transparent',
borderColor: dragOver ? '#000' : '#ccc'
}}
>
Drag and drop a spreadsheet file here
</div>
<div ref={spreadsheet}></div>
</>
);
}
<template>
<div>
<div
@drop.prevent="handleDrop"
@dragover.prevent="dragOver = true"
@dragleave="dragOver = false"
:style="{
border: '2px dashed ' + (dragOver ? '#000' : '#ccc'),
padding: '40px',
textAlign: 'center',
marginBottom: '20px',
backgroundColor: dragOver ? '#f0f0f0' : 'transparent'
}"
>
Drag and drop a spreadsheet file here
</div>
<div ref="spreadsheet"></div>
</div>
</template>
<script>
import { jspreadsheet } from "@jspreadsheet/vue";
import tabularjs from "tabularjs";
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('ZTE3OTMxMTU3N2Y2MWQ1N2Y4MjgyMWEzYzkyZWI3ZWJlMzk1OGZiNjY0NzQyZGE0MDg3YzgxMjg5YzgxMjNjYzY4ODk3Nzk0MTgyNjNmMGQ5MTY2NDk4NWE1NjBlYzU2NTE4Y2JjYTIxMDQ4NDE0YjgyZjM0NjIyMTQ1MmUzZTMsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpZMU5ETTFOamsyTENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0p6ZEdGamEySnNhWFI2TG1sdklpd2lkMlZpWTI5dWRHRnBibVZ5TG1sdklpd2liRzlqWVd4b2IzTjBJbDBzSW5Cc1lXNGlPaUl6TkNJc0luTmpiM0JsSWpwYkluWTNJaXdpZGpnaUxDSjJPU0lzSW5ZeE1DSXNJbll4TVNJc0luWXhNaUlzSW1Ob1lYSjBjeUlzSW1admNtMXpJaXdpWm05eWJYVnNZU0lzSW5CaGNuTmxjaUlzSW5KbGJtUmxjaUlzSW1OdmJXMWxiblJ6SWl3aWFXMXdiM0owWlhJaUxDSmlZWElpTENKMllXeHBaR0YwYVc5dWN5SXNJbk5sWVhKamFDSXNJbkJ5YVc1MElpd2ljMmhsWlhSeklpd2lZMnhwWlc1MElpd2ljMlZ5ZG1WeUlpd2ljMmhoY0dWeklpd2labTl5YldGMElsMHNJbVJsYlc4aU9uUnlkV1Y5');
export default {
data() {
return {
dragOver: false
};
},
methods: {
async handleDrop(e) {
this.dragOver = false;
const file = e.dataTransfer.files[0];
if (file) {
const result = await tabularjs(file);
result.tableOverflow = true;
if (this.$refs.spreadsheet) {
jspreadsheet.destroy(this.$refs.spreadsheet);
jspreadsheet(this.$refs.spreadsheet, result);
}
}
}
}
}
</script>
import { Component, ViewChild, ElementRef } from "@angular/core";
import jspreadsheet from "jspreadsheet";
import tabularjs from "tabularjs";
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('ZTE3OTMxMTU3N2Y2MWQ1N2Y4MjgyMWEzYzkyZWI3ZWJlMzk1OGZiNjY0NzQyZGE0MDg3YzgxMjg5YzgxMjNjYzY4ODk3Nzk0MTgyNjNmMGQ5MTY2NDk4NWE1NjBlYzU2NTE4Y2JjYTIxMDQ4NDE0YjgyZjM0NjIyMTQ1MmUzZTMsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpZMU5ETTFOamsyTENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0p6ZEdGamEySnNhWFI2TG1sdklpd2lkMlZpWTI5dWRHRnBibVZ5TG1sdklpd2liRzlqWVd4b2IzTjBJbDBzSW5Cc1lXNGlPaUl6TkNJc0luTmpiM0JsSWpwYkluWTNJaXdpZGpnaUxDSjJPU0lzSW5ZeE1DSXNJbll4TVNJc0luWXhNaUlzSW1Ob1lYSjBjeUlzSW1admNtMXpJaXdpWm05eWJYVnNZU0lzSW5CaGNuTmxjaUlzSW5KbGJtUmxjaUlzSW1OdmJXMWxiblJ6SWl3aWFXMXdiM0owWlhJaUxDSmlZWElpTENKMllXeHBaR0YwYVc5dWN5SXNJbk5sWVhKamFDSXNJbkJ5YVc1MElpd2ljMmhsWlhSeklpd2lZMnhwWlc1MElpd2ljMlZ5ZG1WeUlpd2ljMmhoY0dWeklpd2labTl5YldGMElsMHNJbVJsYlc4aU9uUnlkV1Y5');
@Component({
selector: 'app-root',
standalone: true,
template: `
<div
(drop)="handleDrop($event)"
(dragover)="handleDragOver($event)"
(dragleave)="handleDragLeave()"
[style.border]="'2px dashed ' + (dragOver ? '#000' : '#ccc')"
[style.padding]="'40px'"
[style.text-align]="'center'"
[style.margin-bottom]="'20px'"
[style.background-color]="dragOver ? '#f0f0f0' : 'transparent'"
>
Drag and drop a spreadsheet file here
</div>
<div #spreadsheet></div>
`,
})
export class AppComponent {
@ViewChild('spreadsheet') spreadsheet!: ElementRef;
worksheets: jspreadsheet.worksheetInstance[] = [];
dragOver = false;
handleDragOver(event: DragEvent) {
event.preventDefault();
this.dragOver = true;
}
handleDragLeave() {
this.dragOver = false;
}
async handleDrop(event: DragEvent) {
event.preventDefault();
this.dragOver = false;
const file = event.dataTransfer?.files[0];
if (file) {
const result = await tabularjs(file);
result.tableOverflow = true;
if (this.spreadsheet) {
jspreadsheet.destroy(this.spreadsheet.nativeElement);
this.worksheets = jspreadsheet(this.spreadsheet.nativeElement, result);
}
}
}
}
Supported File Formats
TabularJS supports 16+ spreadsheet file formats, making it compatible with virtually any spreadsheet file you might encounter:
Modern Formats
- Excel: .xlsx, .xls
- OpenDocument Spreadsheet: .ods
- Delimiter-Separated Values: .csv, .tsv
Legacy and Specialized Formats
- Lotus: .wks (Lotus 1-2-3 worksheets)
- SYLK: .sylk, .slk (Symbolic Link files)
- DIF: .dif (Data Interchange Format)
- DBF: .dbf (dBase database files)
- HTML: HTML tables from .html files
- XML: XML spreadsheets
Format Features
- Preserves data types and cell values
- Extracts formulas and calculations
- Maintains cell styling and formatting
- Handles merged cells
- Supports multiple worksheets per file
Best Practices
- Handle Large Files: Use
tableOverflow: truefor better performance with large spreadsheets - Error Handling: Wrap tabularjs calls in try-catch blocks to handle corrupted files
- File Validation: Validate file types before processing
- Memory Management: Destroy existing spreadsheet instances before creating new ones
- User Feedback: Show loading indicators during file processing