In daily Excel document processing, textboxes are often used to add explanatory text, annotations, or tips to data — whether adding comments to reports or extracting annotation content from existing documents, the add/remove/modify operations on textboxes are essential. Spire.XLS for JavaScript completes these operations directly in the browser based on WebAssembly, managing input and output files through a virtual file system (VFS), with no backend service required.

This article covers three core features:

For installation and project configuration, 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.


Add TextBox

Adding textboxes to a worksheet provides supplementary explanations for data, such as operation guidance or notes. Spire.XLS for JavaScript inserts a textbox at a specified position with the Worksheet.TextBoxes.AddTextBox() method, after which you can set the text, alignment, font, and background color of the textbox, or fill it with a picture. The main steps are as follows:

  1. Create a Workbook object and use the LoadFromFile() method to load the Excel document.
  2. Use the Workbook.Worksheets.get() method to get a specific worksheet.
  3. Use the Worksheet.TextBoxes.AddTextBox() method to add the first textbox, and set its text, horizontal/vertical center alignment, font, and background color.
  4. Use the Worksheet.TextBoxes.AddTextBox() method to add a second textbox and fill it with a picture.
  5. Use the Workbook.SaveToFile() method to save the document to a specified path.

Here is a complete code example showing how to add two textboxes to a worksheet in React — one containing text and one filled with a picture:

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

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

    // Load the font, Excel file and picture into the VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = 'TextBox.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);
    await window.spire.FetchFileToVFS('logo.png', '', `${process.env.PUBLIC_URL}data/`);

    // Load the workbook
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: inputFileName });

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

    // Add the first textbox and set its position and size
    const textBox = sheet.TextBoxes.AddTextBox(3, 2, 50, 196);

    // Set the text in the textbox
    textBox.Text = 'Insert Excel TextBox';

    // Set the text to be centered horizontally and vertically
    textBox.HAlignment = xlsModule.CommentHAlignType.Center;
    textBox.VAlignment = xlsModule.CommentVAlignType.Center;

    // Set the font of the textbox (bold, white, 12pt)
    const font = workbook.CreateFont();
    font.FontName = 'Arial';
    font.Size = 12;
    font.IsBold = true;
    font.Color = xlsModule.Color.get_White();
    const rt = xlsModule.RichTextShape.Convert(textBox.RichText);
    rt.SetFont(0, textBox.Text.length - 1, font);

    // Set the background color of the textbox to blue-gray
    textBox.Fill.FillType = xlsModule.ShapeFillType.SolidColor;
    textBox.Fill.ForeKnownColor = xlsModule.ExcelColors.BlueGray;

    // Add the second textbox and set its position and size
    const textBox2 = sheet.TextBoxes.AddTextBox(6, 5, 90, 90);

    // Load a picture and fill the textbox with it
    textBox2.Fill.CustomPicture('logo.png');
    textBox2.Fill.FillType = xlsModule.ShapeFillType.Picture;

    // Set the border of the second textbox to 0
    textBox2.Line.Weight = 0;

    // Save the document
    const outputFileName = 'AddTextBox_output.xlsx';
    workbook.SaveToFile({ fileName: outputFileName });

    // Release resources
    workbook.Dispose();

    // Read the converted file from the VFS and trigger the 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>Add TextBox</h1>
      <button onClick={addTextBox}>
        Start
      </button>
    </div>
  );
}

export default App;

The result of adding the textboxes Add TextBox


Extract Text and Image from TextBox

When you need to aggregate or reuse annotation information in existing documents, you can iterate through the textboxes and extract their text content and fill images. Spire.XLS for JavaScript gets the number of textboxes with Worksheet.TextBoxes.Count and iterates over each textbox with the Worksheet.TextBoxes.get() method: it reads the Text property to obtain the text content, checks the fill type through Fill.FillType, and extracts the fill image through the Fill.Picture property, finally saving the results as a txt file and a png image file respectively. The main steps are as follows:

  1. Create a Workbook object and use the LoadFromFile() method to load the Excel document.
  2. Use the Workbook.Worksheets.get() method to get a specific worksheet.
  3. Iterate over each textbox in the TextBoxes collection with Worksheet.TextBoxes.Count and Worksheet.TextBoxes.get().
  4. Read the Text property of each textbox to collect the text content.
  5. For a textbox filled with a picture, get its fill image through the Fill.Picture property and save it as a png file.
  6. Write the collected text into a txt file.

Here is a complete code example showing how to extract text and images from a textbox in React:

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

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

    // Load the font and Excel file into the VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = 'TextBox.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);

    // Load the workbook
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: inputFileName });

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

    // Iterate over all textboxes in the worksheet and extract text and pictures
    const textLines = [];
    const pictureFiles = [];
    for (let i = sheet.TextBoxes.Count - 1; i >= 0; i--) {
      const shape = sheet.TextBoxes.get(i);

      // Extract the text in the textbox
      if (shape.Text) {
        textLines.push(shape.Text);
      }

      // Extract the fill picture of the textbox
      if (shape.Fill.FillType === xlsModule.ShapeFillType.Picture) {
        const picture = shape.Fill.Picture;
        const imageFile = 'ExtractedImage' + i + '.png';
        picture.Save(imageFile);
        pictureFiles.push(imageFile);
      }
    }

    // Save the extracted text as a txt file
    const textFile = 'ExtractedText.txt';
    window.dotnetRuntime.Module.FS.writeFile(textFile, textLines.join('\r\n'));

    // Release resources
    workbook.Dispose();

    // Read the extracted txt file from the VFS and trigger the download
    const txtArray = window.dotnetRuntime.Module.FS.readFile(textFile);
    const txtBlob = new Blob([txtArray], { type: 'text/plain' });
    const txtUrl = URL.createObjectURL(txtBlob);
    const txtAnchor = document.createElement('a');
    txtAnchor.href = txtUrl;
    txtAnchor.download = textFile;
    txtAnchor.click();
    URL.revokeObjectURL(txtUrl);

    // Read the extracted picture files from the VFS and trigger the downloads
    for (const imageFile of pictureFiles) {
      const imageArray = window.dotnetRuntime.Module.FS.readFile(imageFile);
      const imageBlob = new Blob([imageArray], { type: 'application/png' });
      const imageUrl = URL.createObjectURL(imageBlob);
      const imageAnchor = document.createElement('a');
      imageAnchor.href = imageUrl;
      imageAnchor.download = imageFile;
      imageAnchor.click();
      URL.revokeObjectURL(imageUrl);
    }
  };

  return (
    <div style={{ textAlign: 'center', height: '300px' }}>
      <h1>Extract Text And Image From TextBox</h1>
      <button onClick={extractTextAndImage}>
        Start
      </button>
    </div>
  );
}

export default App;

The result of extracting the text and image from the textbox Extract Text and Image from TextBox


Remove TextBox

When annotation information in a document is no longer needed, you can delete it to keep the worksheet tidy. Spire.XLS for JavaScript deletes a specified textbox by index with the Worksheet.TextBoxes.RemoveAt() method. The main steps are as follows:

  1. Create a Workbook object and use the LoadFromFile() method to load the Excel document.
  2. Use the Workbook.Worksheets.get() method to get a specific worksheet.
  3. Use the Worksheet.TextBoxes.RemoveAt() method to delete the textbox at a specified index.
  4. Use the Workbook.SaveToFile() method to save the document to a specified path.

Here is a complete code example showing how to remove a textbox from a worksheet in React:

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

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

    // Load the font and Excel file into the VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = 'TextBox.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);

    // Load the workbook
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: inputFileName });

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

    // Remove the first textbox
    sheet.TextBoxes.RemoveAt(0);

    // Save the document
    const outputFileName = 'RemoveTextBox_output.xlsx';
    workbook.SaveToFile({ fileName: outputFileName });

    // Release resources
    workbook.Dispose();

    // Read the converted file from the VFS and trigger the 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>Remove TextBox</h1>
      <button onClick={removeTextBox}>
        Start
      </button>
    </div>
  );
}

export default App;

The result of removing the textbox Remove TextBox


Frequently Asked Questions

The added textbox does not display in the result document

Cause: The row and column coordinates specified in the AddTextBox() method are out of range, or the font file was not loaded into the VFS, so the text in the textbox cannot be rendered properly.

Solution: Make sure the row and column coordinates are within the worksheet range, and ensure the required font has been loaded via FetchFileToVFS() before use, for example:

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

An error occurs when extracting an image due to the fill type

Cause: Accessing the Fill.Picture property directly only works for textboxes filled with a picture. If no image fill is set on the textbox (for example, a solid-color fill), accessing this property throws an exception.

Solution: Check whether the Fill.FillType of the textbox is Picture before accessing Fill.Picture; only then get the picture and call the Save() method to save it.


Obtain 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.

In Excel document processing, formulas and functions are among the most essential capabilities — whether summing, averaging, or performing date and trigonometric operations, formulas make data processing automated and efficient. Spire.XLS for JavaScript completes the insertion and reading of formulas and functions directly in the browser based on WebAssembly, and manages input and output files through a virtual file system (VFS), with no backend service required.

This article covers two core features:

For installation and project configuration, 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.


Insert Formulas and Functions into an Excel Worksheet

The Formula property of the cell Range object returned by the Worksheet.Range.get() method in Spire.XLS for JavaScript can be used to add formulas or functions to specified cells in an Excel worksheet. The main steps for adding formulas and functions to an Excel worksheet are as follows:

  1. Create a Workbook object.
  2. Use the Workbook.Worksheets.get() method to get a specific worksheet.
  3. Write data into cells and set the cell formatting.
  4. Use the Range.Formula property to add formulas and functions to the specified cells of the worksheet.
  5. Use the Workbook.SaveToFile() method to save the workbook.

Here is a complete code example showing how to insert mathematical operations, date functions, trigonometric functions, average functions, and sum functions into an Excel worksheet in React:

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

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

    // Load the font into the VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);

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

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

    // Declare two variables: currentRow and currentFormula
    let currentRow = 1;
    let currentFormula = "";

    // Set the column width
    sheet.SetColumnWidth(1, 32);
    sheet.SetColumnWidth(2, 16);

    // Write data into cells
    sheet.Range.get({ row: currentRow, column: 1 }).Value = "Test Data";
    sheet.Range.get({ row: currentRow, column: 2 }).NumberValue = 1;
    sheet.Range.get({ row: currentRow, column: 3 }).NumberValue = 2;
    sheet.Range.get({ row: currentRow, column: 4 }).NumberValue = 3;
    sheet.Range.get({ row: currentRow, column: 5 }).NumberValue = 4;
    sheet.Range.get({ row: currentRow, column: 6 }).NumberValue = 5;
    currentRow += 2;
    sheet.Range.get({ row: currentRow, column: 1 }).Value = "Formula or Function";
    sheet.Range.get({ row: currentRow, column: 2 }).Value = "Result";

    // Set the cell formatting
    let range = sheet.Range.get({ row: currentRow, column: 1, lastRow: currentRow, lastColumn: 2 });
    range.Style.Font.FontName = "Arial";
    range.Style.KnownColor = xlsModule.ExcelColors.LightGreen;
    range.Style.FillPattern = xlsModule.ExcelPatternType.Solid;
    range.Style.Borders.get(xlsModule.BordersLineType.EdgeBottom).LineStyle = xlsModule.LineStyleType.Medium;
    range.Style.Font.IsBold = true;

    // Mathematical operation
    currentFormula = "=1/2+3*4";
    currentRow += 1;
    sheet.Range.get({ row: currentRow, column: 1 }).NumberFormat = "@";
    sheet.Range.get({ row: currentRow, column: 1 }).Text = currentFormula;
    sheet.Range.get({ row: currentRow, column: 2 }).Formula = currentFormula;

    // Date function
    currentFormula = "=TODAY()";
    currentRow += 1;
    sheet.Range.get({ row: currentRow, column: 1 }).NumberFormat = "@";
    sheet.Range.get({ row: currentRow, column: 1 }).Text = currentFormula;
    sheet.Range.get({ row: currentRow, column: 2 }).Formula = currentFormula;
    sheet.Range.get({ row: currentRow, column: 2 }).Style.NumberFormat = "YYYY/MM/DD";

    // Trigonometric function
    currentFormula = "=SIN(PI()/6)";
    currentRow += 1;
    sheet.Range.get({ row: currentRow, column: 1 }).NumberFormat = "@";
    sheet.Range.get({ row: currentRow, column: 1 }).Text = currentFormula;
    sheet.Range.get({ row: currentRow, column: 2 }).Formula = currentFormula;

    // Average function
    currentFormula = "=AVERAGE(B1:F1)";
    currentRow += 1;
    sheet.Range.get({ row: currentRow, column: 1 }).NumberFormat = "@";
    sheet.Range.get({ row: currentRow, column: 1 }).Text = currentFormula;
    sheet.Range.get({ row: currentRow, column: 2 }).Formula = currentFormula;

    // Sum function
    currentFormula = "=SUM(B1:F1)";
    currentRow += 1;
    sheet.Range.get({ row: currentRow, column: 1 }).NumberFormat = "@";
    sheet.Range.get({ row: currentRow, column: 1 }).Text = currentFormula;
    sheet.Range.get({ row: currentRow, column: 2 }).Formula = currentFormula;

    // Save the workbook
    const outputFileName = 'InsertFormulasAndFunctions_output.xlsx';
    workbook.SaveToFile({ fileName: outputFileName, version: xlsModule.ExcelVersion.Version2010 });

    // Release resources
    workbook.Dispose();

    // Read the converted file from the VFS and trigger a 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>Insert Formulas and Functions</h1>
      <button onClick={insertFormulasAndFunctions}>
        Start
      </button>
    </div>
  );
}

export default App;

Insert formulas and function results into Excel worksheets

Insert Formulas and Functions into an Excel Worksheet


Read Formulas and Functions from an Excel Worksheet

To read formulas and functions from an Excel worksheet, you need to loop through all the used cells in the worksheet, then use the HasFormula property of a cell to find the cells that contain formulas or functions, and finally use the Range.Formula property to get the formulas or functions in those cells. The detailed steps are as follows:

  1. Create a Workbook object.
  2. Use the Workbook.LoadFromFile() method to load an Excel workbook.
  3. Use the Workbook.Worksheets.get() method to get the first worksheet.
  4. Loop through the used cells in the worksheet.
  5. Use the HasFormula property to detect whether a cell contains a formula or function. If so, use the Range.RangeAddressLocal property and the Range.Formula property to get the cell name and its formula or function, and output the retrieved content.

Here is a complete code example showing how to loop through a worksheet and read the formulas and functions in React:

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

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

    // Load the font and Excel file into the VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = 'FormulasAndFunctions.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);

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

    // Load the Excel workbook
    workbook.LoadFromFile({ fileName: inputFileName });

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

    // Get the used cell range of the worksheet
    const usedRange = sheet.AllocatedRange;

    // Create an output workbook
    const output = new xlsModule.Workbook();
    const outSheet = output.Worksheets.get(0);
    let outRow = 1;

    // Loop through the used cells
    for (const cell of usedRange.Cells) {
      // Check whether the cell contains a formula or function
      if (cell.HasFormula) {
        // Get the cell name
        const cellname = cell.RangeAddressLocal;

        // Get the formula or function in the cell
        const formula = cell.Formula;

        // Write the cell name and formula that were read
        outSheet.Range.get({ row: outRow, column: 1 }).Value = "Cell " + cellname + " contains: " + formula;
        outRow += 1;
      }
    }

    // Set the output column width so the text displays completely
    outSheet.SetColumnWidth(1, 45);

    // Save the output workbook
    const outputFileName = 'ReadFormulasAndFunctions_output.xlsx';
    output.SaveToFile({ fileName: outputFileName, version: xlsModule.ExcelVersion.Version2010 });

    // Release resources
    output.Dispose();

    // Read the converted file from the VFS and trigger a 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>Read Formulas and Functions</h1>
      <button onClick={readFormulasAndFunctions}>
        Start
      </button>
    </div>
  );
}

export default App;

Read formulas and function results from Excel worksheets

Read Formulas and Functions from an Excel Worksheet


Frequently Asked Questions

HasFormula cannot detect the formula, and the loop returns no results

Cause: The formula in the target cell was actually written as text (using the Text/Value property instead of the Formula property), and HasFormula only returns true for real formulas.

Solution: Make sure to use the Range.Formula property when inserting; otherwise, re-assign the text as a formula before reading.

Confusing the Formula and FormulaNumberValue properties

Cause: The Formula property returns the formula string in the cell, while the FormulaNumberValue property returns the numeric result after the formula is calculated. The two return different content.

Solution: Use cell.Formula when you need the formula string, and cell.FormulaNumberValue when you need the numeric result after calculation. Choose the appropriate property based on your actual needs.


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.

In everyday Excel spreadsheet handling, grouping rows or columns lets you collapse detail data and show only summary information, making large tables cleaner and easier to read. Spire.XLS for JavaScript performs grouping and ungrouping directly in the browser based on WebAssembly, and manages input/output files through a virtual file system (VFS), with no backend service required.

This article covers two core features:

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


Group Rows or Columns

After grouping rows or columns, you can collapse the detail data inside a group and keep only the summary rows or columns you need, making the worksheet tidier. Spire.XLS for JavaScript groups rows with the GroupByRows() method and columns with the GroupByColumns() method. The main steps are as follows:

  1. Create a Workbook object and use the LoadFromFile() method to load the Excel document.
  2. Use the Workbook.Worksheets.get() method to get a specific worksheet.
  3. Use the Worksheet.GroupByRows() method to group rows.
  4. Use the Worksheet.GroupByColumns() method to group columns.
  5. Use the Workbook.SaveToFile() method to save the document to a specified path.

Here is a complete code example showing how to group rows or columns in React:

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

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

    // Load the font and Excel file into the VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = 'GroupRowsAndColumns.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);

    // Load the workbook
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: inputFileName });

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

    // Group rows
    sheet.GroupByRows(6, 10, false);
    sheet.GroupByRows(14, 16, false);

    // Group columns
    sheet.GroupByColumns(2, 7, false);

    // Save the document
    const outputFileName = 'GroupRowsAndColumns_output.xlsx';
    workbook.SaveToFile({ fileName: outputFileName, version: xlsModule.ExcelVersion.Version2010 });

    // Release resources
    workbook.Dispose();

    // Read the converted file from the VFS and trigger a 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>Group Rows And Columns</h1>
      <button onClick={groupRowsAndColumns}>
        Start
      </button>
    </div>
  );
}

export default App;

After grouping, group markers appear on the left side of the grouped rows or above the grouped columns. Click a marker to collapse or expand the detail data.

Group Rows or Columns


Ungroup Rows or Columns

When the grouping structure is no longer needed, you can ungroup the existing groups so that all rows and columns return to their normal display. Spire.XLS for JavaScript ungroups rows with the UngroupByRows() method and columns with the UngroupByColumns() method. The main steps are as follows:

  1. Create a Workbook object and use the LoadFromFile() method to load the Excel document that contains groups.
  2. Use the Workbook.Worksheets.get() method to get a specific worksheet.
  3. Use the Worksheet.UngroupByRows() method to ungroup rows.
  4. Use the Worksheet.UngroupByColumns() method to ungroup columns.
  5. Use the Workbook.SaveToFile() method to save the document to a specified path.

Here is a complete code example showing how to ungroup rows or columns in React:

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

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

    // Load the font and Excel file into the VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = 'GroupRowsAndColumns.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);

    // Load the workbook
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: inputFileName });

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

    // Ungroup rows
    sheet.UngroupByRows(6, 10);
    sheet.UngroupByRows(14, 16);

    // Ungroup columns
    sheet.UngroupByColumns(2, 7);

    // Save the document
    const outputFileName = 'UngroupRowsAndColumns_output.xlsx';
    workbook.SaveToFile({ fileName: outputFileName, version: xlsModule.ExcelVersion.Version2010 });

    // Release resources
    workbook.Dispose();

    // Read the converted file from the VFS and trigger a 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>Ungroup Rows And Columns</h1>
      <button onClick={ungroupRowsAndColumns}>
        Start
      </button>
    </div>
  );
}

export default App;

After ungrouping, the group markers on the rows or columns disappear and the data returns to the normal ungrouped display.

Ungroup Rows or Columns


FAQ

Cannot collapse or expand detail data after grouping

Cause: The third parameter isCollapsed of the GroupByRows() and GroupByColumns() methods is set to false, so the groups are displayed expanded by default.

Solution: Set this parameter to true, and the groups will be displayed collapsed after saving:

sheet.GroupByRows(6, 10, true);

Some rows or columns still show group symbols after ungrouping

Cause: The UngroupByRows() and UngroupByColumns() methods only ungroup the rows or columns within the specified range. If these rows or columns also belong to a higher-level group, the higher-level group symbols are still retained.

Solution: Make sure the range passed when ungrouping matches the range used when grouping. If nested groups exist, call the ungroup methods repeatedly to ungroup level by level:

sheet.UngroupByRows(6, 10);
sheet.UngroupByRows(14, 16);
sheet.UngroupByColumns(2, 7);

Obtain 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.

Reading Excel files directly in a web application is useful for many scenarios, such as displaying spreadsheet data on a webpage, importing business records, analyzing worksheet content, or extracting specific data for further processing. In React applications, developers may also need to distinguish between different Excel data types, including text, numbers, formulas, dates, and Boolean values.

Spire.XLS for JavaScript provides APIs for loading and manipulating Excel files in JavaScript applications. With it, you can access worksheets and cells, retrieve different types of cell values, and extract embedded images without requiring Microsoft Excel. This article demonstrates how to read Excel files with JavaScript in React, including reading worksheet data, retrieving different cell value types, and extracting images.

On this page:

Install Spire.XLS for JavaScript in a React Project

Before working with Excel files, install Spire.XLS for JavaScript in your React project.

Open a terminal in the project directory and run:

npm i spire.office

After installing the package, copy the required Spire.XLS JavaScript and WebAssembly runtime files to the public directory of the React project.

For detailed instructions on setting up the library and its WebAssembly runtime, refer to: How to Integrate Spire.XLS for JavaScript in a React Project

Once the runtime is configured, Excel files can be loaded into the Spire virtual file system and processed in the browser.

Read Excel Data with JavaScript in React

A common requirement when reading Excel files is to retrieve all used data from a worksheet and display it in a web interface.

Spire.XLS provides the AllocatedRange property to obtain the range of cells that are currently in use. You can then loop through its rows and columns and retrieve each cell's value.

The main steps are as follows:

  1. Load and initialize the Spire.XLS WebAssembly module.
  2. Load the Excel file into the Spire virtual file system.
  3. Create a Workbook object and load the Excel file.
  4. Access the desired worksheet.
  5. Get the worksheet's allocated range.
  6. Iterate through the cells and retrieve their values.
  7. Store the extracted values in React state and display them in an HTML table.

The following example reads data from the first worksheet of an Excel file named Data.xlsx and displays the retrieved values in a React table.

import React, { useState, useEffect } from 'react';

function App() {
  const [wasmModule, setWasmModule] = useState(null);
  const [tableData, setTableData] = useState([]);
  const [status, setStatus] = useState('Loading Excel runtime...');
  const [error, setError] = useState('');

  useEffect(() => {
    (async () => {
      try {
        const publicUrl = process.env.PUBLIC_URL || '';
        const spireModule = await import(
          /* webpackIgnore: true */
          `${publicUrl}/spire.xls.js`
        );

        const xlsModule = spireModule.spirexls || window.spirexls;

        if (!xlsModule) {
          throw new Error('Spire XLS module was not initialized.');
        }

        window.wasmModule = xlsModule;
        setWasmModule(xlsModule);
        setStatus('Excel runtime ready.');
      } catch (err) {
        console.error('Failed to load Spire XLS runtime:', err);
        setError(err.message || 'Failed to load Spire XLS runtime.');
        setStatus('');
      }
    })();
  }, []);

  const loadExcelToVfs = async (fileName) => {
    const publicUrl = process.env.PUBLIC_URL || '';
    const response = await fetch(`${publicUrl}/${fileName}`);

    if (!response.ok) {
      throw new Error(
        `Failed to load ${fileName}: ${response.status} ${response.statusText}`
      );
    }

    if (!window.dotnetRuntime?.Module?.FS) {
      throw new Error('Spire virtual file system is not ready.');
    }

    const fileBytes = new Uint8Array(await response.arrayBuffer());

    window.dotnetRuntime.Module.FS.writeFile(
      fileName,
      fileBytes,
      { flags: 'w+' }
    );

    return fileName;
  };

  const readExcelData = async () => {
    if (!wasmModule) {
      setError('Excel runtime is not ready yet.');
      return;
    }

    setError('');
    setStatus('Reading Excel file...');

    const workbook = new wasmModule.Workbook();

    try {
      const inputFile = await loadExcelToVfs('Data.xlsx');
      workbook.LoadFromFile(inputFile);

      const sheet = workbook.Worksheets.get(0);
      const range = sheet.AllocatedRange;
      const rows = [];

      if (range) {
        const firstRow = range.Row;
        const firstColumn = range.Column;

        const lastRow =
          range.LastRow || firstRow + range.RowCount - 1;

        const lastColumn =
          range.LastColumn || firstColumn + range.ColumnCount - 1;

        for (let r = firstRow; r <= lastRow; r++) {
          const row = [];

          for (let c = firstColumn; c <= lastColumn; c++) {
            row.push(sheet.get(r, c).Value);
          }

          rows.push(row);
        }
      }

      setTableData(rows);
      setStatus(`Loaded ${rows.length} rows.`);
    } catch (err) {
      console.error('Failed to read Excel file:', err);
      setError(err.message || 'Failed to read Excel file.');
      setStatus('');
    } finally {
      workbook.Dispose();
    }
  };

  return (
    <div style={{ textAlign: 'center', padding: 30 }}>
      <h1>Read Excel in JavaScript</h1>

      <button onClick={readExcelData} disabled={!wasmModule}>
        Read Excel File
      </button>

      {status && <p>{status}</p>}

      {error && (
        <p style={{ color: 'crimson' }}>
          {error}
        </p>
      )}

      {tableData.length > 0 && (
        <table
          border="1"
          cellPadding="8"
          style={{
            margin: '20px auto',
            borderCollapse: 'collapse'
          }}
        >
          <tbody>
            {tableData.map((row, ri) => (
              <tr key={ri}>
                {row.map((cell, ci) => (
                  <td key={ci}>{cell}</td>
                ))}
              </tr>
            ))}
          </tbody>
        </table>
      )}
    </div>
  );
}

export default App;

Code Explanation

The example first dynamically loads the Spire.XLS JavaScript runtime:

const spireModule = await import(
  /* webpackIgnore: true */
  `${publicUrl}/spire.xls.js`
);

const xlsModule = spireModule.spirexls || window.spirexls;

Since Spire.XLS uses a WebAssembly runtime, the source Excel file is then loaded into its virtual file system:

const fileBytes = new Uint8Array(await response.arrayBuffer());

window.dotnetRuntime.Module.FS.writeFile(
  fileName,
  fileBytes,
  { flags: 'w+' }
);

Next, create a Workbook object and load the Excel file:

const workbook = new wasmModule.Workbook();
workbook.LoadFromFile(inputFile);

The first worksheet can be accessed using:

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

To avoid iterating through unnecessary empty cells, the example retrieves the worksheet's used area through AllocatedRange:

const range = sheet.AllocatedRange;

The starting and ending rows and columns are then determined from this range. A nested loop is used to access each cell:

for (let r = firstRow; r <= lastRow; r++) {
  const row = [];

  for (let c = firstColumn; c <= lastColumn; c++) {
    row.push(sheet.get(r, c).Value);
  }

  rows.push(row);
}

Finally, the resulting two-dimensional array is stored in the tableData React state and rendered as an HTML table.

React page displaying the Excel data as an HTML table

This approach is useful when building spreadsheet viewers, Excel import interfaces, reporting pages, or other applications where worksheet data needs to be presented directly in the browser.

Read Different Types of Cell Data from Excel

Excel cells can contain different kinds of data. Depending on the content you need to retrieve, Spire.XLS provides different properties or methods for accessing the underlying cell value.

The following table lists some commonly used options:

Data to Read API
Text cell.Text
Number cell.NumberValue
Formula cell.Formula
Formula calculation result cell.FormulaValue
Date and time cell.DateTimeValue
Boolean value cell.BooleanValue
Number or text value cell.Value
Date, Boolean, or other value cell.Value2

For example, first access a particular cell:

const cell = sheet.get(rowIndex, colIndex);

You can then retrieve its content according to the expected data type.

Read Text

Use the Text property to retrieve the text representation of a cell:

const text = sheet.get(rowIndex, colIndex).Text;

This is useful when the displayed textual content of a cell is required.

Read Numbers

To obtain a numeric value, use NumberValue:

const number = sheet.get(rowIndex, colIndex).NumberValue;

This can be useful when worksheet values will be used for calculations or numeric processing in JavaScript.

Read Formulas and Formula Results

Excel cells may contain formulas rather than static values. The formula expression itself can be retrieved through the Formula property:

const formula = sheet.get(rowIndex, colIndex).Formula;

For example, a formula cell may contain an expression such as:

=SUM(B2:B10)

If you need the calculated result of the formula instead of the formula expression, use:

const formulaResult = sheet.get(rowIndex, colIndex).FormulaValue;

Being able to retrieve both the formula and its result is useful for spreadsheet analysis and auditing applications.

Read Dates

Excel stores date and time information as a specialized cell value. You can retrieve it using:

const date = sheet.get(rowIndex, colIndex).DateTimeValue;

The returned date value can then be formatted or processed according to the requirements of the React application.

Read Boolean Values

For cells containing Boolean values such as TRUE or FALSE, use:

const bool = sheet.get(rowIndex, colIndex).BooleanValue;

Read General Cell Values

When a cell may contain either a number or text, the Value property provides a convenient general-purpose option:

const value = sheet.get(rowIndex, colIndex).Value;

For values such as dates, Boolean values, or other underlying Excel data types, Value2 can also be used:

const value = sheet.get(rowIndex, colIndex).Value2;

Choosing the appropriate property based on the expected Excel data type makes it easier to preserve the original meaning of the worksheet content when processing it in JavaScript.

Read Images from Excel Worksheets

In addition to cell data, Excel worksheets can contain embedded pictures. Spire.XLS for JavaScript allows you to access these images through the worksheet's Pictures collection.

The following example retrieves the first picture from a worksheet and saves it as a PNG file:

let pic = sheet.Pictures.get(0);

const outputFileName = 'ReadImages-out.png';

pic.Picture.Save(outputFileName);

Because the image is saved inside the Spire WebAssembly virtual file system, it can then be read back into JavaScript:

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

Next, create a JavaScript Blob from the resulting image data:

const modifiedFile = new Blob(
  [modifiedFileArray],
  { type: 'image/png' }
);

The resulting Blob can be used for further browser-side operations. For example, you can create an object URL and display the extracted image directly in a React component:

const imageUrl = URL.createObjectURL(modifiedFile);

Then use the generated URL as the source of an HTML image element:

<img src={imageUrl} alt="Extracted from Excel" />

If a worksheet contains multiple pictures, you can iterate through the Pictures collection and process each image individually.

This capability is useful for applications that need to extract product images, logos, charts saved as pictures, document assets, or other visual content embedded in Excel worksheets.

Conclusion

Reading Excel files in React makes it possible to bring spreadsheet data directly into browser-based workflows. With Spire.XLS for JavaScript, developers can load Excel workbooks, access worksheets and used ranges, iterate through cells, and retrieve data without relying on Microsoft Excel.

In addition to general cell values, Spire.XLS allows JavaScript applications to access specific data types such as text, numbers, formulas, formula results, dates, and Boolean values. Embedded worksheet images can also be retrieved and converted into browser-compatible objects for display or further processing.

These features can be used to build Excel viewers, data import tools, reporting systems, spreadsheet analysis interfaces, and other React applications that need to work with Excel content.

FAQs

Can JavaScript Read Excel Files in a React Application?

Yes. JavaScript can read Excel files in React with the help of an Excel-processing library such as Spire.XLS for JavaScript. After loading the Excel file into the WebAssembly virtual file system, you can access its worksheets, cells, formulas, images, and other spreadsheet content directly in the browser.

How Do I Read All Used Cells in an Excel Worksheet?

You can use the worksheet's AllocatedRange property to determine the range that contains data. After obtaining its starting and ending rows and columns, iterate through the range and access individual cells using:

sheet.get(rowIndex, colIndex)

This avoids unnecessarily iterating through large areas of empty worksheet cells.

How Can I Read an Excel Formula and Its Calculated Result Separately?

Use the Formula property to retrieve the formula expression:

const formula = sheet.get(rowIndex, colIndex).Formula;

Use CalculatedValue when you need the calculated value of the formula:

const result = sheet.get(rowIndex, colIndex).FormulaValue;

This makes it possible to inspect both the formula logic and its resulting value.

Can I Extract Images from Excel with JavaScript?

Yes. Images embedded in a worksheet can be accessed through the Pictures collection. After retrieving a picture, you can save it to the Spire virtual file system, read the generated image bytes, and convert them into a JavaScript Blob. The Blob can then be displayed, downloaded, or processed further in the browser.

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.

Comments are an important tool in Excel for providing supplementary explanations of cell contents, and are commonly used in scenarios such as data review and collaborative notes. Spire.XLS for JavaScript uses WebAssembly to add, read, edit, and delete comments directly in the browser, managing input and output files through a virtual file system (VFS) — no backend server required.

This article covers several commonly used features:

For installation and project configuration, 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.


Add a Comment

A comment can also carry author information, making it easy to identify where the comment comes from.

function App() {
  const addCommentWithAuthor = 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 and the Excel file into VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = 'CommentsSample.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);

    // Load the workbook
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: inputFileName });

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

    // Get the cell where the comment will be added
    const range = sheet.Range.get('C1');

    // Set the author and comment content
    const author = 'E-iceblue:';
    const text = 'This is an example showing how to add a comment with an editable author property.';

    // Add a comment to the cell and set its properties
    const comment = range.AddComment();
    comment.Width = 200;
    comment.IsVisible = true;
    comment.Text = author + ':\n' + text;

    // Set the font style of the author name in the comment
    const font = workbook.CreateFont();
    font.FontName = 'Arial';
    font.KnownColor = xlsModule.ExcelColors.Black;
    font.IsBold = true;
    comment.RichText.SetFont(0, author.length, font);

    // Save the workbook
    const outputFileName = 'AddCommentWithAuthor_output.xlsx';
    workbook.SaveToFile({ fileName: outputFileName, version: xlsModule.ExcelVersion.Version2010 });

    // Release resources
    workbook.Dispose();

    // Read the generated file from VFS and trigger the 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>Add Comment With Author</h1>
      <button onClick={addCommentWithAuthor}>Start</button>
    </div>
  );
}

export default App;

After running, a comment containing the author name and the comment text will appear on cell C1. Add a comment with author


Read Comment Content

You can read the comment on a cell through the CellRange.Comment property.

function App() {
  const readComment = 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 Excel file into VFS
    const inputFileName = 'CommentsSample.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);

    // Load the workbook
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: inputFileName });

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

    // Get the comment text
    const builder = [];
    builder.push(sheet.Range.get('A1').Comment.Text + '\n\t');
    builder.push(sheet.Range.get('A2').Comment.Text);

    // Save the comment content to a txt file
    const outputFileName = 'ReadComment_output.txt';
    window.dotnetRuntime.Module.FS.writeFile(outputFileName, builder.join('\n'));
    workbook.Dispose();

    // Read the generated file from VFS and trigger the download
    const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
    const blob = new Blob([fileArray], { type: 'text/plain' });
    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>Read Comment</h1>
      <button onClick={readComment}>Start</button>
    </div>
  );
}

export default App;

The read comment content The read comment content


Edit Comment Content

Get a comment by index through Comments.get(0), and then modify its text content.

function App() {
  const editComment = 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 and the Excel file into VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = 'CommentsSample.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);

    // Load the workbook
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: inputFileName });

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

    // Get the first comment
    const comment = sheet.Comments.get(0);

    // Edit the comment content
    comment.Text = 'This comment has been edited by Spire.XLS.';

    // Save the workbook
    const outputFileName = 'EditExcelComment_output.xlsx';
    workbook.SaveToFile({ fileName: outputFileName, version: xlsModule.ExcelVersion.Version2010 });

    // Release resources
    workbook.Dispose();

    // Read the generated file from VFS and trigger the 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>Edit Excel Comment</h1>
      <button onClick={editComment}>Start</button>
    </div>
  );
}

export default App;

The edited comment content The edited comment content


Delete Comments

You can delete all comments in a worksheet through the Comments.Clear method.

function App() {
  const removeComment = 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 and the Excel file into VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = 'CommentsSample.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);

    // Load the workbook
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: inputFileName });

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

    // Clear all comments; alternatively, use comments.RemoveAt(0) to delete a comment by index
    comments.Clear();

    // Save the workbook
    const outputFileName = 'RemoveComment_output.xlsx';
    workbook.SaveToFile({ fileName: outputFileName, version: xlsModule.ExcelVersion.Version2010 });

    // Release resources
    workbook.Dispose();

    // Read the generated file from VFS and trigger the 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>Remove Comment</h1>
      <button onClick={removeComment}>Start</button>
    </div>
  );
}

export default App;

After deleting comments After deleting comments


FAQ

Comment is not visible after being added

Cause: The IsVisible property was not set to true after adding the comment, so the comment remains hidden by default.

Solution: Set comment.IsVisible = true after adding the comment to make it visible in the worksheet.

Empty content is returned when reading a comment

Cause: There is no comment on the target cell, or an incorrect cell reference was used.

Solution: Confirm that the target cell has a comment, and access the comment content through methods such as sheet.Range.get('A1').Comment.


Get a Free License

If you want to remove the evaluation messages in the resulting documents, or get rid of functional limitations, please contact sales to obtain a temporary license valid for 30 days.

When creating reports, setting background colors for cells highlights headers and key data, and setting a background image for the worksheet makes the whole report more recognizable. Spire.XLS for JavaScript performs both kinds of settings directly in the browser based on WebAssembly, and manages input/output files through a virtual file system (VFS), with no backend service required.

This article covers two core features:

For installation and project configuration, 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.


Set Cell Background Color

Setting a background color for cells highlights headers, important data, or specific regions. Spire.XLS for JavaScript sets a background color for a cell or a cell range through the CellRange.Style.Color property, with rich built-in colors supported. The main steps are as follows:

  1. Create a Workbook object and use the LoadFromFile() method to load the Excel document.
  2. Use the Workbook.Worksheets.get() method to get a specific worksheet.
  3. Use the CellRange.Style.Color property to set a background color for a specific cell range.
  4. Use the Workbook.SaveToFile() method to save the document to a specified path.

Here is a complete code example showing how to set background colors for cell ranges in React:

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

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

    // Load the font and Excel file into the VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = 'SetBackgroundColor.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);

    // Load the workbook
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: inputFileName });

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

    // Set the header row to a yellow background
    sheet.Range.get("A1:E1").Style.Color = xlsModule.Color.get_Yellow();

    // Set the first two data rows to a light sky blue background
    sheet.Range.get("A2:E2").Style.Color = xlsModule.Color.get_LightSkyBlue();
    sheet.Range.get("A3:E3").Style.Color = xlsModule.Color.get_LightSkyBlue();

    // Save the document
    const outputFileName = 'SetBackgroundColor_output.xlsx';
    workbook.SaveToFile({ fileName: outputFileName, version: xlsModule.ExcelVersion.Version2010 });

    // Release resources
    workbook.Dispose();

    // Read the converted file from the VFS and trigger a 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>Set Cell Background Color</h1>
      <button onClick={setBackgroundColor}>
        Start
      </button>
    </div>
  );
}

export default App;

After setting the background colors, the header row is displayed with a yellow background and the first two data rows with a light sky blue background, making it easy to distinguish cells in different regions.

Set Cell Background Color


Set Worksheet Background Image

In addition to setting background colors for cells, you can also set a background image for the whole worksheet to make the report more recognizable. Spire.XLS for JavaScript sets an image as the worksheet background through the Worksheet.PageSetup.BackgroundImage property. The main steps are as follows:

  1. Create a Workbook object and use the LoadFromFile() method to load the Excel document.
  2. Use the Workbook.Worksheets.get() method to get a specific worksheet.
  3. Use a Stream object to read the image file to be used as the background.
  4. Use the Worksheet.PageSetup.BackgroundImage property to set the image as the worksheet background.
  5. Use the Workbook.SaveToFile() method to save the document to a specified path.

Here is a complete code example showing how to set a background image for a worksheet in React:

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

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

    // Load the font, image, and Excel file into the VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const backgroundImageName = 'Background.png';
    await window.spire.FetchFileToVFS(backgroundImageName, '', `${process.env.PUBLIC_URL}data/`);
    const inputFileName = 'SetBackgroundColor.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);

    // Load the workbook
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: inputFileName });

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

    // Open the image as a stream
    const bm = new xlsModule.Stream(backgroundImageName);

    // Set the image as the worksheet background
    sheet.PageSetup.BackgroundImage = bm;

    // Save the document
    const outputFileName = 'SetBackgroundImage_output.xlsx';
    workbook.SaveToFile({ fileName: outputFileName, version: xlsModule.ExcelVersion.Version2010 });

    // Release resources
    workbook.Dispose();

    // Read the converted file from the VFS and trigger a 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>Set Worksheet Background Image</h1>
      <button onClick={setBackgroundImage}>
        Start
      </button>
    </div>
  );
}

export default App;

After setting the background image, the image fills the back of the worksheet as its background, while the cell contents and data remain clearly displayed on top of the image.

Set Worksheet Background Image


FAQ

The background color is lost after saving and reopening

Cause: The Style.Color property sets the background (fill) color of a cell, not the font color. If the color is overridden by other styles, or the fill pattern is not set correctly, the color may not display properly.

Solution: Set the color directly for the cell range, for example sheet.Range.get("A1:E1").Style.Color = xlsModule.Color.get_Yellow();. If you want to use a patterned fill, combine Style.Interior.FillPattern and Style.Interior.Gradient.

The background image does not appear above the data

Cause: A worksheet background image is always displayed behind the cell contents and only serves as background decoration. It neither covers the data nor is covered by it.

Solution: This is the normal display layering. If you need the image to appear on top of the data, use the Worksheet.Pictures.Add() method to insert a floating image in the worksheet instead of setting a worksheet background.


Obtain 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.

In everyday Excel data processing, sorting is one of the most common operations — whether rearranging data by name, value, or date, it makes tables more organized and easier to search. Spire.XLS for JavaScript performs data sorting directly in the browser based on WebAssembly, and manages input/output files through a virtual file system (VFS), with no backend service required.

This article covers two core features:

For installation and project configuration, 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.


Sort Data in a Cell Range in Ascending Order

Sorting a specified cell range in ascending order is the most common data arrangement requirement. Spire.XLS for JavaScript adds a sort field and specifies the sort order with the Workbook.DataSorter.SortColumns.Add() method, then sorts the specified range with the Workbook.DataSorter.Sort() method. The main steps are as follows:

  1. Create a Workbook object and use the LoadFromFile() method to load the Excel document.
  2. Use the Workbook.Worksheets.get() method to get a specific worksheet.
  3. Use the Workbook.DataSorter.SortColumns.Add() method to add a sort field, specifying the column and the sort order.
  4. Use the Workbook.DataSorter.Sort() method to sort the specified cell range.
  5. Use the Workbook.SaveToFile() method to save the document to a specified path.

Here is a complete code example showing how to sort a cell range in ascending order by a single column in React:

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

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

    // Load the font and Excel file into the VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = 'DataSorting.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);

    // Load the workbook
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: inputFileName });

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

    // Add a sort field: sort by the 5th column (Population) in ascending order
    workbook.DataSorter.SortColumns.Add({ key: 4, orderBy: xlsModule.OrderBy.Ascending });

    // Sort the specified cell range A1:E19
    workbook.DataSorter.Sort(sheet.Range.get("A1:E19"));

    // Save the document
    const outputFileName = 'SortDataAscending_output.xlsx';
    workbook.SaveToFile({ fileName: outputFileName, version: xlsModule.ExcelVersion.Version2010 });

    // Release resources
    workbook.Dispose();

    // Read the converted file from the VFS and trigger a 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>Sort Data in Ascending Order</h1>
      <button onClick={sortAscending}>
        Start
      </button>
    </div>
  );
}

export default App;

After sorting, the data is rearranged in ascending numerical order based on the 5th column (Population), from the smallest to the largest, and the other columns in the same row stay aligned with the Population column.

Sort Data in a Cell Range in Ascending Order


Sort Data by Multiple Columns

When a single-column sort is not enough, you can sort by multiple columns at the same time. Spire.XLS for JavaScript supports adding multiple sort fields by calling the SortColumns.Add() method several times. Data is sorted by the first field first, then by the subsequent fields. The main steps are as follows:

  1. Create a Workbook object and use the LoadFromFile() method to load the Excel document.
  2. Use the Workbook.Worksheets.get() method to get a specific worksheet.
  3. Call the Workbook.DataSorter.SortColumns.Add() method several times to add multiple sort fields.
  4. Use the Workbook.DataSorter.Sort() method to sort the specified cell range.
  5. Use the Workbook.SaveToFile() method to save the document to a specified path.

Here is a complete code example showing how to sort a cell range by multiple columns in React:

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

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

    // Load the font and Excel file into the VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = 'DataSorting.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);

    // Load the workbook
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: inputFileName });

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

    // Add multiple sort fields: first by the 3rd column (Continent), then by the 4th column (Area), ascending
    workbook.DataSorter.SortColumns.Add({ key: 2, orderBy: xlsModule.OrderBy.Ascending });
    workbook.DataSorter.SortColumns.Add({ key: 3, orderBy: xlsModule.OrderBy.Ascending });

    // Sort the specified cell range A1:E19
    workbook.DataSorter.Sort(sheet.Range.get("A1:E19"));

    // Save the document
    const outputFileName = 'SortDataMultipleColumns_output.xlsx';
    workbook.SaveToFile({ fileName: outputFileName, version: xlsModule.ExcelVersion.Version2010 });

    // Release resources
    workbook.Dispose();

    // Read the converted file from the VFS and trigger a 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>Sort Data by Multiple Columns</h1>
      <button onClick={sortMultipleColumns}>
        Start
      </button>
    </div>
  );
}

export default App;

After sorting, the data is first arranged in ascending order by the 3rd column (Continent), grouping countries from the same continent together; when the continents are the same, it is then sorted in ascending order by the 4th column (Area).

Sort Data by Multiple Columns


FAQ

The header row is also included in the sorting

Cause: By default, the DataSorter.Sort() method treats the first row of the sort range as a title row and keeps it in place. If the header is moved into the data rows, it is usually because the starting row of the sort range is set incorrectly.

Solution: Make sure the range passed to the Sort() method includes the header row and that the header row is at the top of the range, for example sheet.Range.get("A1:E19"). You can also start the sort from the data rows, such as sheet.Range.get("A2:E19").

After a single-column sort, other columns do not change accordingly

Cause: The sort only takes effect on the cell range passed to the Sort() method. If you sort only a single column's range, the other columns will not be rearranged, causing data in the same row to become misaligned.

Solution: Make the sort range cover all related columns (for example, the complete range that includes name, capital, continent, area, and population, A1:E19), so that the entire row moves together.


Obtain 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.

Finding and replacing data is a common requirement when processing Excel files in web applications. 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 required. It provides search methods such as FindAllString() and FindAllNumber() that let you locate target data across an entire worksheet or within a specified cell range, quickly replace it with new content, and optionally mark the replaced cells with a highlight color.

With Spire.XLS for JavaScript, you can batch-replace text across an entire worksheet or restrict the search to a specific cell range, giving you both efficiency and flexibility when updating partial data precisely.

This article covers two 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.


Find and Replace Data in a Worksheet in Excel

With Spire.XLS for JavaScript, you can find all cells containing a specified text in an entire worksheet and replace them with new content. The FindAllString() method returns all matching cell ranges. You can then replace the text by setting the range.Text property and highlight the replaced cells by setting the range.Style.Color property, making it easy to identify where modifications were made. The steps are as follows:

  1. Create a Workbook object and load an existing Excel file.
  2. Get the worksheet to operate on via workbook.Worksheets.get().
  3. Use worksheet.FindAllString() to find all cell ranges containing the specified text in the worksheet.
  4. Iterate through the search results, replacing the text via range.Text and setting the highlight color via range.Style.Color.
  5. Save the workbook to an Excel file using SaveToFile().

Below is a complete code example demonstrating how to find and replace data across an entire worksheet in React:

function App() {
  const findAndReplace = 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;
    }

    let excelFileName = 'Sample.xlsx';
    await window.spire.FetchFileToVFS(excelFileName, '', `${process.env.PUBLIC_URL}static/data/`);

    // Create a new workbook and load an existing Excel file
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: excelFileName });

    // Get the first worksheet
    let worksheet = workbook.Worksheets.get(0);

    // Find all cells containing the text "Total" in the worksheet
    let ranges = worksheet.FindAllString("Total", false, false);

    // Iterate through the search results, replace the text, and set the highlight color
    for (let range of ranges) {
      range.Text = "Total Expenses";
      range.Style.Color = xlsModule.Color.get_Yellow();
    }

    // Save the workbook
    const outputFileName = 'FindAndReplaceData.xlsx';
    workbook.SaveToFile({ fileName: outputFileName, version: xlsModule.ExcelVersion.Version2010 });
    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>Find and Replace Data in a Worksheet</h1>
      <button onClick={findAndReplace}>
        Generate
      </button>
    </div>
  );
}

export default App;

Find and replace data in a worksheet in Excel

Find and replace data in a worksheet in Excel


Find and Replace Data in a Specific Cell Range in Excel

When you only need to update part of the data, you can restrict the search to a specific cell range. After specifying the target range with the sheet.Range.get() method, range.FindAllString() searches for cells containing the specified text only within that range, ensuring that data outside the range remains unaffected. The steps are as follows:

  1. Create a Workbook object and load an existing Excel file.
  2. Get the worksheet to operate on via workbook.Worksheets.get().
  3. Specify the cell range to search with sheet.Range.get().
  4. Use range.FindAllString() to find cells containing the target text within the specified range, then iterate through the results to replace the text and set the highlight color.
  5. Save the workbook to an Excel file using SaveToFile().

Below is a complete code example demonstrating how to find and replace data in a specific cell range in React:

function App() {
  const findAndReplaceInRange = 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 sample file into the Virtual File System (VFS)
    let excelFileName = 'FindCellsSample.xlsx';
    await window.spire.FetchFileToVFS(excelFileName, '', `${process.env.PUBLIC_URL}static/data/`);

    // Create a new workbook and load an existing Excel file
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: excelFileName });

    // Get the first worksheet
    let worksheet = workbook.Worksheets.get(0);

    // Specify the cell range to search
    let range = worksheet.Range.get({
      row: 1,
      column: 1,
      lastRow: 12,
      lastColumn: 2,
    });

    // Find all cells containing the text "Total" within the specified range
    let ranges = range.FindAllString("Total", false, false);

    // Iterate through the search results, replace the text, and set the highlight color
    for (let r of ranges) {
      r.Text = "Total Expenses";
      r.Style.Color = xlsModule.Color.get_Yellow();
    }

    // Save the workbook
    const outputFileName = 'FindAndReplaceInRange.xlsx';
    workbook.SaveToFile({ fileName: outputFileName, version: xlsModule.ExcelVersion.Version2010 });
    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>Find and Replace Data in a Specific Cell Range</h1>
      <button onClick={findAndReplaceInRange}>
        Generate
      </button>
    </div>
  );
}

export default App;

Find and replace data in a specific cell range in Excel

Find and replace data in a specific cell range in Excel


FAQ

How to control whether the search is case-sensitive or matches whole words

Cause: The last two boolean parameters of the FindAllString() method control whether the search is case-sensitive and whether it must match whole words. If these parameters are set incorrectly, you may find too many or too few matching results.

Solution: Adjust the parameters of FindAllString() according to your actual needs:

// Case-insensitive, whole-word matching not required
let ranges = worksheet.FindAllString("Area", false, false);

// Case-sensitive, whole-word matching required
let ranges = worksheet.FindAllString("Total", true, true);

How to find and replace numbers in a specific range

Cause: Find and replace works not only with text but also with numbers. If you only use FindAllString() to handle text, numeric cells cannot be matched.

Solution: Use the range.FindAllNumber() method to find numbers within the specified range, then replace the values by setting the Text property:

let numberRanges = range.FindAllNumber(100, true);
for (let r of numberRanges) {
  r.Text = "200";
  r.Style.Color = xlsModule.Color.get_Yellow();
}

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.

A pivot table (PivotTable) is a core tool in Excel for quickly summarizing and analyzing large amounts of data. By dragging and dropping fields, you can easily perform data statistics and comparisons. Spire.XLS for JavaScript is based on WebAssembly and can create, filter, and update pivot tables directly in the browser. It manages input and output files through a virtual file system (VFS), so no backend services are required.

This article covers three core features:

For installation and project configuration, please refer to How to Integrate Spire.XLS for JavaScript in a React Project. The examples below assume that Spire.XLS is installed and the WebAssembly module has been initialized.


Create a Pivot Table

Creating a pivot table usually involves four steps: preparing the source data, adding a pivot table, laying out the fields, and calculating the data. The following example writes a product sales record into the first worksheet, creates a cache based on the data range using the PivotCaches.Add method, adds a pivot table to the worksheet using the PivotTables.Add method, and finally drags fields into the row area and the data area to complete the layout.

function App() {
  const createPivotTable = 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 into the VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);

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

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

    // Write source data to cells
    sheet.Range.get('A1').Value = 'Product';
    sheet.Range.get('B1').Value = 'Month';
    sheet.Range.get('C1').Value = 'Count';

    sheet.Range.get('A2').Value = 'SpireDoc';
    sheet.Range.get('A3').Value = 'SpireDoc';
    sheet.Range.get('A4').Value = 'SpireXls';
    sheet.Range.get('A5').Value = 'SpireDoc';
    sheet.Range.get('A6').Value = 'SpireXls';
    sheet.Range.get('A7').Value = 'SpireXls';   

    sheet.Range.get('B2').Value = 'January';
    sheet.Range.get('B3').Value = 'February';
    sheet.Range.get('B4').Value = 'January';
    sheet.Range.get('B5').Value = 'January';
    sheet.Range.get('B6').Value = 'February';
    sheet.Range.get('B7').Value = 'February';

    sheet.Range.get('C2').Value = '10';
    sheet.Range.get('C3').Value = '15';
    sheet.Range.get('C4').Value = '9';
    sheet.Range.get('C5').Value = '7';
    sheet.Range.get('C6').Value = '8';
    sheet.Range.get('C7').Value = '10';

    // Create a pivot table cache based on the data range
    const dataRange = sheet.Range.get('A1:C7');
    const cache = workbook.PivotCaches.Add({ range: dataRange });

    // Add a pivot table
    const pt = sheet.PivotTables.Add('Pivot Table', sheet.Range.get({ row: 10, column: 5 }), cache);

    // Drag fields into the row area
    const pf1 = pt.PivotFields.get_Item('Product');
    pf1.Axis = xlsModule.AxisTypes.Row;
    const pf2 = pt.PivotFields.get_Item('Month');
    pf2.Axis = xlsModule.AxisTypes.Row;

    // Drag fields into the data area
    pt.DataFields.Add(pt.PivotFields.get_Item('Count'), 'Sum of Count', xlsModule.SubtotalTypes.Sum);

    // Set the pivot table style
    pt.BuiltInStyle = xlsModule.PivotBuiltInStyles.PivotStyleMedium12;

    // Calculate the pivot table data
    pt.CalculateData();
    sheet.AutoFitColumn(5);
    sheet.AutoFitColumn(6);

    // Save the workbook
    const outputFileName = 'CreatePivotTable_output.xlsx';
    workbook.SaveToFile({ fileName: outputFileName, version: xlsModule.ExcelVersion.Version2010 });

    // Release resources
    workbook.Dispose();

    // Read the generated file from the VFS and trigger the 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 Pivot Table</h1>
      <button onClick={createPivotTable}>Start</button>
    </div>
  );
}

export default App;

After calculating with the CalculateData method, the pivot table summarizes the total count of each product by product and month, displayed with the set PivotStyleMedium12 style.

Create a pivot table


Filter a Pivot Table

When a pivot table contains a lot of data, you can add filters to the row fields to keep only the data rows that meet the conditions.

function App() {
  const filterPivotTable = 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 and the Excel file into the VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = 'PivotTableExample.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);

    // Load the workbook
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: inputFileName, version: xlsModule.ExcelVersion.Version2010 });

    // Get the first pivot table in the second worksheet (PivotTable)
    const pt = workbook.Worksheets.get(1).PivotTables.get(0);

    // Get the first row field of the pivot table
    const rowField = pt.RowFields.get(0);

    // Add a value filter to the row field: values of the first data field less than 5300000
    rowField.AddValueFilter(xlsModule.PivotValueFilterType.LessThan, pt.DataFields.get(0), window.spire.Double.Create(5300000), new window.spire.SpireObject(0));

    // Recalculate the pivot table data
    pt.CalculateData();

    // Save the workbook
    const outputFileName = 'FilterPivotTable_output.xlsx';
    workbook.SaveToFile({ fileName: outputFileName, version: xlsModule.ExcelVersion.Version2010 });

    // Release resources
    workbook.Dispose();

    // Read the generated file from the VFS and trigger the 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>Filter Pivot Table</h1>
      <button onClick={filterPivotTable}>Start</button>
    </div>
  );
}

export default App;

Original pivot table data Original pivot table data

After filtering, the row area of the pivot table keeps only the data that meets the filter conditions, making it easy to focus on analyzing data in a specific range. After filtering


Update the Data Source and Refresh the Pivot Table

When the underlying data of a pivot table changes, you need to update the data source and refresh the pivot table cache so that the pivot table reflects the latest summary results.

function App() {
  const updateDataSource = 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 and the Excel file into the VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = 'PivotTableExample.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);

    // Load the workbook
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: inputFileName, version: xlsModule.ExcelVersion.Version2010 });

    // Get the data source worksheet and modify the cell values in it
    const data = workbook.Worksheets.get('Data');
    data.Range.get('A2').Text = 'NewValue';
    data.Range.get('D2').NumberValue = 28000;

    // Get the worksheet that contains the pivot table
    const sheet = workbook.Worksheets.get({ sheetName: 'PivotTable' });

    // Get the first pivot table on the worksheet
    const pt = sheet.PivotTables.get(0);

    // Refresh the pivot table cache
    pt.Cache.IsRefreshOnLoad = true;

    // Calculate and update the pivot table data
    pt.CalculateData();

    // Save the workbook
    const outputFileName = 'UpdateDataSource_output.xlsx';
    workbook.SaveToFile({ fileName: outputFileName, version: xlsModule.ExcelVersion.Version2010 });

    // Release resources
    workbook.Dispose();

    // Read the generated file from the VFS and trigger the 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>Update Pivot Table Data Source</h1>
      <button onClick={updateDataSource}>Start</button>
    </div>
  );
}

export default App;

After the data source is updated and refreshed, the corresponding summary results in the pivot table are updated synchronously.

Update the data source and refresh the pivot table


Frequently Asked Questions

No summary data is displayed after creating a pivot table

Cause: The CalculateData method is not called after adding fields to the pivot table, or the data fields are not correctly added to the data area.

Solution: Call pt.CalculateData() to recalculate the pivot table after completing the field layout, and make sure the numeric fields are added to the data area through the DataFields.Add method.

The pivot table data does not change after adding a filter

Cause: The CalculateData method is not called to recalculate after adding a label or value filter, or the filter is added to the wrong field.

Solution: Call pt.CalculateData() to recalculate the pivot table, and confirm that you use a property such as pt.RowFields.get(0) to get the correct field before adding the filter.

The pivot table data does not change after updating the data source

Cause: The pivot table cache is not refreshed after modifying the data source, so the pivot table still retains the old data.

Solution: After modifying the data source, set pt.Cache.IsRefreshOnLoad to true and call pt.CalculateData(), so that the pivot table is recalculated based on the latest data source.


Get a Free License

If you want to remove the evaluation message from the result document or get rid of the feature limitations, please contact sales to get a 30-day temporary license.

Data validation is an effective way to control the input content of Excel cells. It can intercept incorrect input at the data entry stage, ensuring that data is standardized and accurate. Spire.XLS for JavaScript uses WebAssembly to add, read, and remove data validation directly in the browser, managing input and output files through a virtual file system (VFS) — no backend server required.

This article covers three core features:

For installation and project configuration, 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.


Add Data Validation

In daily forms and reports, we often need to restrict the input of cells, for example only allowing numbers or dates within a certain range, or limiting the text length. Spire.XLS for JavaScript sets validation rules through the DataValidation property of a cell, supporting multiple validation types such as Decimal, Whole Number, Date, Time, Text Length, and List.

function App() {
  const sheetToSVG = 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 into VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);

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

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

    // Add a decimal validation: cell B12 can only accept numbers between 3 and 6
    sheet.Range.get("B11").Text = "Input Number(3-6):";
    let rangeNumber = sheet.Range.get("B12");
    rangeNumber.DataValidation.CompareOperator = xlsModule.ValidationComparisonOperator.Between;
    rangeNumber.DataValidation.Formula1 = "3";
    rangeNumber.DataValidation.Formula2 = "6";
    rangeNumber.DataValidation.AllowType = xlsModule.CellDataType.Decimal;
    rangeNumber.DataValidation.ErrorMessage = "Please input correct number!";
    rangeNumber.DataValidation.ShowError = true;
    rangeNumber.Style.KnownColor = xlsModule.ExcelColors.Gray25Percent;

    // Add a date validation: cell B15 can only accept dates within the year 2024
    sheet.Range.get("B14").Text = "Input Date: 1/1/2024";
    let rangeDate = sheet.Range.get("B15");
    rangeDate.DataValidation.AllowType = xlsModule.CellDataType.Date;
    rangeDate.DataValidation.CompareOperator = xlsModule.ValidationComparisonOperator.Between;
    rangeDate.DataValidation.Formula1 = "1/1/2024";
    rangeDate.DataValidation.Formula2 = "12/31/2024";
    rangeDate.DataValidation.ErrorMessage = "Please input correct date!";
    rangeDate.DataValidation.ShowError = true;
    // Supports setting AlertStyleType.Warning; AlertStyleType.Info; AlertStyleType.Stop
    rangeDate.DataValidation.AlertStyle = xlsModule.AlertStyleType.Warning;
    rangeDate.Style.KnownColor = xlsModule.ExcelColors.Gray25Percent;

    // Add a text length validation: the text length in cell B18 cannot exceed 5 characters
    sheet.Range.get("B17").Text = "Input Text:";
    let rangeTextLength = sheet.Range.get("B18");
    rangeTextLength.DataValidation.AllowType = xlsModule.CellDataType.TextLength;
    rangeTextLength.DataValidation.CompareOperator = xlsModule.ValidationComparisonOperator.LessOrEqual;
    rangeTextLength.DataValidation.Formula1 = "5";
    rangeTextLength.DataValidation.ErrorMessage = "Enter a Valid String!";
    rangeTextLength.DataValidation.ShowError = true;
    rangeTextLength.DataValidation.AlertStyle = xlsModule.AlertStyleType.Stop;
    rangeTextLength.Style.KnownColor = xlsModule.ExcelColors.Gray25Percent;

    // Auto-fit the width of column 2
    sheet.AutoFitColumn(2);

    const outputFileName = "DataValidation_out.xlsx";
    workbook.SaveToFile({ fileName: outputFileName, version: xlsModule.ExcelVersion.Version2010 });

    // Release the workbook object to free resources
    workbook.Dispose();

    // Read the converted file from VFS and trigger the 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>Add Data Validation</h1>
      <button onClick={sheetToSVG}>
        Start
      </button>
    </div>
  );
}

export default App;

Add data validation Add data validation


Get Data Validation Settings

When processing an Excel document that already has data validation, you may sometimes need to read the validation rules to understand the input constraints of a cell. Through the DataValidation property of a cell, you can obtain the validation object and then read settings such as AllowType (validation type), CompareOperator (comparison operator), Formula1 (minimum/lower limit), Formula2 (maximum/upper limit), and IgnoreBlank (whether blank values are ignored).

function App() {
  const sheetToSVG = 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 and Excel file into VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = 'GetSettingsOfDataValidation.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/static/data/`);

    // Load the workbook
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: inputFileName });

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

    // Cell B4 has a decimal validation set
    const cell = worksheet.Range.get("B4");

    // Get the data validation object of this cell
    const validation = cell.DataValidation;

    // Get the validation settings
    let allowType = validation.AllowType.toString();
    let data = validation.CompareOperator.toString();
    let minimum = validation.Formula1.toString();
    let maximum = validation.Formula2.toString();
    let ignoreBlank = validation.IgnoreBlank.toString();

    // Concatenate the result into a string
    let result = `Settings of Validation: \r\nAllow Type: ${allowType}\r\nData: ${data}\r\nMinimum: ${minimum}\r\nMaximum: ${maximum}\r\nIgnoreBlank: ${ignoreBlank}`;

    const outputFileName = 'GetSettingsOfDataValidation-out.txt';

    // Write the result to a txt file
    window.dotnetRuntime.Module.FS.writeFile(outputFileName, result);

    // Release the workbook object to free resources
    workbook.Dispose();

    // Read the converted file from VFS and trigger the download
    const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
    const blob = new Blob([fileArray], { type: 'text/plain' });
    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>Get Data Validation Settings</h1>
      <button onClick={sheetToSVG}>
        Start
      </button>
    </div>
  );
}

export default App;

Get data validation settings


Remove Data Validation

When the validation rules are no longer needed, you can remove data validation in bulk by cell range through the Remove method of the worksheet's DVTable. When removing, you need to pass in an array composed of rectangles, which are used to locate the ranges in the worksheet where the validations should be removed.

function App() {
  const sheetToSVG = 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 and Excel file into VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = 'RemoveDataValidation.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/static/data/`);

    // Load the workbook
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: inputFileName });

    // Create an array of rectangles, which is used to locate the ranges in the worksheet
    let rectangles = [];

    // Add a rectangle to the array. This rectangle specifies the cells from A1 to B3.
    rectangles.push(xlsModule.Rectangle.FromLTRB(0, 0, 1, 2));

    // Remove the validations in the ranges represented by the rectangles
    workbook.Worksheets.get(0).DVTable.Remove(rectangles);

    const outputFileName = 'RemoveDataValidation-out.xlsx';
    workbook.SaveToFile({ fileName: outputFileName, version: xlsModule.ExcelVersion.Version2010 });

    // Release the workbook object to free resources
    workbook.Dispose();

    // Read the converted file from VFS and trigger the 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>Remove Data Validation</h1>
      <button onClick={sheetToSVG}>
        Start
      </button>
    </div>
  );
}

export default App;

Remove data validation Remove data validation


Frequently Asked Questions

The added data validation does not take effect

Cause: Other validation rules already exist on the target cell, or the validation type or comparison operator does not match the requirement.

Solution: Make sure the validation rule is applied to the correct cell range, and check whether the values of properties such as AllowType, CompareOperator, Formula1, and Formula2 meet the expectation.

The result is empty when getting data validation settings

Cause: No data validation is set on the target cell, or the cell range being read does not match the location of the validation.

Solution: Make sure the cell has data validation set, and check whether the cell address referenced by the Range.get method is correct.

Data validation still exists after removal

Cause: The rectangle range passed to the DVTable.Remove method does not cover the actual validation area.

Solution: Adjust the coordinates in the Rectangle.FromLTRB method according to the cell range covered by the validations, ensuring that the rectangle range includes all the cells whose validations need to be removed.


Get a Free License

If you want to remove the evaluation messages in the output documents, or get rid of the feature limitations, please contact our sales team to obtain a free 30-day temporary license.

Page 1 of 4
page 1