DEV Community

Cover image for How to Import Excel Data in ASP.NET Core (Upload, Parse and Read Worksheets)
Chloe
Chloe

Posted on

How to Import Excel Data in ASP.NET Core (Upload, Parse and Read Worksheets)

Importing data from Excel is a common requirement in ASP.NET Core applications. Whether you're building an HR system, inventory platform, CRM, or financial dashboard, chances are you'll eventually need to process spreadsheet data uploaded by users.

At first glance, reading an Excel file seems straightforward: upload the file, open the workbook, and loop through the rows. In practice, real-world imports often involve validation, missing values, and data transformation before records can be used by the application.

In this article, we'll walk through the complete process of reading Excel files in ASP.NET Core. You'll learn how to:

  • Upload an Excel file from a web application
  • Open and access worksheets
  • Read data from rows and columns
  • Convert spreadsheet data into C# objects
  • Prepare imported data for further processing

By the end, you'll have a practical foundation for building Excel import features in your own applications.

Understanding the Excel Import Workflow

Before diving into code, it's helpful to understand the typical workflow of an Excel import feature.

Upload File
    ↓
Open Workbook
    ↓
Select Worksheet
    ↓
Read Rows
    ↓
Extract Values
    ↓
Map to Objects
Enter fullscreen mode Exit fullscreen mode

Excel import workflow

Most ASP.NET Core applications follow a similar process. Users upload a spreadsheet, the application reads the workbook, extracts data from specific worksheets, and then converts that data into business objects that can be validated, processed, or stored in a database.

In this tutorial, we'll use a simple employee import example to demonstrate each step.

Setting Up the Project

There are several libraries available for reading Excel files in .NET, including Open XML SDK, EPPlus, ClosedXML, and Spire.XLS.

For this tutorial, we'll use Spire.XLS for .NET because it provides a straightforward API for working with Excel files and supports common spreadsheet operations such as reading data, creating workbooks, formatting cells, and converting Excel documents.

If you're evaluating Excel libraries for a production project, the best choice will depend on your requirements, such as licensing, feature set, performance, and deployment needs. However, the overall workflow demonstrated in this article is similar regardless of the library you choose.

We'll use the following sample worksheet throughout this tutorial:

Name Email Department
John Smith john@company.com Sales
Sarah Lee sarah@company.com HR
David Chen david@company.com IT

Our goal is to read each row and convert it into a C# object that can be processed by the application.

Install Spire.XLS via NuGet:

Install-Package Spire.XLS
Enter fullscreen mode Exit fullscreen mode

Once installed, we're ready to build the upload and import functionality.

Uploading an Excel File in ASP.NET Core

The first step is allowing users to upload an Excel file to your application.

ASP.NET Core makes this straightforward through the IFormFile interface, which represents a file sent with an HTTP request.

Here's a simple API endpoint that accepts an uploaded Excel file:

[HttpPost("import")]
public IActionResult Import(IFormFile file)
{
    if (file == null || file.Length == 0)
    {
        return BadRequest("Please upload a valid Excel file.");
    }

    // Excel processing logic goes here

    return Ok();
}
Enter fullscreen mode Exit fullscreen mode

Before attempting to read the workbook, it's a good idea to perform some basic validation:

  • Ensure a file was uploaded
  • Check the file extension (.xlsx or .xls)
  • Verify the file size is within acceptable limits
var extension = Path.GetExtension(file.FileName);

if (extension != ".xlsx" && extension != ".xls")
{
    return BadRequest("Only Excel files are supported.");
}
Enter fullscreen mode Exit fullscreen mode

These checks help prevent unnecessary processing and provide better feedback to users.

File upload flow in ASP.NET Core

Opening the Workbook and Accessing a Worksheet

Once the file has been uploaded, the next step is to load it into memory and access the workbook.

A workbook represents the entire Excel file, while a worksheet represents an individual sheet inside that workbook.

Workbook vs. Worksheet hierarchy

The following example loads the uploaded file and retrieves the first worksheet:

using Spire.Xls;

using var stream = file.OpenReadStream();

Workbook workbook = new Workbook();
workbook.LoadFromStream(stream);

Worksheet sheet = workbook.Worksheets[0];
Enter fullscreen mode Exit fullscreen mode

At this point, the workbook has been loaded and is ready for worksheet access and data extraction.

If you're working with spreadsheets provided by end users, it's often worth checking that the expected worksheet actually exists before continuing.

For example, an import template might require a sheet named "Employees":

Worksheet sheet = workbook.Worksheets["Employees"];
Enter fullscreen mode Exit fullscreen mode

Using a known worksheet name can make imports more predictable and easier to maintain.

Reading Data from Rows and Columns

Now comes the core part of the import process: reading values from rows and columns.

Most Excel import scenarios involve a header row followed by data rows.

For example:

Name Email Department
John Smith john@company.com Sales
Sarah Lee sarah@company.com HR
David Chen david@company.com IT

We can loop through the worksheet and extract values from each row:

int lastRow = sheet.LastDataRow;
for (int row = 2; row <= sheet.LastRow; row++)
{
    string name = sheet.Range[row, 1].Text;
    string email = sheet.Range[row, 2].Text;
    string department = sheet.Range[row, 3].Text;

    Console.WriteLine($"{name} - {email} - {department}");
}
Enter fullscreen mode Exit fullscreen mode

Excel index explained with row and column

Notice that we start at row 2 because row 1 contains column headers.

Depending on the workbook, the last used row may include rows that contain formatting but no meaningful data, so additional validation is often recommended in production imports.

The .Text property returns the displayed value of a cell, making it a convenient choice for importing user-entered data.

Running the code above would produce output similar to:

John Smith - john@company.com - Sales
Sarah Lee - sarah@company.com - HR
David Chen - david@company.com - IT
Enter fullscreen mode Exit fullscreen mode

At this stage, we're successfully reading data from Excel. However, simply printing values isn't very useful in a real application. Typically, the next step is converting those values into business objects that can be validated, processed, and saved.

Converting Excel Data into C# Objects

In most applications, the goal isn't simply to read cell values—it's to transform spreadsheet data into objects that the rest of the application can work with.

Let's start by defining a simple model:

public class Employee
{
    public string Name { get; set; }

    public string Email { get; set; }

    public string Department { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

Instead of writing values directly to the console, we can create an Employee object for each row and add it to a collection.

List<Employee> employees = new List<Employee>();

for (int row = 2; row <= sheet.LastRow; row++)
{
    Employee employee = new Employee
    {
        Name = sheet.Range[row, 1].Text,
        Email = sheet.Range[row, 2].Text,
        Department = sheet.Range[row, 3].Text
    };

    employees.Add(employee);
}
Enter fullscreen mode Exit fullscreen mode

After the loop completes, the employees list contains all records from the worksheet and can be used throughout the application.

For example:

foreach (var employee in employees)
{
    Console.WriteLine(employee.Name);
}
Enter fullscreen mode Exit fullscreen mode

This approach keeps the Excel-reading logic separate from your business logic and makes the imported data easier to validate, process, and store.

Handling Empty Cells and Missing Values

Real-world spreadsheets are rarely perfect.

Users may leave cells blank, accidentally delete values, or upload partially completed templates.

For example:

Name Email Department
John Smith john@company.com Sales
Sarah Lee HR
David Chen david@company.com

If your application assumes every cell contains data, these missing values can cause problems later in the import process.

A simple approach is to normalize empty cells when reading them:

string name = sheet.Range[row, 1].Text?.Trim() ?? "";
string email = sheet.Range[row, 2].Text?.Trim() ?? "";
string department = sheet.Range[row, 3].Text?.Trim() ?? "";
Enter fullscreen mode Exit fullscreen mode

You can then decide how your application should handle incomplete records.

For example:

if (string.IsNullOrWhiteSpace(email))
{
    continue;
}
Enter fullscreen mode Exit fullscreen mode

In this example, rows without an email address are skipped.

Whether you skip, reject, or flag incomplete records depends on your business requirements, but it's important to account for missing values from the start.

Handling empty cells in Excel data

Saving Imported Data

Once the spreadsheet data has been converted into objects, the next step is usually storing it somewhere.

A typical workflow looks like this:

Excel File
     ↓
Employee Objects
     ↓
Validation
     ↓
Database
Enter fullscreen mode Exit fullscreen mode

Excel import data flow

For example, after building the employee collection, you might save the records using Entity Framework Core:

foreach (var employee in employees)
{
    dbContext.Employees.Add(employee);
}

await dbContext.SaveChangesAsync();
Enter fullscreen mode Exit fullscreen mode

Because database operations are typically asynchronous, the import endpoint would usually be implemented as an async action method.

The exact implementation will vary depending on your project, but the important point is that Excel data should first be converted into strongly typed objects before being persisted.

This keeps your application easier to maintain and reduces the likelihood of data-related issues later on.

Complete Example

The following example combines all the steps we've covered so far:

[HttpPost("import")]
public IActionResult Import(IFormFile file)
{
    if (file == null || file.Length == 0)
    {
        return BadRequest("Please upload a valid Excel file.");
    }

    var extension = Path.GetExtension(file.FileName);

    if (extension != ".xlsx" && extension != ".xls")
    {
        return BadRequest("Only Excel files are supported.");
    }

    List<Employee> employees = new();

    using var stream = file.OpenReadStream();

    Workbook workbook = new Workbook();
    workbook.LoadFromStream(stream);

    Worksheet sheet = workbook.Worksheets[0];

    int lastRow = sheet.LastDataRow;
    for (int row = 2; row <= sheet.Last; row++)
    {
        string name = sheet.Range[row, 1].Text?.Trim() ?? "";
        string email = sheet.Range[row, 2].Text?.Trim() ?? "";
        string department = sheet.Range[row, 3].Text?.Trim() ?? "";

        if (string.IsNullOrWhiteSpace(email))
        {
            continue;
        }

        employees.Add(new Employee
        {
            Name = name,
            Email = email,
            Department = department
        });
    }

    return Ok(employees);
}
Enter fullscreen mode Exit fullscreen mode

Upload process flowchart

This example demonstrates a simple but practical import workflow:

  1. Receive the uploaded file
  2. Open the workbook
  3. Access the worksheet
  4. Read rows and columns
  5. Create C# objects
  6. Return the imported data

In a production application, you would typically add validation, error handling, and database persistence, but the overall process remains the same.

Common Issues When Reading Excel Files

Reading data from an Excel worksheet is usually the easy part. The real challenges often appear once users start uploading files created by different people, departments, or systems.

Some of the most common issues include:

Empty Rows

Many spreadsheets contain blank rows between records or at the end of the worksheet. If these rows aren't handled properly, your import process may create empty objects or unnecessary database entries.

Mixed Data Types

Unlike a database table, Excel allows different cells within the same column to contain different data types. A column that is expected to contain numeric values may suddenly include text such as:

1001
1002
N/A
1004
Enter fullscreen mode Exit fullscreen mode

This can lead to conversion errors during processing.

Inconsistent Date Formats

Dates are one of the most common sources of import issues.

Different users may enter dates in different formats:

2026-01-15
01/15/2026
15-Jan-2026
Enter fullscreen mode Exit fullscreen mode

Problems are especially common when dates are stored as text rather than native Excel date values.

Duplicate Records

Importing customer, employee, or product data often introduces duplicate records.

For example, the same email address might appear multiple times in a worksheet, creating conflicts when data is stored in a database.

Large Excel Files

A spreadsheet containing a few hundred rows is usually easy to process. However, files containing tens of thousands of rows may require additional considerations around performance, memory usage, and request timeouts.

These issues don't prevent Excel imports from working, but they do require additional validation and error-handling logic in production environments.

Conclusion

Reading Excel files in ASP.NET Core isn't particularly difficult. In fact, with the right library, you can start extracting data from spreadsheets in just a few lines of code.

The bigger challenge is what happens after the data is read.

In real applications, imported data is often incomplete, inconsistent, or simply incorrect. That's why a successful Excel import feature isn't just about opening a workbook and looping through rows—it's about building a workflow that can handle real-world data reliably.

A good import process should not only read data, but also validate it, report errors clearly, and integrate smoothly with the rest of your application.

Once you've mastered the basics of reading Excel files, you'll be in a much better position to build robust import features for customer records, inventory systems, financial reports, and other business workflows.

What looks like a simple file upload today often becomes a critical part of an application's data pipeline tomorrow.

Top comments (0)