SimplyWorks.ExportToExcel 10.0.0

dotnet add package SimplyWorks.ExportToExcel --version 10.0.0
                    
NuGet\Install-Package SimplyWorks.ExportToExcel -Version 10.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SimplyWorks.ExportToExcel" Version="10.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SimplyWorks.ExportToExcel" Version="10.0.0" />
                    
Directory.Packages.props
<PackageReference Include="SimplyWorks.ExportToExcel" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SimplyWorks.ExportToExcel --version 10.0.0
                    
#r "nuget: SimplyWorks.ExportToExcel, 10.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SimplyWorks.ExportToExcel@10.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SimplyWorks.ExportToExcel&version=10.0.0
                    
Install as a Cake Addin
#tool nuget:?package=SimplyWorks.ExportToExcel&version=10.0.0
                    
Install as a Cake Tool

GitHub Actions NuGet License: MIT

SimplyWorks.ExportToExcel

Extension methods that write any IEnumerable<T> (or IAsyncEnumerable<T>) to an .xlsx file.

  • Rows are streamed straight into the file, so memory stays flat no matter how many rows you export.
  • Targets .NET 10 and .NET 8.
dotnet add package SimplyWorks.ExportToExcel

Quick start

using SW.ExportToExcel;

using var stream = new MemoryStream();
await orders.WriteExcelAsync(stream);

This writes every readable property of a supported type, in declaration order, with the property name as the header. To choose the columns, rename them or put them in a different order, pass a map from property name to header:

await orders.WriteExcelAsync(stream, new Dictionary<string, string>
{
    ["Total"] = "Total (€)",
    ["Customer"] = "Customer",
    ["PlacedOn"] = "Date",
});

Columns come out in the order you list them. Names that don't match a property are skipped.

Computed columns

await orders.WriteExcelAsync(stream, new[]
{
    new ExcelColumn<Order>("Customer", o => o.Customer.Name),
    new ExcelColumn<Order>("City", o => o.Customer.Address.City),
    new ExcelColumn<Order>("Total incl. VAT", o => o.Total * 1.2m) { Width = 18 },
});

Dictionary and dynamic rows

Rows of type IDictionary<string, object> (including ExpandoObject) or IDictionary<string, string> are exported by key.

  • Headers: the keys found in the first rows that are read ahead (100 by default; see AutoFitSampleRows below).
  • Later rows: a key a row doesn't have leaves its cell empty.
  • Choosing columns: pass a column map to set which keys appear and in what order.
var rows = new List<Dictionary<string, object>>
{
    new() { ["Sku"] = "A-1", ["Qty"] = 3 },
    new() { ["Sku"] = "B-2", ["Qty"] = 1, ["Note"] = "fragile" },
};
await rows.WriteExcelAsync(stream);

Streaming from a database

Pass an IAsyncEnumerable<T>, such as EF Core's AsAsyncEnumerable(), and rows are written as they arrive, without loading the whole result first:

await db.Orders.Where(o => o.Year == 2026).AsAsyncEnumerable()
    .WriteExcelAsync(stream, cancellationToken: ct);

Cell types

Value Excel cell
int, long, decimal, double and the other numeric types number
bool TRUE / FALSE
DateTime, DateTimeOffset date and time (a DateTimeOffset keeps its own clock time)
DateOnly date
string, char, Guid, enums (by name), TimeSpan, TimeOnly text
null, empty string, dates before year 100 empty cell
NaN, Infinity the text NaN / Infinity

Properties of any other type, such as nested objects and collections, are skipped. Computed columns can return anything; values that aren't listed above are written as text.

Text is cleaned so that it always produces a file Excel can open: characters that XML can't carry (control characters, unpaired surrogates) are removed, and text over Excel's 32,767-character cell limit is truncated.

Options

await orders.WriteExcelAsync(stream, new ExcelExportOptions
{
    SheetName = "Orders",              // invalid characters become '_', truncated to 31
    FreezeHeaderRow = true,            // default true
    BoldHeader = true,                 // default true
    AutoFilter = true,                 // filter drop-downs on the header, default false
    AutoFitColumns = true,             // size columns from the header and the first rows, default true
    AutoFitSampleRows = 100,           // rows read ahead for sizing and dictionary keys
    MaxColumnWidth = 60,
    DateTimeFormat = "yyyy-mm-dd hh:mm", // default: Excel's built-in short date and time
    DateFormat = "yyyy-mm-dd",         // for DateOnly; default: Excel's built-in short date
});

Writing to a web response

The file is written synchronously. ASP.NET Core rejects synchronous writes to a response body, so write to a MemoryStream (or a file) first, then return that:

using var stream = new MemoryStream();
await rows.WriteExcelAsync(stream);
return File(stream.ToArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "export.xlsx");

The original API

WriteExcel(...), ExportToExcel(...) and GenerateExcel(...) are unchanged and produce the same sheets as before:

  • Columns always follow the class's property declaration order. A column map only selects and renames columns; it doesn't reorder them.
  • Booleans are written as the text true / false.
  • Only string, bool, DateTime and numeric properties are exported.
  • Every cell is written, including empty ones.

The original methods run on the same streaming writer, so they get the same speed and memory gains and the same fixes:

  • Characters XML can't carry, NaN and Infinity, over-long text, and types with nothing to export no longer break the export or the file.
  • The header row is now actually frozen; in earlier versions the freeze setting was misplaced and Excel ignored it.
  • The first column is no longer forced to a width of 4.
  • Dictionary rows are matched by key instead of by position.
  • An empty dictionary list gives an empty sheet instead of throwing.

To get ordered columns and typed cells, switch to WriteExcelAsync. The two differ only as described above.

Limits

An Excel sheet holds at most 1,048,576 rows and 16,384 columns. Larger exports are still written, but Excel won't open them; other readers may.

Upgrading from 8.x / 2.x

  • Frameworks: the package now targets net10.0 and net8.0. Projects on older frameworks can stay on 2.0.5 (netstandard2.0).
  • OpenXml 3: the library no longer uses DocumentFormat.OpenXml itself, but still depends on it, now at 3.x instead of 2.13, so projects that get it through this package keep compiling. If you use OpenXml's API directly, check its 3.0 breaking changes.
  • Output changes: the original methods' output changes only where it was broken before, as listed under The original API.

Getting support 👷

If you encounter any bugs, don't hesitate to submit an issue. We'll get back to you promptly!

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on SimplyWorks.ExportToExcel:

Package Downloads
SimplyWorks.ExcelImport

A .NET library for reading, parsing, and validating Excel files with type-safe operations, data annotation validation, and Entity Framework integration. Supports batch processing with comprehensive error handling. See GitHub for full documentation and examples.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
10.0.0 143 10/12/2026
8.0.6 125 9/29/2026
8.0.5 220 8/11/2026
8.0.4 242 7/14/2026
8.0.3 214 7/13/2026
8.0.2 230 7/13/2026
8.0.1 250 6/25/2026
8.0.0 875 9/16/2025
2.0.5 14,495 3/20/2022
2.0.3 2,848 10/23/2021
2.0.2 623 9/8/2021
2.0.0 14,818 7/30/2020