ClosedXML Changelog

What's new in ClosedXML 0.104.0 Preview 2

Nov 2, 2023
  • Second test release for checking SourceLink support on nuget (first failed due to fody/PDB checksum) #2070

New in ClosedXML 0.102.1 (Aug 19, 2023)

  • Update SixLabors.Fonts dependency to version 1.0.0 by @jahav in #2149

New in ClosedXML 0.100.3 (Jan 12, 2023)

  • Insert all number types as numbers by @jahav in #1967

New in ClosedXML 0.100.2 (Jan 10, 2023)

  • Add conversion for nullable numbers/datetime/timespan by @jahav in #1963

New in ClosedXML 0.100.1 (Jan 10, 2023)

  • Add implicit conversion from decimal to double for XLCellValue. by @jahav in #1961

New in ClosedXML 0.100.0 (Jan 9, 2023)

  • Clean Break:
  • These are release notes for a version 0.100. We skipped a few version since the last release (0.97), because 0.100 should denote a major change at the very heart of ClosedXML. Not as clean break as I hoped, but close enough.
  • The list of all things that were changed from 0.97 to 0.100 is at the migration guide at the https://closedxml.readthedocs.io/en/latest/migrations/migrate-to-0.100.html
  • This is more like list of you should upgrade despite breaking changes :)
  • Memory consumption during big was decreased:
  • Memory consumption during saving of large data workbooks was significantly improved. Originally, ClosedXML workbook representation was converted to DocumentFomrat.OpenXML DOM representation and the DOM was then saved. Instead of creating whole DOM, sheet data (=cell values) are now directly streamed to the output file and aren't included in the DOM.
  • To demonstrate difference, see the before and after memory consumption of a report that generated 30 000 rows, 45 columns. Memory consumption has decreased from 2.08 GiB 🡆 0.8 GiB.
  • Cell value is now strongly typed:
  • IXLCell.Value and IXLCellValue.CachedValue have now type XLCellValue. At the core, xlsx consists of addressable cells with a functions that transform a set of values in source cells to different values in target cells. Is is really important to represent potential values of cells by a sane type. All other things, pivot tables, auto filter, graphs rely on this premise.
  • Cell value has been represented as string text and a value. The string depended on the value, e.g. 0/1 for boolean. That has been the case since the beginning of the ClosedXML project (see the original XLCell). The value was also returned as an Object.
  • This approach has several drawbacks
  • Object is not suitable representation of cell value. User had no idea what kind of values could be returned as a cell value. Everything could also break down, if a new type would be returned (e.g. XLError).
  • Setter could accept different types that the getter returned. E.g. it was possible to set cell value to a IXLColumn.
  • Values were always boxed/unboxed. That is not a problem for small amount of data, but it is not great for large workbooks.
  • It caused an potentially buggy behavior in other places of the ClosedXML.
  • Value of a cell is not represented by a XLCellValue structure. It is basically a union of one of possible types that can be value of a cell:
  • blank
  • boolean
  • number
  • text
  • error
  • datetime - basically number representing serial datetime, use serial datetime.
  • duration - basically number representing serial datetime, use serial datetime
  • Since datetime and duration are basically masqaraded number, you can use XLCellValue.GetUnifiedNumber() to get a backing number, no matter if the type is number, datetime and duration.
  • The structure contains implicit operators, as well as other methods to make transaction as seamless as possible
  • // Will use an implicit cast operator to convert string to XLCellValue and pass it to the Value setter
  • ws.Cell("A1").Value = "Text";
  • There is also a new singleton Blank.Value that represent a blank value of a cell. Null is not blank. Empty string is not a blank value of a cell. Null instead of blank was considered and everything is just so much easier to work with, if blank is represented as a custom singleton type and not as a null.
  • XLCellValue will be able to represent all values of a cell and won't be boxed/unboxed all the time.
  • Cell data type is no longer guessed:
  • ClosedXML used to guess a data type from a value. It caused all sort of unexpected behaviors (e.g. text value Z12.31 has been converted to date time 12/30/2022 19:00). Date caused most problems, but other sometimes too (e.g. text "Infinity" was detected as a number).
  • This behavior was likely intended to emulate how user interacts with an Excel. Excel guesses type, but only if the cell Number Format is set to "General" (e.g. if NumberFormat is set to Text, there is no conversion even in Excel). Application is not human and doesn't have to interact with xlsx in the same way.
  • This behavior was removed. Type that is set is the type that will be returned. Note that although XLCellValue can represent date and time as a different types, in reality that is only presentation logic for user. They are both just serial date time numbers.
  • Cell value now can be XLError or Blank:
  • Cell value now can accurately represent error or a blank value.
  • ClosedXML used to throw on error value and cell couldn't contain an error. That was a significant problem, especially for formula calculation where formula referenced a cell that should contain an error value.
  • ClosedXML used to represent blank cell as an empty string, but no longer. It uses Blank.Value singleton, wrapped in XLCellValue. Also brings significant improvement in accuracy for CalcEngine evaluation.
  • Text to number coercion:
  • Excel has a pretty complicated undocumented coercion process from text to number. It can convert fraction text (="1 1/2"*2 is 3), dates (e.g. ="1900-01-05"*2 is 10, though date format is culture specific), percent (e.g. ="100%"*2), braces imply negative value (="(100%)"*2 = -2) and many more. That causes a significant problems for formula evaluation, especially if the source cell contains a date as a text, not as a date.
  • ClosedXml used to only convert test that looked like double, it now coerces nearly everything Excel does. Coercion from dates should mostly work, but Excel has it's own database of acceptable formats and it's own format, while we rely on .NET Core infrastructure.
  • CalcEngine doesn't throw exceptions:
  • Thanks to incorporation of XLError to core of CalcEngine, the exceptions are no longer necessary and have been removed. Error is a normal value type that is used during formula evaluation (e.g. ISNA accepts it and VLOOKUP returns it).
  • Technically speaking CalcEngine can still throw MissingContextException, but only if evaluation is not called from a cell, but from method like XLWorkbook.Evaluate. Functions like ROW just can't work without the context of the cell.
  • Unimplemented functions now return #NAME?:
  • If you ever tried to use CalcEngine, you have encountered a dreaded The function *SomeFunctionwas not recognised. exception.
  • ClosedXML will no longer throw an exception on unimplemented function, but will return #NAME? error instead. It has several reasons
  • It aligns behavior of user defined functions in like with predefined functions. ClosedXML doesn't throw anything on =SOME.UNKNOWN.FUN(4), why should it throw on =LARGE(A1:A5,1)?
  • By default, ClosedXML doesn't save calculated values. A portion of workbook that doesn't use unimplemented function should work correctly, maybe that is enough for some use case? Excel (nearly always) recalculates everything on load anyway.
  • Basically, the exception doesn't bring any benefit and only imposes costs. User can report missing function on #NAME? error just like on exception.
  • Array literal can now be parsed:
  • CalcEngine now can evaluate array literal expressions, so formulas like VLOOKUP(4, {1,2; 3,2; 5,3; 7,4}, 2) now actually work.
  • Array processing is limited to argument parsing across formulas and CalcEngine still needs some love to process it work correctly. Array formulas are still not implemented.
  • Reimplementation of information and lookup functions:
  • Information and lookup functions were reimplemented to take advantage of other improvements. They should now be compliant with Excel (with exception of wildcard search for VLOOKUP).
  • Documentation in the version control:
  • Documentation is being moved from wiki to the ReadTheDocs. It has been there for since 2019, but we didn't actually had any documentation. Documentation is super important and ClosedXML lacks in that area. It is of course WIP, but it should improve over the time (see https://closedxml.readthedocs.io/en/latest/features/protect.html, https://closedxml.readthedocs.io/en/latest/features/cell-format.html#number-format or infamous https://closedxml.readthedocs.io/en/latest/tips/missing-font.html).
  • The move to ReadTheDocs has significant advantages:
  • It is in version control. That means every PR now can contain modification to documentation.
  • It is built as part of CI
  • It is versioned.
  • It uses ReStructured Text (rst) that has more rich style options and even plugins. Commonmark is heavily limited in style application.
  • It can generate documentation from xml comments
  • It can use references and includes. That means all examples can be in separate files and only included to documentation. Separate example files could be just complied and checked for correctness (we are not doing that ATM, but will likely do at some point in the future). That would solve the pesky issue of outdated examples in documentation.

New in ClosedXML 0.76.0 (Dec 17, 2014)

  • Add Remove and RemoveAll methods for conditional formats.
  • Fix issue when changing a table column names
  • Set ApplyNumberFormat and ApplyAlignment to true

New in ClosedXML 0.75.0 (Dec 17, 2014)

  • Fixed comments formatting error
  • Group conditional formatting for same ranges
  • Update IF function to support 2 parameters
  • Fix issue with RangeUsed including styles
  • Load drawing colors with the format "name index"
  • Fix Left, Right, and Mid functions for empty strings
  • Update Adjust to contents (gotta love doubles)
  • Made sure Conditional Format formulas are converted as invariant culture.

New in ClosedXML 0.74.0 (Aug 11, 2014)

  • Multiple thread safe improvements including:L
  • AdjustToContents
  • XLHelper
  • XLColor_Static
  • IntergerExtensions.ToStringLookup
  • Exception now thrown when saving a workbook with no sheets, instead of creating a corrupt workbook
  • Fix for hyperlinks with non-ASCII Characters
  • Added basic workbook protection
  • Fix for error thrown, when a spreadsheet contained comments and images
  • Fix to Trim function
  • Fix Invalid operation Exception thrown when the formula functions MAX, MIN, and AVG reference an empty cell
  • Fix clearing of formats on merged cells
  • Fix Null Reference Exception when input workbook does not have a style sheet

New in ClosedXML 0.73.0 (Jun 30, 2014)

  • Fix pivot table fields
  • Fix worksheets not calling global named ranges created by another worksheet.
  • Fixed a bug with formulas and strings
  • Quick fix
  • Memory and performance improvements
  • AdjustToContents and cell.GetFormattedString now use formulas
  • Add cell.NewDataValidation method
  • Fix OutsideBorder and OutsideBorderColor for Conditional Formats

New in ClosedXML 0.72.3 (Jun 5, 2014)

  • ClosedXML for .Net 4.0 now uses Open XML SDK 2.5
  • Merge branch 'master' of https://git01.codeplex.com/forks/vbjay/closedxml
  • Fix range.Merge(Boolean) for .Net 3.5
  • Make public range.Merge(Boolean checkIntersects)
  • More performance improvements when saving.

New in ClosedXML 0.71.2 (May 31, 2014)

  • More memory and performance improvements.
  • Fixed an issue with pivot table field order.

New in ClosedXML 0.71.1 (May 27, 2014)

  • More performance improvements. It's faster and consumes less memory.

New in ClosedXML 0.71.0 (May 26, 2014)

  • Major improvement when saving large files.

New in ClosedXML 0.69.0 (Aug 10, 2013)

  • Many small fixes.

New in ClosedXML 0.68.1 (Oct 20, 2012)

  • Added all date and time functions

New in ClosedXML 0.68.0 (Oct 8, 2012)

  • ClosedXML now resolves formulas:
  • Yes it finally happened. If you call cell.Value and it has a formula the library will try to evaluate the formula and give you the result.
  • Included formulas:
  • All math and trigonometric formulas.
  • All text formulas except BAHTTEXT, JIS, and PHONETIC.
  • All logical formulas.
  • Many statistical formulas.

New in ClosedXML 0.67.2 (Aug 16, 2012)

  • Fix when copying conditional formats with relative formulas

New in ClosedXML 0.67.1 (Aug 14, 2012)

  • Misc fixes to the conditional formats

New in ClosedXML 0.67.0 (Aug 13, 2012)

  • Conditional formats now accept formulas.
  • Major performance improvement when opening files with merged ranges.
  • Misc fixes.

New in ClosedXML 0.65.1 (Apr 4, 2012)

  • Fixed issue when loading conditional formatting with default values for icon sets

New in ClosedXML 0.63.0 (Jan 24, 2012)

  • Many bug fixes

New in ClosedXML 0.62.0 (Jan 11, 2012)

  • Fixed memory leak issue
  • Improved overall performance and memory usage
  • AdjustToContents() methods are now faster

New in ClosedXML 0.58.0 (Aug 19, 2011)

  • Improved performance
  • Dramatically reduced memory consumption
  • Strongly signed the assembly
  • Fixed issue when collapsing columns
  • IXLWorksheet/IXLRow/IXLColumn .Cells() now return the cells used instead of all cells in the worksheet/row/column
  • Removed .ClearStyles, use .Clear(XLClearOptions.Formats) instead
  • worksheet.Cell/Cells/Range/Ranges now accept named ranges as parameters.
  • Added the following methods to the workbooks so you can easily reference named ranges with a workbook scope: workbook.Cell/Cells/Range/Ranges
  • Removed property namedRange.Range. Use namedRange.First() instead or better yet use ws/wb.Range("NamedRange") instead.
  • Fixed issues 7076, 7065, 7064, 7026, 7071

New in ClosedXML 0.57.2 (Aug 6, 2011)

  • Added worksheet.RightToLeft property
  • Fixed absolute hyperlinks
  • Fixed issue with \r\n characters
  • When changing a cell's data type from number to text it will no longer preserve the formatting (as it happens in Excel)
  • Removed cell.GetRichText() as it's redundant to cell.RichText
  • Fixed issues 6932, 6975, 6989, 6993

New in ClosedXML 0.56.0 (Jun 30, 2011)

  • Major performance improvements.
  • Added Rich Text functionality.
  • Added Phonetic functionality.
  • Updated AdjustToContents methods.
  • Fixed default column behavior
  • Issue of InsertData returns invalid Range
  • Setting a cell to an empty string will convert the datatype to Text.
  • Rich text composed only of spaces now work.
  • Added unit tests
  • Added table.Fields property.
  • Added ws.Table(index) overload.
  • It now throws an error when attempting to retrieve an invalid row/column
  • Fixed issues 6838, 6848, 6872, 6859, 6865, 6799

New in ClosedXML 0.55.0 (Jun 17, 2011)

  • Major performance improvements on load and save.
  • Fixed range.RangeUsed when no cells were used.
  • Added methods row.AddHorizontalPageBreak and column.AddVerticalPageBreak
  • Added properties worksheet.TabSelected, worksheet.TabActive
  • Creation of non existing directories in XLWorksheet.Load and XLWorksheet.SaveAs
  • Added property Count to IXLWorksheets
  • Added method TryGetWorksheet to IXLWorksheets
  • Added method range.SetDataType(...)
  • Cell contents formatted with @ will be treated as text
  • Fixed issue with XLColor.GetHashCode()
  • Fixed issue when deleting rows from a workbook loaded.
  • Fixed issues 6804, 6817

New in ClosedXML 0.54.0 (Jun 9, 2011)

  • Mayor performance improvements.
  • AdjustToContents now take into account the text rotation.
  • Fixed issues 6782, 6784, 6788

New in ClosedXML 0.53.1 (May 26, 2011)

  • Added FindCells, FindColumns, and FindRows methods to the workbook object.
  • Added cell.ValueCached property that holds Excel's cache of formula evaluations.
  • Added the following properties to the worksheets:
  • ShowFormulas
  • ShowGridLines
  • ShowOutlineSymbols
  • ShowRowColHeaders
  • ShowRuler
  • ShowWhiteSpace
  • ShowZeros
  • Added methods Worksheets.Add(DataTable), Worksheets.Add(DataSet). See examples Adding DataTable as Worksheet, Adding DataSet
  • Fixed issues 6609, 6532, 6510, 6499, 6705, 6508
  • Breaking Changes:
  • Removed static method XLWorkbook.GetXLFont(). When you add a header/footer text which you want to format just modify the rich text/font returned by the .AddText(...) methods.

New in ClosedXML 0.45.2 (Feb 24, 2011)

  • Added data validation.
  • Deleting or clearing cells deletes the hyperlinks too.

New in ClosedXML 0.45.1 (Feb 16, 2011)

  • Added data validation. See Data Validation
  • Deleting or clearing cells deletes the hyperlinks too.
  • Fixed issues 6237, 6240