How to Export Data to Excel Files with ASP.NET Core Minimal API

How to Export Data to Excel Files with ASP.NET Core Minimal API
Mount Ida between Balıkesir Province and Çanakkale Province. 

As a developer, you may need to work with file-based data sources, and exporting data to Excel files is a common requirement in many applications. In this article, we'll explore how to export data to Excel files in a ASP.NET Core application using the MiniExcel library. We'll start by creating a new web API project and adding the MiniExcel dependency. Then, we'll create a model class for the data we want to export and configure our API to export the data to an Excel file using MiniExcel. By the end of this article, you'll have a working example of how to export data to Excel files in your ASP.NET Core application. Let's get started!

Creating the Application

First, let’s create the application.

dotnet new webapi -n "ExportExcel"

Adding the Dependencies

Let’s download the MiniExcel dependency that we’ll be using later. For that, you can download it via the link MiniExcel NuGet or add the code below in the project’s .csproj file:

<PackageReference Include="MiniExcel" Version="1.30.2" />

Note that in this example .NET version 7.0 will be used and the MiniExcel version is 1.30.2. Make sure you use compatible versions of both.

Creating the Model Classes

Model class will be Todo, which will contain the fields corresponding to the header of the Excel file.

So, create a new folder called Todos and inside it the class below:

using MiniExcelLibs.Attributes;

namespace ExportExcel.Todos;

public class Todo
{
	[ExcelColumn(Name = "Id", Index = 0, Width = 40)]
	public Guid Id { get; set; }

	[ExcelColumn(Name = "Title", Index = 1, Width = 100)]
	public string Title { get; set; } = default!;

	[ExcelColumn(Ignore = true)]
	public bool IsComplete { get; set; }

	public static IEnumerable<Todo> GetList()
	{
		return new List<Todo>()
		{
			new Todo{
				Id = Guid.NewGuid(),
				Title = "Write an article about export excel.",
				IsComplete = true
			},
			new Todo{
				Id = Guid.NewGuid(),
				Title = "Code review: davidfowl/TodoApi",
				IsComplete = true
			},
			new Todo{
				Id = Guid.NewGuid(),
				Title = "Read 'Implementing Domain Driven Design' book. https://abp.io/books/implementing-domain-driven-design",
				IsComplete = true
			},
			new Todo{
				Id = Guid.NewGuid(),
				Title = "Make a plan for next week.",
				IsComplete = false
			},
		};
	}
}
  • With ExcelColumnAttribute you can specify column name, index and more. It is not required, but it is one of the attributes you can use when you want to customize your Excel table while using MiniExcel.
  • GetList method returns the Todo list. In order not to deviate from the purpose of the article, I do not use a database.

And now a brief pause for a personal note

Topkapı Palace Museum in Istanbul, Turkey.

I want to make sure that my newsletter is meeting your needs and providing you with valuable content. That's why I am taking a brief pause to ask for your input.

My next articles will be shaped according to your demands, so I want to hear from you! What topics would you like to see covered in future newsletters? Is there anything specific you're struggling with that you'd like to see addressed in our content?

Simply reply to this email and let me know your thoughts. I value your feedback and look forward to incorporating your suggestions into our upcoming newsletters.

Performing the Writing of the Excel File

Now, let's configure our relevant API under the Todos folder.

using Microsoft.AspNetCore.Http.HttpResults;
using MiniExcelLibs;

namespace ExportExcel.Todos
{
	internal static class TodoApi
	{
		public static RouteGroupBuilder MapTodos(this IEndpointRouteBuilder routes)
		{
			var group = routes.MapGroup("/todos");

			group.WithTags("Todos");

			group.MapGet("/", async () => await Task.FromResult(Todo.GetList()));

			group.MapGet("/export", async Task<Results<FileStreamHttpResult, NotFound>> (bool isComplete, CancellationToken token) =>
			{
				var filteredList = Todo.GetList().Where(x => x.IsComplete == isComplete).ToList();
				if (filteredList.Count == 0)
				{
					return TypedResults.NotFound();
				}

				var memoryStream = new MemoryStream();
				await memoryStream.SaveAsAsync(filteredList, cancellationToken: token);
				memoryStream.Seek(0, SeekOrigin.Begin);
				return TypedResults.File(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "todos.xlsx");
			});

			return group;
		}
	}
}

This code block determines a static class TodoApi with a single method MapTodos. The method extends the IEndpointRouteBuilder interface by adding new endpoints for todos.

The MapTodos method generates a new route group with the base path /todos and the tag Todos. The group has two defined endpoints:

  • The first endpoint maps a HTTP GET request to the base path and returns a list of todos.
  • The second endpoint maps a HTTP GET request to /export and returns a file stream of an Excel file containing a filtered list of todos. The filter is based on the boolean parameter isComplete passed in the request URL. If the filtered list is empty, it returns a NotFound HTTP result. Otherwise, it saves the filtered list to a memory stream using the MiniExcel library and returns the memory stream as a file.

We used TypedResults as the return value instead of Results because TypedResults is the implementation type that automatically provides the response type metadata for OpenAPI to describe the endpoint.

Note: If you are using minimal API with ASP.NET Core, I recommend grouping the endpoints in separate extension methods, as above, for code maintainability.

Finally, let's use our MapTodos extention method in our Program class as follows:

using ExportExcel.Todos;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.Map("/", () => Results.Redirect("/swagger"));

// Configure the APIs
app.MapTodos(); // added this line

app.Run();

Executing the Application

Now, just run the project and the Swagger interface will open in the browser as shown in the picture below:

Conclusion

In this article, we learned how to export data to Excel files from a .NET application using the MiniExcel library. We started by creating a model class for the data we wanted to export, and then added endpoints to our application using the IEndpointRouteBuilder interface to enable exporting data as Excel files. We used the MiniExcel library to write the data to an Excel file and return it as a file stream.

Exporting data to Excel files is a common requirement in many applications, and with the MiniExcel library, it's a straightforward process in .NET. By following the steps outlined in this article, you can easily export data to Excel files from your .NET applications, enabling your users to work with the data in their preferred format.

You can find the completed source code here.

Thanks for reading! If you enjoyed this newsletter, please share it with your friends and / or subscribe!

Read more

[TR] İş hayatına nasıl daha kolay adapte olunur? Yeni mezunlar nelere dikkat etmeli?

[TR] İş hayatına nasıl daha kolay adapte olunur? Yeni mezunlar nelere dikkat etmeli?

Herkese merhaba, bu yazıda Engincan Veske ile birlikte açtığımız yeni podcast kanalının (dotcode), ikinci bölümünde konuştuğumuz “İş hayatına nasıl daha kolay adapte olunur? Yeni mezunlar nelere dikkat etmeli?” konusuna hazırlanırken çıkardığım notlardan bahsediyor olacağım. Bu bölüm için hazırlanırken birkaç maddeden oluşan notlar çıkardım. Kendi tecrübe ettiğim şeyleri listelemek ve bunları