Gooseberry.ExcelStreaming
1.6.0
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
<PackageReference Include="Gooseberry.ExcelStreaming" Version="1.6.0" />
<PackageVersion Include="Gooseberry.ExcelStreaming" Version="1.6.0" />
<PackageReference Include="Gooseberry.ExcelStreaming" />
paket add Gooseberry.ExcelStreaming --version 1.6.0
#r "nuget: Gooseberry.ExcelStreaming, 1.6.0"
#:package Gooseberry.ExcelStreaming@1.6.0
#addin nuget:?package=Gooseberry.ExcelStreaming&version=1.6.0
#tool nuget:?package=Gooseberry.ExcelStreaming&version=1.6.0
Gooseberry.ExcelStreaming
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 | Versions 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. |
-
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 |