Excel-PRIME
3.2512.21-XLSB-Beta
Please use the latest V3 (V4 recommended)
See the version list below for details.
dotnet add package Excel-PRIME --version 3.2512.21-XLSB-Beta
NuGet\Install-Package Excel-PRIME -Version 3.2512.21-XLSB-Beta
<PackageReference Include="Excel-PRIME" Version="3.2512.21-XLSB-Beta" />
<PackageVersion Include="Excel-PRIME" Version="3.2512.21-XLSB-Beta" />
<PackageReference Include="Excel-PRIME" />
paket add Excel-PRIME --version 3.2512.21-XLSB-Beta
#r "nuget: Excel-PRIME, 3.2512.21-XLSB-Beta"
#:package Excel-PRIME@3.2512.21-XLSB-Beta
#addin nuget:?package=Excel-PRIME&version=3.2512.21-XLSB-Beta&prerelease
#tool nuget:?package=Excel-PRIME&version=3.2512.21-XLSB-Beta&prerelease
Excel_PRIME 🌟
- Excel_Performant Reader via Interfaces for Memory Efficiency.
- Without using any external libraries.
- Optimised for Range extraction.
What does that mean?
- Yet another Excel reader ?,
- Starting with .Net 8 as the performant Runtime (See Benchmarks)
- V9 gives an extra 5% boost,
- V10 Another 5% 😉
Lets take each of the above elements and explain:
Excel 📈
- Open Large 2007 (Onwards) XLSX file formats and XLSB in V3.##
- Zip Deflate format Only
Performant 🚀
- Try to be as fast as possible, i.e.
- Forward only Lazy loading
- Only "Quick" decipher / convert of the cell(s) types to ease GC pressure
- No attempt at "creating / using" datatables with headers etc.
- Use
IEnumerables with initial offset starts (Row / Column) - Allow
CancellationTokens to be used to allow page transitioning cancellation (More on this later)
- Now the fastest in Real world usage 2025-11-19 onwards
Q & A's
- Q: There are others that are faster
- A: Agreed, but then
- They do not have range extraction.
- Or
optionallyallow the use of the OS's TempFile System to store massive sheets - Or re-use of already extracted (massive) sheets
- Or allow multiple sheets to be read at the same time
- because others use global memory to represent the current row
- Or have a single access into the Zip Excel file
Reader 📋
- Read only
- Therefore no calculations or updates to formula calls
Interfaces 🏗️
- Will use the DotNet core functionality by default
- But, if your target deployment allows for the use of native performant binaries, then via the use of interfaces these will be pluggable
- i.e. Using
Zlib.Netfor getting the data streams out of the compressed Excel file faster. (OrSharpZipLib/PowerPlayZipper) - A faster / slimmer implementation for xml stream reading (i.e. TurboXml)
- i.e. Using
- Allow the implementation of different source files (i.e. XLSB)
Q & A's
- Q: Why?
- A: As mentioned above, this is to allow a developer to replace with external nugets that might perform better XML speed etc.
Memory 🌐
- The reason for this project, is to handle very large XSLX files (i.e. > 500K rows with > 180 columns per sheet, with multiple sheets of this size)
- For
ETLvalidation scenarios, i.e. make sure that the user modified data that has been transferred has interaction rules applied, before moving onto theTandLstages - Try not to hit / store in the LOH
- No internal .Net memory of previously loaded sheets / rows.
Q & A's
- Q: It appears that this uses more memory than other implementations
- A: Currently yes, but it is being optimised for
Range Extraction,- AND for allowing multiple rows (With cell data) to be stored in memory at the same time, (i.e. via
ToList()call); - AND there is work in place to allow multiple sheets to be read at the same time (Unlike some to of the others that use global memory to represent a row)
- And it appears that the current benchmarks do not extract unless a
ToStringand a check on the result is used (Otherwise the Jit removes the unassigned dead code)
- AND for allowing multiple rows (With cell data) to be stored in memory at the same time, (i.e. via
Efficiency 📦
- As hinted by the above statements, this is to be targetted at memory restricted environments (i.e. ASP Net VM's)
- Use the OS's
Temp Filecaching, so if the memory is tight then the Owner app will not have to worry about OOM exceptions, or having to use Swap Disk speeds. - Only unzip the sheet(s) when they are asked for
- Only load the shared strings upto the current request number
Q & A's
- Q: Sometimes the
Asyncawait s add too much overhead - A: true, that is why there are also the equivalent base interfaces that perform the same functionality without the need for the
async awaitoverheads.
Etc. 🔧
CancellationTokens
- This is to allow the Large files to be Aborted
- Make "Most" of the "Net Cores'" API's Asynchronous
Tasks
IDisposable
- Got to tidy up those
Temp Files, and release theFileStream's
It will not ⛔:
Be: Same sheet Thread safe 📊
- It will Not be same sheet Instance thread safe, because the xml reader will be locked (Forward only) to the sheet in use.
- but you can Open the sheet more than once, and have different threads running over it,
- And you can have Parallel threads access the Excel file
- Just remember to set
Options{ AccessExcelFileInForwardOnlyMode = false}
Do: Dynamic Ranges ⚠️
- i.e. Ones that contain formulas:
<definedName name="Prices">OFFSET(Sheet1!$A$1,0,0,COUNTA(Sheet1!$A:$A),1)</definedName>
Do: Poco 🤖
- A POCO / Type populator (Extensions can be written for that later)
Be a: Writer / Modifier 📚
- Totally beyond the scope of this project remit
| Product | Versions 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 is compatible. 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. |
-
net10.0
- No dependencies.
-
net8.0
- No dependencies.
-
net9.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 | |
|---|---|---|---|
| 4.2605.17 | 107 | 5/17/2026 | |
| 4.2605.5 | 132 | 5/5/2026 | |
| 4.2604.28-RC3 | 124 | 4/28/2026 | |
| 4.2604.22-RC2 | 142 | 4/22/2026 | |
| 4.2604.16-RC1 | 140 | 4/16/2026 | |
| 4.2604.10-Beta | 144 | 4/10/2026 | |
| 4.2604.5-Beta | 120 | 4/5/2026 | |
| 4.2604.5-Alpha | 127 | 4/5/2026 | |
| 4.2601.31-Alpha | 250 | 1/31/2026 | |
| 4.2601.18-Alpha | 193 | 1/18/2026 | |
| 3.2601.16 | 149 | 1/16/2026 | |
| 3.2601.11 | 127 | 1/11/2026 | |
| 3.2601.4-XLSB-RC1 | 132 | 1/4/2026 | |
| 3.2601.2-XLSB-Beta | 131 | 1/2/2026 | |
| 3.2512.21-XLSB-Beta | 217 | 12/21/2025 | |
| 2.2512.14 | 184 | 12/14/2025 | |
| 2.2512.10 | 516 | 12/10/2025 | |
| 2.2512.7-Beta | 273 | 12/7/2025 |
# 2025-12-21 - V3 XLSB-Beta
- ⛓️💥 **Breaking Change(s)
- `FileType` has been removed, and Open via the Public class type
- `IXmlReaderHelpers` has become `IOpenXmlReaderHelpers`, with slightly different methods
- `IXmlWorkBookReader` has become `IOpenXmlWorkBookReader`
- `IXmlSheetReader` has become `IOpenXmlSheetReader`
- ✅ Implement Sheet loading
- ✅ Implement Row extraction
- ✅ Skip
- ✅ Delayed read - until a cell is actually needed
- ✅ Deal with Null / Empty cells
- ✅ Cell object type 📅
- [>] 👟 [2nd Pass Performance on 2025-12-21](https://github.com/Smurf-IV/Excel_PRIME/blob/main/Performance.md#2025-12-21)
# 2025-12-10 - RC
- User defined, using the `"A1:B10"` or `"$A$1:$B$10"` syntax
- [Range Performance on 2025-12-10](https://github.com/Smurf-IV/Excel_PRIME/blob/main/Performance.md#2025-12-10)
# 2025-12-07 - Beta V2
- Investigate _memory usage_(s) 🧑💻
- Removed finalizers from several classes
- Added a lightweight Row pooling strategy
- More performance improvements 🏃➡️ [Performance on 2025-12-04](https://github.com/Smurf-IV/Excel_PRIME/blob/main/Performance.md#2025-12-04)
- Replaced the `ReadString` implementation (Memory optimisation)
- Some code Cleanup
- Prefer returning ReadOnlyMemory<char> to avoid allocating a new string
- Sacrificed a little speed..
- [Performance on 2025-12-07](https://github.com/Smurf-IV/Excel_PRIME/blob/main/Performance.md#2025-12-07)
# 2025-12-01 - Beta V2
- Investigate _memory usage_(s) 🧑💻
- Replaced the dictionary with a fixed-size Cell?[]
- Defensive bounds checks when assigning parsed cells to avoid out-of-range writes.
- `Row` disposal when going out of `yield` scopes
- Add `ThreadStringBuilderPool` for memory efficiency
- Add `AccessPivotTable` and explain why the other libraries do **not work**
- [Performance on 2025-12-01](https://github.com/Smurf-IV/Excel_PRIME/blob/main/Performance.md#2025-12-01)
# 2025-11-18 - Beta V2
- Implement usage of _commercial_ `Aspose.Cells`
- Switch to `EPPlus-LPGL` (It's faster than v8.x ;-))
- [Performance on 2025-11-28](https://github.com/Smurf-IV/Excel_PRIME/blob/main/Performance.md#2025-11-28)
# 2025-11-27 - Beta V2
- Change benchmarks to use `ToString` to be fair on `ClosedXML`
- Attempt to use `FastExcel` - Failed due to Bug
- Use _commercial_ `FreeSpire`
- [Performance on 2025-11-27](https://github.com/Smurf-IV/Excel_PRIME/blob/main/Performance.md#2025-11-27)
# 2025-11-25 - Beta V2
- Make `DefinedName`'s work with `localSheetId`definitions
- Start to Add Benchmarks for range extraction
- [Performance on 2025-11-25](https://github.com/Smurf-IV/Excel_PRIME/blob/main/Performance.md#2025-11-25)
# 2025-11-19 - Beta V2
- Add `IEnumerable`s _All_ the way down ⤵️
- i.e. remove the need for Asynchronous awaits
- 🚀 Yielding More Performance improvements
- [Performance on 2025-11-16](https://github.com/Smurf-IV/Excel_PRIME/blob/main/Performance.md#2025-11-16)
- ⛓️💥 **Breaking Change** 🔩
- The Async classes now have `Async` appended to be distinct from the non async versions
- But, `Async` inherit from the non, so they are interchangable
# 2025-11-16 - Beta V2
- Read `definedName`s (Ranges / Cell / Value / Dynamic) 📇
- Implement RangeExtraction
- Global rangeNames
- Deal with blank rows in a sheet 🗋
- Return a `null` cell row
- Deal with Empty cells in a row 🗅
- Return a `null` cell
- Remove some warnings