Blazor is a relatively new framework for building an interactive client-side web UI with the power of .NET. A common use case is being able to import your existing Excel files to your Blazor application, present the spreadsheet data to your users, allow any changes to be made, then export that data back out to an Excel file or save to a database. SpreadJS is a very powerful and extensible JavaScript spreadsheet component that makes this process easy.

If you want to follow along with this tutorial, the download for the sample can be found here.

Try SpreadJS's spreadsheet components

Download the latest version of SpreadJS

Download Now!

Creating the SpreadJS Blazor Component

Before we can put SpreadJS in a Blazor application, we must first create a Blazor component to contain SpreadJS. In this tutorial, we will be using Visual Studio 2019 and SpreadJS v14. To create a component, first start by creating a Razor Class Library:

RazorClassLibrary

For simplicity, you can name it something like "SpreadJS_Blazor_Lib":

ConfigureNewProject

After the project is created, we will need to copy the SpreadJS files to the "wwwroot" folder:

RootFolder

Creating this project should have also created a file called "exampleJSInterop.js", so we will need to edit it to add logic that will help connect the C# code to the JavaScript code of SpreadJS:

// This file is to show how a library package may provide JavaScript interop features
// wrapped in a .NET API

window.sjsAdaptor = {
    init: function (host, config) {
        if (config.hostStyle) {
            var hostStyle = config.hostStyle;
            var styles = hostStyle.split(';');
            styles.forEach((styleStr) => {
                var style = styleStr.split(':');
                host.style[style[0]] = style[1];
            });
            delete config.hostStyle;
        }

        return new GC.Spread.Sheets.Workbook(host, config);
    },

    setValue: function (host, sheetIndex, row, col, value) {
        var spread = GC.Spread.Sheets.findControl(host);
        if (spread) {
            var sheet = spread.getSheet(sheetIndex);
            sheet.setValue(row, col, value);
        }
    },

    openExcel: function (host, inputFile) {
        var spread = GC.Spread.Sheets.findControl(host);
        if (spread) {
            var excelIO = new GC.Spread.Excel.IO();
            excelIO.open(inputFile.files[0], function (json) {
                spread.fromJSON(json);
            })
        }
    }
};

The application should have also created a default "Component1.razor" file, which we can rename to "SpreadJS.razor". This will be the component we will use as a wrapper:

@using Microsoft.JSInterop
@inject IJSRuntime JSRuntime

<div @ref="host"></div>

@code {
    [Parameter]
    public int SheetCount { get; set; }

    [Parameter]
    public string HostStyle { get; set; }

    private ElementReference host;

    public void setValue(int sheetIndex, int row, int col, object value)
    {
        JSRuntime.InvokeVoidAsync("sjsAdaptor.setValue", host, sheetIndex, row, col, value);
    }

    public void OpenExcel(ElementReference inputFile)
    {
        JSRuntime.InvokeVoidAsync("sjsAdaptor.openExcel", host, inputFile);
    }

    protected override void OnAfterRender(bool firstRender)
    {
        if (firstRender)
        {
            JSRuntime.InvokeVoidAsync("sjsAdaptor.init", host, new Dictionary<string, object>() {
                { "sheetCount", SheetCount},
                { "hostStyle", HostStyle }
            });
        }
    }
}

Creating a Blazor Application with SpreadJS

Now that we have created a component with SpreadJS, we can use in in a Blazor application. To start, we can add a new project with the "Blazor WebAssemblyApp" template:

AddNewProject

To add the SpreadJS component, we will want to right-click on the Dependencies of this new project in the Solution Explorer and click "Add project reference". Our SpreadJS_Blazor_Lib should be listed as one of the options:

AddProjectReference

In this new project, there should be a Pages folder that contains a few different razor files. In this, we will want to edit the Index.razor file to set the code-behind for the HTML:

@page "/"
@using SpreadJS_Blazor_Lib

<h1>Hello, SpreadJS!</h1>
<SpreadJS SheetCount="3" HostStyle="@HostStyle" />

@code {
    private string HostStyle { get; set; } = "width:90wh;height:70vh;border: 1px solid darkgray";
}

Now we can edit the index.html file in the "wwwroot" folder. In this file, we can add references to the SpreadJS JavaScript and CSS files:

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <title>BlazorApp1</title>
    <base href="/" />
    <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
    <link href="css/app.css" rel="stylesheet" />


    <link href="_content/SJS_Blazor_Lib/sjs/css/gc.spread.sheets.excel2013white.14.1.0.css" rel="stylesheet" />
    <script src="_content/SJS_Blazor_Lib/sjs/scripts/gc.spread.sheets.all.14.1.0.min.js" type="text/javascript"></script>
    <script src="_content/SJS_Blazor_Lib/sjs/scripts/interop/gc.spread.excelio.14.1.0.min.js" type="text/javascript"></script>
    <script src="_content/SJS_Blazor_Lib/exampleJsInterop.js" type="text/javascript"></script>
</head>

<body>
    <app>Loading...</app>

    <div id="blazor-error-ui">
        An unhandled error has occurred.
        <a href="" class="reload">Reload</a>
        <a class="dismiss">??</a>
    </div>
    <script src="_framework/blazor.webassembly.js"></script>
</body>

</html>
@page "/"

@using SJS_Blazor_Lib

<h1>Hello, SpreadJS!</h1>

<table>
    <tr>
        <td>
            <label>Sheet Index</label>
            <input @bind-value="@SheetIndex" />
        </td>
        <td>
            <label>Row Index</label>
            <input @bind-value="@Row" />
        </td>
        <td>
            <label>Column Index</label>
            <input @bind-value="@Column" />
        </td>
        <td>
            <lable>Value</lable>
            <input @bind-value="@Value" />
        </td>
    </tr>
    <tr>
        <td>
            <button @onclick="doSomething">Update Text</button>
        </td>
    </tr>
    <tr>
        <td>
            <input type="file" @ref="inputFileEle" />
        </td>
        <td>
            <button @onclick="ImportExcel">Import File</button>
        </td>
    </tr>
</table>
<br />
<SpreadJS SheetCount="3" HostStyle="@HostStyle" @ref="ss" />


@code {
    private SpreadJS ss;

    private ElementReference inputFileEle;

    public int SheetIndex { get; set; } = 0;

    public int Row { get; set; } = 0;

    public int Column { get; set; } = 0;

    public string Value { get; set; } = "";

    private string HostStyle { get; set; } = "width:90wh;height:70vh;border: 1px solid darkgray";

    private void doSomething()
    {
        ss.setValue(SheetIndex, Row, Column, Value);
    }

    private void ImportExcel()
    {
        ss.OpenExcel(inputFileEle);
    }
}

That is all that is needed to run SpreadJS in a Blazor application:

SpreadJS

Excel Import/Export

The previous code was just a basic usage of SpreadJS in a Blazor application, but we can add to it by including some Excel Import/Export functionality. With the power of SpreadJS, you can import and export your own Excel files within your Blazor applications. The implementation is similar to the basic SpreadJS Blazor code, but we would simply need to edit the Index.razor file to add some code for setting values and opening Excel files:

@page "/"

@using SpreadJS_Blazor_Lib

<h1>Hello, SpreadJS!</h1>

<table>
    <tr>
        <td>
            <label>Sheet Index</label>
            <input @bind-value="@SheetIndex" />
        </td>
        <td>
            <label>Row Index</label>
            <input @bind-value="@Row" />
        </td>
        <td>
            <label>Column Index</label>
            <input @bind-value="@Column" />
        </td>
        <td>
            <lable>Value</lable>
            <input @bind-value="@Value" />
        </td>
    </tr>
    <tr>
        <td>
            <button @onclick="doSomething">Update Text</button>
        </td>
    </tr>
    <tr>
        <td>
            <input type="file" @ref="inputFileEle" @onchange="ImportExcel" />
        </td>
    </tr>
</table>
<br />
<SpreadJS SheetCount="3" HostStyle="@HostStyle" @ref="ss" />


@code {
    private SpreadJS ss;

    private ElementReference inputFileEle;

    public int SheetIndex { get; set; } = 0;

    public int Row { get; set; } = 0;

    public int Column { get; set; } = 0;

    public string Value { get; set; } = "";

    private string HostStyle { get; set; } = "width:90wh;height:70vh;border: 1px solid darkgray";

    private void doSomething()
    {
        ss.setValue(SheetIndex, Row, Column, Value);
    }

    private void ImportExcel()
    {
        ss.OpenExcel(inputFileEle);
    }
}

This blog showed how you can implement SpreadJS in your own Blazor applications and leverage the power of .NET. To give this a try and see what other amazing features SpreadJS has, download a trial today!

Try SpreadJS's spreadsheet components

Download the latest version of SpreadJS

Download Now!