How to Download / Export Excel Files in JavaScript & React

Excel File Export in JavaScript and React

Modern web applications often need to generate downloadable Excel reports directly in the browser without relying on backend services. Whether you're building dashboards, reporting tools, or data-heavy business applications, browser-based spreadsheet export has become a common frontend requirement.

The challenge lies in creating Excel files that work across different browsers while maintaining formatting, supporting multiple output formats, and ensuring fast downloads—all without sending sensitive data to a server. Traditional approaches often require complex server-side processing or rely on limited client-side libraries.

Spire.XLS for JavaScript enables developers to generate, export, and download Excel files using JS entirely in the browser using WebAssembly technology. This approach provides true client-side Excel generation with support for multiple formats including XLS, XLSX, XLSB, ODS, PDF, XML, and XPS.

This article demonstrates how to generate and download Excel files in modern JavaScript and React applications using browser-side processing with Spire.XLS for JavaScript. We'll cover basic file generation, stream-based exports, React integration, and HTML table conversion with practical code examples.

Quick Navigation


Why Export Excel in Browser

Browser-side Excel export provides significant advantages over traditional server-side approaches:

  • Enhanced Privacy – Sensitive data never leaves the client device, reducing security risks and compliance concerns
  • Faster Downloads – Eliminating server round-trips reduces latency and improves user experience
  • No Server-Side Processing – Reduces backend infrastructure costs and eliminates server bottlenecks
  • Works Offline – Client-side generation functions even without network connectivity
  • Scalable Architecture – Each user's browser handles their own export, distributing computational load
  • Framework Agnostic – Works seamlessly with React, Vue, Angular, and vanilla JavaScript applications

By implementing Excel export functionality in the browser, developers can create responsive, secure, and cost-effective solutions that scale naturally with user demand.


Install Spire.XLS for JavaScript

Before generating and downloading Excel files in JavaScript, you need to install Spire.XLS for JavaScript and configure it in your development environment.

Installation via npm

Spire.XLS for JavaScript can be installed via npm:

npm i spire.xls

After installation, include the library in your project:

import { Workbook } from '@e-iceblue/spire.xls';

Note: The current WebAssembly runtime is provided through the spire.office package structure internally, even when installing spire.xls from npm. This is why initialization imports reference /node_modules/spire.office/.

Manual Installation

Alternatively, you can download the package from the e-iceblue website and copy the dependencies to your project directory.

For detailed setup instructions, refer to the Getting Started with Spire.XLS for JavaScript.

Initialize the WASM Module

Before using Spire.XLS, you must initialize the WebAssembly module. The initialization process loads required resources and sets up the runtime:

// Import and initialize the common module first
import('/node_modules/spire.office/spire.common.js').then(async (commonModule) => {
    // Initialize the WASM runtime
    await commonModule.initializeWasm();
    
    // Load the XLS module
    await import('/node_modules/spire.office/spire.xls.js');
    
    console.log('Spire.XLS ready');
});

Important Notes:

  • Initialization is required before accessing window.spirexls or window.xlswasm
  • The browser downloads required WebAssembly resources during first load
  • Always verify the module exists before performing Excel operations

Version Note: This article uses spire.office v11.4.1+. The module is accessed via window.spirexls or window.xlswasm. Older examples using window.wasmModule.spirexls may require updates.

Spire.XLS for JavaScript integrates seamlessly with all major frontend frameworks and build tools:

  • React – Use with hooks (useState, useEffect) for state-driven Excel export components
  • Vue.js – Integrate with Vue's reactive data system and lifecycle methods
  • Angular – Compatible with Angular services and dependency injection patterns
  • Next.js – Works in client-side components for server-rendered React applications

The WebAssembly module loads once at application initialization and can be shared across components, making it efficient for multi-page applications regardless of the framework choice.


Download Excel File in JavaScript

The following example demonstrates how to generate an Excel file with Spire.XLS for JavaScript and download it directly in the browser.

Create and Download an XLSX File

// Ensure the WASM module has been initialized
if (!window.spirexls && !window.xlswasm) {
    console.error("Spire.XLS is not initialized.");
    return;
}

// Get the initialized WebAssembly module
const wasmModule = window.spirexls || window.xlswasm;

// Create a new workbook
const workbook = new wasmModule.Workbook();
const worksheet = workbook.Worksheets.get(0);

// Create sample data
const products = [
    ["Product", "Quantity", "Price"],
    ["Laptop", 10, 999.99]
    ["Mouse", 50, 24.99]
]

// Insert data into the worksheet
for (let i = 0; i < products.length; i++) {
    for (let j = 0; j < products[i].length; j++) {
        if (typeof products[i][j] === "string") {
            worksheet.Range.get({ row: i + 1, column: j + 1 }).Text = products[i][j];
        }
        else {
            worksheet.Range.get({ row: i + 1, column: j + 1 }).NumberValue = products[i][j];
        }
    }
}

// Add a total column
worksheet.Range.get({ row: 1, column: products[0].length + 1 }).Text = "Total";
worksheet.Range.get({ row: 2, column: products[0].length + 1 }).Formula = "=B2*C2";
worksheet.Range.get({ row: 3, column: products[0].length + 1 }).Formula = "=B3*C3";

// Save the workbook to the virtual file system (VFS)
const outputFileName = "Report.xlsx";

workbook.SaveToFile({
    fileName: outputFileName,
    version: wasmModule.ExcelVersion.Version2016
});

// Release workbook resources
workbook.Dispose();

// Read the generated file from VFS
const fileArray =
    window.dotnetRuntime.Module.FS.readFile(outputFileName);

// Create a Blob object
const excelBlob = new Blob(
    [fileArray],
    {
        type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
    }
);

// Trigger browser download
const url = URL.createObjectURL(excelBlob);
const a = document.createElement("a");
a.href = url;
a.download = outputFileName;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);

Below is a preview of the generated XLSX file:

Generate and Download an Excel File in JavaScript

How the Export Process Works

  1. Create a workbook and populate worksheet data
  2. Save the workbook into the WebAssembly virtual file system (VFS)
  3. Read the generated XLSX file from VFS
  4. Convert the file data into a Blob object
  5. Trigger the browser download using a temporary URL

About the Virtual File System (VFS)

The file generated by SaveToFile() is stored in the WebAssembly virtual file system rather than the user's physical disk. This in-memory file system allows Spire.XLS to perform standard file operations securely inside the browser environment. The downloaded XLSX file is created after reading the generated file data from VFS and converting it into a browser Blob object.

Advantages of This Approach

  • Works entirely in the browser
  • No server-side processing required
  • Uses standard browser Blob download APIs
  • Supports direct XLSX file generation with Spire.XLS

If you also need to work with lightweight data exchange formats, you can further explore how to convert Excel files to CSV and import CSV data into Excel using JavaScript.


Export HTML Tables to Excel in JavaScript

In dashboard and reporting applications, business data is often displayed as HTML tables. Instead of rebuilding spreadsheet structures manually, you can directly convert existing frontend tables into Excel workbooks using Spire.XLS for JavaScript.

The following example demonstrates a complete browser-side workflow that:

  • Reads an existing HTML table from the page
  • Converts the HTML table into an Excel workbook
  • Applies Excel-native formatting
  • Downloads the generated XLSX file directly in the browser

HTML Table Export Example

async function exportTableToExcel() {

    if (!window.spirexls && !window.xlswasm) {
        alert("Spire.XLS module not loaded yet.");
        return;
    }

    const button = document.getElementById("exportBtn");

    button.disabled = true;
    button.innerText = "Exporting...";

    const wasmModule = window.spirexls || window.xlswasm;

    try {

        // Get HTML table
        const tableHtml =
            document.getElementById("salesTable").outerHTML;

        // Remove inline styles
        const safeTableHtml =
            tableHtml.replace(/style="[^"]*"/g, '');

        const htmlContent = `
            <!DOCTYPE html>
            <html>
            <head>
                <meta charset="UTF-8">
            </head>
            <body>
                ${safeTableHtml}
            </body>
            </html>
        `;

        const htmlFileName = "Table.html";

        window.dotnetRuntime.Module.FS.writeFile(
            htmlFileName,
            htmlContent
        );

        const workbook = new wasmModule.Workbook();

        workbook.LoadFromHtml(htmlFileName);

        const sheet = workbook.Worksheets.get(0);

        const lastRow = Number(sheet.LastRow);
        const lastCol = Number(sheet.LastColumn);

        const headerRow =
            sheet.Range.get_Item(1, 1, 1, lastCol);

        headerRow.BuiltInStyle =
            wasmModule.BuiltInStyles.Heading3;

        for (let i = 2; i <= lastRow; i++) {

            const row =
                sheet.Range.get_Item(i, 1, i, lastCol);

            row.BuiltInStyle =
                i % 2 === 0
                    ? wasmModule.BuiltInStyles.Accent3_20
                    : wasmModule.BuiltInStyles.Accent3_60;
        }

        for (let j = 1; j <= lastCol; j++) {
            sheet.AutoFitColumn(j);
        }

        const outputFileName = "SalesReport.xlsx";

        workbook.SaveToFile({
            fileName: outputFileName,
            version: wasmModule.ExcelVersion.Version2016
        });

        workbook.Dispose();

        const fileData =
            window.dotnetRuntime.Module.FS.readFile(outputFileName);

        const blob = new Blob([fileData], {
            type:
                "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
        });

        const url = URL.createObjectURL(blob);

        const a = document.createElement("a");

        a.href = url;
        a.download = outputFileName;

        document.body.appendChild(a);
        a.click();

        document.body.removeChild(a);

        URL.revokeObjectURL(url);

    } catch (error) {

        alert("Export failed: " + error.message);

    } finally {

        button.disabled = false;
        button.innerText = "Export Excel";
    }
}

The following screenshot shows the HTML-based sales report table example displayed in the browser before export.

HTML-based Sales Report Table

After exporting, the generated Excel workbook preserves the tabular structure and applies additional Excel-native formatting.

Export HTML Table to Excel in JavaScript

Why Use HTML-based Excel Export

Using HTML-based export provides several advantages for modern web applications:

  • Reuse existing frontend tables without rebuilding spreadsheet layouts
  • Reduce duplicate data formatting and export logic
  • Apply Excel-native styles after importing HTML tables
  • Export business reports directly from dashboard pages

With Spire.XLS for JavaScript, you can quickly convert browser-rendered HTML tables into downloadable Excel files while keeping the entire export workflow on the client side.

For scenarios that require rendering Excel spreadsheets as browser-based HTML tables, you can also refer to our article about converting Excel to HTML in JavaScript.


Export Excel in React with JavaScript

Integrating Excel export into React applications is straightforward. The key is initializing the WebAssembly runtime before rendering React components and properly releasing workbook resources after export operations.

Initialize Spire.XLS in React

Before creating export components, initialize the WebAssembly module in your app entry file (main.jsx or index.js):

import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import App from './App.jsx';

// Initialize Spire.XLS before mounting React
const initializeSpire = async () => {

    // Load the common runtime
    const commonModule = await import(
        '/node_modules/spire.office/spire.common.js'
    );

    // Initialize WebAssembly runtime
    await commonModule.initializeWasm();

    // Load Spire.XLS module
    await import(
        '/node_modules/spire.office/spire.xls.js'
    );

    // Optional: preload fonts if needed
    // await window.spire.FetchFileToVFS(
    //     'ARIAL.TTF',
    //     '/Library/Fonts/',
    //     '/'
    // );
};

// Start React app after initialization
initializeSpire().then(() => {

    createRoot(document.getElementById('root')).render(
        <StrictMode>
            <App />
        </StrictMode>
    );

});

Then use the React export component below in your application.

Simplified React Excel Export Component

Here's a minimal React component that demonstrates the core export pattern:

import { useState } from 'react'

const ExcelExportButton = () => {
    const [isProcessing, setIsProcessing] = useState(false);

    const handleExport = async () => {
        if ((!window.spirexls && !window.xlswasm) || isProcessing) return;

        setIsProcessing(true);
        const wasmModule = window.spirexls || window.xlswasm;

        try {
            // Create a new workbook and get the first default worksheet
            const workbook = new wasmModule.Workbook();
            const worksheet = workbook.Worksheets.get(0);

            // Insert data into the worksheet
            worksheet.Range.get("A1").Text = "Product";
            worksheet.Range.get("B1").Text = "Revenue";
            worksheet.Range.get("A2").Text = "Laptop";
            worksheet.Range.get("B2").NumberValue = 9999.90;
            worksheet.Range.get("A3").Text = "Smartphone";
            worksheet.Range.get("B3").NumberValue = 4999.99;

            const outputFileName = "Report.xlsx";

            // Save the workbook to a file in the VFS
            workbook.SaveToFile({
                fileName: outputFileName,
                version: wasmModule.ExcelVersion.Version2016
            });

            workbook.Dispose();

            const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);

            const excelBlob = new Blob([fileArray], {
                type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
            });

            const url = URL.createObjectURL(excelBlob);

            const a = document.createElement('a');
            a.href = url;
            a.download = outputFileName;
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);

            URL.revokeObjectURL(url);

        } catch (error) {
            console.error("Excel export failed:", error);
        } finally {
            setIsProcessing(false);
        }
    };

    return (
        <button onClick={handleExport} disabled={isProcessing}>
            {isProcessing ? "Generating..." : "Export to Excel"}
        </button>
    );
}

export default function App() {
    return (
        <div>
            <h1>Spire.XLS Demo</h1>
            <ExcelExportButton />
        </div>
    );
}

Key Implementation Details:

  • Minimal state – Only track isProcessing to disable the button during export
  • Direct download – Trigger download immediately without storing URLs in state
  • Resource cleanup – Always call Dispose() on workbook objects to prevent memory leaks
  • Error handling – Wrap export logic in try-catch blocks for robust error management
  • Loading states – Disable buttons during processing to prevent duplicate exports

Usage in Your App:

import { ExcelExportButton } from './ExcelExportButton';

function App() {
    return (
        <div>
            <h1>Sales Dashboard</h1>
            <ExcelExportButton />
        </div>
    );
}

This simplified approach focuses on the essential export flow without unnecessary complexity. For more advanced scenarios like loading external files or fonts, refer to the complete documentation.

If you also need browser-side document distribution workflows, you can further explore how to convert Excel files to PDF in JavaScript and React applications.


Client-Side Excel Generation in JavaScript Without Backend

Modern web applications increasingly generate Excel files directly in the browser instead of relying on backend services. With Spire.XLS for JavaScript, spreadsheet creation, formatting, and export operations run entirely on the client side using WebAssembly.

Why No Backend Server Is Needed

Traditional Excel export workflows usually require a server to:

  1. Receive frontend data
  2. Generate spreadsheet files
  3. Return downloadable files to the browser

With WebAssembly-based processing, these steps happen entirely inside the browser runtime instead.

Benefits of Browser-side Excel Export

Compared with traditional server-side export workflows, client-side Excel generation provides several advantages:

Feature Browser-side Export Server-side Export
Data Processing Runs locally in browser Requires backend server
Privacy Data stays on client device Data sent over network
Response Speed Instant local processing Depends on network latency
Infrastructure Cost No export server required Requires backend resources
Offline Support Supported Usually unavailable
Scalability Handled by client devices Limited by server capacity

How Browser-side Export Works

When using Spire.XLS for JavaScript:

  1. The WebAssembly runtime loads in the browser
  2. Spreadsheet processing runs locally in memory
  3. Files are temporarily stored in the browser virtual file system (VFS)
  4. JavaScript converts the generated file into a downloadable Blob
  5. The browser triggers the download directly

This architecture makes browser-based Excel export especially suitable for dashboards, reporting systems, internal business tools, and privacy-sensitive applications.


Troubleshooting and Best Practices

When using Spire.XLS for JavaScript in browser environments, the following issues are commonly encountered.

WASM Module Not Initialized

If window.spirexls or window.xlswasm is undefined, ensure the WebAssembly runtime is fully initialized before using the API:

await commonModule.initializeWasm();
await import('/node_modules/spire.office/spire.xls.js');

Missing Resource or ZIP Loading Errors

If the browser console shows 404 errors or WebAssembly loading failures:

  • Ensure ZIP and WASM resources are placed in the correct static directory
  • Vite projects should place assets in the public/ folder
  • Verify the browser can successfully load .zip and .wasm files

Font-related Warnings

Some environments may display warnings such as:

"Arial font is not installed"

You can preload fonts before creating workbooks:

await window.spire.FetchFileToVFS(
    'ARIAL.TTF',
    '/Library/Fonts/',
    '/'
);

Invalid or Corrupted XLSX Files

If Excel opens with repair warnings, explicitly specify the Excel version during export:

workbook.SaveToFile({
    fileName: outputFileName,
    version: wasmModule.ExcelVersion.Version2016
});

Memory Management

Always release workbook resources after export to avoid memory leaks in long-running applications:

const workbook = new wasmModule.Workbook();

try {
    // Excel operations
} finally {
    workbook.Dispose();
}

Browser-side Performance Considerations

For very large datasets, browser-side processing may become slow or memory-intensive. In such scenarios:

  • Show loading indicators during export
  • Avoid exporting extremely large datasets in a single operation
  • Consider server-side processing for enterprise-scale reports

Conclusion

Spire.XLS for JavaScript provides a practical way to generate and export Excel files directly in modern web applications using JavaScript and WebAssembly. Its browser-based architecture makes it suitable for dashboards, reporting systems, and frontend applications that require downloadable spreadsheet generation without relying on backend services.

The examples in this article demonstrate how to build browser-based Excel export workflows using JavaScript, React, and WebAssembly while keeping spreadsheet processing entirely on the client side. You can apply for a 30-day free license to evaluate all features before purchasing.


FAQ

Q1: Can I download Excel files in JavaScript without a backend server?

A1: Yes. Spire.XLS for JavaScript uses WebAssembly technology to generate and download Excel files entirely in the browser. The workbook is created in browser memory and downloaded directly without requiring any backend API or server-side processing.

Q2: How do I export HTML tables to Excel in JavaScript?

A2: You can extract an existing HTML table from the DOM, write the HTML into the WebAssembly virtual file system, and load it into a workbook using LoadFromHtml(). This approach allows you to reuse browser-rendered tables without rebuilding spreadsheet layouts manually.

Q3: Can I use Spire.XLS for JavaScript in React applications?

A3: Yes. Spire.XLS for JavaScript works with React, Vite, and other modern frontend frameworks. You only need to initialize the WebAssembly module before rendering components and then perform Excel operations directly inside React components or utility functions.

Q4: Why does Excel show a repair warning when opening exported files?

A4: This usually happens when the Excel version is not explicitly specified during export. To avoid compatibility issues, specify the output version when calling SaveToFile():

workbook.SaveToFile({
    fileName: outputFileName,
    version: wasmModule.ExcelVersion.Version2016
});