Blazing‑fast, flexible, convention‑first CSV/XLSX exporter for .NET 9+
Powered internally by two battle‑tested libraries:\
- CsvHelper --- industry‑standard CSV writer\
- SpreadCheetah --- extremely fast, fully streaming XLSX generator
PandaTech.FileExporter focuses on performance, stability, and
developer happiness.
Version 5.x is a complete redesign of 4.x --- simpler, safer,
faster. API is fully modernized (minimal APIs, DI‑friendly,
async‑ready).
⚠️ Breaking Change Notice
v5 breaks compatibility with v4. Migration is straightforward: - enums changed values --- do not reuse v4 enum values - PDF support removed (too slow, not worth maintaining) - All exporters rebuilt around a simpler, more predictable format system
- Convention‑based export (zero config)\
- Fluent export rules via
ExportRule<T>\ - Super‑fast XLSX via SpreadCheetah (safe for millions of rows)\
- CSV export using CsvHelper\
- Automatic ZIP compression when file size is large\
- Multi‑sheet XLSX for datasets > 1M rows\
- Async streaming support (
IAsyncEnumerable<T>)\ - Custom formatting & transforms\
- Minimal API ready\
- Simple DI registration\
- No controllers required
dotnet add package PandaTech.FileExportervar builder = WebApplication.CreateBuilder(args);
builder.AddFileExporter(); // scans entry assembly for ExportRule<T>app.MapGet("/export", async () =>
{
var data = new List<MyRow>
{
new() { Id = 1, Name = "Alice" },
new() { Id = 2, Name = "Bob" }
};
var file = await data.ToFileFormatAsync(ExportFormat.Xlsx);
return file.ToFileResult();
});Done. Zero configuration required.
using FileExporter.Rules;
public sealed class MyRowExportRule : ExportRule<MyRow>
{
public MyRowExportRule()
{
WithName("My Custom Export");
RuleFor(x => x.Id)
.HasOrder(0)
.HasFormat(ColumnFormatType.Integer);
RuleFor(x => x.Name)
.HasOrder(1)
.WriteToColumn("Full Name");
}
}Just add this class; it will be auto‑discovered.
ExportFormat Description
Csv UTF‑8 CSV, auto‑quote, stable for huge datasets Xlsx Multi‑sheet, streaming, low memory usage
Every file receives a timestamp:
Orders 2025-01-01 10:33:00.xlsx
Automatically sanitized for safety.
Option Description
WriteToColumn("Name") Override header text
HasOrder(1) Column ordering
Ignore() Exclude property
HasFormat(...) Text, Integer, Decimal, Currency,
Percentage, Boolean, Date, DateTime
HasPrecision(2) Decimal digit precision (not rounding, for rounding refer .Transform())
HasWidth(20) XLSX column width override
WithDefaultValue("N/A") Replaces null values
Transform(v => ...) Custom transformation
Rules support:
MixedIntAndName(default) →"1 - Active"Int→"1"Name→"Active"
- Handles millions of rows with constant memory usage\
- XLSX splits automatically into multiple sheets\
- ZIP is only applied when final file exceeds threshold\
- Async pipelines (
IAsyncEnumerable<T>) supported
- Keep DTOs simple; exporters use reflection only once\
- Add custom rules only for overrides --- conventions already
cover:
- ordering\
- decimal precision\
- date formatting\
- booleans\
- For extremely large exports: prefer
IAsyncEnumerable<T>
app.MapGet("/export/orders", async (ExportFormat format) =>
{
var orders = Enumerable.Range(1, 2000000)
.Select(i => new OrderDto { Id = i, Total = i * 1.25m });
var file = await orders.ToFileFormatAsync(format);
return file.ToFileResult();
});Exports 2M rows in under a few seconds (depending on disk/CPU).
PandaTech.FileExporter is built to stay small, clean, and blazing
fast.
If you need CSV/XLSX export without pain --- you're covered.