Create and Save Excel Files through Streams with JavaScript in React

Operating Excel files as streams in web applications allows developers to dynamically create, load, modify, and save Excel files, enabling flexible and efficient data processing. Spire.XLS for JavaScript runs entirely in the browser via WebAssembly, using a virtual file system (VFS) to manage input and output files — no backend server is required. It provides a simple, easy-to-use Stream API that makes creating and saving Excel files through streams more convenient.

Working with streams greatly reduces direct disk I/O operations, improving application performance and responsiveness, especially in scenarios that involve real-time data processing or limited storage. With Spire.XLS for JavaScript, you can dynamically create an Excel file and save it to a stream, load and read workbook data from a stream, or modify content in a stream and save it as a new Excel file — all directly in the browser, simplifying data exchange and system integration.

This article covers three core features:

For installation and project setup, refer to Integrating Spire.XLS for JavaScript in a React Project. The examples below assume Spire.XLS is installed and the WebAssembly module is initialized.


Dynamically Create an Excel File and Save It to a Stream

With Spire.XLS for JavaScript, you can dynamically create an Excel file in the browser, fill it with data and formatting, and then save the workbook to a file stream via the SaveToStream() method. This approach eliminates the need to store files directly on disk while improving application performance and responsiveness. The steps are as follows:

  • Create a Workbook instance to generate a new Excel workbook, clear the default worksheets, and add a new worksheet.
  • Access a specific worksheet using the Worksheets.get() method.
  • Define the data to write to the worksheet, for example, organizing data with a two-dimensional array.
  • Use the Range.get_Item() method to access cells and set their values one by one.
  • Format the worksheet cells, such as setting colors, fonts, borders, or adjusting column widths.
  • Create a Stream object and save the workbook to the file stream using the SaveToStream() method. The saved stream can be used for further processing, such as downloading as a file or transferring over the network.

Below is a complete code example demonstrating how to dynamically create an Excel file and save it to a stream in React:

function App() {
  const createAndSaveToStream = async () => {
    // Get the Spire.XLS WASM module
    const xlsModule = window.wasmModule?.spirexls;

    // Check if the module is ready
    if (!xlsModule) {
      alert('Spire.Xls is not ready yet');
      return;
    }

    // Load the font file to ensure proper text rendering
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}font/`);

    // Create a new workbook instance
    const workbook = new xlsModule.Workbook();

    // Clear the default worksheets and add a new worksheet
    workbook.Worksheets.Clear();
    const sheet = workbook.Worksheets.Add('Data');

    // Define the sample data to write to the worksheet (two-dimensional array)
    const headers = ['ID', 'Name', 'Age', 'Country', 'Salary (¥)'];
    const data = [
      [1, 'Zhang Wei', 29, 'China', 8000],
      [2, 'Li Na', 35, 'China', 12000],
      [3, 'Wang Qiang', 42, 'China', 15000],
      [4, 'Jack', 26, 'USA', 9500],
      [5, 'Chen Si', 31, 'China', 11000],
      [6, 'Ishihara Yasuko', 28, 'Japan', 8800]
    ];

    // Write the headers to the first row
    for (let col = 0; col < headers.length; col++) {
      sheet.Range.get_Item({ row: 1, column: col + 1 }).Text = headers[col];
    }

    // Write the data to the following rows
    for (let row = 0; row < data.length; row++) {
      for (let col = 0; col < data[row].length; col++) {
        sheet.Range.get_Item({ row: row + 2, column: col + 1 }).Text = String(data[row][col]);
      }
    }

    // Format the header row
    sheet.Range.get('A1:E1').Style.Color = xlsModule.Color.get_LightSkyBlue();
    sheet.Range.get('A1:E1').Style.Font.FontName = 'Arial';
    sheet.Range.get('A1:E1').Style.Font.Size = 12;
    sheet.Range.get('A1:E1').Style.Font.IsBold = true;

    // Format the data rows
    for (let i = 2; i <= data.length + 1; i++) {
      const dataRange = sheet.Range.get({
        row: i, column: 1,
        lastRow: i, lastColumn: headers.length
      });
      dataRange.Style.Color = xlsModule.Color.get_LightGray();
      dataRange.Style.Font.FontName = 'Arial';
      dataRange.Style.Font.Size = 11;
    }

    // Add borders to the header and all data cells
    const usedRange = sheet.Range.get({
      row: 1, column: 1,
      lastRow: data.length + 1,
      lastColumn: headers.length
    });
    usedRange.Borders.LineStyle = xlsModule.LineStyleType.Thin;
    usedRange.Borders.Color = xlsModule.Color.get_LightSteelBlue();

    // Adjust column widths to fit the content
    for (let col = 1; col <= headers.length; col++) {
      sheet.AutoFitColumn(col);
    }

    // Create a stream and save the workbook to it
    const outputFileName = 'CreateExcelToStream.xlsx';
    const fileStream = new xlsModule.Stream(outputFileName);
    workbook.SaveToStream(fileStream, xlsModule.FileFormat.Version2010);

    // Dispose of the workbook object to release resources
    workbook.Dispose();

    // Read the file from VFS and trigger download
    const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
    const blob = new Blob([fileArray], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = outputFileName;
    a.click();
    URL.revokeObjectURL(url);
  };

  return (
    <div style={{ textAlign: 'center', height: '300px' }}>
      <h1>Create Excel and Save to Stream</h1>
      <button onClick={createAndSaveToStream}>
        Generate
      </button>
    </div>
  );
}

export default App;

Excel file dynamically created and saved to a stream with Spire.XLS for JavaScript

Excel file dynamically created and saved to a stream with Spire.XLS for JavaScript


Load and Read an Excel File from a Stream

With Spire.XLS for JavaScript, you can load an Excel file directly from a stream using the LoadFromStream() method. Once loaded, the cell data of the Excel file in the stream can be easily read, enabling fast and flexible data processing without file I/O operations. The steps are as follows:

  • Create a Stream object pointing to the Excel file to be loaded.
  • Create a Workbook object and load the file from the stream using the LoadFromStream() method.
  • Get the first worksheet using the Worksheets.get() method.
  • Iterate through the rows and columns of the worksheet and extract cell data using the Range.get() method.
  • Display the extracted data on the page, or use it for other operations.

Below is a complete code example demonstrating how to load and read an Excel file from a stream in React:

import React, { useState } from 'react';

function App() {
  const [extractedData, setExtractedData] = useState('');

  const loadAndReadFromStream = async () => {
    // Get the Spire.XLS WASM module
    const xlsModule = window.wasmModule?.spirexls;

    // Check if the module is ready
    if (!xlsModule) {
      alert('Spire.Xls is not ready yet');
      return;
    }

    // Load the font file to ensure proper text rendering
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}font/`);

    // Load the sample Excel file into VFS
    await window.spire.FetchFileToVFS('Sample.xlsx', '', `${process.env.PUBLIC_URL}data/`);

    // Create a workbook object and load the Excel file from a stream
    const workbook = new xlsModule.Workbook();
    const fileStream = new xlsModule.Stream('Sample.xlsx');
    workbook.LoadFromStream(fileStream, xlsModule.FileFormat.Auto);

    // Get the first worksheet of the workbook
    const sheet = workbook.Worksheets.get(0);

    // Iterate through the rows and columns to extract cell data
    const data = [];
    for (let row = sheet.FirstRow; row <= sheet.LastRow; row++) {
      const line = [];
      for (let col = sheet.FirstColumn; col <= sheet.LastColumn; col++) {
        line.push(sheet.Range.get({ row: row, column: col }).Text);
      }
      data.push(line.join(' | '));
    }

    // Dispose of the workbook object to release resources
    workbook.Dispose();

    // Display the extracted data on the page
    setExtractedData(data.join('\n'));
  };

  return (
    <div style={{ textAlign: 'center', height: '300px' }}>
      <h1>Load and Read Excel Data from Stream</h1>
      <button onClick={loadAndReadFromStream}>
        Read
      </button>
      <pre style={{ marginTop: '20px', textAlign: 'left' }}>{extractedData}</pre>
    </div>
  );
}

export default App;

Excel file loaded and read from a stream with Spire.XLS for JavaScript

Excel file loaded and read from a stream with Spire.XLS for JavaScript


Modify and Save an Excel File in a Stream

With Spire.XLS for JavaScript, you can modify an Excel file in memory. First load the Excel file in the stream into a Workbook object via the LoadFromStream() method; after completing modifications such as changing cell styles or content, save the file back to a stream using the SaveToStream() method. This enables real-time changes to Excel file data without relying on direct file storage operations. The steps are as follows:

  • Create a Stream object pointing to the Excel file and load the file from the stream via the LoadFromStream() method.
  • Access the worksheet using the Worksheets.get() method.
  • Modify the styles of the header row and data rows (font name, size, background color, etc.) through the CellRange.Style property.
  • Use the AutoFitColumn() method to automatically adjust column widths to fit the content.
  • Set the border style of the cells.
  • Create a new Stream object, save the modified workbook to the stream using the SaveToStream() method, read the result file from VFS, and trigger the download.

Below is a complete code example demonstrating how to modify and save an Excel file in a stream in React:

function App() {
  const modifyAndSaveInStream = async () => {
    // Get the Spire.XLS WASM module
    const xlsModule = window.wasmModule?.spirexls;

    // Check if the module is ready
    if (!xlsModule) {
      alert('Spire.Xls is not ready yet');
      return;
    }

    // Load the font file to ensure proper text rendering
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}font/`);

    // Load the sample Excel file into VFS
    await window.spire.FetchFileToVFS('Sample.xlsx', '', `${process.env.PUBLIC_URL}data/`);

    // Create a workbook object and load the Excel file from a stream
    const workbook = new xlsModule.Workbook();
    const fileStream = new xlsModule.Stream('Sample.xlsx');
    workbook.LoadFromStream(fileStream, xlsModule.FileFormat.Auto);

    // Get the first worksheet of the workbook
    const sheet = workbook.Worksheets.get(0);

    // Modify the style of the header row
    const headerRow = sheet.Range.get({
      row: sheet.FirstRow, column: sheet.FirstColumn,
      lastRow: sheet.FirstRow, lastColumn: sheet.LastColumn
    });
    headerRow.Style.Font.FontName = 'Arial';
    headerRow.Style.Font.Size = 12;
    headerRow.Style.Font.IsBold = true;
    headerRow.Style.Color = xlsModule.Color.get_LightSkyBlue();

    // Modify the styles of the data rows, with alternating colors (even rows)
    for (let i = sheet.FirstRow + 1; i <= sheet.LastRow; i++) {
      const dataRow = sheet.Range.get({
        row: i, column: sheet.FirstColumn,
        lastRow: i, lastColumn: sheet.LastColumn
      });
      dataRow.Style.Font.FontName = 'Arial';
      dataRow.Style.Font.Size = 10;
      dataRow.Style.Color = xlsModule.Color.get_LightGray();
      if (i % 2 === 0) {
        dataRow.Style.Color = xlsModule.Color.get_DarkGray();
      }
    }

    // Adjust column widths to fit the content
    for (let col = sheet.FirstColumn; col <= sheet.LastColumn; col++) {
      sheet.AutoFitColumn(col);
    }

    // Set the border color
    sheet.AllocatedRange.Borders.Color = xlsModule.Color.get_White();

    // Save the modified workbook to a new stream
    const outputFileName = 'ModifyExcelInStream.xlsx';
    const outStream = new xlsModule.Stream(outputFileName);
    workbook.SaveToStream(outStream, xlsModule.FileFormat.Version2010);

    // Dispose of the workbook object to release resources
    workbook.Dispose();

    // Read the file from VFS and trigger download
    const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
    const blob = new Blob([fileArray], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = outputFileName;
    a.click();
    URL.revokeObjectURL(url);
  };

  return (
    <div style={{ textAlign: 'center', height: '300px' }}>
      <h1>Modify and Save Excel in Stream</h1>
      <button onClick={modifyAndSaveInStream}>
        Generate
      </button>
    </div>
  );
}

export default App;

Excel file modified and saved in a stream with Spire.XLS for JavaScript

Excel file modified and saved in a stream with Spire.XLS for JavaScript


FAQ

How to handle the stream-saved file being unable to open in Excel?

Cause: When saving a workbook via the SaveToStream() method, if the correct output file format is not specified through the FileFormat parameter, the generated file format may not match its extension, causing it to fail to open properly.

Solution: Specify a concrete file format enum value when saving to a stream, such as xlsModule.FileFormat.Version2010:

const fileStream = new xlsModule.Stream(outputFileName);
workbook.SaveToStream(fileStream, xlsModule.FileFormat.Version2010);

How to ensure the workbook loaded from a stream correctly recognizes the file format?

Cause: The LoadFromStream() method needs to identify the file type based on the actual format of the stream data. If the format parameter is set incorrectly, loading may fail or data parsing may produce errors.

Solution: Use xlsModule.FileFormat.Auto when loading so that the library automatically detects the format of the file in the stream:

const fileStream = new xlsModule.Stream('Sample.xlsx');
workbook.LoadFromStream(fileStream, xlsModule.FileFormat.Auto);

Get a Free License

Spire.XLS for JavaScript offers a 30-day full-featured free trial license with no functional limitations. Apply here to evaluate before purchasing.