Descargar archivo de Excel en ASP .NET C#: Exportar datos a XLSX, CSV y más
Implementing spreadsheet export functionality is a common requirement for enterprise web applications, yet the manual process of generating and delivering these files often introduces significant technical complexity. Developers must frequently navigate the nuances of MemoryStream management and configure precise HTTP content-disposition headers to ensure consistent browser behavior and prevent data corruption.
This article walks through everything needed to create and download Excel file in ASP .NET C# MVC controllers using the IronXL library. We'll cover exporting data to real Excel files in XLSX format, streaming CSV files, converting uploads for re-export, and returning file downloads to the browser, all without installing Microsoft Office or relying on Excel Interop. Install the IronXL NuGet package and start a free trial to follow along with the source code examples.
How to Create and Download an Excel File from a Controller?
The core pattern for any download excel file in ASP.NET Core scenario involves three steps: create the workbook, write it to a stream, and return the stream as a file response. The following code shows a complete MVC controller action that builds an XLSX file from scratch and pushes it to the browser.
using IronXL;
using Microsoft.AspNetCore.Mvc;
public class ReportController : Controller
{
// Export employee data as a downloadable Excel file
public IActionResult DownloadExcel()
{
// Create a new workbook and worksheet
var workbook = WorkBook.Create(ExcelFileFormat.XLSX);
var worksheet = workbook.CreateWorkSheet("Employees");
// Add header row with column names
worksheet["A1"].Value = "Name";
worksheet["B1"].Value = "Department";
worksheet["C1"].Value = "Salary";
// Populate cells with data values
worksheet["A2"].Value = "Alice Torres";
worksheet["B2"].Value = "Engineering";
worksheet["C2"].Value = 95000;
worksheet["A3"].Value = "James Park";
worksheet["B3"].Value = "Marketing";
worksheet["C3"].Value = 78000;
// Export workbook to a MemoryStream for download
var stream = workbook.ToStream();
string filename = "Employees.xlsx";
var content = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
// Return file to the browser with content disposition attachment
return File(stream, content, filename);
}
}
using IronXL;
using Microsoft.AspNetCore.Mvc;
public class ReportController : Controller
{
// Export employee data as a downloadable Excel file
public IActionResult DownloadExcel()
{
// Create a new workbook and worksheet
var workbook = WorkBook.Create(ExcelFileFormat.XLSX);
var worksheet = workbook.CreateWorkSheet("Employees");
// Add header row with column names
worksheet["A1"].Value = "Name";
worksheet["B1"].Value = "Department";
worksheet["C1"].Value = "Salary";
// Populate cells with data values
worksheet["A2"].Value = "Alice Torres";
worksheet["B2"].Value = "Engineering";
worksheet["C2"].Value = 95000;
worksheet["A3"].Value = "James Park";
worksheet["B3"].Value = "Marketing";
worksheet["C3"].Value = 78000;
// Export workbook to a MemoryStream for download
var stream = workbook.ToStream();
string filename = "Employees.xlsx";
var content = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
// Return file to the browser with content disposition attachment
return File(stream, content, filename);
}
}
Imports IronXL
Imports Microsoft.AspNetCore.Mvc
Public Class ReportController
Inherits Controller
' Export employee data as a downloadable Excel file
Public Function DownloadExcel() As IActionResult
' Create a new workbook and worksheet
Dim workbook = WorkBook.Create(ExcelFileFormat.XLSX)
Dim worksheet = workbook.CreateWorkSheet("Employees")
' Add header row with column names
worksheet("A1").Value = "Name"
worksheet("B1").Value = "Department"
worksheet("C1").Value = "Salary"
' Populate cells with data values
worksheet("A2").Value = "Alice Torres"
worksheet("B2").Value = "Engineering"
worksheet("C2").Value = 95000
worksheet("A3").Value = "James Park"
worksheet("B3").Value = "Marketing"
worksheet("C3").Value = 78000
' Export workbook to a MemoryStream for download
Dim stream = workbook.ToStream()
Dim filename As String = "Employees.xlsx"
Dim content = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
' Return file to the browser with content disposition attachment
Return File(stream, content, filename)
End Function
End Class
Archivo de Excel de salida

The WorkBook.Create method generates a new Excel document, and CreateWorkSheet adds the first worksheet to it. After populating cells with values, the ToStream method converts the entire workbook into a MemoryStream, no temporary files touch the disk. The File() return method on the controller sets the content disposition header to attachment, which tells the browser to download the file rather than try to render it. The third parameter controls what the file name appears as in the user's download dialog.
This public IActionResult pattern works across .NET Framework and ASP.NET Core projects alike, making it the go-to approach for web applications that need to export data to Excel.
How to Export Database Data to a Downloadable Spreadsheet?
Most real-world scenarios involve exporting data from a database table rather than hardcoded values. The pattern stays the same, query the data, populate worksheets, and return the file. Here's an example that simulates pulling records from a database and writing them into an Excel document.
using IronXL;
using Microsoft.AspNetCore.Mvc;
public class DataExportController : Controller
{
// Export database records to an xlsx file for download
public IActionResult ExportDatabaseReport()
{
// Simulate a database query returning order records
var orders = new[]
{
new { OrderId = 1001, Customer = "Acme Corp", Total = 4500.00m },
new { OrderId = 1002, Customer = "Globex Inc", Total = 12300.50m },
new { OrderId = 1003, Customer = "Initech LLC", Total = 890.75m },
};
var workbook = WorkBook.Create(ExcelFileFormat.XLSX);
var worksheet = workbook.CreateWorkSheet("Orders");
// Write headers
worksheet["A1"].Value = "Order ID";
worksheet["B1"].Value = "Customer";
worksheet["C1"].Value = "Total";
// Write each row of data from the query results
for (int i = 0; i < orders.Length; i++)
{
int row = i + 2;
worksheet[$"A{row}"].Value = orders[i].OrderId;
worksheet[$"B{row}"].Value = orders[i].Customer;
worksheet[$"C{row}"].Value = orders[i].Total;
}
var stream = workbook.ToStream();
string filename = $"OrderReport-{DateTime.Now:yyyyMMdd}.xlsx";
return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", filename);
}
}
using IronXL;
using Microsoft.AspNetCore.Mvc;
public class DataExportController : Controller
{
// Export database records to an xlsx file for download
public IActionResult ExportDatabaseReport()
{
// Simulate a database query returning order records
var orders = new[]
{
new { OrderId = 1001, Customer = "Acme Corp", Total = 4500.00m },
new { OrderId = 1002, Customer = "Globex Inc", Total = 12300.50m },
new { OrderId = 1003, Customer = "Initech LLC", Total = 890.75m },
};
var workbook = WorkBook.Create(ExcelFileFormat.XLSX);
var worksheet = workbook.CreateWorkSheet("Orders");
// Write headers
worksheet["A1"].Value = "Order ID";
worksheet["B1"].Value = "Customer";
worksheet["C1"].Value = "Total";
// Write each row of data from the query results
for (int i = 0; i < orders.Length; i++)
{
int row = i + 2;
worksheet[$"A{row}"].Value = orders[i].OrderId;
worksheet[$"B{row}"].Value = orders[i].Customer;
worksheet[$"C{row}"].Value = orders[i].Total;
}
var stream = workbook.ToStream();
string filename = $"OrderReport-{DateTime.Now:yyyyMMdd}.xlsx";
return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", filename);
}
}
Imports IronXL
Imports Microsoft.AspNetCore.Mvc
Public Class DataExportController
Inherits Controller
' Export database records to an xlsx file for download
Public Function ExportDatabaseReport() As IActionResult
' Simulate a database query returning order records
Dim orders = New() {
New With {.OrderId = 1001, .Customer = "Acme Corp", .Total = 4500.0D},
New With {.OrderId = 1002, .Customer = "Globex Inc", .Total = 12300.5D},
New With {.OrderId = 1003, .Customer = "Initech LLC", .Total = 890.75D}
}
Dim workbook = WorkBook.Create(ExcelFileFormat.XLSX)
Dim worksheet = workbook.CreateWorkSheet("Orders")
' Write headers
worksheet("A1").Value = "Order ID"
worksheet("B1").Value = "Customer"
worksheet("C1").Value = "Total"
' Write each row of data from the query results
For i As Integer = 0 To orders.Length - 1
Dim row As Integer = i + 2
worksheet($"A{row}").Value = orders(i).OrderId
worksheet($"B{row}").Value = orders(i).Customer
worksheet($"C{row}").Value = orders(i).Total
Next
Dim stream = workbook.ToStream()
Dim filename As String = $"OrderReport-{DateTime.Now:yyyyMMdd}.xlsx"
Return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", filename)
End Function
End Class
Resultado

In production, the orders array would come from an Entity Framework Core query, a Dapper call, or any data access layer connected via a connection string to the database. The loop iterates through results and writes each value into the correct cells on the worksheet. Note how the string filename includes a date stamp, a small detail that saves headaches when users download files repeatedly.
IronXL's cell addressing system (worksheet[$"A{row}"]) keeps things readable, and the WorkBook API handles all the heavy lifting of building a valid XLSX file internally. For more complex scenarios involving formulas, styling, or multi-sheet workbooks, the same approach scales cleanly.
How to Download Data as CSV Files Instead of XLSX?
Sometimes a lightweight CSV file is the better choice, particularly when feeding data into other systems, databases, or tools that don't need the rich set of features in a real Excel file. IronXL makes switching between formats trivial.
using IronXL;
using Microsoft.AspNetCore.Mvc;
public class CsvController : Controller
{
// Export data as a CSV file download
public IActionResult ExportCsv()
{
var workbook = WorkBook.Create(ExcelFileFormat.XLSX);
var worksheet = workbook.CreateWorkSheet("Products");
worksheet["A1"].Value = "SKU";
worksheet["B1"].Value = "Product";
worksheet["C1"].Value = "Price";
worksheet["A2"].Value = "WDG-001";
worksheet["B2"].Value = "Widget Pro";
worksheet["C2"].Value = 29.99;
// Convert to CSV stream instead of XLSX
var stream = workbook.ToCsvStream();
string filename = "Products.csv";
return File(stream, "text/csv", filename);
}
}
using IronXL;
using Microsoft.AspNetCore.Mvc;
public class CsvController : Controller
{
// Export data as a CSV file download
public IActionResult ExportCsv()
{
var workbook = WorkBook.Create(ExcelFileFormat.XLSX);
var worksheet = workbook.CreateWorkSheet("Products");
worksheet["A1"].Value = "SKU";
worksheet["B1"].Value = "Product";
worksheet["C1"].Value = "Price";
worksheet["A2"].Value = "WDG-001";
worksheet["B2"].Value = "Widget Pro";
worksheet["C2"].Value = 29.99;
// Convert to CSV stream instead of XLSX
var stream = workbook.ToCsvStream();
string filename = "Products.csv";
return File(stream, "text/csv", filename);
}
}
Imports IronXL
Imports Microsoft.AspNetCore.Mvc
Public Class CsvController
Inherits Controller
' Export data as a CSV file download
Public Function ExportCsv() As IActionResult
Dim workbook = WorkBook.Create(ExcelFileFormat.XLSX)
Dim worksheet = workbook.CreateWorkSheet("Products")
worksheet("A1").Value = "SKU"
worksheet("B1").Value = "Product"
worksheet("C1").Value = "Price"
worksheet("A2").Value = "WDG-001"
worksheet("B2").Value = "Widget Pro"
worksheet("C2").Value = 29.99
' Convert to CSV stream instead of XLSX
Dim stream = workbook.ToCsvStream()
Dim filename As String = "Products.csv"
Return File(stream, "text/csv", filename)
End Function
End Class
Fichero CSV de salida

The ToCsvStream method exports the first worksheet as a CSV-formatted MemoryStream. CSV files work great for data interchange, but they strip out any formatting, formulas, and multi-sheet structure. When you need those features, stick with the XLSX file format via ToStream() or ToXlsxStream(). For a deeper look at format conversions, refer to the spreadsheet conversion guide.
How to Re-Export an Upload in a Different Format?
A common web application scenario involves accepting uploaded files from users and exporting them in another format, say, converting an XLS upload to XLSX, or producing CSV files from a workbook originally saved in a legacy format.
public IActionResult ConvertUpload(IFormFile upload)
{
using var memoryStream = new MemoryStream();
upload.CopyTo(memoryStream);
memoryStream.Position = 0;
// Load uploaded Excel file from the stream
var workbook = WorkBook.Load(memoryStream);
// Re-export as XLSX regardless of the original file extension or file type
var stream = workbook.ToXlsxStream();
string filename = Path.GetFileNameWithoutExtension(upload.FileName) + ".xlsx";
return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", filename);
}
public IActionResult ConvertUpload(IFormFile upload)
{
using var memoryStream = new MemoryStream();
upload.CopyTo(memoryStream);
memoryStream.Position = 0;
// Load uploaded Excel file from the stream
var workbook = WorkBook.Load(memoryStream);
// Re-export as XLSX regardless of the original file extension or file type
var stream = workbook.ToXlsxStream();
string filename = Path.GetFileNameWithoutExtension(upload.FileName) + ".xlsx";
return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", filename);
}
Imports Microsoft.AspNetCore.Mvc
Imports System.IO
Public Function ConvertUpload(upload As IFormFile) As IActionResult
Using memoryStream As New MemoryStream()
upload.CopyTo(memoryStream)
memoryStream.Position = 0
' Load uploaded Excel file from the stream
Dim workbook = WorkBook.Load(memoryStream)
' Re-export as XLSX regardless of the original file extension or file type
Dim stream = workbook.ToXlsxStream()
Dim filename As String = Path.GetFileNameWithoutExtension(upload.FileName) & ".xlsx"
Return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", filename)
End Using
End Function
Resultado: Converting CSV to XLSX Format

The WorkBook.Load method accepts a MemoryStream, so there's no need to save uploaded files to disk first. It auto-detects whether the source is an XLS, XLSX, or CSV file and parses it accordingly. From there, ToXlsxStream() generates a clean new MemoryStream in the modern XLSX format, every byte properly structured. This is useful for normalizing user submissions before further processing or storage.
Which File Formats Can Be Exported?
IronXL supports exporting data to multiple spreadsheet and data interchange formats. The table below summarizes the available output options and their best uses.
| Formato| File Extension | Stream Method | Best Use Case | | ---| ---| ---| ---| | XLSX | .xlsx | ToXlsxStream() | Modern Excel spreadsheets with formatting and formulas | | XLS | .xls | ToXlsStream() | Legacy system compatibility | | CSV | .csv | ToCsvStream() | Database imports, data pipelines, lightweight export | | XML | .xml | ToXmlStream() | Enterprise system integration | | JSON | .json | SaveAsJson() | Web API responses and data exchange | | HTML | .html | ExportToHtml() | Web page display of spreadsheet data |
Every stream method returns a MemoryStream that plugs directly into ASP.NET Core's File() return helper. The byte array alternative (ToByteArray()) is also available for scenarios where a byte[] is more convenient, for example, when saving to a blob database or attaching to an email response stream. All of these methods are available immediately after installing the IronXL NuGet package. For a complete walkthrough of each export format, see the export to Excel documentation.
Whether the goal is to download files in XLSX format for business analysts, export CSV files for data engineers, or generate XML for enterprise integration, IronXL keeps the code clean and the output reliable across .NET Core and .NET Framework applications. Ready to ship spreadsheet exports in your next project? Get a free trial license or explore licensing options to get started today. For step-by-step setup instructions, refer to the IronXL getting started guide.
Preguntas Frecuentes
¿Cómo puedo descargar un archivo Excel en ASP.NET Core usando C#?
Puede descargar un archivo de Excel en ASP.NET Core con C# utilizando IronXL. IronXL permite exportar datos a varios formatos, como XLSX, CSV y XML, directamente desde los controladores MVC. Esto se puede gestionar eficientemente con MemoryStream y el método File().
¿Cuáles son los beneficios de utilizar IronXL para exportar archivos Excel?
IronXL simplifica la exportación de archivos de Excel mediante la gestión eficaz de MemoryStream y la configuración de encabezados HTTP de disposición de contenido. Garantiza un comportamiento uniforme del navegador y evita la corrupción de datos, lo que lo hace ideal para aplicaciones web empresariales.
¿A qué formatos de archivo puede IronXL exportar datos?
IronXL puede exportar datos a múltiples formatos de archivo, como XLSX, CSV y XML. Esta versatilidad permite a los desarrolladores gestionar sin problemas diferentes requisitos de exportación de datos.
¿Qué desafíos técnicos ayuda IronXL a superar al exportar archivos Excel?
IronXL ayuda a superar desafíos como la gestión de MemoryStream y la configuración de encabezados HTTP precisos para la disposición de contenido. Estas funciones garantizan que los archivos Excel exportados sean procesados correctamente por los navegadores y evitan la corrupción de datos.
¿Se puede utilizar IronXL para exportar datos desde controladores MVC?
Sí, IronXL se puede usar para exportar datos desde controladores MVC. Ofrece una forma sencilla de exportar datos en formato Excel, lo que lo convierte en una opción práctica para aplicaciones web ASP.NET Core .
¿Cómo IronXL mejora el proceso de generación de archivos Excel?
IronXL mejora el proceso al automatizar tareas complejas como MemoryStream y la gestión de encabezados HTTP, lo que permite a los desarrolladores centrarse en la funcionalidad principal en lugar de en las complejidades técnicas.



