Skip to main content Skip to footer

How to Add a React Excel XLSX Viewer to Your Web Application

Quick Start Guide
What You Will Need
Controls Referenced

SpreadJS - React Spreadsheet Component

Documentation | Demos

Tutorial Concept Learn to integrate a client-side Excel .XLSX viewer with a secure spreadsheet component in a React web application.

Many businesses rely on spreadsheets, especially Microsoft Excel, for managing operations. Therefore, it's crucial to access and manage these files within enterprise React applications. SpreadJS, a React spreadsheet component, allows users to load, edit, and save complex XLSX files across various frameworks. In this blog, we'll demonstrate how to add an XLSX Viewer to your React 18 web application using SpreadJS. This article will guide you through importing Excel files into a user-friendly interface and protecting the React worksheet to restrict user edits.

Add Spreadsheets to Your React Enterprise Web Apps. Download SpreadJS Now!

How to Add an Excel XLSX Viewer to React Web Applications:

  1. Create a React Spreadsheet Application
  2. Add Excel Import Code
  3. Invoke the Protect and Unprotect Methods

Download the sample application to follow along with this blog.

React web app


Create a React Spreadsheet Application

First, create a React project by opening the Command Prompt window and then type the following commands:

npx create-react-app sjs-react-viewer
cd sjs-react-viewer
npm start

Install the necessary SpreadJS NPM modules in your project using the following command:

npm install @mescius/spread-sheets @mescius/spread-sheets-react @mescius/spread-sheets-io @mescius/spread-sheets-charts @mescius/spread-sheets-shapes

Import the SpreadJS CSS in your app's index.js file using the following code:

import '@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css';

At the beginning of your App.js file, import the required modules. These imports will enable access to the spreadsheet object of SpreadJS and add support for charts, shapes, and importing/exporting in the React spreadsheet instance.

import React, { Component } from "react";
import { SpreadSheets } from "@mescius/spread-sheets-react";
import * as GC from "@mescius/spread-sheets";
import "@mescius/spread-sheets-charts";
import "@mescius/spread-sheets-shapes";
import "@mescius/spread-sheets-io";

Define some constants that will be used in the application:

const passwordWrongTip = "Password is not correct!";
const alreadyProtect = "The worksheet is already protected!";
const unprotectImg = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB0UlEQVR4nO2YzU7CQBDHNyae9A30qF6NNlFv7QzhqheukN1An4Mbnv14A70YwgERX0XiWRNBKl8eMDGuGWy0LopoS0tl/8kkZLMT/r+dmW1axrS0tAKTYRjziJgCgFNEvAKAR0Tsub9pLUV72DTKsqw9ALhGRDkqaA/tZdOifD4/h4j7PxlX4gURC5QbtX/2B/PeKERqnlrBPU1vi/QR8dCyrO1kMrlAYZrmDgAcAcCTWgkA2I3EPA2j2vMAcAMA69/lJBKJDQC4VWfCiGKw6UZRT36UeU/e5heVSLGw5V6LXhMHv8g9VuBPWNhCxJoCsDVuLs2EkltjYct9QL2bME1zcdxc2qsA9FjYUq/EsPN9SwOgrsD4yuVyy5zzIue8K4SQkwz+9h8lzvlqkOadSRsXwyBOJpNZ8g1AJx+2efEBcRYEQDdCgLZvgKjMCzc0gNAVELqFfGkmW8i2bXl5cS7bTkO2mnVZrZQHa7EBqFbKUj73PwWtxQag7TSGAGgtNgCtZn0I4OH+Lj4A1bi3kG3bA8NUiVgOsQgwmAYQugJSt9Cst1An7q+UpQgBir4B0un0mhCiGYF5J5vNrrAgRN9n6BNHSO3UoZMPzLyW1j/XK1zJDTLJ864hAAAAAElFTkSuQmCC";
const protectImg = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB10lEQVR4nO2Yz0rDQBDGB0Ev+gZ6VK+iAfWWzJRe9dL3qfVQlWwR/7yBXqT0JepD2Nar0h4s2ERq3YArW4LGrdZq0qSx+8FACDvw/XZmNmQBtLS0IpNhGLNElEPESyK6QcQnInL9Z/kuJ9fAJMqyrF1EbBCRGBZyjVwLk6J8Pj9DRAc/GVfilYiKMjdp//AH88EoJmpetoK/m8EW6RHRqWVZW9lsdl6GaZrbiHiGiC9qJRBxJxHzchjVnkfEO0Rc+y4nk8msI+K9OhNGEoMtTxR154eZD+RtfFGJHMQt/1gMmjj5Re65An8BcYuIagrA5qi5ciaU3BrELf8D9W7CNM2FUXPlWgXAhbilHolx54eWBiBdgdElDmGJMyhzBo7HQIwzOAOHM6j0jmAlOvM2tMdt3FNBbGiLEiyGBpA7H7d576MaV1EAOAkCPIYGSMq854cG8HQFQLdQKE1nCx3Pie71vnBbDeE266JbLfTfpQagWy0Ix3E+RR8iLQBuqzEA4LZuUwTQrA8CNGtpb6G9lA1xtdCvRCqH2IswQAMwXQGhW2iqW4jb0En1LyVnUEkQoBwaoMdglTN4iN28De3nEixDFJL3M/KKI4524jZ05M5HZl5L65/rDc6nQtkkwmMVAAAAAElFTkSuQmCC";

Update the component App, which initializes its state to manage a selected file, spreadsheet protection status, and password. It sets up inline styles for a spreadsheet container and prepares a placeholder for the spreadsheet reference.

class App extends Component {
  constructor(props) {
    super(props);
    this.hostStyle = {
      width: "950px",
      height: "600px",
    };

    this.spread = null;
    this.state = {
      selectedFile: null,
      protectSheet: false,
      password: "",
    };
  }
}

Update the render method to extract protectSheet and password from the state and organize the layout with a flex container. It includes a div for the SpreadJS react spreadsheets component, which initializes the workbook, a sidebar containing a file input, a button to open the selected file, an image indicating sheet protection status, a password input field, and buttons to protect or unprotect the sheet, with their disabled state based on protectSheet.

  render() {
    const { protectSheet, password } = this.state;
    return (
      <div style={{ display: "flex" }}>
        <div style={{ width: "950px", height: "600px" }}>
          <SpreadSheets
            workbookInitialized={(spread) => this.initSpread(spread)}
            hostStyle={this.hostStyle}
          ></SpreadSheets>
        </div>
        <div style={{ width: "15%", padding: "20px", background: "#ddd" }}>
          <p>Open Excel Files (.xlsx)</p>
          <input type="file" onChange={this.handleFileChange} />
          <button onClick={this.handleOpenExcel}>Open Excel</button>
          <br />
          <br />
          <img
            id="protectStatus"
            style={{ height: "25px" }}
            src={protectSheet ? protectImg : unprotectImg}
          />
          <p>
            Password:
            <input
              id="protectPassword"
              type="password"
              value={password}
              onChange={(e) => this.setState({ password: e.target.value })}
            />{" "}
          </p>
          <br />
          <input
            type="button"
            value="Protect"
            id="protectBtn"
            onClick={() => {
              this.setProtectSheet();
            }}
            style={{ width: "100px" }}
            disabled={protectSheet}
          />
          <input
            type="button"
            value="Unprotect"
            id="unprotectBtn"
            onClick={() => {
              this.setUnprotectSheet();
            }}
            style={{ width: "100px", marginLeft: "10px" }}
            disabled={!protectSheet}
          />
        </div>
      </div>
    );
  }

Users can modify the workbook when it is being initialized; in this case, we want two worksheets in the instance on page load.

initSpread(spread) {
    this.spread = spread;
    this.spread.setSheetCount(2);
  }

Create empty functions for all of the needed actions. We will add the code logic for each of these functions later in this blog.

  // Get the selected Excel file
  handleFileChange = (e) => {
  };
  // Open the instance as an Excel File
  handleOpenExcel = () => {
  };
  // Unprotect the worksheet
  setUnprotectSheet() {
  };
  // Protect the workshet
  setProtectSheet() {
  };

Save all the files, and run the React app:

npm start

You have now created a React Spreadsheet app.

React Spreadsheet app


Add Excel Import Code to the React App

Importing an Excel file into the React spreadsheet application requires us to handle the change and invoke the spreadsheets import method. The handleFileChange function will be used to capture the selected Excel file when it's changed and update the component's state with the selected file.

// Get the selected Excel file
  handleFileChange = (e) => {
    this.setState({
      selectedFile: e.target.files[0],
    });
  };

The handleOpenExcel function is triggered when the user clicks the "Open Excel" button. It first checks if a file is selected. If not, it returns early. If a file is selected, it constructs import options specifying the FileType as Excel. Then, it calls the import method of the SpreadJS instance (this.spread) with the selected file and import options.

  // Open the instance as an Excel File
  handleOpenExcel = () => {
    const file = this.state.selectedFile;
    if (!file) {
      return;
    }
    // Specify the file type to ensure proper import
    const options = {
      fileType: GC.Spread.Sheets.FileType.excel,
    };
    this.spread.import(
      file,
      () => {
        console.log("Import successful");
      },
      (e) => {
        console.error("Error during import:", e);
      },
      options
    );
  };

Alternatively, you can read an Excel file from a URL on a server. Read more in this blog.

Run the app, notice an Excel (.xlsx) file can now be imported, viewed, and modified in the React spreadsheet component.

Import and export


Protect the React Spreadsheet

After successfully importing an Excel file into SpreadJS, users can easily interact with the spreadsheet data. Alternatively, you may find it necessary to restrict editing on the spreadsheet. To accomplish this, SpreadJS offers the Worksheet protect method

In the setProtectSheet() function, get the active worksheet, check to see if it is already protected, and if not, then invoke the protect method with a password if one is applied:

// Protect the worksheet
  setProtectSheet() {
    let sheet = this.spread.getActiveSheet();
    if (sheet.options.isProtected) {
      alert(alreadyProtect);
      return;
    }
    const password = this.state.password;
    sheet.protect(password);
    this.setState({
      protectSheet: true,
      password: "",
    });
  }

Allow authorized users to unprotect a worksheet to make changes by providing a password and invoking the worksheets unprotect method within the setUnprotectSheet() function.

// Unprotect the worksheet
  setUnprotectSheet() {
    const password = this.state.password;
    let sheet = this.spread.getActiveSheet();

    if (sheet.hasPassword()) {
      let success = sheet.unprotect(password);
      if (!success) {
        alert(passwordWrongTip);
        return;
      }
    } else {
      sheet.unprotect();
    }
    this.setState({
      protectSheet: false,
      password: "",
    });
  }

Run the sample app and notice users can now protect and unprotect the React spreadsheet using a password.

React Viewer Protect


Learn More About React Spreadsheet Components

This article only scratches the surface of the full capabilities of SpreadJS, a React spreadsheet component. Review the documentation to see some of the many available features, and check out our online demos to see the features in action and interact with the sample code. Integrating a spreadsheet component into your applications allows you to customize your users' experience and provide them with familiar spreadsheet functionality without referring them to an external program. Check out our video to learn more:

Tags:

comments powered by Disqus