Name | Modified | Size | Downloads / Week |
---|---|---|---|
Parent folder | |||
0.104.1 source code.tar.gz | 2024-09-30 | 9.0 MB | |
0.104.1 source code.zip | 2024-09-30 | 10.2 MB | |
README.md | 2024-09-30 | 20.7 kB | |
Totals: 3 Items | 19.3 MB | 0 |
Release notes from 0.102.1 to the 0.104.1.
Summary of breaking changes is available at docs.closedxml.io: * Migration from 0.102 to 0.103 * Migration from 0.103 to 0.104 * New calculation engine just works in a different way and will behave slightly differently.
OpenXML SDK
OpenXML SDK has released version 3. The 0.104.0 uses it as a dependency.
XLParser replaced with ClosedParser
The XLParser has been replaced with ClosedParser. The key benefits are * performance - ~2μs/formula, it's likely formulas will be parseable on the demand, necessary for construction of dependency tree * A1/R1C1 parsing parity - both modes can be parsed with no problems * AST oriented - it's likely a construction of AST in memory won't even be necessary, just use AST factory to evaluate formula directly
There is also a visualizer to display AST in a browser at https://parser.closedxml.io
Formula Calculation
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 * dependency tree for checking which formulas are dirty and need to be recalculated * calculation chain that manages dependencies and order of formulas during calculation
For more info, see docs, the Microsoft has a page about principles Excel Recalculation and there is one with API at docs.closedxml.io.
Structured references
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
:::csharp
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
Renaming sheet updates formulas
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.
:::csharp
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
Workbook structure
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
performance
Insert 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 |
Loading of cells is now done through streaming
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.
Pivot tables
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.
AutoFilter
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.
Source link
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).
CommonCrawl dataset
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.
What's Changed
Technical debt
- Add shared string table for plain text by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2115
- Store rich text as an immutable rich text by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2116
- Save SST part directly from SST instance. by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2118
- Move saving of parts into separate writers by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2177
- Enable nullable in a few more classes by @sbeca in https://github.com/ClosedXML/ClosedXML/pull/2188
Performance improvements
- Convert InsertData to streaming&bulk by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2173
- Load cells from workbook using a streaming by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2174
- Improve sorting performance by @igitur in https://github.com/ClosedXML/ClosedXML/pull/1649
- Remove multiple enumerations by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2236
- Optimise workbook loading by stopping unneeded invalidation by @sbeca in https://github.com/ClosedXML/ClosedXML/pull/2284
- Remove IXLStylized.Styles property by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2361
- Convert XLNumberFormatKey and XLAlignmentKey to readonly structs by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2364
- Convert XLBorderKey, XLFillKey, XLFontKey and XLProtectionKey to readonly structs by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2365
- Convert XLStyleKey to readonly struct by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2366
- Eliminate a couple of performance killers - cherry pick for develop by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2371
Features
- Add FontScheme property to a font by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2114
- Implement loading of workbook theme colors by @sbeca in https://github.com/ClosedXML/ClosedXML/pull/2117
Bugfixes
- update accessibility of string.Contains(char) polyfill to internal by @Applesauce314 in https://github.com/ClosedXML/ClosedXML/pull/2134
- Make SheetId a unique across XLWorksheets by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2142
- Fix incorrect logic check in Array Rescale by @sbeca in https://github.com/ClosedXML/ClosedXML/pull/2157
- Fix ROUND (and probably others) not handling the result of binary operations on refs by @sbeca in https://github.com/ClosedXML/ClosedXML/pull/2153
- Load and save data validations from/to worksheet extension by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2203
- Handle invalid length hex colors by @Bobbar in https://github.com/ClosedXML/ClosedXML/pull/2191
Documentation
- Add themes documentation by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2154
- Add documentation about how formulas are calculated. by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2176
- Update README.md - link update by @sikanderiqbal in https://github.com/ClosedXML/ClosedXML/pull/2234
- Document how are functions evaluated by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2274
- Fix typo "makred" by @JuliusJacobsohn in https://github.com/ClosedXML/ClosedXML/pull/2368
Breaking changes
- First page number can be negative -> change API type to int by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2237
- Rename IXLNamedRange to IXLDefinedName by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2258
AutoFilter
- AutoFilter rework - 1/? - Regular filter matches string. by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2238
- AutoFilter rework - 2/? - fix types for custom filters by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2239
- AutoFilter rework - 3/? - Top and average filter refactor, remove setters of internal state by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2240
- AutoFilter rework - 4/? - Top/Average filters work after loading by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2241
- AutoFilter rework - 5/? - Unify Regular and DateTimeGrouping filters by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2242
- AutoFilter rework - 6/7 - Add tests by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2243
- AutoFilter rework - 7/7 - Add documentation by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2245
Formulas
- Replace XLParser with ClosedParser. by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2138
- Update ClosedXML.Parser to 1.0 by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2250
- Implement structured references by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2251
- Replace regex-powered code for A1-R1C1 formula conversion with AST-based one by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2253
- Change source of truth for defined names from union of ranges to a formula by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2263
- When sheet is renamed, rename it also in defined name formula by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2264
- Update sheet names in formulas when sheet is renamed by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2273
- Get areas a formula depends on by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2152
- An initial work on a dependency tree for formulas by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2155
- Add names areas to dependency tree by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2156
- Add API to remove cell formula from dependency tree by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2160
- Add XLCalculationChain by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2167
- Add ability to detect cycle in calculation chain by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2169
- Evaluate calculation chain by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2172
Functions
- Implement FV and IPMT Excel functions and adapt 2 existing functions by @sbeca in https://github.com/ClosedXML/ClosedXML/pull/2199
- Reimplement COUNTA function. by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2277
- Reimplement FACT function by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2280
- Reimplement COMBIN function by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2281
- Add BINOMDIST function by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2282
- Implement Large Formula - Targets [#1716] by @NickNack2020 in https://github.com/ClosedXML/ClosedXML/pull/2050
- Reimplement legacy MAX function. by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2269
Dependencies
- Remove outdated transitive package upgrades by @Arjan321 in https://github.com/ClosedXML/ClosedXML/pull/2267
- Update OpenXML SDK to 3.0. by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2248
- Update language level and use polyfill for missing functions. by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2194
Fixes
- Preserve VML part with form controls across load/save. by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2205
- Ignore sheets with invalid id by @mihailmacarie in https://github.com/ClosedXML/ClosedXML/pull/2008
- Fixed NullReferenceException at loading workbook with empty si element by @psynomorph in https://github.com/ClosedXML/ClosedXML/pull/2218
- Fix InvalidCastException at workbook loading by @lvxiao312 in https://github.com/ClosedXML/ClosedXML/pull/2231
- Get formula only if it is neither null or empty by @PascalGeschwillBIS in https://github.com/ClosedXML/ClosedXML/pull/2216
- Fix column/row style combination for non-materialized cells. by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2249
- Fix ROW function so it works in array formulas. by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2268
- Make legacy functions work with error argument by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2270
- Write cells with empty text to file (used to be treated as blanks) by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2278
- Add a load test for dialog sheet by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2334
- Fix TimeSpan conversion by @OldBuddy in https://github.com/ClosedXML/ClosedXML/pull/2318
- Fix an edge case when ranges got unmerged when the adjacent range of the same size got deleted by @Pankraty in https://github.com/ClosedXML/ClosedXML/pull/2358
- Correctly load quoted and unquoted sheet names in print area definitions by @igitur in https://github.com/ClosedXML/ClosedXML/pull/2380
- Change format of symbol package to snupkg by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2204
- Convert Blank to DateTime as 0 serial date in legacy functions by @georgheimltwat in https://github.com/ClosedXML/ClosedXML/pull/2180
- Correctly interpret date and time values by @TheObliterator in https://github.com/ClosedXML/ClosedXML/pull/2184
- Fix NRE in IXLCell.Active by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2195
Pivot tables
- Implement a data structure to hold pivot table close to file structure by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2275
- Load all PivotTableDefinition fields into the XLPivotTable by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2285
- Start new pivot table part writer by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2287
- Write pivot table row/column axes, filter fields and data fields by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2290
- Add conditional formatting structure to pivot table by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2297
- Reimplement pivot table logic by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2307
- Pivot table grand total styles by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2374
- Modify pivot field labels style by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2375
- Fix the pivot table Layout property by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2384
- Add style API for pivot field headers by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2385
- Pivot style subtotals by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2386
- Pivot style data by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2393
- Improve error message when adding a pivot value field by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2394
- Style intersection of pivot value field and axis field by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2395
- Style pivot area based on pivot field axis values by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2396
- Add support for Excel files containing 'Adobe' branded jpeg images by @ctmatt in https://github.com/ClosedXML/ClosedXML/pull/2391
- Fix O(n^2) issue in pivot cache creation by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2403
- Load pivot records by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2178
- Represent pivot field statistics by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2182
- Write loaded pivot records to the output file by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2183
- Detach source reference of pivot cache from a range by @jahav in https://github.com/ClosedXML/ClosedXML/pull/2186
New Contributors
- @mihailmacarie made their first contribution in https://github.com/ClosedXML/ClosedXML/pull/2008
- @psynomorph made their first contribution in https://github.com/ClosedXML/ClosedXML/pull/2218
- @lvxiao312 made their first contribution in https://github.com/ClosedXML/ClosedXML/pull/2231
- @PascalGeschwillBIS made their first contribution in https://github.com/ClosedXML/ClosedXML/pull/2216
- @sikanderiqbal made their first contribution in https://github.com/ClosedXML/ClosedXML/pull/2234
- @Arjan321 made their first contribution in https://github.com/ClosedXML/ClosedXML/pull/2267
- @OldBuddy made their first contribution in https://github.com/ClosedXML/ClosedXML/pull/2318
- @JuliusJacobsohn made their first contribution in https://github.com/ClosedXML/ClosedXML/pull/2368
- @ctmatt made their first contribution in https://github.com/ClosedXML/ClosedXML/pull/2391
- @Applesauce314 made their first contribution in https://github.com/ClosedXML/ClosedXML/pull/2134
- @sbeca made their first contribution in https://github.com/ClosedXML/ClosedXML/pull/2117
Full Changelog: https://github.com/ClosedXML/ClosedXML/compare/0.104.0-preview2...0.104.0-rc1