Gooseberry.ExcelStreaming 1.6.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Gooseberry.ExcelStreaming --version 1.6.0
                    
NuGet\Install-Package Gooseberry.ExcelStreaming -Version 1.6.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="Gooseberry.ExcelStreaming" Version="1.6.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Gooseberry.ExcelStreaming" Version="1.6.0" />
                    
Directory.Packages.props
<PackageReference Include="Gooseberry.ExcelStreaming" />
                    
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 Gooseberry.ExcelStreaming --version 1.6.0
                    
#r "nuget: Gooseberry.ExcelStreaming, 1.6.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 Gooseberry.ExcelStreaming@1.6.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=Gooseberry.ExcelStreaming&version=1.6.0
                    
Install as a Cake Addin
#tool nuget:?package=Gooseberry.ExcelStreaming&version=1.6.0
                    
Install as a Cake Tool

Gooseberry.ExcelStreaming

NuGet

Create Excel files with high performance and low memory allocations.

Features

  • Extremely fast streaming write (100 columns * 100 000 rows in 0.65 second, 20Kb allocated memory)
  • Most basic excel column types are supported (incl. hyperlinks)
  • Shared strings and utf8 binary strings
  • Cell formatting, styling and merging
  • Basic pictures support
  • Asynchronous compression
  • Used in heavy-load production environment

Create Excel file

await using var file = new FileStream("myExcelReport.xlsx", FileMode.Create);

await using var writer = new ExcelWriter(file, token: cancellationToken);

// optional sheet configuration
var sheetConfig = new SheetConfiguration(
    Columns: [new Column(Width: 10m), new Column(Width: 13m)], // column width
    FrozenColumns: 1, // freeze pane: colums count
    FrozenRows: 3, // freeze pane: rows count
    ShowGridLines: true);

await writer.StartSheet("First sheet", sheetConfig);

writer.AddEmptyRows(3); // three empty rows

await foreach(var record in store.GetRecordsAsync(cancellationToken))
{
    await writer.StartRow();

    writer.AddEmptyCell(); // empty
    writer.AddEmptyCells(5); // five empty cells
    writer.AddCell(42); // int
    writer.AddCell(DateTime.Now.Ticks); // long
    writer.AddCell(DateTime.Now); // DateTime
    writer.AddCell(123.765M); // decimal
    writer.AddCell(Math.PI); //double
    writer.AddCell("string"); // string
    writer.AddCell('#'); // char
    writer.AddCellUtf8String("string"u8); // utf8 string
    writer.AddCellSharedString("shared"); // shared string
    // hyperlink
    writer.AddCell(new Hyperlink("https://[address]", "Label text")); 
    // cell with picture
    writer.AddCellPicture(someStreamOrByteArray, PictureFormat.Jpeg, new Size(100, 130));
}

// Adding picture from stream to "First sheet" placed to
// cell (column 4, row 2, values are zero-based) with fixed size
writer.AddPicture(someStream, PictureFormat.Jpeg, new AnchorCell(3, 1), new Size(100, 130));

// Adding picture from byte array or ReadOnlyMemory<byte> to "First sheet" 
// with top left corner placed in the cell (column 11:row 2, values are zero-based) 
// and right bottom corner is placed in another cell (column 16:row 11)
writer.AddPicture(someByteArray, PictureFormat.Jpeg, new AnchorCell(10, 1), new AnchorCell(15, 10));


await writer.StartSheet("Second sheet");
for (var row = 0; row < 100; row++)
{
   ... //write rows
}

await writer.Complete(); // DisposeAsync method also will call Complete

More examples

IUtf8SpanFormattable support (.net8+)###

Effective way to write standard and custom types to cell without string allocation.

//write any IUtf8SpanFormattable value as string cell or numeric cell
//format, format provider and styles are optional

writer.AddCellString(Guid.NewGuid(), ['N']);  

float value = 0.3f;
writer.AddCellNumber(value);

Write Excel file to Http response

The data isn't accumulated in memory. It is flushed to Http response streamingly.

Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.Headers.Add("Content-Disposition", $"attachment; filename=fileName.xlsx");

await Response.StartAsync();

await using var writer = new ExcelWriter(Response.BodyWriter.AsStream(), token: cancellationToken);

await writer.StartSheet("Sheet name");
await writer.StartRow();
writer.AddCell(123);

await writer.Complete();

Row Attributes


//add row with specified height
await writer.StartRow(height: 15);

//or specify optional row attributes
await writer.StartRow(new RowAttributes(
    Height: 25, 
    OutlineLevel: 1,
    IsCollapsed: true,
    IsHidden: true)); 

Using styles

// 1. Define styles

var styleBuilder = new StylesSheetBuilder();

staticSomeStyle = styleBuilder.GetOrAdd(
    new Style(
        Format: "0.00%",
        Font: new Font(Size: 24, Color: Color.DodgerBlue),
        Fill: new Fill(Color: Color.Crimson, FillPattern.Gray125),
        Borders: new Borders(
            Left: new Border(BorderStyle.Thick, Color.BlueViolet),
            Right: new Border(BorderStyle.MediumDashed, Color.Coral)),
        Alignment: new Alignment(HorizontalAlignment.Center, VerticalAlignment.Center, false)));

// 2. Build styles. We can reuse single style sheet many times to increase performance. 
//    Style sheet is immutable and thread safe.

staticStyleSheet = styleBuilder.Build();

// 3. Using styles

await using var writer = new ExcelWriter(file, staticStyleSheet);

await writer.StartSheet("First sheet");
await writer.StartRow(15); //optional row height specified

writer.AddCell(123, staticSomeStyle);  // all cells support style reference

await writer.Complete();

Shared strings

Shared strings decrease the size of the resulting file when it contains repeated strings. It's implemented as unique list of strings, and cell contains only reference to the list index.

// 1. We can use global shared strings table

var tableBuilder = new SharedStringTableBuilder();

staticSharedStringRef1 = tableBuilder.GetOrAdd("String");
staticSharedStringRef2 = tableBuilder.GetOrAdd("Another String");

// 2. Build table

staticSharedStringTable = sharedStringTableBuilder.Build();

// 3. Using shared strings

await using var writer = new ExcelWriter(stream, sharedStringTable: staticSharedStringTable);

await writer.StartSheet("First sheet");
await writer.StartRow();

// using refernce from global table
writer.AddCell(staticSharedStringRef1);  
writer.AddCell(staticSharedStringRef2);  

// using local dictionary automatically maintained in the ExcelWriter instance
writer.AddCellSharedString("Some string from exteranal store");
writer.AddCellSharedString("Some string from exteranal store");

await writer.Complete();

Benchmarks

Benchmarks results and source code

Real world report

100 columns: numbers, dates, strings

RowsCount Mean Error StdDev Median Gen0 Allocated
100 987.2 μs 16.59 μs 14.70 μs 985.1 μs 1.9531 14.94 KB
1000 7,346.7 μs 146.30 μs 129.69 μs 7,322.4 μs - 13.83 KB
10000 64,722.2 μs 1,291.23 μs 2,048.02 μs 64,900.7 μs - 15.18 KB
100000 645,843.6 μs 12,911.60 μs 35,126.97 μs 660,441.0 μs - 17.13 KB
500000 3,278,696.3 μs 65,158.05 μs 122,382.62 μs 3,263,196.8 μs - 74.73 KB
OpenXml comparison
Method RowsCount Mean Gen0 Gen1 Gen2 Allocated
ExcelWriter 100 1.400 ms - - - 14.4 KB
OpenXml 100 3.501 ms 187.5000 187.5000 187.5000 1162.12 KB
ExcelWriter 1000 11.570 ms - - - 14.61 KB
OpenXml 1000 33.550 ms 1533.3333 933.3333 933.3333 9941.06 KB
ExcelWriter 10000 112.128 ms - - - 26.11 KB
OpenXml 10000 330.799 ms 9000.0000 3000.0000 3000.0000 136777.02 KB
ExcelWriter 100000 1,119.574 ms - - - 142.23 KB
OpenXml 100000 3,310.667 ms 68000.0000 6000.0000 6000.0000 1171460.91 KB
Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  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 was computed.  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.
  • net6.0

    • No dependencies.
  • net8.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.8.4 275 8/25/2025
1.8.3 137 8/13/2025
1.8.2 143 4/25/2025
1.8.1 133 2/6/2025
1.8.0 145 2/4/2025
1.7.0 125 1/12/2025
1.6.0 161 10/28/2024
1.5.5 167 9/19/2024
1.5.4 167 6/23/2024
1.5.3 155 6/3/2024
1.5.2 151 5/30/2024
1.5.1 137 5/10/2024
1.5.0 158 5/3/2024
1.4.1 160 4/27/2024
1.4.0 153 4/26/2024
1.3.0 392 12/25/2022
1.2.0 521 3/31/2022
1.1.0 503 2/25/2022
1.0.2 496 2/18/2022
1.0.1 446 12/15/2021
1.0.0 441 12/13/2021