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

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 worksheets array 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

  1. Handle Large Files: Use tableOverflow: true for better performance with large spreadsheets
  2. Error Handling: Wrap tabularjs calls in try-catch blocks to handle corrupted files
  3. File Validation: Validate file types before processing
  4. Memory Management: Destroy existing spreadsheet instances before creating new ones
  5. User Feedback: Show loading indicators during file processing

Related Resources