NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
NuGet · #264 most downloaded on NuGet
See release notes https://github.com/ClosedXML/ClosedXML/releases/tag/0.105.1 ClosedXML is a .NET library for reading, manipulating and writing Excel 2007+ (.xlsx, .xlsm) files. It aims to provide an intuitive and user-friendly interface to dealing with the underlying OpenXML API.
Last release 2 months ago
25 Jul 2026
Release timing varies
gaps range from 2 weeks to 1.2 years
Rarely documented
notes for 7 of 56 stable releases
11 versions withdrawn
withdrawn after publishing
127 years old
89 releases · first in 1900
fix: bound SixLabors.Fonts to version range [1.0.0,3.0.0) by @igitur in #2870
Full Changelog: 0.105.0...0.105.1
Automatic fixer of function names
Correct name for newer functions (post 2013) is not what is seen in the GUI (e.g. correct name for CONCAT is _xlfn.CONCAT). That is rather obscure fact not known to most developers. The formula setters (e.g. IXLCell.FormulaA1) now automatically fix function names, so it is stored correctly in the file.
using var wb = new XLWorkbook();
var ws = wb.AddWorksheet();
// Originally required "_xlfn.CONCAT(\"hello\", \" world!\")";
ws.Cell("A1").FormulaA1 = "CONCAT(\"hello\", \" world!\")"; In many cases, the sorted area has a column with references. The formula often references another row. Pre-0.105, the references in the formulas weren't updated correctly.
using var wb = new XLWorkbook();
var ws = wb.AddWorksheet();
ws.Cell("A1").Value = 4;
ws.Cell("B1").FormulaA1 = "A1+1";
ws.Cell("A2").Value = 2;
ws.Cell("B2").FormulaA1 = "A2+1";
ws.Cell("A3").Value = 1;
ws.Cell("B3").FormulaA1 = "A3+1";
ws.Range("A1:B3").Sort(1, XLSortOrder.Ascending);Basically all implemented functions should be more faithful to how Excel behaves and evaluation of functions should be faster. implemented functions should be "complete" in sense that they correctly work for various arguments (e.g. various forms of ROMAN or pattern search in SUMIFS).
The functions (before refactoring) had serious problems with ranges, errors or type coercion or structured references. The original parser back then didn't even parse literal arrays ({1,2,3;4,5,6}). Parser and other things were updated, but because there was ~180 functions, original implementation was kept and functions were functions were reused through an adapter. Except the adapter never worked right and there were some other serious problems.
Note truncated.
One column per quarter.
Automatic fixer of function names
Correct name for newer functions (post 2013) is not what is seen in the GUI (e.g. correct name for CONCAT is _xlfn.CONCAT). That is rather obscure fact not known to most developers. The formula setters (e.g. IXLCell.FormulaA1) now automatically fix function names, so it is stored correctly in the file.
using var wb = new XLWorkbook();
var ws = wb.AddWorksheet();
// Originally required "_xlfn.CONCAT(\"hello\", \" world!\")";
ws.Cell("A1").FormulaA1 = "CONCAT(\"hello\", \" world!\")"; In many cases, the sorted area has a column with references. The formula often references another row. Pre-0.105, the references in the formulas weren't updated correctly.
using var wb = new XLWorkbook();
var ws = wb.AddWorksheet();
ws.Cell("A1").Value = 4;
ws.Cell("B1").FormulaA1 = "A1+1";
ws.Cell("A2").Value = 2;
ws.Cell("B2").FormulaA1 = "A2+1";
ws.Cell("A3").Value = 1;
ws.Cell("B3").FormulaA1 = "A3+1";
ws.Range("A1:B3").Sort(1, XLSortOrder.Ascending);Basically all implemented functions should be more faithful to how Excel behaves and evaluation of functions should be faster. implemented functions should be "complete" in sense that they correctly work for various arguments (e.g. various forms of ROMAN or pattern search in SUMIFS).
The functions (before refactoring) had serious problems with ranges, errors or type coercion or structured references. The original parser back then didn't even parse literal arrays ({1,2,3;4,5,6}). Parser and other things were updated, but because there was ~180 functions, original implementation was kept and functions were functions were reused through an adapter. Except the adapter never worked right and there were some other serious problems.
Note truncated.
Update DocumentFormat.OpenXml due to vulnerability in System.IO.Packaging 8.0.0 by @jahav in #2503
Full Changelog: 0.104.1...0.104.2
Summary of breaking changes is available at docs.closedxml.io :
Release notes from 0.102.1 to the 0.104.1.
Summary of breaking changes is available at docs.closedxml.io:
OpenXML SDK has released version 3. The 0.104.0 uses it as a dependency.
The XLParser has been replaced with ClosedParser. The key benefits are
There is also a visualizer to display AST in a browser at https://parser.closedxml.io
In previous version, formulas used to be calculated recursively. Each formula checked it's supporting cells for other formulas and if there were some, they were recursively evaluated. There was some logic to decrease number of evaluations. That works for a very simple cases, but isn't very good for various non-happy paths (i.e. cells weren't calculated when they should be).
This version has replaced it with a standard
For more info, see docs, the Microsoft has a page about principles Excel Recalculation
and there is one with API at docs.closedxml.io.
New parser also allows a basic evaluation of structured references. Format of structured reference must use official grammar, not Excel friendly names (e.g. Pastry[@Name] is user-friendly name for Pastry[[#This Row],[Name]]). It's now possible to
using var wb = new XLWorkbook();
var ws = wb.AddWorksheet();
ws.Cell("A1").InsertTable(new Pastry[]
{
new("Cake", 14),
new("Waffle", 3),
}, "Pastry");
ws.Cell("D1").FormulaA1 = "SUM(Pastry[Price])";
ws.Cell("D3").FormulaA1 = "\"Pastry \" & Pastry[[#This Row],[Name]]";
wb.RecalculateAllFormulas();
Console.WriteLine($"Expected: {17}, Actual: {ws.Cell("D1").Value}");
Console.WriteLine($"Expected: \"Pastry Waffle\", Actual: {ws.Cell("D3").Value}");Expected: 17, Actual: 17
Expected: "Pastry Waffle", Actual: Pastry Waffle
When a sheet is renamed, a formula referencing the sheet is also updated. This is a part of long term effort to fix effects of structural changes of a workbook. It will be a long road (e.g. sheet still delete doesn't swicth to #REF!),** but is one of basic features that should be working acorss the board.
using var wb = new XLWorkbook();
var sheet = wb.AddWorksheet();
var anotherSheet = wb.AddWorksheet("Another");
sheet.Cell("A1").FormulaA1 = "Another!B4";
anotherSheet.Name = "Changed";
Console.WriteLine(sheet.Cell("A1").FormulaA1);Changed!B4
Internal structure has been cleaned up and optimized.
The dirty tracking has been moved out of cells to formulas and thus memory taken up by a single cell value is now only 16 bytes instead of 24 (?) bytes in 0.102. Of course there are some other structures around that take up memory as well, but the single cell value is now 16 bytes (I hoped for 8, but not feasible with double, DateTime and TimeSpan as possible cell values - all take up 8 bytes... not enough bits).
The same string in different instances is now not duplicated, but only one instance is used. As seen on following test, it can lead to significant decrease in memory consumption. 250k rows with 10 text rows (same string, different instance): 117 MiB om 0.103 vs 325 MiB in 0.102.1.
InsertData performanceInsert 250k rows of 10 columns of text and 5 columns of numbers (gist).
| Description | Rows | Columns | Time/Memory to insert data | Save workbook | Total time/memory |
|---|---|---|---|---|---|
| 0.103.0-beta | 250 000 | 15 | 1.619 sec / 117 MiB | 6.343 sec | 477 MiB |
| 0.102.1 | 250 000 | 15 | 7.160 sec / 325 MiB | 6.676 sec | 692 MiB |
Basically workbooks with a large amount of cells should see ~15%-20% speedup (as long as there are mainly values, not styles or OLAP metadata....).
Reading the 250k from previous chapter:
| Description | Rows | Columns | Time to load data | Used memory |
|---|---|---|---|---|
| 0.103.0-beta | 250 000 | 15 | 15.648 sec | 236 MiB |
| 0.102.1 | 250 000 | 15 | 20.460 sec | 329 MiB |
Of course, this includes all stuff from 0.103.0-beta. Version 0.103 never got a non-beta release.
The internal structure of pivot tables, along with most other features, has been completely overhauled. This update should significantly reduce crashes when loading and saving workbooks containing pivot tables.
The main issue with the previous internal structure was that it didn't align with the structure used by OOXML. This was problematic because we need to support all valid files. As a result, we have to handle a wide range of inputs and correctly convert them to our internal structure, which is rather hard. A more clear 1:1 mapping with OOXML is much simpler and more reliable.
The Autofilter feature has been revamped, which includes some API changes. Its behavior is now more closely aligned with how Excel operates. The XML documentation provides detailed explanations, and there is a dedicated documentation page. Several bugs have also been fixed.
For more details, refer to the Autofilter section of the migration guide.
Although ClosedXML still doesn't have source package (Fody static weaving causes pdb mismatch and nuget will refuse symbol package), there is a source link info in the package.
SourceLink basically takes a repository and a commit from the package and retrieves source from directly from forge (in this case GitHub).
When workbook is a valid one, ClosedXML shouldn't throw on load. That is a rather high priority (more than saving or manipulation). Unfortunately, that is hard to find such areas that cause most problems.
One of activities that was going in a background is trying to use excel files around the internet (found by CommonCrawl) to evaluate how bad it is. There aren't results yet, but it is something that is going on.
Note truncated.
Bump version to 0.104.0 for release
Bump version to 0.104.0 for release
Nothing published for this version
Second test release for checking SourceLink support on nuget (first failed due to fody/PDB checksum) #2070
Second test release for checking SourceLink support on nuget (first failed due to fody/PDB checksum) #2070
Nothing published for this version
Nothing published for this version
Eliminate a couple of performance killers by @Pankraty in #2363
Full Changelog: 0.102.2...0.102.3
Add a warning about allowed ranges of DocumentFormat.OpenXML see issue #2220 and PR #2246 .
Add a warning about allowed ranges of DocumentFormat.OpenXML see issue #2220 and PR #2246.
Full Changelog: 0.102.1...0.102.2
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Breaking change: XLCellValues enum has been renamed to XLDataType .
e63fa4e
Breaking change: XLCellValues enum has been renamed to XLDataType .
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →