HotXLS Release Notes
Version history covering HotXLS user-visible features, fixes, XLS/XLSX enhancements, export updates, compatibility changes, and documentation changes
Last release
- Latest version: 2.384.120; Release date: 2026-10-09
Version 2.384.120
Added
- Portable Classic XLS capture now covers ordinary column, bar, line, scatter, pie, doughnut and single-series area charts, with validated locally stored values, core appearance and caller-declared plot, title and legend bounds
- Read-only chart appearance declarations keep worksheet and chart identities, explicit frame dimensions, effective legend point sizes and native font geometry for detached PDF, SVG and PNG output
- Bounded helpers inspect simple stored formula references and cached chart cells without evaluating formulas or expanding sparse cells
Fixed
- Classic chart capture preserves fractional stored font and marker sizes, source ownership and read leases, and rejects malformed records, unresolved appearance and exhausted resource budgets before producing output
- Chart double-valued property updates reject non-finite values before any comparison or mutation
- Repeated native portable cell initialisation releases the previous managed strings during capture
Version 2.384.119
Fixed
- Classic chart inspection validates stored series text, trendline names and data-label separators before typed state is applied, and releases partial models when malformed text raises an error
- Compressed Unicode data-label separators keep their complete stored characters
Version 2.384.118
Added
- Classic chart inspection exposes marker diameters in points, including fractional sizes, whilst preserving the original stored units
Fixed
- Supported native Classic chart fill tables decode their properties after complex entries, and malformed tables keep the preceding typed fill
Version 2.384.117
Added
- Explicit byte-encoding helpers preserve embedded nulls and reject text the selected code page cannot represent
Changed
- Classic BIFF5 text, formulas and workbook metadata use their declared encoding on Windows, Linux and macOS, honouring encoded byte lengths and complete-character boundaries
- Supported legacy chart text keeps its original decoding after codepage edits and copies, and is explicitly transcoded before being saved under a different encoding
Fixed
- Compressed BIFF8 Unicode preserves exact code units, while legacy custom styles, chart text and double-byte formula-cache continuations use their actual record layouts
- Native Unicode text calculation, criteria, lookup keys, local formula bindings and Classic search and replace preserve supported case matching
- Named-style lookup resolves the first stored entry without treating it as a missing name
- Repeated ZIP entry reads release earlier header metadata whilst retaining concurrent stored and deflated stream behaviour
Version 2.384.116
Added
- Local SUM calculated Pivot fields evaluate formulas from leaf, subtotal and grand-total context sums, including dependencies missing from the displayed measures
- Cache-owned calculated items keep native member identities, hidden dependencies and the global solve order across supported ungrouped string-member fields
- Supported calculated-item display calculations and aggregate filters preserve visible member order, original filter order and unambiguous displayed-measure identities
Fixed
- Native Pivot formula date projection preserves the workbook date system across cache import, cloning and calculation
- Missing-item cache cleanup preserves validated materialised report ownership across both workbook date systems and legacy saved reports
- Unsupported calculated Pivot metadata and edited native output are rejected before worksheet results are mutated
Version 2.384.115
Added
- Native portable PDF, SVG and PNG output supports rich text, modelled shapes, ordinary images, in-cell images, Boolean checkboxes and seven supported cached XLSX chart families
- Immutable workbook print plans apply complete print areas, repeated row and column titles, page breaks, paper setup, margins, orientation, centring, scaling and page order on Linux and macOS
- Explicit native font geometry supports generation-checked capture without touching the workbook's geometry provider
Fixed
- Fit-to-page mode survives workbook round trips and disregards stale percentage scaling, including unlimited fit dimensions
- Supported chart title fonts, line appearance and marker fill and borders keep their explicit imported and authored values, including black
- Rich text honours explicit false overrides and distinguishes effective run appearance during string reuse and semantic comparison
Version 2.384.114
Added
- Native Linux x64 and macOS ARM64 applications can load, edit, calculate and save Classic BIFF8 workbooks, including supported document properties and RC4 encryption
- Portable compound storage handles nested scopes, large chained DIFAT containers, metadata and explicit native storage interface ownership
Fixed
- 128-bit CryptoAPI workbooks advertise a compatible cryptographic provider and keep readable plaintext document properties
- Native document timestamps use the correct FILETIME epoch and preserve UTC values across all platforms
- Classic defined names share a canonical Unicode identity across scope lookup, formulas and workbook reopening
- Escaped date-format separators and embedded quoted literals keep the selected complete date format
Version 2.384.113
Added
- Range clearing and Unicode text paste support bounded atomic undo and redo with protection and structural preflight checks
- Typed local in-cell images and Checkbox formats survive XLSX roundtrips and support accessibility metadata and ownership-aware content edits
- Sparse row and column Checkbox formats keep precedence, explicit clears and absent cells intact through edits and XLSX roundtrips
- Expanded XLSB support covers formulas and caches, names, merges, hyperlinks, panes, tables and filters
- Native workbook APIs on Linux x64 and macOS ARM64 load, edit, calculate and save supported XLSX, XLSB and ODS files
- Native Pivot output supports numeric, date and manual grouping plus all eleven custom subtotal functions
Fixed
- Scoped names use consistent Unicode normalisation and case matching on Windows, Linux and macOS without discarding accents or symbols
- Modern aggregation formulas compile consistently under Free Pascal on Windows
- Opening another workbook replaces named styles instead of keeping style definitions from the previous file
- Modern image and control content survives range undo and saving without materialising absent cells
- Imported formula caches keep their original value metadata, and ordinary metadata is distinguished from in-cell image content
- Semantic comparison distinguishes local image content, accessibility metadata and effective inherited control formats using bounded sparse traversal
Version 2.384.112
Added
- Regular expression testing, extraction and replacement handle UTF-16 text, captures, array broadcasting and bounded evaluation on Windows, Linux x64 and macOS ARM64
- GROUPBY and PIVOTBY gain scoped aggregate callbacks, multiple measures, headers, filters, hierarchical totals, sorting and relative percentages
Fixed
- Scalar SUM arguments keep Boolean and numeric-text coercion whilst range and array aggregation retain their existing ignoring rules
- Scoped Boolean literals and aggregate callback formulas survive future-function storage and the workbook being reopened
Version 2.384.111
Added
- Native local Pivot output covers base-item differences and percentages, running totals, row and column percentages, index, parent percentages, cumulative percentages and dense ranking
Fixed
- Display calculations retain native total, missing-value, zero-divisor and sorted-member semantics, including non-additive averages
- Extended display modes and base-field identities survive saving, reopening and an explicit Excel refresh
Version 2.384.110
Added
- Native local Pivot output offers compact, tabular and outline layouts, repeated ancestor labels, default subtotal placement and multiple measures on either data axis
Fixed
- Repeated-label settings survive imported namespace aliases and save/reopen cycles, whilst native output distinguishes absent intersections from numeric zero
- Staged layout metadata keeps field and data captions consistent when Excel explicitly refreshes the generated reports
Version 2.384.109
Added
- Workbook comparison distinguishes typed values and exact large integers, supports finite numeric tolerances and optional comparison of stored formula caches, styles and geometry
- Bounded semantic comparison spans supported names, rules, tables, drawing order, blank-style regions, effective rich-text runs, local Pivot models, Slicer selections and Timeline state
Changed
- Comparison preserves packed and absent cells, resolves resource identities to effective values and keeps the previous successful result when models are unsupported or resources are exhausted
Fixed
- Typed database REAL parameter precision validation compiles with Delphi XE5 whilst keeping exact-value, overflow and null checks
Version 2.384.108
Added
- ODS round trips keep ordinary note text and authors, representable value and custom filters, explicit cell protection and equivalent passwordless worksheet protection
- Conversion reports keep a precise record of metadata losses through worksheet copies and later saves, including unsupported filter expressions and non-equivalent protection
Fixed
- Cancelled or failed ODS stream saves preserve the destination bytes, size and position through bounded temporary-file staging
- Successful ODS saves starting from a nonzero stream position preserve the prefix and the correct ZIP entry offsets
Version 2.384.107
Added
- Stored-formula inspection and reference-aware Pivot aggregate formulas work in Classic XLS, XLSX, read-only and isolated evaluation contexts, covering available array results and typed errors
- Pivot aggregate queries honour modelled visible members, report filters and supported subtotals through bounded detached cache evaluation without refreshing the source data
Fixed
- Native Excel XLS Pivot caches retain successive inline numeric values and current cache-validity metadata rather than returning incorrect repeated-value totals
- Pivot references include the modelled report-filter area above the main table location
Version 2.384.106
Added
- Automatic database queries bind typed literal and stored-cell parameters in positional order, preserving Unicode, empty text, zero, Boolean values, dates and nulls without substituting values into the SQL text
- Cell parameters read available formula caches and compact stored values without recalculation or materialisation, with bounded metadata validation and transactional application of results
Fixed
- Jet and ACE date parameters preserve DATE, TIME and TIMESTAMP values through typed OLE DATE bindings, independently of locale-dependent timestamp projections
Version 2.384.105
Added
- Formula metadata reads the actual referenced file identity, supported base number formats, negative colours, positive parentheses, text alignment, locked state, column width and calculation mode across XLS and XLSX evaluation contexts
- Detached base-style and sparse axis-footprint inspection preserves stored and packed cells, worksheet defaults, theme colours and borrowed workbook ownership
Changed
- Column-width metadata returns its rounded character width and default-width flag as a two-column array; unavailable Excel application environment information and unclassifiable formats raise explicit errors
Version 2.384.104
Added
- Import validation covers strict scalar types, numeric and date bounds, explicit Excel date systems, composite uniqueness and cross-column relationships
- Structured violations identify the worksheet, cell, rule, related column and first duplicate row, whilst stored-value validation preserves packed cells and reports unavailable formula caches without implicit recalculation
Version 2.384.103
Added
- Automatic text queries refresh fixed-width files using the declared field starts, supported character encodings, typed field conversion, skipped fields and header or first-row selection
- Fixed-width refresh preserves literal quotes, trims field padding and rejects invalid boundaries, oversized input and cancellation before worksheet changes are applied
Version 2.384.102
Changed
- Classic formula symbol audits scan faster whilst preserving function and name findings, case-insensitive deduplication, scope and finding order
Fixed
- Windows workbook saves, direct package patching, PDF output and page-image output can atomically replace an existing file held by delete-sharing metadata or reader handles on supported filesystems, whilst retaining lock checks, read-only protection and the legacy path on unsupported filesystems
Version 2.384.101
Added
- INDEX area-selector arrays broadcast with row and column selectors over calculated arrays and supported same-sheet reference unions, preserving orientation, selected value types and individual errors
- Defined names and LET bindings keep supported multi-area reference identity, and scalar CHOOSE retains the selected reference for downstream calculation
Fixed
- INDEX accepts an explicit area argument of 1 for calculated sources and distinguishes between invalid, missing, fractional and out-of-range area selectors
- Cross-sheet unions and calculated-array unions reject with their supported error contract instead of picking up incorrect reference identity
- Invalid references qualified by existing local worksheets keep their reference errors through direct formulas and defined names, including quoted sheet names, without formula strings being changed or unknown qualifiers being treated as local sheets
Version 2.384.100
Added
- Portable headless PDF, SVG and PNG output on Linux using explicit font files, native text shaping, bounded resources and staged exclusive file publication
- Read-only Windows capture of supported Classic XLS and XLSX rectangles into immutable transferable snapshots, covering stored formula results, scoped Table and conditional appearance, physical dimensions and complete merges
Fixed
- Portable appearance validation rejects invalid enum representations consistently across optimised compiler builds
Version 2.384.99
Added
- Explicit automatic query refresh for supported Windows Text, ADO, ODBC and Web connections, plus custom provider registration and bounded results
Fixed
- Native query result relationships and column identities persist through supported table-backed or standalone save and reopen cycles
- Invalid provider connection kinds are rejected before dispatch without worksheet results being changed
Version 2.384.98
Added
- Local Pivot Timeline creation, shared-view connections, inclusive whole-day filtering and guarded removal that either clears or preserves the selection
- Explicit native Slicer no-data item refresh across connected views, with cumulative resource limits, cancellation, and selection and item identity preserved
Fixed
- Native Timeline relationship and filter ownership handling preserves supported imported selections through materialisation, saving and reopening
- Pivot Slicer cross-filter settings persist by way of their native tabular representation
- Timeline discovery keeps UTF-16 workbook and linked-part decoding during Open XML loading
Version 2.384.97
Added
- Scalar and calculated-array defined names work in supported numeric and counting aggregate calculations, with native coercion, dependency tracking and resource limits
Fixed
- Numeric aggregation propagates typed errors from local worksheet references, empty averages return division-by-zero errors, and failed named references keep their errors without restarting the partial traversal
Version 2.384.96
Added
- Calculated-array arguments for text joining and for supported median, order-statistic, percentile, quartile, percent-rank, multiple-mode and population covariance calculations
Changed
- Array and reference collection preserves native scalar coercion, typed errors, the original covariance pairing and calculation resource limits
Fixed
- Finite median midpoint calculations avoid same-sign overflow, and exclusive percentiles accept valid endpoint and singleton ranks
Version 2.384.95
Added
- Transactional native compact Pivot report output with synchronised worksheet values, layout metadata and persisted cell ownership
- Read-only Slicer member availability across connected views whilst other filters are active
- Explicit historical Pivot cache member cleanup with configurable retention and coordinated remapping of linked selections
Changed
- Supported native Pivot output keeps the current manual filters and captions, rejecting unsupported layouts or edited owned cells before any mutation
Version 2.384.94
Added
- Shared-cache PivotTable views plus local Pivot Slicer creation with explicit worksheet bounds
- Transactional Slicer removal that either clears its restriction or preserves the selection as ordinary Pivot filters, including the future-member policy
- Fixed numeric, date and discrete grouped-cache reconstruction with member identities kept stable
- Detached previews of native compact Pivot layout metadata using exact member and aggregate identities
Fixed
- Reopening a populated workbook now replaces previous typed Pivot caches, and authored native Slicer links remain recognised by Excel
- Grouped cache serialisation preserves declared native member domains and the official grand-total and data-axis attributes
Version 2.384.93
Added
- A validated XLSB reader and writer covering typed cell values, basic styles, ordinary worksheet views and dimensions
- Explicit binary output from workbook file and stream saving, with automatic detection of binary input and conversion fidelity reports
Changed
- XLSB conversion stages whole packages and rejects unsupported features or calculation settings before output, including unchecked or loss-allowed saves
Fixed
- Configured ZIP compression levels are applied before deflater initialisation
Version 2.384.92
Added
- Transactional Pivot cache refresh and safe worksheet materialisation for supported local defined-name and table sources
- Worksheet-scoped defined-name lookup and caller-resolved source bounds for the cache refresh
Fixed
- Local source identity and defined-name scope survive worksheets being moved and renamed, including quoted and Unicode names
- Defined-name formula XML omits the optional leading equals sign that only the in-memory formula syntax requires
- Table totals membership follows the actual totals-row count, keeping all data rows when only the totals UI hint is present
Version 2.384.91
Added
- Calculated-array inputs and typed results for transpose, matrix multiplication, determinants and matrix inversion
- Ordered selector vectors, duplicates and negative indices for row and column selection
- Calculated lookup vectors and array-valued lookup requests, with complete scalar lookup slices and typed fallback values
Changed
- Matrix work, lookup scanning, selector traversal, copying and padding honour evaluation-step and array-memory limits across composition
Fixed
- Formula and array-result text caches are displayed correctly in Excel before recalculation
- Modern rich-error caches include the workbook version and calculation-feature declarations needed for native cached display
- Lookup and flattening options reject out-of-range values before numeric narrowing, whilst fractional options follow native truncation
- Empty take, drop and flatten results keep their typed calculation errors
Version 2.384.90
Added
- Isolated Pivot result previews retain shared Slicer selections and caller filters without touching the live calculated cache
- Safe worksheet materialisation for supported local Pivot sources stages results, rejects conflicting content and structures, and preserves existing cell objects, formatting and comments
- Exact typed-value ownership survives XLSX saving and reopening, enabling safe result resizing, movement and explicit adoption of existing scalar Pivot values
Fixed
- Deleting the last bound Pivot Slicer view is rejected before its drawing, cache, reserved name or selection is removed
- Clearing Slicer views validates every affected cache before mutation and cleans up permitted views, drawings and unbound caches together
Version 2.384.89
Added
- INDEX accepts array-valued row and column selectors over calculated arrays and worksheet ranges, including paired selections and cross products of rows and columns
Fixed
- Selector results preserve typed values and errors, pad missing selector positions with #N/A, and respect the calculation memory and evaluation-step limits
- Fractional scalar selectors that truncate to zero produce complete row or column spills, whilst negative selectors return #VALUE! before truncation
- Scalar range selection retains reference behaviour, and selector spills recover from obstructions, resize and recalculate after saving and reopening
Version 2.384.88
Added
- Typed member inspection, shared-member selection and clearing for supported imported non-OLAP Pivot Slicer caches
- Connected PivotTable calculations intersect Slicer selections with independent restrictions on other fields and with caller-supplied record filters
Changed
- Selection changes validate every connection and member before committing, reject ambiguous imported same-field masks and preserve unsupported cache representations
- Slicer cache collection changes respect workbook write protection whenever they affect connected PivotTable calculations
- Deleting bound non-OLAP Pivot Slicer caches is rejected atomically so runtime and saved filter state stay consistent
Fixed
- Edited Pivot Slicer selections and connected view member masks save together whilst retaining imported namespaces and unknown extensions
- Supported Slicer connections follow saved sheet identities and resolve extended cache identifiers independently of the ordinary workbook cache identifiers
- Imported PivotTable definitions stay associated with their original views when worksheets are reordered
Version 2.384.87
Changed
- Local rectangular Pivot cache refresh preserves existing field and member identities, appends new typed members and keeps shared-view filters and selections bound to their original members after sources are reordered, removed or reintroduced
- Source headers match database fields by name, allowing columns to be reordered whilst calculated fields keep their formulas and receive fresh empty record placeholders for subsequent evaluation
- Refresh validates and stages the complete source before updating the cache, rejecting unsupported schemas, source types, derived grouping and new unmapped discrete-group members without partial changes
Fixed
- Pivot error values keep their types and codes in shared items and records through XLSX saving and reopening
- Refreshed shared-item domains recompute type flags and representable bounds, and XLSX cache metadata accurately describes mixed values, dates, errors, Boolean values and blanks
- Source refresh reads absent cells without creating worksheet cells and compares Unicode field headers without narrowing the text
- Saved refreshed PivotTable views include new cache members before subtotal items whilst retaining existing member order, hidden flags and imported layout extensions
- Page selections stay bound to the correct member when view order differs from cache order, calculated fields no longer shift saved source records, and refresh timestamps use the numeric XLSX representation
Version 2.384.86
Added
- INDEX accepts computed arrays and constants with scalar selection, complete-array selection and row or column extraction whilst retaining reference behaviour for range sources
- SORT and UNIQUE accept calculated arrays and constants, allowing direct composition with FILTER, SEQUENCE, LET and other array-producing expressions
Changed
- Composed array expressions retain automatic XLSX spill resizing, fixed-range array calculation, typed errors and recalculation after saving and reopening
Fixed
- Array selection and sorting truncate fractional numeric options, invalid Boolean option text returns #VALUE!, and computed-array operations honour memory and evaluation-step limits
Version 2.384.85
Added
- XLSX dynamic arrays now calculate into automatically resized spill ranges, preserve user obstructions with #SPILL!, support spill references and explicit implicit intersection, and recover cached spill ownership after the workbook is reopened
- Conversion preflight reports known target-format losses, and checked saving can reject those losses before an existing file or stream is written
- Explicit macro-enabled template output keeps existing VBA projects intact in XLTM packages
- Caller-provided query-table refresh supports bounded fixed-schema results, synchronised table and filter ranges, progress, cancellation and transactional rollback
Changed
- Repeated report bands clone complete threaded conversations with remapped identities and preserve rollback whenever a target fails
- ODS custom Boolean validation, supported formula-valued bounds, list sources and qualified references translate with base-cell rebasing; unsupported definitions and cell references are omitted together
Fixed
- Fixed-range array formulas evaluate raw range arithmetic element-wise, multiple-array MAP accepts matching lambda parameters, and FILTER evaluates calculated arrays and masks
- Modern #SPILL! and #CALC! errors retain typed XLSX rich-value metadata whilst preserving unrelated imported metadata and rich-value buckets
- Newly authored XLSX formulas save with canonical argument separators and future-function prefixes for Excel interoperability; saving preserves the in-memory expression and reopening hands back the canonical formula syntax
- Supported local chart series refresh numeric, text, date, error, bubble and hierarchical category caches after edits and recalculation
- Native pagination renders merged spans through their original anchor, clips page fragments and suppresses interior borders and gridlines
Version 2.384.84
Changed
- The Delphi and C++Builder getting-started examples now include a practical sales order with typed dates, prices, discounts and calculated totals, and verify the saved XLS and XLSX workbooks after reopening
- The invoice example now connects a printable invoice to editable payment terms and a receipt ledger, working out discounts, tax, payments and the outstanding balance
- The worksheet layout example now demonstrates creating, enumerating, removing and preserving merged headings after reopening
- Nine more focused API example families have moved into Miscellaneous, keeping the main catalogue centred on complete business workflows and interactive tools
Removed
- The minimal standalone merged-cell and rich-text examples have been folded into the worksheet layout and dashboard examples
Version 2.384.83
Changed
- The demo catalogue now separates complete experiences and substantial workflows from focused API recipes in each platform's Miscellaneous folder, with direct navigation and ready-to-build projects in both tiers
Removed
- Three redundant range and worksheet-layout demos have been removed; their complete scenarios remain available under RangeOps and SheetLayout
Version 2.384.82
Changed
- Delphi and C++Builder dashboard galleries open straight onto a populated workbook with live totals, rendered charts, editable details, price scenarios and exports of the current result
- The API tour provides direct dashboard, sales data, chart preview and API recipe navigation with a repeatable dataset covering all twelve months
- Examples carry their required scenario units and manifest resources locally, so each project can be copied without a separate common directory
Fixed
- The API tour creates its sales data before entering dashboard formulas, allowing its live showcase to initialise successfully
- Live showcase charts refresh their cached values and labels after recalculation, and repeated C++Builder gallery exports preserve the current edits without accumulating generated report sheets
Version 2.384.81
Changed
- Worksheet copying examples verify independent content, remapped formats, formulas and embedded objects after reopening their output
- Date-system, search, grouping, array-formula and picture examples verify their distinct behaviour and report failed output through a nonzero exit code
Fixed
- Classic XLS AutoFilter ranges keep their complete row and column bounds after saving and reopening, including copied filters with active criteria
- Dashboard galleries create referenced worksheets before entering formulas, calculate totals before export and generate all the requested companion formats even when another output fails
- The C++Builder dashboard gallery produces the documented CSV, HTML and RTF companion files
- Compiled reports preserve ordinary failure reporting in classic Win64 C++Builder static builds whenever a destination cannot be replaced
- Interactive API examples report PDF, HTML and CSV export failures instead of claiming the files were written
- The feature showcase completes its supported semantic-hash demonstration and validates its saved workbooks without resorting to unsupported modern drawing snapshots
Version 2.384.80
Changed
- The example catalogue groups projects by learning task and identifies recommended entry points, format-specific lessons and compatible project names
- Worksheet layout and range relocation examples share complete scenarios whilst preserving their existing project and output names
- Memory, advanced CSV, printing, document properties, text box and worksheet protection examples demonstrate complete workflows with saved-data verification and explicit failure reporting
Fixed
- Reopened XLSX text boxes keep their drawing relationships when saved again, so annotations remain available through repeated save and reopen cycles without duplicate XML namespace declarations
- Batch conversion examples honour Skip existing before opening sources or invoking writers, and verify workbook success codes before reporting completion
- The invoice example includes the payment terms and its complete title in the printable area
- The page setup console example starts with ordinary user privileges rather than triggering Windows installer detection
Version 2.384.79
Fixed
- ODS file saves with export options preserve the existing destination when serialisation fails or saving is cancelled, and report destination replacement errors consistently
- ODS export options use the normal save lifecycle, including recalculation policy, progress cancellation, diagnostics and workbook write protection for file and stream output
- XLSX stream saves honour the configured recalculation policy, preserving cached values in manual mode and refreshing dirty formulas when requested
- Completed XLSX and ODS save notifications no longer turn an already committed output into a cancellation failure
- Failed streaming worksheet patch initialisation and finalisation release source file handles, allowing callers to clean up their temporary sources and reuse the writer after initialisation failure
Version 2.384.78
Fixed
- Range copies and clones keep intersecting virtual formatting and replace prior overlay formatting only inside the destination, including overlapping copies and cross-workbook formatting
- Explicit formatting resets stay effective after saving and reopening workbooks with row or column default formatting
- XLSX cells that explicitly use the workbook's default formatting retain its custom fonts, fills and number formats
Version 2.384.77
Fixed
- Whole-row and whole-column conditional-format and data-validation targets follow row and column edits and range cloning whenever fully contained in the source, with bounded target geometry and preserved relative formula anchors
- Finite repeated blank styles imported from ODS retain their full used-range extent and newly created or reset workbooks report the current library version in document properties
- Whole-row, whole-column and whole-sheet cell copies retain sparse storage, clear replaced destination contents without expanding blank coordinates and preserve overlapping source data and cross-workbook formatting
Version 2.384.76
Fixed
- Conditional-format and data-validation rules now apply uniformly to absolute, reversed, whole-row, whole-column and whitespace-separated targets during lookup, deletion, conditional calculation and validation checks
- Malformed and out-of-grid target areas no longer match cells, whilst valid areas in the same rule remain active; full-grid conditional statistics retain sparse cell storage
- ODS validation targets use valid cell anchors for whole rows and columns and equivalent overlapping conditional targets no longer create duplicate rules when reopened
Version 2.384.75
Fixed
- ODS cell comparison and expression rules keep their full whole-row, whole-column and wide target ranges in Excel-compatible output; repeated blank carriers keep sparse ranges compact and preserve overlapping rules and worksheet metadata
- Reopening ODS repeated styled blank regions keeps their base formatting compact and standard conditional rules retain overlapping precedence and coverage inside merged regions
Version 2.384.74
Fixed
- ODS conditional formatting retains supported font, background and number-format overrides when saved and reopened, including explicit resets; rules with different highlights or target ranges stay separate
- XLSX conditional formatting keeps built-in and custom number formats, including formats used only by a conditional rule; saving no longer removes those custom formats or points rules at a different format
- ODS percentage styles include the percent symbol required by other spreadsheet applications and reopen without that symbol being duplicated
Version 2.384.73
Fixed
- Copying text to the clipboard, reading clipboard text and pasting text or XML Spreadsheet data no longer fail at random on Windows 10 and 11. After every clipboard change, Explorer and the Clipboard User Service (clipboard history) open the clipboard for a few milliseconds to read it; text operations only tried to open it once and could fail with "access denied" during that moment
- All clipboard operations now use the same policy as the BIFF8 (Excel format) copy and paste: they keep trying to open the clipboard for about 500 ms. When another application holds the clipboard for longer, the operation still fails and the existing clipboard content stays unchanged
Version 2.384.72
Fixed
- Opening an ODS file reads the General number format correctly. Excel and LibreOffice write General as a number style without a decimal-place count, which was read as two fixed decimal places, so a value such as 1.5 showed as 1.50; such cells now carry no number format, as in the source application
- Text around a General number is kept, for example
General" kg"
Version 2.384.71
Fixed
- ODS files saved by Excel or LibreOffice no longer report a used range covering the whole sheet. Both give every row and column a size out to row 1048576 and column 16384; empty rows whose height is automatic now keep the default height, and the column sizes that run out to the last column become the sheet's standard column width. A 10-row Excel file opened and saved again shrinks from roughly 2.8 MB to a few KB
- Row heights set by hand and automatic heights on rows with content (for example rows grown to fit wrapped text), are still kept
- Saving to ODS writes the sheet's standard column width (
StandardWidth) on columns that have no width of their own; it used to be omitted, since ODS has no sheet-wide default column width
Version 2.384.70
Fixed
- ODS files saved by Excel or LibreOffice open in milliseconds again. Both pad every row out to column 16384 and add a padding block down to row 1048576; a 10-row file from Excel used to take more than 5 minutes to open and one from LibreOffice did not finish either
- Empty padding cells that look exactly like the document's Default cell style are no longer turned into formatted blank cells; a 10-row Excel sheet used to gain about 180,000 of them. Empty cells with their own fill, border, font, alignment, number format or protection are still preserved
Version 2.384.69
Fixed
- Conditional formats saved to ODS now appear in Excel. Value rules (equal, between, greater than and so on) and formula rules are also written as standard ODF
style:mapconditions on the cells they cover, the only form Excel reads; Excel used to open HotXLS ODS files without any of those rules - LibreOffice now imports ODS value rules written by HotXLS with their real operator and bounds; it used to turn each one of them into "equal to 0"
- Opening an ODS file reads conditional formats stored as
style:mapconditions, as written by Excel and other ODF producers. When a file also carries the same rules in LibreOffice's own form, each rule gets read once - Opening an ODS file reads LibreOffice's spelling of value rules (
=5,between(1,10),!="x"); files from earlier HotXLS versions still open as before
Version 2.384.68
Fixed
- Formulas that apply an operator to a multi-cell range or an inline array, for example
=SUM(A1:B1*{10,100}),=SUM((A1:B2>2)*1)or=MAX(A1:B2-1), are stored the way Excel 365 stores them, so Excel shows the same result as HotXLS: in XLSX as single-cell dynamic-array formulas, in XLS as one-cell array formulas. Excel would open them with implicit intersection (=SUM(@A1:B1*@{10,100})) and show #VALUE! or a wrong value - XLS array formulas write their references and array constants in array form, just as Excel does; Excel used to evaluate array formulas written by HotXLS with implicit intersection
- XLSX files with dynamic-array formulas (including those created with
SetDynamicArrayFormula) open in Excel; Excel rejected the whole file because the dynamic-array metadata used a differently cased extension identifier
Version 2.384.67
Fixed
- Text comparisons follow Excel's order in both engines: they ignore case and use the system locale's word sort, so hyphens and apostrophes just break ties (
"a-b">"ab"is TRUE) and other punctuation sorts before digits and letters ("a~b">"ab"and"a_b">"ab"are FALSE). This applies to the comparison operators,>text/<textcriteria in COUNTIF, SUMIF, the *IFS family and the database functions, array comparisons, lookups, SORT-style functions as well as range sorting - VLOOKUP and HLOOKUP compare text case-insensitively, so
VLOOKUP("ABC",...)finds "abc" as in Excel
Version 2.384.66
Fixed
- Formula-based conditional formatting written to ODS is now recognised by LibreOffice: the rule gets stored as
formula-is(...)with its base cell, the form LibreOffice itself writes. Before, LibreOffice read each such rule as a plain "cell value equals 0" rule - Conditional formatting formulas written to ODS translate inline arrays, unions, whole-column and whole-row references and retain
$markers the same way as cell formulas (COUNTIF($A:$A,A1)>1becomesCOUNTIF([.$A:.$A];[.A1])>1) - Opening an ODS file reads formula-based conditional formatting produced by LibreOffice (
formula-is) as well as files from earlier HotXLS versions
Version 2.384.65
Fixed
- Whole-column and whole-row references (
A:A,$A:$B,1:1,$1:$2) in formulas written to ODS use the OpenFormula reference form ([.A:.A]). Excel used to open such cells as=SUM(A:(A))with #NAME? or drop the formula; ODS files from HotXLS now show the same formulas and values in Excel and LibreOffice
Version 2.384.64
Fixed
- Database functions (DSUM, DCOUNT, DCOUNTA, DAVERAGE, DGET and the rest) treat a text criterion with no operator as "begins with", as Excel does:
abin the criteria range matches abc, ab and AB, and wildcards continue to apply (a?matches every entry of two or more characters starting with a).=aband<>abkeep comparing the whole entry
Version 2.384.63
Added
- Formulas can contain inline array constants such as
{1,2;3,4}(commas for columns, semicolons for rows, with numbers, text, TRUE / FALSE and error values) and reference unions such as(A1:B2,D4), in both the XLS and XLSX engines; typing them used to fail with "invalid formula syntax" - Array constants are evaluated as arrays (
=SUM({1,2}*{3,4}),=ROWS({1,2,3;4,5,6}),=SUMPRODUCT(A1:A2,{1;10})) and unions work in SUM, COUNT, AVERAGE, MIN, MAX and COUNTA, in AREAS, in ISREF and in the area_num argument of INDEX
Fixed
- XLS files store array constants so that Excel reads them: the constant was written as a reference, which Excel displayed as
=#N/A; XLS formulas that contain array constants or unions also come back with their formula text
Version 2.384.62
Fixed
- The intersection operator (a space between two references) returns the cells the two references cover, as in Excel:
=SUM(A1:B2 B1:B2)is 6 instead of 2, references without a common cell give #NULL!, and an intersection can be passed to functions that take references such as ROWS, COLUMNS and INDEX. This covers both engines, calculated formulas and formulas stored in cells - XLS files keep intersection formulas usable in Excel: the referenced ranges are now written out as references, so Excel no longer reads
=SUM(A1:B2 B1:B2)as=SUM(@A1:B2 @B1:B2)and shows #VALUE! - An intersection used as a single value with more than one common cell takes the cell in the formula's row or column, like any multi-cell reference
Version 2.384.61
Fixed
- SUMPRODUCT accepts array expressions such as
(B1:B2>0)*1,--(B1:B2>0),B1:B2*C1:C2and a single argument, in both the XLS and XLSX engines; these used to return #N/A. Arguments of different shapes return #VALUE!, an error inside any argument is returned, and text and logical values count as 0, matching Excel - Operator expressions over ranges inside SUM, COUNT, AVERAGE, MIN, MAX and COUNTA are evaluated element-wise, as under Excel's dynamic arrays:
=SUM((B1:B2>0)*1)counts both rows instead of using only the first cell - TRUE counts as 1 in arithmetic:
=TRUE*1returned -1 - Element-wise comparisons treat a blank element as 0, "" or FALSE to match the other side and compare logical values as logical values; joining a logical value with
&in an array gives TRUE / FALSE
Version 2.384.60
Fixed
- Wildcard Find and Replace with whole-cell matching (
FindText,ReplaceText,FindTextIn,ReplaceTextInin both engines) match the whole cell the way Excel does:a*bnow findsabcb, which was rejected because matching stopped at the firstb - In wildcard Find and Replace,
~makes whatever character follows it literal and a trailing~is ignored, as in Excel:a~bfindsab, anda~~bfindsa~b
Version 2.384.59
Fixed
- XLSX document creation and modification times (
Created,Modified) and date-valued custom properties now read correctly when the stamp has fractional seconds (2026-03-15T08:30:00.123Z) or a time zone offset (+08:00,-05:00): the time is converted to local time instead of being assumed local and left unchanged - Date-only stamps (
2026-07-01) are read as that date; stamps with a time but no zone, which the W3CDTF format does not allow, continue to be read as local time
Version 2.384.58
Fixed
- XLSX AutoFit through
TXLSAutoFit(FitXlsxSheet,FitXlsxSheetColumns,FitXlsxSheetRows,MarkSheet) measures each cell in the font it is displayed with; since 2.384.46 it picked the next font in the workbook's font list, so a bold heading could be measured in another cell's small font and end up too narrow - AutoFit also uses the font a cell inherits from its row or column style
Version 2.384.57
Fixed
- "Precision as displayed" (
FullPrecision = False) in the XLSX engine now rounds the way Excel and the XLS engine do: percent formats hold two extra decimals (0.1234 shown as0.0%stores 0.123, not 0.1), negative and zero values use their own format section and halves round away from zero (2.5 shown as0stores 3, not 2) - Both engines honour thousands-scaling commas with "precision as displayed": 12345.678 shown as
0.0,(12.3) stores 12300, as in Excel - A logical formula result in a cell with a number format is no longer converted to -1 by the XLS engine's "precision as displayed"
Version 2.384.56
Fixed
- ODS files written by HotXLS declare the namespaces for their formula prefixes, so LibreOffice evaluates the formulas instead of showing #VALUE! in every formula cell
Version 2.384.55
Fixed
- Formulas written to ODS keep their meaning: inline arrays take OpenFormula's row separator (
{1,2;3,4}becomes{1;2|3;4}instead of a single row), a reference union such as(A1,B2)becomes the~operator instead of two function arguments and absolute references keep their$markers - Reading such a union back from ODS no longer adds a second pair of parentheses, so such formulas survive an XLSX to ODS to XLSX round trip unchanged
Version 2.384.54
Fixed
- Password-protected XLS files saved in the Excel 5.0/95 format (XOR obfuscation) now open in Excel. The key stored in the file is derived from the password instead of being random and the obfuscation array uses the bit rotation Excel expects; before, Excel reported a wrong password for every such file, and with the key alone corrected it reported the file as damaged
- XOR-obfuscated workbooks are read with the same corrected array, so files whose key matches the password decrypt the way Excel encrypts them; XOR files written by earlier HotXLS versions still open
Version 2.384.53
Fixed
- Comparing a blank cell against a logical value treats the blank as FALSE in both the XLS and XLSX engines, as Excel does: with A1 empty,
=A1=FALSEand=A1<TRUEnow return TRUE and=A1=TRUEreturns FALSE. Before, the blank was compared as 0, which sorts below every logical value
Version 2.384.52
Fixed
- COUNTIF, COUNTIFS, SUMIF, SUMIFS, AVERAGEIF, AVERAGEIFS and the database functions match text criteria by Excel's wildcard rules in both the XLS and XLSX engines:
~*and~?match a literal asterisk or question mark, square brackets are ordinary characters and a criterion without*or?is a plain case-insensitive comparison. Previously, a criterion such as"[x]"was read as a character set,"~*"did not match an asterisk, and a malformed pattern silently matched nothing at all "<>text"criteria count numbers, logical values and blank cells as not equal, and a bare"<>"counts every non-blank cell, as in Excel; text comparison under<>is now case-insensitive- MATCH and XLOOKUP wildcard matching treat
~as an escape for whatever character follows it and ignore a trailing~, as Excel does
Version 2.384.51
Changed
- Read-only cell snapshots retain worksheet names in shared UnicodeString storage; SheetName is now a readable and writable WideString property with the same familiar read and assignment syntax as before, but its raw field address and the previous record layout are unsupported; callers must recompile against this release
- Report output to an empty destination stream skips the unnecessary backup snapshot whilst preserving rollback of the destination contents and position if output fails
- Deep formula audits process numeric caches more efficiently while preserving cached Variant values, evaluation results and reported findings
Fixed
- XLS and XLSX clipboard paste captures BIFF8 data and fallback text together under one clipboard lock, so both formats come from the same clipboard state; readable BIFF8 remains usable when its text companion cannot be retrieved, unavailable text alone inserts no cells and the existing clipboard-open retry policy is unchanged
- Failed required text or BIFF8 clipboard publication keeps the original Win32 error code across cleanup so callers can retrieve the failure diagnostic immediately after the call
- The single-attempt clipboard text reader preserves native data-retrieval failures across clipboard cleanup without changing its retry behaviour
Version 2.384.50
Changed
- Formula symbol audits run faster on sparse XLS workbooks whilst preserving the reported findings and their order
Version 2.384.49
Fixed
- WorkbookAudit demos (Delphi and C++Builder):
AuditReport.jsonis written without a UTF-8 byte order mark so strict JSON parsers accept it; XLS sheets report their AutoFilter range; XLSX defined names that point at another workbook show the linked file instead of its index; command-line runs no longer overwrite the saved settings; an empty folder box falls back to the program folder rather than the drive root; a failed sample save is logged instead of reported as created - ApiTour demos: rebuilding the showcase workbook keeps the previous one when the rebuild fails, so the export buttons no longer crash; workbooks are freed when building throws; the HTML export logs its errors; the log lists the five conditional formats that are actually created
- ExcelGraphics demos: an unsupported picture type is reported instead of saving an empty sheet and the open dialog lists only supported formats
- OdsExport demos compare the font size in the round-trip check and return a non-zero exit code when the check or the save fails; the C++Builder OdsImport demo checks the save result and no longer creates empty cells as it reports
- DataExport / ExportWithColoring demos narrow only the first column, as their comments say, and the C++Builder export demos open the save dialog in the program folder
- Demo readmes list the APIs and output files that the demos actually use
Version 2.384.48
Fixed
- Document creation and last-saved times are now written in UTC, as the file formats require and read back as local time: XLSX
Created/Modifiedand custom date properties, and XLSCreatedDate/LastSavedDate. Before, the local time was stored as if it were UTC, so Excel and Windows Explorer showed the stamps displaced by the time-zone offset; values written and read by HotXLS itself are unchanged
Version 2.384.47
Fixed
- XLS files with XOR obfuscation (the password protection used by Excel 5.0/95 workbooks,
EncryptionType = xletXor): the key position used for each record now follows the file format specification, as other spreadsheet applications read and write it. Before, HotXLS could only read its own XOR files, and any record whose length was not a multiple of 16 decoded as garbage elsewhere
Version 2.384.46
Fixed
- XLSX AutoFit (
FitXlsxSheet,FitXlsxSheetColumns,FitXlsxSheetRows,MarkSheet) measures each cell in its own font, size, bold and italic rather than always Arial 10, so Calibri 11 text, bold headers and large titles no longer come out too narrow - XLSX AutoFit measures the text as shown through the number format (dates, currency, percentages) rather than the raw stored value
- XLSX AutoFit keeps fitted column widths within
MaxWidth; the cell margin used to be added after the limit was applied - XLSX AutoFit sizes rows of wrapped cells in columns that have no explicit width against the sheet default width; before, such cells were measured as a single line and the row ended up too short
Version 2.384.45
Fixed
- XLS workbooks:
ApplyAutoFiltercriteria such as'>=100'or'=2.5'are now saved as number conditions; they were saved as text, which Excel compares as text, so the filter hid all numeric rows. A value without a comparison operator (such as'North'or'100') is still saved as text, the way Excel stores a chosen list item Criteria1.DataTypereports 4 (number) for such criteria instead of 6 (text);Criteria1.Valuestill reads back as 100
Version 2.384.44
Fixed
INDIRECTwith an A1 reference text read the cell one row down and one column right (INDIRECT("D1")returned E2), in both XLS and XLSX workbooks; R1C1 text was already handled correctly. A reference past the last row or column now returns#REF!
Version 2.384.43
Fixed
- XLSX workbooks: formulas can now address the whole 1,048,576 × 16,384 sheet. References past column IV or row 65,536 (
=XFD1,=A100000,=SUM(XFC1:XFD1),Data!C1048576) used to be rejected as unknown names on entry or evaluated to an error; they now parse, calculate, shift with inserted rows and columns and save as written - XLSX workbooks: whole-column and whole-row references (
A:A,1:1) cover the full sheet, soROWS(A:A)returns 1048576 andSUM(A:A)includes values below row 65,536;ADDRESSreturns three-letter columns such as$XFD$1 - XLS workbooks: references to the final row and column of the 65,536 × 256 sheet (
=A65536,=IV1) are accepted; they were rejected as unknown names
Version 2.384.42
Fixed
- Legacy
lxRows/lxColsunits (kept for source-compatibility reasons; the workbook classes do not use them): a row index past 1,048,575 raisesERangeErrorinstead of wrapping around to row 1, the ROW record no longer marks every outline-level change as collapsed and writing COLINFO for a column without its own settings uses the defaults instead of crashing
Version 2.384.41
Fixed
- Lazarus / Free Pascal builds compiled in ANSI string mode: scratch files whose path contains characters outside the system code page are now removed during cleanup; before, their names were stored lossily and the files were left behind in the temp folder
Version 2.384.40
Fixed
TlxCellMMU(the packed cell store) raisesEInvalidOperationwhen a cell is written out of row sequence within a 256-row block or over an existing cell, andERangeErrorfor a negative position or a column past 65,534; before, such a write silently corrupted the adjacent row. The library's own bulk writes already keep row order and are not affected
Version 2.384.39
Changed
- XLSX workbooks: assigning
TXLSXWorksheet.TabColornow also setsTabColorIsAutoto False, so the tab colour shows without a second assignment, matching the font, fill and border colour properties. SettingTabColorIsAutoto True afterwards still removes the tab colour
Version 2.384.38
Changed
- XLS workbooks:
TXLSWorksheet.AddPivotTablenow treatsDestRowandDestColas 1-based, likeCells[Row, Col], the documentation and the XLSX engine;AddPivotTable('Data!A1:C9', 3, 1, ...)anchors the pivot table at A3. Code that passed 0-based positions must add 1 and an anchor of 0 or outside the sheet now returnsnil - XLS workbooks: the positions on
TXLSPivotTable(FirstRowtoFirstDataCol) and the source range onTXLSPivotCache(SourceFirstRowtoSourceLastCol) are now 1-based for new and opened pivot tables, so the same code reads the same cells in both engines and a pivot table copied between them stays put
Version 2.384.37
Fixed
- XLSX workbooks: a pivot table placed below row 65,535 or one pushed there by inserting rows, kept its true position; previously the anchor was cut down to 16 bits and the saved pivot table landed on the wrong rows
- The pivot table position properties (
FirstRow,FirstCol,LastRow,LastCol,FirstHeaderRow,FirstDataRow,FirstDataCol) are nowIntegerinstead ofWord - XLSX workbooks:
AddPivotTableandAddPivotTableCopyreturnnilwhen the anchor lies outside the sheet or the copied block would overrun the last row or column, instead of writing a pivot table Excel rejects
Version 2.384.36
Fixed
- C++Builder demos XlsTables, XlsCondFormat12, XlsCreateChart and InteractiveFeatures write their text columns as plain text; passing a
const wchar_t*toOleVariantpicked theboolconstructor and every header and label came out as TRUE - The DefinedNames demo lists the XLS names from index 1 instead of crashing on index 0, WorkbookAudit counts external references in XLS workbook names and FileMonitor writes
Monitored.xlsxinstead of the misspelled.xlsxxthat made every sheet-name read fail - The Pictures and OdsExport demos embed a valid PNG; the byte literal was corrupted during the string conversion and the Pictures chunk lengths were wrong
- ApiTour evaluates its
DEMOADDstep on the API Tour sheet instead of the active Dashboard sheet, where a text argument could abort the start-up; the C++Builder classic tour now shows the step's result - FreezePanes, QuickStart and ApiTour freeze precisely their header rows and columns;
FreezePanestakes counts, not the first scrollable cell - Conditional format colours in ApiTour, CondFormatGallery, OdsExport and WorkbookAudit are given in BGR as the API expects, so data bars and colour scales show their intended colours; CondFormatGallery gives its top-N, duplicate and above-average rules a visible highlight
- MemoryDataExport and HtmlExport no longer report successful CSV, HTML and RTF exports as failures (these writers return 0 on success) and MemoryDataExport writes all three files even if one fails
- Demos that save and then report or open the file (QuickStart, ExcelGraphics, HotXLSInMemory, OrderCalc, PurchaseOrder and several console demos) check the save result rather than announcing success when the file is locked
- ConversionWorkbench treats any negative writer result as a failure and removes the old output first, so a stale file no longer hides a failed conversion; the C++Builder version exports every sheet to HTML
- InvoiceTemplate, OrderCalc and DataExport no longer depend on the Windows number and date format: tax formulas, prices and date thresholds work on systems using a comma decimal separator or a year-first date order
- Smaller corrections: QuickStart totals use dark text on their light fill, DateSystems shows the raw serials and a valid 1904 epoch date, CrossWorkbookCopy keeps its merged cells outside the table, CrossWorkbookCopyXls uses a comma-separated list and a real light blue, Hyperlinks shows the intended link text, SheetProtection describes and sets the allowed actions correctly, OdsImport no longer creates empty cells while scanning, InteractiveFeatures saves a workbook without a VBA payload as .xlsx, WorkbookAudit reports encrypted XLS files and their VBA projects, ChartTypes keeps its charts clear of the data, the C++Builder data export demos find Demos.mdb from the IDE output folder and FormulaFunctions checks the reopened cell and counts reopen failures
Version 2.384.35
Fixed
- Assigning a colour to an XLSX font, fill, border edge or rich text run now takes effect on its own. These objects start with the automatic colour, and an explicit
Color,ForegroundColororBackgroundColorwas silently dropped unless the matchingColorIsAuto/ForegroundIsAuto/BackgroundIsAutoflag was also cleared - Assigning an RGB colour also clears an earlier theme or indexed colour source, which would otherwise win over it; assigning a theme or indexed slot of 0 or more clears the automatic flag
- Border colours pasted into an XLSX workbook from the clipboard, border colours of classic workbooks exported to XLSX, and the font colour passed to
TXLSXComment.SetFontare now written instead of being lost to the automatic colour
Version 2.384.34
Fixed
- Subtotal, grand total and blank items in a pivot field's item list are no longer read as data items; copying such a pivot table would write an item pointing at cache index -1
- Pivot fields from Excel files keep their default subtotal: Excel omits
defaultSubtotalwhen it is on, and HotXLS treated the missing attribute as off - Pivot cache fields whose shared items leave out
containsStringare read as text fields, following the schema default, instead of mixed fields
Version 2.384.33
Fixed
- Pivot tables from the XLSX engine use the schema's axis values (
axisRow,axisCol,axisPage); earlier versions wroterowAxis/colAxis/pageAxis, which are not valid OOXML. HotXLS still reads files carrying the old values - Pivot fields used in the values area are flagged with
dataField="1", and fields without items no longer get an empty<items>list that the schema does not allow - Hidden and collapsed pivot items keep their state when a pivot table is copied or rebuilt and each field's item list ends with the subtotal items Excel expects for its subtotal functions
- Pivot cache fields carry a numeric
numFmtIdinstead of the textGeneral
Version 2.384.32
Fixed
- ODS import converts inline array rows correctly:
{1;2|3;4}becomes{1,2;3,4}instead of a formula Excel cannot parse - ODS import converts the reference union operator:
SUM([.A1:.B2]~[.C3])becomesSUM((A1:B2,C3))
Version 2.384.31
Fixed
- ODS import reads time cells whose duration carries a date part, such as
P0Y0M0DT12H30M15S, and week durations such asP1W, instead of falling back to the display text - An
Mbefore theTseparator of an ODS duration is a month, not a minute; non-zero years and months, which have no fixed length, now fall back on the display text instead of turningP1Minto one minute
Version 2.384.30
Fixed
TGWmfEmfReadcloses the metafile when the file is too short or damaged, rather than keeping it locked until the process exitsTGWmfEmfReadtreats a placeable WMF whose header gives zero units per inch as unsized rather than dividing by zeroTGWmfEmfReadkeeps 32-bit sizes and bounds inBSEWMF, matching the picture header it describes
Version 2.384.29
Fixed
- WMF and EMF pictures of 64 KB or more in classic XLS workbooks survive open and save; their stored and uncompressed sizes were truncated to 16 bits, so Excel could not decode the picture in the saved file
- Metafile picture bounds outside the -32768..32767 range are kept rather than wrapping around
Version 2.384.28
Fixed
TXMLWriterno longer produces malformed XML when text or attribute values contain control characters, unpaired surrogates or U+FFFE / U+FFFF; characters that XML 1.0 cannot represent are omittedTXMLWriterwrites a carriage return in element text as a character reference, so the text comes back unchanged instead of having CR turned into LFTXMLWriterraises an error when the target stream accepts fewer bytes than written, such as on a full disk, rather than leaving a silently truncated file
Version 2.384.27
Fixed
- Copying a range whose formulas point above or to the left of the source block, such as
=B4+1copied from B5, now pastes with the reference still one row up; it used to stay pinned to the original cell and a formula could end up referring to itself - The Excel clipboard data HotXLS publishes keeps the copied cells at their sheet position, so applications that read it see the original cell addresses
Version 2.384.26
Fixed
- The zlib string helpers (
ZCompressStr,ZDecompressStrand the in-place variants) now process the whole string; with Unicode strings only the first half of the text was compressed, so a round trip lost characters
Version 2.384.25
Fixed
- Hyperlinks in classic workbooks whose display text is flagged without the site flag are read correctly and hyperlinks with an unusual target type no longer fail the whole open or return a garbled sub-address
Version 2.384.24
Fixed
- An exception raised by the file monitor change handler no longer stops the monitor silently; it keeps watching and reports subsequent changes
Version 2.384.23
Fixed
- Theme colours with a tint below -1 in a malformed file are clamped to black instead of producing random colours when exporting or printing
Version 2.384.22
Fixed
- Data connections created through the API are saved with the refresh version attribute the file format requires
- A connection with a missing or repeated name or id no longer makes the whole workbook fail to open; the entry is kept as it stands and saved back unchanged
Version 2.384.21
Fixed
- Changing the source code of a VBA module now takes effect in Excel: the project is saved so that Office compiles the new source rather than running the cached compiled code of the old one
- VBA module source is now saved in the compressed form the format specifies; the last block of every module was stored in a way Office treats as damaged
- A malformed VBA directory stream no longer makes opening the workbook hang and a module entry missing its stream information no longer leaves an empty module in the project
Version 2.384.20
Fixed
- Defined names loaded from a classic workbook keep their shifted references after rows or columns are inserted or deleted and the workbook is saved; the file previously still held the original reference
Version 2.384.19
Fixed
- Fitting only the rows or only the columns of an XLSX sheet no longer sets the width of every measured column or the height of every measured row, to zero when it had no explicit size
Version 2.384.18
Fixed
- AutoFilter criteria in classic workbooks are joined the way they were set: AND conditions were saved as OR and the other way round, so Excel showed the incorrect rows
- Boolean AutoFilter criteria are saved as TRUE or FALSE; they were kept in a form Excel reads as an error value
Version 2.384.17
Fixed
- The created and last-saved dates of classic workbooks now match Excel; they were written a day late and read a day early
- The last-saved date is stored under its correct document property; it was saved in the page-count slot, where Excel and Windows did not show it as a date
- The total editing time is stored as a duration, so Excel and Windows show the actual number of minutes instead of about 299 years; times written by earlier versions are still read correctly
Version 2.384.16
Fixed
- The unique-value rule of the import check now compares the cell values; every value after the first one in a column was previously flagged as a duplicate
- Adding a second rule for the same column replaces the first one cleanly; the old rule was freed but still checked and freeing the checker raised an invalid pointer error
- Checking a sheet no longer creates empty cells for the blanks it reads
- Keeping only the violating rows no longer writes past its row table when a violation lies below the used range and the caption row is inserted above the data instead of overwriting the first violation
Version 2.384.15
Fixed
- Reading a ZIP entry in small pieces no longer loses the last bytes of the entry when the compressed data ends in the middle of a repeated sequence, which could make a valid XLSX file fail with an entry size error
- Decompressing data that expands beyond 2 GB now raises an error rather than crashing the 64-bit process
- The decompression stream returns all remaining data after its input is exhausted rather than stopping early
Version 2.384.14
Fixed
- Interlaced PNG images with 1, 2 or 4 bits per pixel no longer write past the image buffer, which could crash or corrupt neighbouring pixels when exporting or printing a workbook that contains them
- Interlaced PNG images decode correctly when a pass begins with the Average or Paeth filter
- 2-bit greyscale PNG images now render their true grey levels, and reading single pixels of 2-bit greyscale and palette images returns the right colours
- PNG images whose compressed data has trailing bytes no longer hang the decoder and valid images with a large image data chunk are no longer rejected with a CRC error
- Images with an invalid bit depth or a chunk length beyond the end of the file are rejected cleanly rather than crashing or allocating gigabytes of memory
- Text chunks saved into PNG images are no longer truncated or corrupted
Version 2.384.13
Fixed
- Classic workbooks encrypted with RC4 now use the correct password hash for passwords of 28 characters or more, so they open in Excel; passwords of 32 characters or more previously produced files that even HotXLS was unable to open
- RC4 passwords of up to 255 characters are accepted when opening and files with 28 to 31 character passwords saved by earlier versions still open
- A malformed RC4 CryptoAPI header with an oversized length is reported as a corrupt file rather than raising a generic error
Version 2.384.12
Fixed
- Agile-encrypted workbooks that declare SHA-256 now decrypt correctly; the data segments were always decrypted with SHA-512 initialisation vectors, so the workbook failed to open even with the right password
- Agile files whose key data and password key encryptor use different hash algorithms are no longer reported as carrying a wrong password
- A spin count above the 10,000,000 limit of the format is rejected immediately rather than keeping the CPU busy for hours
- A truncated password verifier no longer reads past its buffer and the integrity key written by
SaveAsEncryptedAgilenow has the length the format requires
Version 2.384.11
Fixed
- Workbooks saved with
SaveAsEncryptednow open in Excel. The ECMA-376 Standard Encryption key was derived without its final step and the package size was encrypted together with the data, so Excel rejected the password; workbooks encrypted that way by Excel 2007 can now be opened too - Encrypted workbooks saved by earlier HotXLS versions still open with the correct password
- A malformed encryption header with an oversized length no longer causes an access violation whilst opening
Version 2.384.10
Fixed
- Copying and pasting formulas between cells and sorting with formulas copied along, no longer moves absolute references:
$A$1stays put,A$1moves only its column and$A1only its row, matching Excel - Function names that look like cell addresses, such as
LOG10(, are no longer moved as references when a formula is pasted, so the pasted formula no longer turns intoLOG11(and#NAME? - References qualified with a sheet name, such as
Sheet2!A1or'My Sheet'!B3, now shift on paste like unqualified ones - Pasting text that starts with
=or an apostrophe into a classic workbook keeps it as text; it was previously made into a formula or lost its first character
Version 2.384.9
Fixed
- Elapsed-time number formats such as
[h],[mm]and[ss].00are now recognised as time formats rather than being mistaken for colour names; with precision as displayed turned off (FullPrecisionset toFalse), a duration formatted as[ss].00is no longer rounded as if it were a plain two-decimal number, which previously reduced values of a few seconds to zero - Minute tokens separated from the hour or second by a literal, as in
h:mmandmm:ss, are now read as minutes rather than months when a number format is analysed
Version 2.384.8
Fixed
- Copying text, HTML or spreadsheet data to the Windows clipboard now uses a valid temporary owner, including in console programs and worker threads without an application window; copied data remains available after that owner is destroyed
- Failed clipboard publication now releases each allocated data block that Windows did not accept, including companion text and HTML blocks when spreadsheet publication fails
Version 2.384.7
Fixed
- Compiling the library from source with RAD Studio XE5 through RAD Studio 12 Athens failed once the Free Pascal support and the
DATEleap-day fix landed: those compilers still parse the Free Pascal version check whilst skipping it, and reject the numeric cast behind theDATE(1900,2,29)special case. Both spots now use forms that every supported compiler accepts, so the full RAD Studio range builds again
Version 2.384.6
Fixed
- Copying cells that carry a comment in a classic .xls workbook, whether within a workbook, into another workbook or by shifting rows and columns, kept the comment text but dropped its formatted runs, so every copy showed the whole note in one font; the runs now travel with the text, and across workbooks their fonts are added to the destination workbook
- Copying a whole sheet with
Sheets.AddCopyin a classic .xls workbook dropped comments on cells that held no value or formatting; those comments now get copied too - Comments in .xlsx workbooks reopened without the font name, strikethrough and colour of their formatted runs, and saved runs never carried underline or superscript/subscript; all of these now survive a save and reopen, including runs copied from another workbook with
CloneRangeTo
Version 2.384.5
Fixed
- Formatted runs in comments and text boxes in classic .xls workbooks no longer lose their fonts on save. A font used only by such a run could be dropped from the saved font list, most often when HotXLS re-saved a workbook it had already saved once and the run then showed the default font in Excel or picked up a font added in the meantime; those fonts are now kept and the runs are renumbered together with the rest of the font list
TextRuns.FontIndexon comments and text boxes follows the file's font numbering, where index 4 is never used and the fifth font is index 5; the palette reservation for indexed font colours now reads these indexes the same way
Version 2.384.4
Fixed
- The font-numbering change in 2.384.1 was itself the bug: classic .xls files number fonts the way Excel does ([MS-XLS] §2.5.129), where index 4 is never used and the fifth font is index 5, but 2.384.1 switched to a plain zero-based count; saved workbooks then showed every custom font one slot early in Excel (the first one fell back to the default font) and Excel-authored workbooks opened with every custom font shifted one slot late. Saving and opening follow Excel's numbering again, verified against workbooks written and read by Excel itself
- Rich-text cells keep the font of each formatted run through open, save and cross-workbook sheet copies, including runs whose font no cell uses directly
- Workbooks saved by 2.384.1 through 2.384.3 with five or more fonts already carry the shifted numbering, which neither Excel nor HotXLS can tell apart from valid data; regenerate them from their source or reapply the affected fonts and save again
Version 2.384.3
Fixed
- In both workbook engines, dates between 1900-01-01 and 1900-02-28 landed one day off against Excel, since Excel's 1900 calendar carries a phantom 1900-02-29; reading and writing now apply the correction as documented,
DATE(1900,2,29)returns 1900-02-28 rather than#VALUE!, and the shared-string table copes with embedded NUL characters and two-byte code pages across record boundaries without losing sync - Comparisons chain left to right as Excel evaluates them, so
=1<2<3is now read as(1<2)<3and returns FALSE like Excel (TRUE outranks every number in a comparison), where it previously grouped as1<(2<3)and yield TRUE; in comparisons a blank operand matches both 0 and an empty string; wildcard criteria work with "not equal" inCOUNTIFandSUMIFjust as they already did for "equal"; the sum range ofSUMIFand its siblings is resized starting from its top-left cell to the shape of the criteria range rather than clamped; andINDIRECTrespects its second argument (absolute R1C1 text) and rejects trailing junk following the reference YEARFRACwith basis 0 now applies the NASD end-of-February adjustmentsDAYS360has had all along, so spans that touch the end of February count correctly- A cell containing the text "endstream" can no longer truncate a PDF page during stream compression; the total-pages token patch holds the stream length steady when compression gets skipped, object offsets past 32 bits fail loudly rather than corrupting the cross-reference table, and greyscale or CMYK JPEGs are tagged with their true colour space instead of
/DeviceRGB - A workbook whose pivot-cache storage has been stripped or truncated now opens with the affected caches flagged as incomplete instead of failing the whole load, and those caches are re-saved through the legacy inline layout rather than raising an error
- A shared-string table whose declared count of strings exceeds what the record chain actually delivers now fails the open instead of quietly filling leftover cells with empty strings
Version 2.384.2
Fixed
- Converting a classic .xls workbook to .xlsx silently dropped merged cells sitting to the left of an earlier merge in a lower row; the scan no longer recycles its used-range variable for the merge area
- An XML comment inside a workbook extension list came back with doubled
<!--markers on every save, giving a file Excel has to repair; comment nodes now round-trip byte-for-byte - Unrecognised worksheet records picked up from an opened .xls were dropped from every later save despite being kept for replay, and leaked memory at each open; they now persist and go back in verbatim via the standard record writer
- Defined names over 255 characters and name comments over 65535 characters broke the framing of the NAME record on save; both are now rejected outright
- An aborted save leaked the workbook and worksheet record buffers whenever an encryption mismatch appeared mid-store; every exit path now releases the buffers
- The in-place patching writer removed the original file before the replacement was renamed into position, meaning a failed rename destroyed the workbook; the swap is now one atomic replace that leaves both files in place on failure
- Direct-reader cell references now enforce the 16384-column and 1048576-row limits instead of taking overflowed coordinates at face value, malformed integer attributes fall back to defaults instead of killing the whole read, and dates in the 1900-01-01 to 1900-02-28 window convert in both directions with Excel's phantom leap day taken into account
- Attribute values holding tabs, line feeds, or carriage returns round-trip unchanged rather than collapsing into spaces, and an unterminated entity in element text is now rejected just as in the attribute branch
- Verbatim copies of ZIP entries of 4 GiB or more, which the copy path cannot frame correctly, are now refused like the streaming writer does instead of yielding a corrupt archive
- The corpus runner writes out its results atomically so an interrupted run cannot wipe retained evidence, records build timeouts rather than crashing, and puts up with malformed stage-trace lines; the LibreOffice verifier writes out its evidence atomically, and the file-replacement probe once again collects the antivirus product list
Version 2.384.1
Fixed
- Every font from the fifth onwards went into the file with a record index one past the end of the font list, and Excel would then repair the workbook while custom fonts came back as the default; saving and opening now both use the documented zero-based index, so custom fonts survive a round trip and files authored by Excel keep their fonts when opened in HotXLS
- Evaluating
=0^-1or a negative base raised to a fractional exponent crashed recalculation with a floating-point exception rather than returning#DIV/0!or#NUM! - Conditional-format expression rules taken from an existing .xls were re-saved as an orphan CF12 record beneath the plain legacy header, which Excel throws away; they now keep the legacy record form along with their highlight formatting
- The intersection operator for references, and the implicit intersection taken by resized
OFFSETand multi-cellINDIRECTresults, picked the wrong axis or turned away valid single-row and single-column ranges, handing back the wrong cell or#REF! - When reading classic .xls files, the streaming row reader called every cached formula boolean FALSE and reported every cached error as
#NULL! - Large .xls files whose compound-file container went past the 109 header-resident FAT sectors were unreadable to the self-contained compound-file reader, as the DIFAT extension chain was never followed
- Custom table styles brought their fill and font colours back in with the red and blue channels swapped over, so a saved style returned in the wrong colour
- Malformed PNG images embedded in a workbook could crash the process via an out-of-bounds write while embedding PDF images or through an unbounded text-chunk scan; embedded PNGs are now dimension-checked, and malformed chunks get rejected
- Multi-rectangle EMF regions rendered as nothing more than their bounding box, EMF pictures lacking an explicit viewport extent came out scaled wrongly, and superscript text landed below the baseline on canvas, print, and metafile output
- Auto-prioritised BIFF conditional-format rules all went out with priority 1, which Excel treats as a repair trigger; auto priorities are now unique per sheet, matching their XLSX counterparts
- The
xlSlantDashDotborder style came out asxlDashDotDotin classic .xls border output - A truncated encrypted-workbook header record threw an exception through
Openrather than handing back the password-error code, and several error paths leaked memory while malformed image or workbook files were being parsed
Version 2.384.0
Changed
- Classic XLS pivot caches are saved just the way Excel saves them: each cache's records go into their own storage stream, while the stream identifier, cache scope, and the worksheet or named-range source definition are written a single time in the workbook globals; caches that older HotXLS versions authored keep their earlier inline layout unless you enable the opt-in framing upgrade
- Password-protected workbooks encrypt each pivot cache stream as a record stream of its own that starts afresh at the beginning of the stream rather than continuing the workbook stream's encryption position
Fixed
- After saving a workbook that mixed caches taken from an existing file with caches created in code, a PivotTable could point at the wrong cache; the view-to-cache reference now tracks the actual save order
- Every HotXLS package still carried the 2.379.7 version resource, and a package rebuilt under C++Builder could lose the version resource entirely; all packages now carry the current version
Version 2.383.4
Fixed
- Deep formula audits now keep changed results available to the formulas that depend on them even when those changes sit inside the reporting tolerance, and an explicit apply refreshes these unreported results
- Relative tolerance is now honoured for double-precision cached results in both workbook engines, while results that have not changed skip the duplicate comparison
Version 2.383.3
Fixed
- Saves of a workbook to a file now preserve the native Windows error when a finished XLSX, XLTX, or ODS output cannot replace its destination, including where cleanup or a progress callback disturbs the thread error state
Version 2.383.2
Fixed
- Repeated report-band and range copies reuse the defined-name suffix searches rather than rescanning every earlier copy, while keeping the first available name, the worksheet scope, and the reuse of names freed by later edits
Version 2.383.1
Fixed
- Rebuilding formula dependencies no longer scans preceding formula rows over and over, which cuts the cost of large calculation chains while array-output references, cross-sheet dependencies, and lookup ordering all stay intact
Version 2.383.0
Added
- Macro-free Excel templates can be saved as XLTX via an explicit output-format selection, working with files or streams and with buffered or streaming output
- Template output keeps formulas, defined names, print areas, and worksheet metadata, while the default workbook save behaviour stays untouched; workbooks containing VBA are rejected before anything is written to the destination
Version 2.382.5
Fixed
- Phonetic settings retain the required default font index, preventing Excel from rejecting saved workbooks where the index is zero
- Dynamic print-area formulas and sheet-qualified range unions survive a round trip without adding a sheet prefix to a function or clipping references inside an expression
- Generated and preserved package parts share unique content-type declarations and custom properties no longer collide with opaque root relationship identifiers
Version 2.382.4
Fixed
- Scalar defined-name references use the current row or column intersection whilst range arguments retain their full ranges, avoiding false dependency cycles in loan templates
- Mixed integer and floating-point formula arithmetic retains floating-point precision rather than being truncated to four decimal places
- Recalculation prioritises available lookup precedents before reading their caches, avoiding stale payment counts and similar lookup results
Version 2.382.3
Fixed
- AGGREGATE handles uncalculated errors and nested aggregation with independent selection settings, preserves array calculations and propagates original error types
- Classic XLS saves preserve existing formula caches until explicit recalculation, including shared and array formula roots; shared formulas translate relative references for their target cells
- Structured references support backslashes and periods in table names, nested current-row syntax and escaped column names without changing similar text inside formula strings
- XLSX conditional formatting retains RGB colours, explicit font flags, underline styles, font names, sizes, and schemes
- Unmodified charts preserve their original definitions and nonzero anchor offsets, avoiding changes to series colours, positions, and sizes
- Setting page margins no longer writes an unspecified page orientation and Classic XLS preserves absent imported page margins rather than adding defaults that change print placement
Version 2.382.2
Fixed
- ODS workbooks containing large repeated blank row ranges open and save without expanding every row height and inherited blank-cell style into separate objects
- ODS output preserves explicit row heights and compact repeated styled rows, including single-row overrides and cleared heights; row-height ranges also survive worksheet copying, row insertion and deletion, tiling and XLSX export
Version 2.382.1
Fixed
- Opening and saving XLSX workbooks with full-width column settings no longer repeatedly scans column metadata or copies the growing column XML, eliminating round-trip timeouts in date and template workbooks whilst retaining column settings
- ODS pivot definitions retain inherited XML namespace declarations, including producer extensions, so their saved XML stays well formed
Version 2.382.0
Fixed
- Saving a classic XLS workbook now keeps nested
SUBTOTALcells out of enclosing subtotal results, preserving the original cached totals rather than double-counting group rows - XLSX charts are loaded only through the drawing relationship referenced by each worksheet, so an unlinked conventional drawing part can no longer end up duplicating a chart during a round trip
- OpenDocument data-pilot table definitions survive an ODS save, including their source ranges, fields, target ranges, buttons and producer extension attributes
AGGREGATEoptions 0-7 now follow the documented hidden-row, error, and nestedSUBTOTAL/AGGREGATEselection rules across reference and array calculation forms
Version 2.381.0
Added
- Table slicers (Excel 2013+):
Worksheet.Slicers.Add(Table, ColumnName)creates a slicer view for any table column from end to end — the backing slicer cache namedSlicer_<column>, the reserved#N/Adefined name, the worksheetslicerListextension and a markup-compatibility drawing anchor with a fallback notice for older Excel versions are all emitted automatically, and the view can be positioned, captioned and styled viaCaption,ColumnCount,StartItem,StyleName,RowHeightandSetBounds - Slicer round-trip model: slicer views and caches are parsed back on open (shared caches are reused across views, and deleting the last view drops its cache), unmodified slicer parts and anchors replay byte-for-byte, and a table cache keeps its table binding valid even when saving renumbers table ids
Fixed
- Slicer caches written by earlier versions referenced the table id the file held at open time; when saving renumbered table ids workbook-globally, the stale
tableIdcould send Excel into repair mode. The binding now tracks the table through the renumbering
Version 2.380.0
Added
- Waterfall and treemap charts: the Excel 2016 extended chart types can be created, saved and reopened. They are serialised as dedicated extended-chart parts with their own content type, worksheet data binding and markup-compatibility drawing anchor carrying a fallback notice for older readers
- Treemap charts support hierarchical categories: every category level of the series is written to and read back from its own level inside the category dimension, preserving leaf and parent labels
Version 2.379.4
Fixed
- A corrupt or hostile classic XLS container no longer corrupts memory while being opened. The compound file reader copied a whole sector into the mini stream even when only part of it belonged there, followed the mini allocation table past the end of that stream, accepted sector sizes the format does not define, and sized its allocation table from an unchecked count. Sector and mini sector chains are now cycle-guarded and a stream name that fills its field without a terminator is bounded
- A style record naming a cell format index beyond the format table no longer writes through that index. The reference counters in the shared format and key lists checked only the lower bound, so a 12-bit index from the file could run past the array
- A local file header written with ZIP64 extended information no longer overruns its buffer: the declared header size now accounts for the 28-byte extra field the writer appends. Entry offsets and stream positions are tracked as 64-bit values, a ZIP64 entry is read using the length from its extra field rather than the sentinel and an entry larger than 4 GiB is refused instead of being recorded as its remainder
- A ZIP entry name containing a Windows separator is normalised. A single backslash was never turned into a forward slash, so
..\..\namepassed the directory traversal check that splits on forward slashes - A mask range with no upper bound, such as
[a-, no longer reads past the end of the mask and building a mask that starts with a character set no longer leaks a set per mask. Both are reachable from COUNTIF and SUMIF criteria - Whole-cell search with wildcards now demands that the pattern match the entire cell, matching both the documented behaviour and the non-wildcard whole-cell comparison.
FindTextwith patternabcpreviously also matched a cell containingabcdef - Precision as displayed no longer rounds cells whose number format has no digit placeholders. A cell formatted
Generalby name, as text with@or with a literal-only format was rounded to a whole number - The shared string table no longer reports more unique strings than it writes, no longer attaches a deleted string's rich text runs to whichever string reuses its slot and no longer emits a continuation record holding nothing but its option byte when a string overflows only because of its formatting tail
- RTF import stops duplicating non-ASCII characters. A
\\uNescape is followed by fallback characters written as\\'hh, which the skip logic did not recognise, so each one was also written out as text. Skipped groups now honour\binNraw payloads, and a table wider or taller than the worksheet grid stops at the edge rather than raising - A number reference outside the character range XML defines is rejected on read rather than producing an embedded NUL, a lone surrogate or a wrapped code point. Tab, line feed and carriage return survive an OPC round trip as character references rather than being normalised to spaces
- CSV import keeps the
SkipRowsvalue across parses; it was decremented in place, so a second file read through the same loader skipped nothing - A
xl/tables/part is recognised when deciding which parts to preserve; the prefix comparison was a character short and never matched
Version 2.379.3
Fixed
- HTML import decodes decimal character references.
éand every other&#NNN;form produced a NUL character instead of the character itself, because the conversion wrote its result and its error position into the same variable and the success code overwrote the value. Hexadecimal references were unaffected; both forms now reject values outside the representable range rather than emitting a stray character - HTML export keeps the whole sub-address of an internal hyperlink when building its anchor target. A sub-address longer than 255 characters was cut short, so the generated anchor no longer matched the link
Version 2.379.2
Fixed
- A GIF inserted through
AddPictureorImages.AddFromFilenow takes its size from the logical screen descriptor. Every GIF previously reported 100 by 100 points regardless of its real dimensions, so the picture came out stretched or squashed - BMP sizing reads the bitmap header the file actually declares: a
BITMAPCOREHEADERwith its 16-bit dimensions is understood instead of being read as 32-bit fields and a top-down BMP with a negative height no longer yields a negative picture height - JPEG sizing accepts every SOFn frame marker rather than only baseline, extended sequential and progressive. Lossless, arithmetic-coded and hierarchical JPEGs previously landed on the 100 by 100 default
Version 2.379.1
Fixed
- WMF pictures now decode as vector scenes for SVG, PDF and paginated output. Since 2.363.0 the decoder read each record as a 16-bit size followed by the function code, but a metafile record starts with a 32-bit size, so every WMF from Windows or Office stopped at its first record and the picture fell back to a raster placeholder. Records are now framed per
[MS-WMF] §2.3and the pen, brush, font, text, shape and polygon parameters are read from their specified offsets META_STRETCHDIBexpected the DIB ahead of the destination rectangle and assumed a 40-byte bitmap header; the rectangle now precedes the DIB as the format specifies,BITMAPV4HEADER/BITMAPV5HEADERand colour tables are honoured when locating the pixel bits and the record contributes an image command atXDest,YDestsizedDestWidthbyDestHeightMETA_EXTTEXTOUTskips its optional rectangle when eitherETO_OPAQUEorETO_CLIPPEDis set, so text drawn with an opaque background is no longer read from the incorrect offset- Metafile images embedded in a page render read their pixels from the offset the bitmap header gives rather than a fixed 40 bytes, so a
BITMAPV4HEADERorBITMAPV5HEADERimage no longer renders as shifted colour noise
Version 2.379.0
Added
TGridToXLSnow ships in the Free Pascal runtime package, so a LazarusTDBGridexports the way it does under the VCL: explicit columns keep their titles, fonts, colours, alignment, widths and visibility, a grid without explicit columns exports one column per dataset field and the result saves as XLS, XLSX, HTML or RTF through the sameSaveAscall
Version 2.378.4
Fixed
- TEXTBEFORE and TEXTAFTER read their argument count from a local that was never assigned, so the optional instance, match-mode, match-end and if-not-found arguments could be ignored or a valid call rejected with #VALUE!, depending on leftover stack contents; the count now comes from the call itself
- A resized OFFSET, one with a height or width other than 1, evaluated in a single cell compared the formula cell against an anchor that had yet to be computed, so the implicit intersection could return #REF! or the wrong cell; the shifted anchor is now computed before the intersection test
Version 2.378.3
Fixed
- Under Free Pascal, matching or replacing an empty string threw the regular-expression error, so a report expression such as
regexreplace(Code,"[^0-9]","")failed withREPORT_EXPRESSION_INVALID_REGEXwherever the field was blank. The FPC backend now answers the wayTRegExdoes under Delphi: a pattern that allows an empty string, such as^$or.*, matches it and yields its replacement text, whilst[0-9]+or\s+reports no match
Version 2.378.0
Added
- HotXLS now builds with Free Pascal 3.2.2 and Lazarus/LCL on Windows, Win32 and Win64. The XLS and XLSX workbook APIs, formulas, styles, the direct reader and writer, dataset export and the rendering helpers all operate from FPC code with Delphi Unicode string semantics; the Free Pascal and Lazarus support topic covers application setup and the backend differences
- The runtime package
Lib/FPC/HotXLSLaz.lpkopens in Lazarus or builds for each architecture from the command line throughbuild-FPC-Lib.cmd, and the Lazarus smoke suites underTests/Lazarusspan workbook round trips, compression, encryption, COM streams, graphics, text reading, regular expressions, dataset export and report expressions - FPC builds use bundled Pascal backends for ZIP, compression streams and AES, so XLSX files, including password-protected ones, need neither a zlib DLL nor the prebuilt object files Delphi links; PNG keeps its alpha channel, EMF drawing and playback go through Windows metafiles and multipage TIFF export uses the GDI+ runtime
Version 2.377.2
Added
- A classic XLS PivotCache written by HotXLS now carries the records the format defines the cache header against. The header's stream id and source-data type named an SXStreamID and an SXVS that were never written, so no reader could check either one; both records are now written and both header fields are taken from the same values, so they agree by construction
- Cache substreams also carry SXDBEx, the record that follows the cache header in every cache Excel writes. It notes when the cache was last refreshed, so
TXLSPivotCache.RefreshedDatenow survives a classic XLS save and reload as it already did in XLSX TXLSPivotCache.StreamIdandTXLSPivotCache.SourceDataTypeexpose the two values, read back from a file giving them and written into the pair of records plus the cache header. A cache built byAddPivotTablereports stream 0 and a worksheet-range source
Changed
- The opt-in rewrite of old cache framing (
UpgradeLegacyPivotCacheFraming) now produces these three records as well, so an upgraded cache is not merely correctly framed but complete in the same way freshly written ones are. A cache that already carried an SXStreamID, an SXVS or an SXDBEx keeps what it carried; one whose SXDBEx claims formula records HotXLS does not write stays on raw replay - Reading is unaffected: files written before this release load exactly as before and cache records HotXLS still has no model for — the DConRef or DConName naming a source range among them — go on being preserved byte for byte across a round trip
Version 2.377.1
Added
- A workbook can now request a rewrite of its old PivotCache substreams on save.
TXLSWorkbook.UpgradeLegacyPivotCacheFramingis off by default; turned on, a classic XLS file whose caches were written by HotXLS before v2.377.0 is saved with those caches re-emitted through the corrected SXDB / SXFDB / SXDBB writers, so the run of pivot cache fixes in v2.376.1 through v2.376.7 reaches existing files instead of only new output - The upgrade applies only where it provably costs nothing. A cache read from a file is re-emitted only when its whole substream held records HotXLS models and its framing is one HotXLS itself wrote wrong; anything else — every cache Excel produced and any cache carrying a record such as SXDBEx that HotXLS keeps only as opaque bytes — goes on replaying its own bytes with the opt-in on.
TXLSPivotCache.CanUpgradeFramingreports the verdict for a single cache andRawFramingIsLegacy/RawModelIsCompletereport the two halves it rests on - An upgraded cache is written where its substream sat rather than moved ahead of the others, so a PivotTable view still resolves to the cache it named before saving
Fixed
- A classic XLS PivotCache read from a file and then handed to the writer with its raw-replay flag cleared yielded two cache substreams, the model's and the file's. It now produces one
Version 2.377.0
Added
- Classic XLS worksheets accept embedded chart objects:
AddChartObjecton a worksheet anchors a chart frame on the sheet grid (OBJ type 5 host-control shape plus the MSODRAWING client anchor), builds the chart substream through the shared chart builder and rides the sheet's record list so the file layout matches what the reader reattaches on open; a round trip brings the frame back with its chart model — series, title and range references intact
Fixed
- SeriesText records decode their string payload with the right width: the reader passed the character count where a byte count was expected, so 16-bit captions and series labels came back cut to half their length (a five-character title read as two characters)
Version 2.376.7
Fixed
- The cached rows behind a PivotTable in a classic XLS file are written the way [MS-XLS] 2.4.276 describes them: one record per row of cached data, holding one index per cache field, a single byte wide or two bytes for a field with more than 255 distinct values. HotXLS had been writing a scheme of its own instead, squeezing each field into just enough bits to count its values and packing many rows into one record, which no other program could decode and which contradicted the more-than-255-values flag the field definition already carried
- Excel can now read the values a HotXLS PivotCache holds instead of having to rebuild them from the source range when the workbook opens, which is what a workbook whose source data has since been moved, changed or deleted had been relying on
- Cached rows are read back as well. HotXLS ignored the record entirely before, so a cache loaded from a file came back with every row pointing at the first value of every field and anything computed from that cache followed those wrong values. This applies to a workbook written by Excel just as much as to one written by HotXLS
- A cache field carrying no values contributes nothing to a cached row and a field with more than 255 values is stored and read at the wider size the format requires
- Workbooks written by HotXLS v2.376.6 and earlier still load with cached rows intact
Version 2.376.6
Fixed
- The PivotCache header record in a classic XLS file is laid out the way [MS-XLS] 2.4.275 describes it. The record count is a four-byte field there and HotXLS was writing it in two bytes, so every field behind it went out one position early and the record ran four bytes long — the number of cache fields ended up inside the record count, the flag word landed on the stream identifier and the field count landed on the length of the name of whoever last refreshed the cache, promising a name the record was too short to hold
- The header's flags now say what the cache actually is: whether its records are stored in the file, whether it refreshes when the workbook opens, whether refreshing is allowed and whether the refresh query runs in the background. Those four settings already appeared in XLSX output and now travel with a classic XLS file as well, together with the name of whoever last refreshed the cache
- The source data type in the header is written as a worksheet range rather than left at a value the format does not define and the field counts and the used record count carry the cache's real totals
- The refresher name is trimmed to the 255 characters the record allows and a cache without one writes no name at all instead of an empty placeholder
- Workbooks written by HotXLS v2.376.5 and earlier still load and still give up their cache record count. Nothing else was ever stored in the old header — the writer filled every field behind the record count with fixed values it never read from the cache — so the flags and the refresher name of such a file come back as defaults rather than as recovered values
Version 2.376.5
Fixed
- PivotCache field names survive a save and reload of a classic XLS file. The name length was being read from the wrong place in the cache field definition — an index that is always $FFFF — so the name was discarded each time and every cache field came back unnamed
- The cache field definition record is laid out the way [MS-XLS] 2.4.283 describes it: grbit, ifdbParent, ifdbBase, citmUnq, csxoper, cisxoper, catm and then the field name. HotXLS had been writing three fields the record does not have — a subtype item index, a number format and a second item count — and putting $FFFF into indexes the specification bounds by the number of fields in the cache
- The record's flag word now describes the field it belongs to: whether the field carries cache items, whether those items include numbers, dates or text, whether a minimum and maximum can be computed, whether any item is not a date and whether there are more than 255 of them. The item count in the record now matches the number of cache item records that actually follow it
- Cache field names longer than the 255 characters the record allows are trimmed to 255 rather than being written out at their full length
- Workbooks written by HotXLS v2.376.4 and earlier still load with their cache field names intact — the name occupied the same position in the old layout, so nothing carrying a name loses it
Version 2.376.4
Fixed
- PivotTable caches in classic XLS files now use the record numbers [MS-XLS] gives them. Seven records in the cache substream had been going out under some other record's number: the cache field definition as $00C8 (SXDBB), the field type as $00FB (SxFormat), the per-record item indices as $00C5 (SXDI) and the numeric, boolean, error, date and blank cache values as $00CE, $00CF, $00D0, $00CC and $00CB (SXDtr, SxNil, SXTbl, SXInt, SxErr). They are now SXFDB $00C7, SXFDBType $01BB, SXDBB $00C8, SXNum $00C9, SxBool $00CA, SxErr $00CB, SXDtr $00CE and SxNil $00CF, so Excel can read a pivot cache HotXLS wrote and HotXLS can read one Excel wrote
- Blank values in a pivot cache field survive a round trip. The writer had always emitted them but the reader had no case for them, so every blank was discarded on load and each value after it in that field shifted down one position, leaving the PivotTable's item references pointing at the wrong values
- Workbooks written by HotXLS v2.376.3 and earlier keep loading with their cache values intact. Each pivot cache substream is read in whichever numbering it was written with, decided from its own field-definition record and a cache read out of an existing file is written back under the numbers it came in with, so reopening and saving an old workbook does not quietly change its bytes
Version 2.376.3
Fixed
- PivotTable views in classic XLS files now write their SXEx extension record under the number [MS-XLS] gives it, $00F1; the writer had been using $00C6, which is SXDB, the pivot cache header record — Excel looking for the view extension found nothing and a record claiming to be a cache header sat in the middle of a worksheet, so the view properties SXEx carries went missing even after the field-layout fix in v2.376.1
- Workbooks written by HotXLS v2.376.2 and earlier still open with their PivotTable views intact: inside a worksheet the old $00C6 is still accepted as the view extension it was meant to be and inside a pivot cache substream $00C6 is still read as the cache header, so nothing that used to load stops loading
Version 2.376.2
Fixed
- Classic XLS 3-D chart sheets created without an explicit scene now carry the flags they are documented to carry: the default Chart3d flag word set a bit the record reserves instead of the automatic-scaling bit, so a default 3-D chart reopened with clustering on but automatic scaling off and never matched the scene it claimed to record; charts that pass an explicit 3-D scene were unaffected and their bytes are unchanged
Version 2.376.1
Fixed
- PivotTable views write an SXEx record whose fields sit where readers expect them: the fixed 24-byte body was shifted by two fields, so it announced two formatting records that never followed and left every optional-string length at zero, which [MS-XLS] 2.4.282 forbids — those lengths must be either the absent marker or a real length from 1 to 255; the body now starts at the correct field and marks every optional string absent, so Excel reads the view properties rather than a garbled block
- The SXEx record length is derived from the bytes actually written rather than a hardcoded constant, so the declared size and the payload can no longer drift apart as they did before v2.376.0
Version 2.376.0
Added
- Classic XLS chart sheets can link to a PivotTable view: a new
AddChartSheetoverload accepts the source pivot view name and the hide-field-captions flag, which write into the SXViewLink ($0858, [MS-XLS] 2.4.316) and PivotChartBits ($0859, 2.4.196) records in the chart globals before Units per the Chart Sheet Substream ABNF; chart inspection decodes both records — including 8-bit and 16-bit string encodings — back into the typed model (pivot-chart marker, source view name, caption flag) and the canonical semantic snapshot, whilst charts without the link records stay unmarked
Fixed
- PivotTable views write a correctly sized SXEx record: the emitter declared a 24-byte body but wrote 26 bytes, so the two surplus bytes landed where the next record header was expected and every record after the view (including the worksheet EOF and any chart-sheet substream that followed a pivoted sheet) misparsed, leaving workbooks that combine a PivotTable with a chart sheet to reopen without their chart
- Trendline display names in classic charts decode 8-bit string payloads correctly; the previous wide-character reader gave back an empty name for records Excel writes with 8-bit characters
Version 2.375.0
Added
- Classic XLS chart series accept theme-coloured fills: the per-series style now carries a theme colour index and tint which write into a GelFrame record after the AreaFormat per [MS-XLS] 2.4.131, using the OfficeArt theme colour extension (fillType, fillColor with the flattened RGB, fillColorExt scheme index, fillColorExtMod tint payload); when no explicit fill colour is supplied the flattened colour resolves from the default Office theme with the tint applied, and chart inspection decodes the theme intent back into the typed model and the canonical semantic snapshot
Fixed
- The full multi-version library build is green again for every supported compiler: casts and calls that only newer compilers accept (an Extended type cast of Int64 values, a hard Double cast of an integer, a nil procedural argument in overload resolution, access to TPicture.LoadFromStream where it is protected and the GdiplusStartup token type that changed between VCL generations) were made version-safe from XE5 through the current release
Version 2.374.0
Added
- 3-D chart scenes are configurable and inspectable: a new
AddChartSheetoverload accepts rotation, elevation, perspective distance, height, depth, gap and the cluster, autoscale, right-angle-scaling and two-dimensional-walls flags which are written into the Chart3d record per [MS-XLS] 2.4.46, and chart inspection decodes the scene back into the typed model (Scene3D) on read; charts that keep the previous overloads still write the Excel-matching defaults byte-for-byte
Version 2.373.0
Added
- Classic XLS chart series accept per-series style overrides: line colour and style, fill colour, and marker shape, colours, and size write into the series formatting block with the automatic flag cleared so Excel honours the supplied values, and chart inspection decodes the LineFormat, AreaFormat, and MarkerFormat records back into the typed model and the canonical semantic snapshot
Version 2.372.0
Added
- Classic XLS chart series accept named and external references for categories and values: text that is not a plain A1 range compiles through the workbook formula engine, and the BRAI record carries a chart area item holding the compiled formula so the save pass re-serialises it with the current defined-name store indexes; chart inspection decompiles the reference back to its name on read, while unresolvable text keeps the empty placeholder BRAI
Version 2.371.0
Added
- Classic XLS chart series may bind to the secondary axis group: marking a series in
AddChartSheetraises AXESUSED to two, emits a second AxisParent block with its own category and value axes plus its own chart group per the [MS-XLS] Chart Sheet Substream ABNF and routes the series through SerToCrt to the second group; chart inspection decodes the per-series chart-group binding on read
Version 2.370.0
Added
- Classic XLS chart series accept data labels:
AddChartSheetemits an AttachedLabel record with the show-value, show-percent, show-category-name, show-label-and-percent, show-bubble-size and show-series-name flags ([MS-XLS] 2.4.5 bit layout), and chart inspection decodes both AttachedLabel and the DataLabExtContents extended-label record including its separator back into the typed model and the canonical semantic snapshot
Version 2.369.0
Added
- Classic XLS chart inspection now decodes the axis group structure: AXESUSED surfaces the declared axis group count and every axis states whether it belongs to the primary or secondary AxisParent group, with the group index carried into the canonical semantic snapshot
Version 2.368.0
Added
- BIFF chart trendlines and error bars now decode into the typed chart model on read: each Series block surfaces its Trendline records with regression kind, order or period, intercept (including automatic), equation and R-squared display flags, forecast and backcast periods and display name, plus its SerErrBar records with direction side, value type, end caps and magnitude
- The Classic semantic snapshot maps trendlines and error bars into the shared canonical containers rather than raising, so workbooks with advanced chart series compare deterministically and trendline changes alter the canonical stream
Version 2.367.0
Added
- RecalcAndVerifyEx runs a deep calculation audit on both workbook engines: every formula evaluates once through the dependency graph into an isolated result overlay so dependent cells read this pass instead of stale caches, evaluation failures classify into typed categories (unsupported arguments, circular references, denied or missing external references, skipped data tables, cancellation, internal failures) with result codes and each failure carries a bounded call stack
- The audit honours an issue budget with a stable sheet, row, column and category ordering, a progress sink that can cancel at node boundaries, configurable numeric tolerances, and an opt-in ApplyResults that commits recomputed values atomically after a fully successful pass over an unchanged workbook structure; the default stays strictly read-only
Changed
- The existing RecalcAndVerify and CalculateAndVerify entry points keep their previous shallow-compare semantics as compatibility shims whilst sharing the new report fields
Version 2.366.0
Changed
- PDF export now assembles documents through a sequential object writer that streams every object straight to the destination, so no whole-document intermediate copy is built; unsigned documents stream directly into forward-only streams, whilst signed documents assemble into a bounded spool that receives the ByteRange and signature contents patches before a single forward copy
- PDF attachment payloads copy from their provider spools to the final document in fixed chunks and reference their stream size through an indirect length object, holding peak memory flat for multi-hundred-megabyte attachments
Fixed
- Signature digests are now computed incrementally over the two covered byte ranges of the assembled document rather than through a full document copy and the reserved signature fields are located from the signature object itself rather than by scanning the assembled bytes
Version 2.365.0
Added
- Visible PDF signature text now renders through the embedded Unicode font pipeline with left, centred, or right alignment, configurable size, colour, and bold or italic styling, covering any script in signer names, reasons, and locations
- PDF signature appearance images accept JPEG payloads with dimensions derived from the frame marker, whilst oversized or corrupt images fail deterministically before the digest is computed
- PDF attachments expose an explicit duplicate-name policy, spool large provider payloads to a temporary file beyond a configurable byte threshold and reject leaf-hostile names containing path separators or control characters
Changed
- PDF attachment name trees are now sorted by their encoded name bytes per ISO 32000-1 7.9.6 and the attachment collection stays frozen while providers run so reentrant additions fail atomically
Version 2.364.0
Added
- Embedded EMF and WMF pictures replay path brackets with fill, stroke and combined stroke-and-fill passes, rounded rectangles, arcs, chords, pies and angle arcs through exact arc-to-Bézier conversion, region fills and frames resolved from bounded RGNDATA rectangles, and geometric or cosmetic extended pens, all flattened into the immutable shared scene with the same fail-closed boundaries against clipping, escape and private records
Version 2.363.0
Added
- Embedded EMF and WMF pictures now replay through an expanded safe record whitelist: device-context state stacks with save and restore, window and viewport mapping with world transforms, pen and brush object tables including stock objects, rectangles, ellipses, line chains, polygons, polylines, and Bézier curves with dash styles, bounded text runs with fonts, colours, and alignment, and restricted stretch-DIB images re-encoded as PNG, while unknown state records still fail closed into the bounded raster fallback instead of invoking platform metafile playback
Fixed
- WMF pictures now parse the standard two-byte record header layout, so real placeable and standard metafiles decode rather than only synthetic fixtures
Version 2.362.0
Added
- Classic XLS and XLSX now preserve table-formula array state, typed data-validation IME modes, calculation-thread hints, force-full-calculation presence, refresh-all hints and workbook code names through their native binary or OOXML representations
RecalcAndVerifyreturns a bounded structured calculation audit with stable cache, parse, missing-function and missing-name categories while leaving formula caches and workbook semantics unchangedTXLSPageImageExporter.ExportRangerenders a requested cell rectangle as one compact PNG or JPEG without paper, margins, headers, footers, print titles or page breaks and page-image before and after events can draw on the actual encoding canvas- A dedicated cell-image exporter measures, renders, and saves any classic or XLSX cell rectangle as a single compact image with configurable resolution, scale, format, and JPEG quality; transparent or coloured backgrounds, independent object, gridline, and cell-border switches, pixel and byte budgets, and file saving through an atomic same-folder replacement that leaves an existing target untouched when anything fails
- Page-image paint events now receive a complete read-only context carrying the live canvas, pixel bounds, page size in points, resolution, scale, document and in-sheet page numbers, total page count and the originating worksheet, fire exactly once per rendered frame including multipage TIFF frames, stay silent during measurement, and never trigger their trailing event or write partial image bytes when the leading event raises
TXLSSvgExportsupports complete per-page callbacks, deterministic document and page ID namespaces and opt-in safe hyperlink overlays with ScreenTips and secure new-window attributes- Classic and XLSX HTML exporters provide an opt-in spreadsheet view with semantic row and column headings plus bounded pure-CSS hot tracking and both reject active or local URI schemes while retaining link display text
- Visible PDF signatures can use contained, covered or stretched PNG appearance images, and PDF attachments can obtain their payload lazily from a single-call source interface during each save
- A bounded EMF and WMF vector decoder validates headers, record sizes, totals, exact EOF placement and escape restrictions, then replays its safe rectangle command subset through the shared Canvas and SVG backends without invoking driver metafile playback
Changed
- Direct XLSX writing can author table formula array attributes and typed data-validation IME modes, whilst array table formulas are no longer silently expanded as scalar per-row formulas
Version 2.361.99
Changed
- Automatic tagged PDF now emits informative XLSX pictures as independent Figure structure elements with Unicode alternative text, dense page-local marked-content identifiers, exact parent-tree entries, and one semantic element per visible instance while equal image payloads still share one XObject; pictures without alternative text remain decorative artefacts
Version 2.361.98
Fixed
- Lookup formulas that scan a range covering their own cell (VLOOKUP, HLOOKUP, LOOKUP, XLOOKUP, XMATCH, MATCH) no longer report false circular-reference errors during recalculation, whilst edits inside the scanned range still trigger recalculation of the formula
- AutoFilter text criteria longer than 255 characters are capped to the filter record limit rather than writing a corrupted autofilter condition
- Consecutive spaces used by the implicit intersection operator are preserved when formula text is regenerated rather than collapsing to a single space
- Built-in defined names beyond print areas, print titles and filter databases (consolidate areas, extract, database, criteria, recorder, sheet titles and Auto_Open-family markers) are kept verbatim when classic XLS workbooks are opened and saved
Version 2.361.97
Added
- Classic XLS and XLSX workbooks now expose a shared three-state object display policy with lossless untouched source preservation and cross-format mapping; hidden objects no longer swell paginated or HTML output or enter drawing and media rendering paths
- The workbook viewer renders lightweight named placeholders for placeholder-mode objects, whilst PDF, SVG, bitmap, print and HTML exporters retain full objects by default and offer an explicit placeholder option that avoids image decoding and chart-scene construction
Version 2.361.96
Changed
- Manual chart layouts now preserve independent source fields and invalid tokens, resolve factor and edge coordinates with bounded size-preserving placement, honour inner and outer plot targets plus title and legend overlay, convert supported ODF geometry through absolute chart distances, and render consistent title, legend, plot-area and axis-title placement across pagination, SVG, PDF, image, preview, print, viewer and HTML output
Version 2.361.95
Changed
- XLSX cell-sourced chart data labels now belong to each series with complete formulas, indexed caches, explicit shared and per-point visibility, live worksheet refresh, external-cache fallback, formula translation during copies and report expansion and consistent custom-first label composition across pagination, SVG, PDF, image, preview, print, viewer and HTML output
Version 2.361.94
Changed
- Multi-level chart category axes now preserve sparse hierarchical caches and live two-dimensional ranges, build parent-aware spans in linear time, honour single-level, reversed, right-to-left, hidden and blank-category behaviour, and render consistent hierarchy labels and separators across pagination, SVG, PDF, image, preview, print, viewer and HTML output; ODS export uses the leaf category range
Version 2.361.93
Changed
- Date axes now infer calendar units once across all visible series, choose bounded automatic intervals from the visible span, axis width, measured label font, number format and rotation, and derive labels, coordinates, ticks and gridlines from shared major and minor tick collections across pagination, SVG, PDF, image, preview, print, viewer, and HTML output
Version 2.361.92
Changed
- XLSX date axes now preserve axis number formats and source-link state, render formatted labels with text styling and rotation, and honour reversed direction while retaining continuous spacing for duplicate and sparse dates across pagination, SVG, PDF, image, preview, print, viewer, and HTML output
Version 2.361.91
Changed
- XLSX date axes now preserve whether base, major and minor calendar units and automatic-category detection were omitted or explicitly supplied, including explicit day units and false values; Classic date-axis extension records expose typed fields, retain masked or invalid raw values, and can map active settings into the XLSX axis model
Version 2.361.90
Changed
- XLSX date-axis charts now preserve continuous date spacing and render day, month, or year major intervals with the workbook's 1900 or 1904 date system across paginated, SVG, PDF, image, preview, print, viewer, and HTML output; pagination-based output also honours configured minor ticks and gridlines
Version 2.361.89
Added
- The workbook viewer now tiles valid worksheet backgrounds behind unfilled cells, while print, PDF, SVG, bitmap, metafile and Classic or XLSX HTML output expose an explicit
ExportSheetBackgroundImagesopt-in that is disabled by default
Changed
- Paginated background rendering now preserves worksheet-relative tile phase across pages, decodes each background once per render session, reuses one PDF image XObject or SVG resource and skips corrupt payloads with one diagnostic
Version 2.361.88
Added
- Classic worksheets now expose typed background-image authoring and a shared read-only background resource, read and write BIFF8 background records with continuous payload splitting, reconstruct bitmap payloads as standard BMP data, preserve unsupported native and unknown formats byte-for-byte with diagnostics, deep-copy background ownership and convert known backgrounds in either direction between XLS and XLSX
Version 2.361.87
Fixed
- XLSX worksheet copies now retain sheet background image bytes and media type in same-workbook and cross-workbook copies, whilst same-workbook copies reuse preserved source media and cross-workbook copies rebase media ownership before save
Version 2.361.86
Added
- Classic XLS and XLSX workbooks expose
AllowUnsafeFormulaCallbacks, whilst contextual evaluation provides the matching per-call option and the structuredxlfeUnsafeFunctionDeniedstatus
Security
- Dangerous external and macro-style formula names no longer reach workbook-local, process-wide, resolver or event user-function handlers by default, and denial occurs before formula arguments are evaluated
Version 2.361.85
Added
- Classic XLS and XLSX workbooks expose
AuditFormulaSymbolsfor structured unknown-function, unknown-name and syntax diagnostics across formula cells and defined names, with per-operation unique-formula and cache-hit statistics
Changed
- Preserved unknown functions and names now evaluate to Excel
#NAME?errors through direct, dependent, contextual, serial and parallel calculation paths - Workbook-local or process-wide user-function registration changes and defined-name formula changes now invalidate affected calculation state before the following recalculation
Fixed
- Formula errors read from dependent cached cells now remain typed errors rather than entering scalar conversion and raising a Variant conversion exception
Version 2.361.84
Added
- Normal Classic XLS and XLSX formula assignment now applies the workbook formula-entry policy atomically, so strict rejection leaves the cell value, formula cache and dependencies unchanged while preservation mode stores unknown functions and names
Changed
- Classic XLS writes preserved unknown calls through BIFF add-in user-function tokens and retains preserved unknown-name text across save, reopen and XLS/XLSX conversion
- Formula entry validation recognises configured callback user functions,
LAMBDAandLETcallables, defined-name lambdas, report placeholders, registered external links and valid structured references without invoking handlers
Fixed
- XLSX validation now preserves valid nested and current-row structured references and no longer reuses stale column text whilst scanning an unresolved table reference
Version 2.361.83
Changed
- Classic XLS and XLSX value assignment now applies
FormulaEntryPolicy.EmptyStringModeconsistently: the default clears exact empty strings, preservation mode stores a constant empty string andNullorUnassignedalways clears the cell - Native XLS, XLSX and ODS loading plus XLS-to-XLSX and XLSX-to-XLS conversion now preserve trusted constant empty strings without confusing them with absent cells or formulas such as
="" - XLSX string and Variant row or column writers retain packed-storage fast paths whilst leaving cleared entries absent and storing exact empty strings only in preservation mode
Version 2.361.82
Added
- Classic XLS and XLSX workbooks now expose a shared
FormulaEntryPolicy, whilst both worksheet engines provide mutation-freeValidateFormulaEntrymethods that return a structured issue, action and unknown symbol before a caller changes a cell
Changed
- Formula entry validation now distinguishes exact empty input from formulas returning an empty string, separates unknown functions, unknown names, syntax failures, invalid targets, and target-format limitations, and recognises registered user functions without invoking their handlers
Version 2.361.81
Changed
- Whole-row and whole-column insertions or deletions now remap every pane's ordered selection areas and active area consistently in XLS and XLSX, preserving surviving order and creating a boundary-cell fallback where every area is removed
- Large pane selection normalisation, structural editing, and queries now use amortised-linear builders and capacity growth instead of repeated full-string or array copies
Fixed
- Classic XLS now preserves malformed or contradictory
Selectionrecord bodies byte-for-byte while reportingxlsDiagnosticSelectionRecordInvalidinstead of exposing partially trusted typed state
Version 2.361.80
Added
TXLSWorksheetandTXLSXWorksheetnow expose matchingTryGetWindowScrollandScrollWindowmethods for reading and changing the first visible cell of any existing logical pane with one-based coordinates
Changed
- Four-pane scroll state now preserves the shared upper, lower, left and right axes independently through XLS and XLSX save, open, and worksheet copy, while missing panes and invalid coordinates fail without changing view state
Version 2.361.79
Changed
- Classic XLS worksheets keep independent ordered selection groups for every pane, aggregate consecutive BIFF
Selectionrecords into one logical sequence, preserve untouched record bodies and copy the complete selection state with the worksheet - Classic selections with more than 1369 areas are written as consecutive standards-compliant chunks whilst keeping one aggregate active-area index across every chunk
Version 2.361.78
Added
TXLSWorksheetandTXLSXWorksheetnow expose matching pane-awareGetSelectedAreasandSelectAreasmethods through the sharedTXLSPanePositiontype
Changed
- Pane selection queries return caller-owned ordered snapshots with the active area index, preserve overlapping areas and leave worksheet state unchanged when a pane is absent or an update is invalid
Version 2.361.77
Added
IXLSWorkbook,TXLSWorkbook, andTXLSXWorkbooknow expose matching streamingSaveSemanticSnapshotand incremental SHA-256ComputeSemanticHashmethods with Content and SecurityComplete profiles plus explicit viewer-state, volatile-metadata and formula-cache options
Changed
- Semantic snapshots traverse sparse workbook models without materialising a complete snapshot, and both snapshot and hash operations hold a read lease so concurrent public mutations fail before changing workbook state
Version 2.361.76
Added
- The typed Classic XLS chart model now exposes chart, category-axis and value-axis titles
Fixed
- Classic XLS chart model extraction now identifies series, legends, chart groups, axes, 3-D state, series labels and series source formulas from their defined BIFF records
- Legend positions and pie-versus-doughnut classification come from their defined record fields
Version 2.361.75
Added
- The Delphi FeatureShowcase and C++Builder XlsxFeatureGallery now demonstrate the same compiled report data context, memory table, strict data access, recoverable-error continuation, diagnostics worksheet, immutable run result and atomic file-output workflow
- The compiled reporting topic now provides matching Delphi and C++Builder examples, including the C++Builder smart-interface acquisition needed for interfaced report tables
Fixed
- The C++Builder XLSX feature gallery links the complete version-matched HotXLS static package so compiled-report implementation dependencies resolve without brittle per-unit linker directives
Version 2.361.74
Changed
RunToStream,RunToFile, andRunToEncryptedFilenow share one output transaction that publishes a serialised workbook only after report generation and saving complete- Unencrypted report output preserves the template workbook format, including ODS output from ODS templates, whilst encrypted output remains an encrypted Office container
Fixed
- Serialisation, replacement, cancellation, and fatal report failures leave existing destination streams, files, and encrypted files unchanged and release per-run data sessions and temporary storage before returning
Version 2.361.73
Added
- Named range and Excel-table report bands now expose
ErrorMode,StrictDataAccess,RuntimeLimits, and immutableLastResultsnapshots, with a distinctCompletedWithErrorsband state
Changed
WriteAndContinuecan write an explicitly recoverable row error as literal diagnostic text, record the source cursor row and actual output cell, then carry on with later targets in that row and later input rows- Report expressions consume typed band snapshot values before falling back to text, preserving numeric, date, Boolean and other supported Variant values during expression evaluation
Fixed
- Fatal target, cancellation and runtime-limit failures during band expansion restore source targets and inserted structure, clear rolled-back diagnostic flags, and publish zero applied targets
Version 2.361.72
Added
TXLSReportRuntimeLimitsbounds retained runtime issue count, sanitised message length, and issue memory, whileRuntimeDiagnosticsSheetNameoptionally writes one structured diagnostics worksheet- Explicit resolver data errors, expression division by zero and invalid regular expressions now carry stable provider or expression issue categories and error codes
Changed
WriteAndContinuepreserves safe non-cell targets and records their issue, whilst worksheet names and defined-name formulas remain fail-fast structural targets- Resolver data-error results remain recoverable when served from the per-run alias cache, whilst exceptions thrown by a resolver remain fatal
Security
- Runtime messages stop at the first line, redact common credential and bearer-token forms, and enforce count, length and memory limits before mutating the failing target
Version 2.361.71
Added
- Exact
{{#usertable(alias, logicalName, providerKey, name=expression)}}cells compile into typed lazy table declarations, andTXLSCompiledReportTemplate.UserTableCountreports the declaration count separately from output targets TXLSReportTemplateChecker.DataContextpreflights registered provider keys, typed parameter bounds, malformed declarations and case-insensitive alias conflicts without invoking a resolver
Changed
- Report templates and generators evaluate declaration parameters before target writes, register them in the current run session and resolve a declared table only when
dbvalueordbcountfirst references its alias - Repeated equal declarations share one request, while declarations that reuse an alias with a different logical name, provider, parameter order, type or value fail with the declaring cell location before workbook mutation
Security
- User-table declarations accept only a registered provider key and bounded typed data parameters, reject data-table access inside parameter expressions and expose no template field for SQL, paths, URLs or command text
Version 2.361.70
Added
TXLSReportDataRequestcarries named or user-table identity, typed parameters, source location and read-only run control toIXLSReportDataResolver, whose explicit result states distinguish unhandled, resolved, not-found and data-error outcomesTXLSReportDataContext.RegisterResolver,RemoveResolver, andClearResolversmanage a case-insensitive named resolver registry, whileTXLSReportDataLimitsbounds aliases, resolvers, parameters, names, messages and returned table schemas
Changed
- Each report data session snapshots the resolver registry into an O(1) lookup, keeps explicit tables authoritative, adapts legacy table providers, caches typed requests by alias and rejects a reused alias whose logical name, provider, parameter order, type or value differs
- Report runners and bands now pass one thread-safe cancellation control through data resolution, stop after cancellation without committing the active target, and leave a cancelled alias available for a clean retry instead of caching cancellation as a data error
Security
- Typed data requests reject control characters, negative source coordinates, duplicate parameter names, unsupported Variant arrays or references, excessive strings, excessive aliases or providers and oversized table schemas before unsafe work or workbook mutation
Version 2.361.69
Added
TXLSXWorksheet.ClearRowHeightandClearColWidthremove one explicit dimension override without upsetting other row or column metadata
Changed
- Compiled report targets now finish expression evaluation before invoking dynamic formatting and commit cell content, number formats, row heights and column widths through one rollback boundary
- Recoverable cell diagnostics derive red-font and yellow-fill styles from the cell's existing font, preserve the remaining cell style and reuse pooled styles across equal base fonts and repeated runner executions
Fixed
- A recoverable evaluation failure no longer leaves dynamic number formats or explicit row and column dimensions behind and diagnostic writes now clear any formula before storing literal text
Version 2.361.68
Added
- Compiled report runners and generators expose
ErrorMode,StrictDataAccess, and an immutableLastResultwith terminal state, applied count, failure details, and ordered runtime issues WriteAndContinuecan replace explicitly recoverable cell data failures with literal diagnostic text and finish asCompletedWithErrors, while the defaultStopmode remains compatible
Changed
- Strict data access reports missing tables, unavailable random access, missing rows and missing fields through stable error codes when no explicit template fallback exists
- Only explicitly marked recoverable data failures may continue; structural, callback, cancellation, resource, security, serialisation, and other fatal failures still stop the report
Fixed
- File and encrypted-file output failures now publish a failed run result rather than retaining a completed result from the preceding workbook generation phase
Version 2.361.67
Changed
- Compiled templates, runners, range bands, and Excel-table bands now resolve
dbvalueanddbcountthrough one isolated data session per logical run - Repeated aliases are loaded once within a run, later runs reload provider data, concurrent runs keep independent caches and both passes of
PreprocessAndRunshare one consistent table snapshot - Report-band expressions bind only their row or column variables, so literal table names and built-in location variables can no longer be mistaken for source columns
Fixed
- Report data sessions and their provider snapshots are released after successful, cancelled, or failed execution, including provider exceptions and reusable runner retries
Version 2.361.66
Added
TXLSReportDataContext.BeginRunreturns an isolatedIXLSReportDataSessionsnapshot with state inspection and resolved or cached alias counts
Changed
- Report data sessions use a case-insensitive hash cache for explicit tables, lazy provider results, missing aliases and provider data errors
- Each distinct alias reaches the provider chain at most once per session, provider results stay bound to the requested alias and same-alias recursion fails immediately
- Direct
TXLSReportDataContext.TryGetTableandRequireTablecalls retain a separate compatibility cache invalidated whenever registrations change
Version 2.361.65
Added
IXLSXImageBlobandTXLSXImageBlobprovide immutable raster and SVG payloads with one-time SHA-256 digests, byte size and an optional cache keyTXLSReportImageResult.CacheKeylets a V2 image provider explicitly identify reusable content whilst conflicting content for the same key is rejected before worksheet mutation
Changed
- Repeated report images share one immutable payload by explicit cache key or exact digest match whilst retaining independent anchors and transforms
- XLSX and ODS save each distinct image payload once, reuse its media relationship across sheets and restore shared payloads when the workbook is reopened
- XLSX reopening now restores SVG companion data from DrawingML extension relationships and couples it with the raster fallback
Version 2.361.64
Added
TXLSReportImageResultcan declare source pixel dimensions and DPI, whilst image requests and results expose anchor-relative target offsets in EMUTXLSXImage.OffsetXEMUandOffsetYEMUpreserve picture placement within an anchor through XLSX and ODS save/open cycles
Changed
- V2 image binding derives physical geometry from PNG, JPEG, GIF, BMP, EMF and WMF headers, applies Natural, Contain, Cover or Stretch sizing, and centres contained images without decoding their pixels
- Raster geometry is rejected before worksheet mutation when headers are truncated, declared dimensions disagree, a side exceeds 100,000 pixels or total decoded size exceeds 100 million pixels
Version 2.361.63
Added
IXLSReportImageDataProviderV2can return image bytes or caller-borrowed and provider-transferred streams with workbook, worksheet, target, band, table, row, anchor and cancellation contextOnTransformImagecan replace or resize an image before binding, whilst compiled range and Excel-table bands expose a read-only snapshot of each actual data row
Changed
- V2 image streams are read in bounded blocks with a configurable 64 MiB default limit; borrowed seekable streams restore their position and transferred streams get released exactly once
- V2 payloads reject empty data, mismatched format signatures, inconsistent dimensions, invalid anchors and out-of-grid offsets before mutating the worksheet
- Compiled range and Excel-table bands bind image targets once per generated row from materialised bound columns without scanning generated worksheet cells
Version 2.361.62
Added
TXLSCompiledReportRunnerandTXLSReportGeneratornow accept an existingIXLSReportImageProviderwith missing-image and directive-cell policiesTXLSReportImageBinder.ApplyTargetbinds one precompiled image directive without touching unrelated worksheet cells
Changed
- Exact
{{#image Key}}cells compile into typed report targets, remain unchanged when no provider is configured and reuse their compiled key and coordinates across runner sessions
Version 2.361.61
Added
TXLSCompiledReportRunnernow exposes paired workbook and worksheet generation events with stable worksheet identity, original and current coordinates, read-only report data, target counts, cancellation and failure detailsTXLSReportGeneratorruns workbook, file, stream or encrypted-file templates through template-read and generation lifecycle events with selectable in-place or atomic-clone modification
Changed
- Report generation freezes the original worksheet set, recompiles after callback-driven structure changes, rejects concurrent mutation of the same workbook, pairs entered events during cancellation and failure and preserves the first exception
- Report streams remain caller-owned, seekable template streams restore their position, forward-only streams are consumed in bounded blocks and stream, file and encrypted-file destinations change only after successful completion
- Compiled reports without lifecycle handlers retain the direct target loop without worksheet scans, event contexts or per-target lifecycle allocations
Version 2.361.60
Added
- XLSX workbooks now expose
HasWebAddinTaskPanes,WebAddinTaskPaneCount, andRemoveWebAddinTaskPanesfor exact package-root task pane inspection and removal
Changed
- Web Add-in task pane removal now validates a bounded internal relationship graph before mutation, preserves shared and unrelated package parts, removes exclusive descendants and owned relationship parts, rebuilds content types, prevents source-copy resurrection and is idempotent
- Classic XLS and ODS workbooks report Web Add-in task pane removal as unsupported without inspecting package content
Version 2.361.59
Added
- Classic XLS and XLSX workbooks now expose matching
SaveExternalLinkValuesandUpdateLinksproperties for cache persistence and file-declared link-update preference
Changed
- Disabling external-link cached values now omits only Classic
XCT/CRNrecords or XLSXsheetDataSetcontent while retaining link definitions, defined names, relationships, unknown XML and in-memory caches - External-link policies now round-trip reserved source values losslessly until edited, convert between XLS and XLSX, preserve unchanged compressed package parts and never initiate external file or network access
Version 2.361.58
Added
TXLSHTMLExportandTXLSXHtmlExportSessionnow expose the immutableRenderGeometrysnapshot used by the current HTML operation
Changed
- Classic XLS and XLSX HTML exporters now convert Excel character widths to fixed CSS lengths through backend-specific maximum-digit-width geometry rather than hard-coded conversion factors or CSS character units
- Workbook, worksheet, range and incremental multi-sheet HTML exports capture one operation-local calibration with a bounded metric cache and never modify stored row heights or column widths
Version 2.361.57
Changed
- PDF, SVG, bitmap, print-preview and workbook-viewer operations now capture distinct immutable render-geometry snapshots with backend-aware bounded metric caches
- Shared page rendering and SVG wrapping now use operation-local font measurement instead of process-global GDI bitmap and string-list state, whilst preserving stored row heights and column widths
Version 2.361.56
Changed
- Classic XLS and XLSX AutoFit now capture one immutable workbook render-geometry service per operation, including calibrated text measurement, wrapping, line spacing, cell margins and actual XLSX visible fonts
- Pagination now captures workbook-local geometry for each build, removes process-global normal-font and maximum-digit-width state and applies calibrated implicit column widths without modifying stored row heights or column widths
Version 2.361.55
Added
- Classic XLS and XLSX workbooks now create immutable operation-owned geometry and font-measurement services with bounded local caches, shared width conversions and no AutoFit process-global DPI or base-width cache
Version 2.361.54
Added
- Classic XLS and XLSX workbooks now expose validated
TXLSRenderCalibrationvalues plus independentCaptureRenderCalibrationsnapshots andResetRenderCalibrationdefaults for future rendering operations
Version 2.361.53
Added
- XLSX loading now reports
xlsDiagnosticPrinterSettingsRelationshipInvalidwhen a worksheet printer-settings relationship is missing, mistyped or dangling
Changed
SaveXLSWorkbookAsXLSXandSaveXLSXWorkbookAsXLSnow carry typed page-setup fields and opaque printer-driver bytes independently, with standard fields preferred over duplicate private defaults
Fixed
- XLSX loading no longer binds a stray printer-settings part when the relationship named by
pageSetupis invalid - XLSX-to-BIFF8 conversion now rejects oversized or unrepresentable printer settings before any destination bytes are written
Version 2.361.52
Added
- Classic XLS and XLSX worksheets now expose copy-isolated
PrinterDriverDataandHasPrinterDriverDataproperties plusClearPrinterDriverDatafor direct opaque printer-driver payload control
Fixed
- Clearing XLSX printer-driver data now removes its worksheet relationship and binary package part even where unsupported-part preservation is enabled
Version 2.361.51
Changed
- XLSX loading and saving now keeps each worksheet's binary printer settings through the
pageSetuprelationship, content-type declaration andprinterSettingsN.binpackage part - Printer settings survive same-workbook and cross-workbook worksheet copies with byte-exact independent ownership, whilst unchanged source parts can retain their original compressed payload
Version 2.361.50
Changed
- Classic XLS loading and saving now preserves the complete BIFF
PLSprinter-driver payload together with every immediately followingContinuesegment - Printer-driver payloads are deep-copied with worksheets, emitted before
Setupin exact BIFF-sized chunks and rejected when structurally incomplete or larger than the 1 MiB safety limit
Version 2.361.49
Added
- Classic XLS page setup now exposes read-only
HasSetupRecordandPrinterSettingsInitializedproperties so callers can distinguish missing or uninitialised printer settings from defined values
Changed
- Saving an untouched classic worksheet now preserves a missing BIFF
Setuprecord and retains every byte of an existing 34-byte record, including reserved and unmodelled flag bits - Page-setup setters now create a missing
Setuprecord only when needed and initialise printer-dependent or orientation fields according to the affected property
Version 2.361.48
Added
SaveXLSXWorkbookAsXLSnow converts an XLSX-model workbook to BIFF8 through file and stream overloads, preserving loaded values, formulas, core styles, merged ranges, row and column dimensions, workbook date mode and active sheet state
Changed
- XLSX-to-XLS conversion builds one deterministic 56-colour palette before writing styles, preserves indexed slots already in use, and applies weighted OKLab quantisation when direct colours exceed BIFF8 capacity
- The conversion path traverses loaded sparse or packed cells without materialising the source grid, rejects coordinates outside BIFF8 limits before touching the destination, and is now available in the Delphi and C++Builder ConversionWorkbench examples
Version 2.361.47
Added
- Classic XLS and XLSX workbooks now expose matching
ApplyBiffPalettePlanmethods that validate and atomically apply a current 56-slot palette plan - Classic workbooks now expose
BiffPaletteSavePolicy, with an explicit BIFF8 optimisation option and a default that preserves historical palette output
Changed
- Palette-plan application now validates source generation, source hash, all slot identities and colours, aggregate counts, preservation locks, change flags, and opaque targets before the first mutation, then rebuilds the cached OKLab matcher once
- Optimised BIFF8 saves leave the applied palette in the workbook after success but restore all 56 source colours and the original generation if output fails or is cancelled; BIFF5 and non-BIFF output paths remain unchanged
Version 2.361.46
Added
- Classic XLS and XLSX workbooks now expose matching
BuildBiffPalettePlanmethods that return a mutation-free 56-slot plan with source palette identity, locked slots, proposed colours, aggregated true-colour mappings, exact coverage, and perceptual error statistics
Changed
- BIFF palette planning now preserves indexed consumers and existing exact colours before assigning free slots, then uses deterministic frequency-weighted OKLab clustering only when direct and resolved theme colours exceed the remaining capacity
- Palette plan construction reads stored style and conditional-format metadata without changing palette entries, custom-colour counts, cells, save behaviour, or sparse storage
Version 2.361.45
Added
- Classic XLS and XLSX workbooks now expose matching
ScanIndexedColorUsagemethods that return a deterministic 56-slot inventory with public and physical indexes, normalised ARGB values, definition and reference counts, consumer kinds, and preservation locks
Changed
- Indexed-colour usage scanning now covers workbook style pools, sparse cell references, named styles, range overlays, worksheet gridlines, shapes, comments, rich text, chart fonts, differential styles, data bars, and colour scales without materialising unused cells or changing workbook state
- Indexed conditional-format colours now round-trip through classic BIFF and OpenXML differential styles, data bars, and colour scales, including streaming saves that emit differential-style identifiers before worksheet parts
Version 2.361.44
Added
- Classic XLS and XLSX workbooks now expose matching
NearestIndexedColormethods that return the closest public palette index, physical slot, normalised ARGB value, squared perceptual distance, and exact-match status
Changed
- Nearest indexed-colour matching now shares one cached OKLab implementation across both workbook engines and the legacy colour manager, with deterministic lowest-index tie breaking and cache updates limited to effective palette mutations
- Nearest-colour queries scan only the 56 physical BIFF palette entries, reject partially transparent inputs, and never modify palette or workbook state
Version 2.361.43
Added
- Classic XLS and XLSX workbooks now expose matching
ResolveIndexedColoroverloads that classify public colour indexes, BIFFicvvalues, and OOXML indexed colours while returning palette, automatic, system, or invalid metadata - The typed indexed-colour result reports the raw index, palette slot, system-colour role, normalised ARGB value, and whether a concrete colour was resolved
Changed
- Automatic and system colour tokens no longer query the current Windows desktop implicitly; callers can supply an explicit resolver when a concrete environment colour is required
- Theme system colours now use their stored fallback RGB value, keeping load, save, and headless processing deterministic across machines
Fixed
- Invalid OOXML indexed-colour values no longer resolve to opaque black, and the legacy colour-manager defaults now use the exact 128-channel palette values
Version 2.361.42
Added
TXLSWorksheetandTXLSXWorksheetnow expose matchingTryGetOutlineNode,SetOutlineNodeCollapsed, andSetOutlineDisplayLevelmethods for one-based row or column summary nodes
Changed
- Worksheet outline queries and updates now adapt sparse engine metadata to compressed plans, preserve nested child state by default and apply hidden and collapsed changes without scanning unused worksheet coordinates
- OpenDocument row and column groups now preserve native nested display state across direct metadata changes, structural edits, ODS round trips and conversion to XLSX summary-node markers
TXLSXWorksheet.ToggleRowGroupedandToggleColGroupedstay available as direction-aware compatibility wrappers around the summary-node API
Version 2.361.41
Added
TXLSOutlineGeometrycan now build compressedTXLSOutlineMutationPlaninstances supporting idempotent node collapse or expansion and one-based outline display-level changes- Outline mutation plans expose explicit preserve, collapse and expand child modes while keeping nested collapse markers independent by default
Changed
- Expanding a nested outline node now accounts for collapsed ancestors and collapsed descendants when deriving visibility, and bulk node discovery traverses only materialised spans with a linear monotonic-stack pass
Version 2.361.40
Added
- The new engine-neutral
lxOutlineunit builds row or column outline geometry from sorted sparse spans and discovers summary-before or summary-after nodes, nested detail ranges, summary levels, hidden state and explicit collapse markers without scanning unused worksheet coordinates
Version 2.361.39
Added
- Classic XLS column metadata now carries the independent outline collapse marker through
TXLSColumnInfo.CollapsedandTXLSColumnInfoList.Collapsed
Fixed
- Classic XLS column outline collapse markers now survive BIFF round trips, column-format copies, worksheet copies and adjacent-record coalescing while defined width, best-fit and phonetic flags remain intact
Version 2.361.38
Fixed
- Classic XLS outline summary columns now preserve their logical left or right position across left-to-right and right-to-left worksheet views rather than writing the opposite
WSBOOLdirection bit
Version 2.361.37
Added
- Classic XLS and XLSX worksheets now expose
EvaluateFormulaAtfor read-only A1 or R1C1 formula evaluation in an explicit target-cell context IXLSFormulaEvaluationTemplatecompiles an immutable formula anchor once and evaluates the anchor repeatedly at other cells throughEvaluateAtorEvaluateAtWithOptions- Formula evaluation options now include limits for formula length, syntax-item steps, recursion depth and generated array bytes, with exhaustion reported as
xlfeResourceLimit
Changed
- One-shot and reusable evaluation now share worksheet-local names, structured references, uncached formula dependencies, array roots, volatile status, cancellation, and explicitly authorised external references without writing workbook state
- The existing workbook and worksheet
Calculatemethods remain compatibility facades over the typed contextual evaluator
Fixed
- Contextual evaluation now preserves formula error variants and distinguishes parse, unsupported-function, circular-reference, external-reference, cancellation, worksheet-lifetime and resource-limit failures
- Reusable R1C1 templates now translate relative row and column offsets from their compile anchor when evaluated at some other target cell
Version 2.361.36
Added
ConvertExternalDefinedNamesToRefErrorsis now available on Classic XLS and XLSX workbooks to detach confirmed external-workbook defined names without touching ordinary cell formulas- Skipped malformed or unsupported definitions are reported through
xlsDiagnosticDefinedNameConversionSkipped
Changed
- The conversion replaces selected definitions atomically with native
#REF!while retaining workbook or worksheet scope, visibility, comments, macro and built-in flags, unknown attributes and external-link parts
Fixed
- External defined-name slot syntax such as
=[1]!RemoteNamenow resolves through the declared workbook link and dependent formulas retain the resulting Excel error value during recalculation
Version 2.361.35
Added
TXLSWorkbookWorkspace.Recalculatenow evaluates registered Classic XLS, XLSX and ODS formula nodes in one cross-workbook topological pass with strongly connected component detection and dirty-generation propagationTXLSWorkspaceRecalcResultreports graph reuse, dirty and evaluated nodes, cycles, blocked dependents, invalidations and runtime cache hits and misses
Changed
- The workspace retains its dependency graph until registrations or formula topology change, whilst ordinary value edits dirty only the affected workbook nodes and their transitive dependents
- Repeated external-cell reads in one calculation pass share an exact workbook, worksheet, row and column cache that is invalidated before each scheduled formula update
Fixed
- Bidirectional links between workbooks are no longer treated as circular unless the formula-cell graph contains a real cycle; cycle members and their blocked dependents are invalidated rather than returning stale cached values
- A failed or cycle-invalidated workspace session now retains the engine-local dirty state so a later workbook recalculation retries unfinished formulas rather than treating a partial pass as complete
Version 2.361.34
Added
TXLSWorkbookWorkspace.BuildDependencyGraphnow creates one dependency graph across registered Classic XLS, XLSX and ODS workbooks, retaining workbook, worksheet, cell, rectangular range and scoped defined-name identitiesTXLSWorkspaceDepGraphexposes formula-node, reference, edge, cell-dependent and defined-name-dependent queries plus candidate-check diagnostics for performance verification
Changed
- Large formula ranges remain compact intervals instead of expanding into individual cells, while row-interval trees prune both dependent lookup and edge construction without materialising packed worksheet values
- Local defined names retain both their symbolic dependency and statically resolved cell or range dependencies, while external defined names preserve their declared external-workbook slot, name and worksheet scope
Fixed
- Ordinary defined names are no longer cleared whilst the formula parser checks for an optional external-workbook prefix
Version 2.361.33
Added
TXLSWorkbookWorkspace.OnLoadWorkbookcan now request an external workbook through caller-controlled policy at most once per normalised identity, whileResolveWithLoaderreports typed not-found, error, cycle, and resource-limit diagnosticsMaxLoadDepth,MaxWorkbookCount, andResetLoadAttemptsprovide explicit bounds and retry control for external workbook loading
Changed
- Concurrent external-workbook requests now share one in-flight load result and nested re-entry is rejected without waiting in a cross-thread load cycle; the default workspace still performs no file-system or network access
Version 2.361.32
Added
- Classic XLS workbooks now expose
CreateWorkspaceWorkbook,RegisterExternalWorkbook,UnregisterExternalWorkbook, andExternalWorkspace, allowing Classic, XLSX and ODS workbooks to serve external formula values through one engine-neutral workspace - Classic XLS external-link caches now decode number, string, Boolean, error, and blank values from typed XCT and CRN records into a sparse constant-time lookup without materialising worksheets
Changed
- External formula evaluation now resolves worksheet names before positional fallbacks and always reads an explicitly registered live workbook first, then a typed file cache, then returns
#REF!, whilst destroyed registrations are revoked without implicit file or network access - Quoted external workbook identities can contain URI schemes, Windows drive letters and other colons without being mistaken for a three-dimensional worksheet range separator, so ODF external-source IRIs remain intact during formula import
Version 2.361.31
Added
TXLSWorkbookWorkspace,IXLSWorkspaceWorkbook, andTXLSXWorkbook.CreateWorkspaceWorkbookprovide a thread-safe external-workbook identity and registration foundation with explicit resolution status, generation tracking and revocable workbook adapters
Changed
TXLSXWorkbook.RegisterExternalWorkbooknow preserves paths and extensions, resolves relative relationship targets against the owning workbook, rejects ambiguous aliases or same-basename targets instead of silently choosing one, revokes registrations when a target workbook is destroyed and retains typed external-link cache fallback without implicit file or network access
Version 2.361.30
Added
- Classic and XLSX read-only workbook views can now calculate formulas on demand through
xlsvEvaluateFormulasand report the independent result throughFormulaEvaluationwithout replacing stored formula caches
Changed
- Concurrent read-only views now isolate formula recursion flags, scalar results, compiled XLSX formulas and array matrices, while XLSX external formulas use only file-local external-link caches and never dereference live-workbook registrations
Fixed
- XLSX external-link cached values now resolve the one-based worksheet index carried by external XTI records onto the correct zero-based cached sheet entry
Version 2.361.29
Added
- XLSX workbooks now expose
IXLSXWorkbookOwner.CreateReadOnlyViewwith view-local active sheets, by-value materialised and packed cell snapshots, cached formula results, opt-in formula text, safe owner or view release order, and fail-fast write exclusion
Changed
- XLSX read-only views use only locally stored external-formula caches and never follow weak live-workbook registrations
Version 2.361.28
Added
- Classic workbooks now expose
CreateReadOnlyViewandIXLSReadOnlyWorkbookViewfor constant-time shared-model views with independent active sheets, by-value cell snapshots, cached formula results, opt-in formula text, reference-counted owner lifetime and fail-fast write exclusion
Version 2.361.27
Added
- Classic, XLSX and ODS workbooks now expose
CreateFormulaCacheReaderand the sharedIXLSFormulaCacheReaderinterface for engine-neutral formula-cache examination with safe lifetime invalidation
Changed
- Shared-formula cache inspection now preserves each member's independent stored result, so a follower without a cached value reports missing rather than inheriting the root member's value
Version 2.361.26
Added
TXLSXWorkbook.TryGetCachedFormulaValuenow reports XLSX and ODS formula-cache presence, provenance and value kind without calculation or workbook mutation
Fixed
- XLSX and ODS formula caches now preserve missing and explicit blank results, empty strings, Boolean false, numeric zero, typed errors, and explicit dates across save and reopen, while changed formulas no longer serialise stale cached results
Version 2.361.25
Added
- Classic workbooks now expose
TryGetCachedFormulaValuewith explicit cache presence, provenance and value kind, allowing a stored formula result to be read without calculation, user-function callbacks, token decompilation or workbook mutation
Fixed
- Classic XLS formula Boolean and error caches now use the specified BIFF payload byte in ordinary and shared formulas and loaded error results remain typed
varErrorvalues across save and reopen
Version 2.361.24
Added
- Classic and XLSX workbooks now provide a
CreateLoadedCellCursor(Boolean)overload that can include independently styled stored blanks asxlckBlanksnapshots
Changed
- Opt-in blank traversal preserves worksheet, row and column order, keeps packed XLSX storage compressed and excludes inherited-format coordinates plus unstyled Empty and Null placeholders
Version 2.361.23
Added
- XLSX workbooks now expose
TXLSXWorkbook.CreateLoadedCellCursorfor constant-state row-major traversal of stored value and formula cells across all worksheets TXLSLoadedCellKindnow includesxlckErrorso stored XLSX error values retain their distinct value kind
Changed
- XLSX cursors traverse materialised sparse row blocks or packed storage directly without sorting cells or materialising packed values, and formula snapshots return the currently stored cached value without recalculation
- Workbook-wide topology changes and workbook release invalidate XLSX cursors through a shared lifetime lease, whilst edits to existing cell content keep traversal valid and captured snapshots owned
Version 2.361.22
Added
- Classic workbooks now expose
IXLSWorkbook.CreateLoadedCellCursorfor constant-state row-major traversal of stored value and formula cells across all worksheets TXLSLoadedCellSnapshotreturns owned sheet identity, one-based coordinates, style, value kind, value and formula text without exposing internal cell objects
Changed
- Loaded-cell cursors fail fast after cell topology, worksheet collection or workbook model replacement changes, while edits to existing cell content keep traversal valid and previously captured snapshots unchanged
Version 2.361.21
Added
- Classic and XLSX worksheet cell stores and worksheet collections now expose independent structural generation counters for safe long-lived traversal
XlsValidateStructureGenerationandEXLSLoadedCellCursorInvalidatedprovide one fail-fast validation contract for loaded-cell readers
Changed
- Cell creation, removal, clearing, coordinate reordering, packed-storage transitions, index rebuilds and worksheet add, delete or move operations advance the relevant generation, while existing-cell content edits, worksheet rename or activation and no-op mutations keep it stable
Version 2.361.20
Added
TXLSForwardReadernow accepts ODS input through the same callback surface as XLS, XLSX, CSV and TSVPeakRowBufferedBytesandSheetPassesStartedsurface the shared row backend's peak logical-row working set and successful worksheet pass count
Changed
TXLSForwardReadernow adaptsTXLSRowCursorfor every supported format, sharing row bounds, column projection, formula state, rich text, password, skipped-record, and stream-position behaviour instead of maintaining separate scan paths- Forward-reader sheet indexes are consistently one-based and worksheets skipped by
OnSheetare not opened or decompressed
Version 2.361.19
Added
TXLSRowCursornow exposes explicit closed, before-first, active, EOF, cancelled and faulted states plus an idempotentCancelmethod that releases the active worksheet stream without closing the sourceCurrentRowViewprovides a generation-checked borrowed view of the current row without duplicating its cell array; advancing, selecting a sheet, cancelling, closing or destroying the cursor invalidates prior views withEXLSRowCursorViewInvalidated- Stream opens now accept
xsoBorrowedorxsoOwned, transferring ownership only after a successful open, andPeakRowBufferedBytesreports the estimated peak logical-row buffer since the last open
Changed
- Worksheet-part and pass-start failures now preserve their original read exception and place the cursor in the faulted state rather than appearing as cancellation or normal EOF; explicitly selecting a sheet resets the pass for retry
Version 2.361.18
Added
TXLSDirectCellandTXLSRowCursorCellnow exposeHasFormulaandFormulaTextAvailable, distinguishing plain values, formulas with available text and formulas whose text is suppressed or unavailableTXLSDirectReader,TXLSForwardReader, andTXLSRowCursornow provideIncludeFormulaText; disabling it preserves cached values, coordinates, styles and formula presence while avoiding formula-text accumulation in XLSX and ODS streams
Changed
- Row bounds and column projection now push into XLS, XLSX, ODS, CSV and TSV backends before value, formula and rich-text allocation; repeated ODS column spans jump directly between selected columns and repeated row blocks are clipped to the requested range
- Row-cursor pass options are frozen while a worksheet pass is active and become mutable again after EOF, sheet selection or close, preventing a pass from mixing incompatible filter or decoding settings
Version 2.361.17
Added
TXLSRowCursornow opens ODS files or caller-owned streams, auto-detects ODS packages by their mimetype orcontent.xml, preloads worksheet names and streams the selected table throughFindFirstandFindNextwithout materialising a workbook
Changed
- ODS row traversal expands repeated rows and columns lazily, omits covered cells as independent values, preserves styled blanks and cached formula values, restores borrowed stream positions and reports invalid or grid-limited repeat counts through
OnSkippedRecord
Version 2.361.16
Added
TXLSRowCursornow streams CSV and TSV files or caller-owned streams with UTF-8 and UTF-16 BOM detection, multiline quoted records, escaped quotes, comma, semicolon, tab or pipe delimiter sniffing, optional delimiter override and optional number, ISO date, Boolean and error type recognition
Changed
TXLSForwardReaderandTXLSRowCursornow share one pausable text-row backend, preserving identical callback and pull results whilst releasing Variant, formula and rich-text payloads from the previous row before advancing
Version 2.361.15
Added
TXLSRowCursornow opens classic.xlsworkbooks from files or streams, auto-detects BIFF compound containers and returns cached numeric or string formula results plus storedBlankandMulBlankcells while retaining only the current logical row
Changed
- Row-cursor
Openoverloads accept an optionalTXLSForwardFormat; file opens own the internal BIFF stream, stream opens borrow the caller's stream and restore its initial position onClose, and repeatedFindFirstpasses seek directly to the selected worksheet
Version 2.361.14
Added
- Formula calculation now supports
ISFORMULAfor individual cells, cross-sheet references and rectangular ranges, returning a same-shaped Boolean array for range inputs without evaluating the referenced formulas
Changed
- Formula-presence checks distinguish ordinary values and blanks, shared-formula members, classic and XLSX array-formula members, dynamic-array anchors and dynamic spill children; generated arrays are bounded by
FormulaArrayMemoryLimit - XLSX stores
ISFORMULAwith the_xlfn.prefix, ODS emits the standard OpenFormula spelling and Classic XLS saves reject the unsupported future function without committing a partial stream
Fixed
- Formula text parsing now recognises the seven standard Excel error literals, allowing
#REF!to propagate through reference-only functions, whilst a defined name that resolves to a scalar reports#VALUE!instead of#NAME?
Version 2.361.13
Added
- Formula calculation now supports
UNICHARacross the Unicode scalar range, including supplementary and private-use characters, with Excel-compatible errors for zero, out-of-range values, surrogate code points and Unicode noncharacters - Formula calculation now supports
BAHTTEXTwith Thai baht and satang text, two-decimal midpoint rounding away from zero, negative values, repeated million groups and finite scientific-notation inputs
Changed
UNICHARandBAHTTEXTmap ranges and generated arrays element by element whilst preserving local errors; XLSX storesUNICHARwith its future-function prefix whileBAHTTEXTremains a standard bare function in both XLS and XLSX
Version 2.361.12
Added
- Formula calculation now supports
COMBINAandPERMUTATIONAwith truncated non-negative arguments, checked overflow, singleton array broadcasting and per-element errors, plusMUNITidentity matrices without a fixed dimension ceiling - Classic and XLSX workbooks expose
FormulaArrayMemoryLimitwith a 64 MiB default to cap generated formula-array payloads, including parallel XLSX recalculation workers
Changed
PERMUTATIONAuses logarithmic exponentiation,COMBINAshortens its multiplicative recurrence, andMUNITallocates a compact numeric matrix while writing only its diagonal
Fixed
- Numeric formula arrays are no longer classified as scalar numbers and newly created classic workbooks apply BIFF97 grid limits during formula calculation before their first save
Version 2.361.11
Added
- Formula calculation now supports
COT,ACOT,COTH,ACOTH,CSC,CSCH,SEC, andSECHwith principal-value, domain, singularity, finite-input and large-argument rules across scalar and broadcast-array operands
Fixed
- Mapped formula functions now keep direct scalar failures as spreadsheet error values, use cancellation-resistant reciprocal and exponential-tail branches for large valid inputs, write exact
_xlfn.names without_xlws., and reject unsupported Classic BIFF formulas cleanly
Version 2.361.10
Added
- Formula calculation now supports
CEILING.MATHandFLOOR.MATHwith omitted significance and mode arguments, sign-independent significance, precise decimal-multiple boundaries and the specified negative-number mode directions
Changed
- Formula-level array functions can now share a linear element mapper with singleton-row and singleton-column broadcasting, one-time range snapshots and per-element conversion or calculation errors; XLSX uses the
_xlfn.prefix for both new functions whilst Classic BIFF saves reject unsupported formulas cleanly
Version 2.361.9
Added
- Formula calculation now supports
SORTBYwith stable multi-key row or column ordering, independent ascending or descending directions, omitted-direction defaults, range or generated-array keys and one-time source and key snapshots followed by O(n log n) sorting
Fixed
- Classic BIFF saves now fail cleanly when a formula cannot be represented rather than reporting success after an internal future-function identifier is rejected, while XLSX writes
SORTBYwith_xlfn.and never adds_xlws.
Version 2.361.8
Changed
- Worksheet zero-display mode now uses one raw-value decision across the workbook viewer, preview, print, bitmap, EMF, SVG, PDF, Classic HTML and XLSX HTML paths; actual numeric zero is hidden before number formatting and text measurement, while formula-display mode retains precedence
Fixed
- XLSX worksheet views now parse, write and copy zero-display state through one setting, correctly handle the 1904 date base, preserve conditional-format visuals and hyperlink geometry for hidden zero cells, and leave stored values, public formatted text, CSV, and ODS output unchanged
Version 2.361.7
Changed
- Worksheet formula-display mode now uses one protected-cell-aware text decision across the workbook viewer, preview, print, bitmap, EMF, SVG, PDF, Classic HTML and XLSX HTML paths; formula text uses text alignment under General alignment, preserves explicit alignment, and receives a non-persistent twofold effective layout width without overflowing into neighbouring cells
Fixed
- XLSX worksheet views now accept both
showFormulas="1"andshowFormulas="true", preserve the setting during same-workbook and cross-workbook worksheet copies and emit the requiredsheetViewstate without changing formula caches, CSV output, ODS persistence or the public formatted-value contract
Version 2.361.6
Changed
- XLSX external-workbook formulas now use one shared grammar-aware book-prefix lexer across
OnlyExternalconversion, formula diagnostics, calculation binding, cross-workbook copying and generated formula serialisation; numeric link slots are canonical, while structured references, string literals, malformed indexes and ambiguous filename prefixes fail closed TXLSXExternalLinknow exposes its sourceRelationshipId, one-basedSourceSlot, and typedLinkKindso workbook, DDE, OLE and unresolved external-reference entries can be audited without inferring identity from collection order or target text
Fixed
- Changing an XLSX external-link target or sheet list now invalidates compiled external-formula bindings by revision instead of rescanning every cell and unchanged DDE or OLE external-link parts without relationship files remain byte-preserved during save
Version 2.361.5
Fixed
- XLSX external-workbook formula slots now follow the document order of
workbook.xmlexternal references rather than relationship-file order; missing, unresolved and wrong-type relationships retain empty slots so later[N]references do not shift
Version 2.361.4
Changed
- Classic XLS formula freezing with
OnlyExternalnow classifies preserved BIFF references and converts only confirmed external-workbook formulas, while internal, add-in, DDE/OLE and malformed references remain formulas
Fixed
- Formula results beginning with an equals sign or apostrophe now remain literal strings during value conversion and array-formula groups are snapshotted before any root or spill formula is released
Version 2.361.3
Changed
- Classic XLS supporting links and external-sheet indexes now use bounded typed classification for self, same-sheet, add-in, external-workbook, DDE/OLE, unused and unknown records
Fixed
- Malformed supporting-link payloads are preserved byte-for-byte instead of being reconstructed as a different link type and truncated external-sheet tables no longer read beyond their record data
Version 2.361.2
Fixed
- Classic XLS formulas now resolve the zero-based XTI index in external defined-name tokens to the right internal external-sheet entry, including the first entry
Version 2.361.1
Fixed
- The direct XLSX writer now emits the base SpreadsheetML
showDropDownsuppression flag only whenShowDropDownis disabled, preserving the public display-oriented API semantics
Version 2.361.0
Added
- Chart series gained
CategoriesMultiLevel: set it to emit the categories as amultiLvlStrRef(hierarchical axis labels) rather than a flat string reference, with round-trip recovery from saved charts
Version 2.360.0
Fixed
- Classic XLS name comments now use the correct
NAMECMTrecord identifier ($0894); the identifier previously used ($0019) belongs toWINDOWPROTECTper the BIFF specifications
Added
WindowProtectedon classic workbooks round-trips the workbook's window-protection flag through theWINDOWPROTECTrecord ($0019), with raw captured bodies taking precedence unless the property is explicitly written
Version 2.359.0
Added
- Chart data tables expose independent
showHorzBorder/showVertBorder/showOutlineswitches instead of always drawing every border - Line charts gained drop lines (
HasDropLines) and stacked bar charts gained series lines (HasSeriesLines), both round-tripped; a series can be removed from the legend individually throughLegendDeletedwhile staying plotted
Version 2.358.0
Added
- Report bands gained fixed and empty-dataset semantics:
EmptyBandPolicykeeps, clears or deletes the template rows whenever the data set is empty (no more unresolved placeholders left behind),FixedBandwrites the copies over the rows below without inserting anything for overlay-style form bands andDeleteLastRowcollapses the final copy so trailing content joins flush (X-range behaviour)
Version 2.357.0
Added
- PDF export can embed standalone OpenType fonts with CFF outlines through a
FontFile3OpenType stream andCIDFontType0descendant; automatic and full modes retain the complete program, whilst an unavailable required subset fails before output is committed OnGetFontDirectoriessupplies semicolon-separated directories for a requested font family and style; accepted trees get searched recursively once and indexed by internal font metadata for cached fallback resolution
Changed
- Embedded fonts carrying OpenType GPOS or legacy kern data now use positioned glyph advances for simple text as well as complex scripts, keeping measurement, wrapping, alignment and PDF glyph placement consistent
Version 2.356.0
Added
- PDF font embedding became a configurable four-mode policy:
FontEmbeddingselects automatic historical behaviour, required subsetting, full-program embedding or map-only fonts whose programs are stripped while the CID mapping and ToUnicode tables survive; PDF/A rejects map-only output - The
OnFontEmbedevent fires once per Unicode font before metrics and glyph mappings are resolved, receives its name and file path and can accept a per-font mode or replacement font bytes through the explicitHandledcontract
Version 2.355.0
Added
- Classic XLS recalculation now uses a lazily built dependency graph, propagates input changes only to transitive dependants, recalculates volatile formulas on every pass and evaluates formulas in dependency order instead of rescanning the entire sparse cell heap
- Circular references in classic XLS now follow
EnableIteration,MaxIterations, andMaxIterationChange; strongly connected components isolate independent cycles, iterate them deterministically and then calculate downstream formulas - PDF/A-3 associated files gained a detailed
AddAttachmentoverload with Unicode display names, descriptions, modification times, escaped MIME names, byte-size metadata and Source, Data, Alternative, Supplement or Unspecified relationships TXLSPDFWritercreates standalone PDF documents without a workbook, with explicit page sizes, multi-page output, rectangles, lines, ellipses, measured styled text, coordinate transforms, rectangular clipping and graphics-state control
Changed
- Disabling
UseFullPrecisionon classic XLS now rounds formula and What-If data-table cached results to the effective displayed numeric precision before dependant formulas consume them, covering percentage formats and half-away-from-zero midpoint rounding
Fixed
- Classic formula recalculation now uses the native zero-based cell coordinates, keeps calculation failures out of the success cache and preserves error propagation through dependent array functions
Version 2.354.0
Added
- Chart axes gained the crossing-mode enumeration (
Crosses: autoZero / max / min, emitted ascrosseswhen no explicitCrossesAtis set) and per-axis major / minor tick-mark styles (in,out,cross), all round-tripped AutoTitleDeletedon charts replaces the hardcoded automatic-title flag and suppresses the series-derived title once set
Version 2.353.0
Added
- Chart series gained
Smooth/SmoothSetfor curved line rendering andMarkerFillColor/MarkerBorderColorfor explicit marker colours; both persist through save and open and the shared renderer draws smoothed segments as quadratic curves and consumes the marker colours
Version 2.352.0
Added
- Chart space formatting round-trips:
RoundedCorners, explicit chart background and border colours and the plot-area background colour persist through save and open and the shared chart renderer consumes the background and border colours instead of always drawing white on grey - Chart protection switches round-trip behind a single master:
ProtectionEnabledplusProtectedChartObjects,ProtectedDataEditing,ProtectedFormatting,ProtectedSelectionandProtectedUserInterfaceemit and parse the OOXMLprotectionelement
Version 2.351.0
Changed
- Bar and column charts in the shared pagination renderer now follow the plot group's layout options: GapWidth sizes the cluster, Overlap widens and pulls neighbouring bars together and stacked / percent-stacked groupings accumulate one full-cluster bar per category instead of drawing series side by side
Version 2.350.0
Added
- Cross-workbook range copy now remaps each cell style by value into the destination workbook's font, fill, border, number-format, alignment and protection pools, so
CopyRangeToandCloneRangeTobetween two open workbooks keep their formatting independent of pool order - Classic XLS workbooks now round-trip the numeric and date built-in document properties:
CreatedDate,LastSavedDate,RevisionNumberandEditTimeMinutespersist through the OLE SummaryInformation stream, with zero values omitted and a full clear removing them
Version 2.349.0
Added
- Classic XLS workbooks surface the shared-workbook revision protection state behind structured properties:
SharedRevisionProtectedandSharedRevisionPasswordHashround-trip, whilst raw record bodies captured from parsed files still win unless the properties are explicitly written - Report encryption awareness:
TXLSCompiledReportTemplate.CreateEncryptedopens a password-protected template directly, andRunToEncryptedFileruns the report and writes an ECMA-376 encrypted result in one call
Version 2.348.0
Added
- Clipboard paste options for both engines:
PasteFromClipboardaccepts values-only (keep cached results, skip formulas, formats and merges) and insert-rows / insert-columns modes shifting existing content before the block lands - Forward readers report skipped content: the direct reader, row cursor and forward reader expose
OnSkippedRecord, raised when a malformed cell reference is skipped or a BIFF sheet scan aborts on truncated or mismatched records
Version 2.347.0
Added
- Report table shaping combinators:
Filterstreams matching rows lazily,Sortperforms a stable multi-key sort, andDistinctkeeps the first row per key tuple - Data source adapters:
FromDataSetsnapshots an openTDataSetinto a report table (field names become columns, the dataset position is restored) andFromObjectsmaps the published properties of arbitrary object lists and arrays to columns - Bidirectional report bands:
RunBidirectionalhas each master row drive its own columns from a related child table, producing jagged column layouts where shorter rows leave the extra clones blank PreprocessAndRunruns a template twice: the first pass fills values and executes structural directives so the template adapts to the data, the second pass then recompiles the reshaped workbook and fills the remaining placeholders
Version 2.346.0
Added
- Report placeholders accept a default value:
{{name;fallback}}writes the fallback text when the key is missing or empty - Report expressions gained
dbvalue(table, row, field[, default])anddbcount(table)for reading any registered data-context table by row and column, plustonumber(text)for string-to-number conversion andref(rowOffset, colOffset)relative references that follow band copies; templates, runners and bands expose aDataContextproperty - A bare
{{=formula(...)}}cell now writes a live formula into the cell instead of plain text and other bare expressions keep their evaluated type (numbers stay numeric) - New structural report directives:
{{#imgsize zoom=150}}rescales the image anchored at the directive cell,{{#comment text}}attaches a cell comment,{{#html <b>bold</b>}}feeds a fragment into rich text, and{{#sheetvisible Sheet false}}/{{#deletesheet Sheet}}control worksheet visibility and removal
Version 2.345.0
Added
- XLSX workbooks gained a save-time recalculation policy:
RecalcBeforeSaveselects manual (default), recalculate-if-dirty, or always-recalculate behaviour when a file is saved RecalcNeededreports whether a formula cell or captured edit is currently dirty, andRecalcCellrecalculates the workbook and returns the newly computed value of a single cell by sheet, row and column
Version 2.344.0
Added
- Report templates support structural directives in cell text:
{{#delete A2}}clears the named range,{{#format fmt=0.00 bold fill=FFFF00}}applies number formats, bold, italic, font and fill colours to the column above the directive cell and{{#aggregate sum A2:A99}}writes=SUM(A2:A99)style formulas — all run after value placeholders fill, with directive cells consumed afterwards and unknown directive verbs still reported as template diagnostics
Version 2.343.0
Added
- The ZIP writer produces ZIP64 archives: entries at or beyond the 32-bit size limits reserve a ZIP64 extra field in their local header with sentinel classic fields, central directory records emit 64-bit sizes and offsets with a version-needed bump and the end-of-central-directory record is preceded by the ZIP64 EOCD record and locator whenever any classic field saturates
- Write-side entry and archive size ceilings climb to 16 GB and 64 GB respectively; read-side decompression guards are unchanged
Version 2.342.0
Added
- Embedded pictures carry accessibility metadata:
AltTextandAltTextTitleon every image serialise as the drawingdescrandtitleattributes and come back into the typed model for workbooks that do not replay the raw anchor XML
Changed
- Slicer and timeline parts already round-trip losslessly through the opaque package layer (verified end to end this release); the round-trip contract is now locked down by a regression test covering open and re-save of slicer-bearing packages
Version 2.341.0
Added
- Report runners can autofit the finished output:
AutofitModeselects row, column, or both passes over every sheet after all targets applied and before serialisation, andAutofitAdjustmentadds optional headroom above the measured sizes - Wrapped rows size from the measured line count against the column width, so multi-line cell text produced by templates grows the row as Excel's own autofit would
Version 2.340.0
Added
- PDF exports can set the initial viewer mode — bookmarks, thumbnails, full screen, optional content, or attachments — through the catalogue
/PageModeentry - PDF exports can define an open action that jumps to a chosen page at an explicit zoom factor or shows the bookmark panel when the document loads
- XMP metadata now carries
DocumentIDandInstanceIDidentifiers, anxmpMM:Historyevent, modify and metadata dates, and thedc:formatdeclaration expected by archival validators
Version 2.339.0
Added
- A physical print pipeline: the new
TXLSPrintDocumentprints worksheets, workbooks or all visible sheets through the shared pagination model with page windows, copy collation, a document title and before-new-page / after-generate-page events - The workbook viewer preview gains zoom modes — fit page, fit width or an explicit 25% to 400% factor — with Ctrl+wheel zoom, wheel page turning and horizontal panning when the zoomed page exceeds the window
Version 2.338.0
Added
- Chart rendering draws the value axis: tick marks and right-aligned numeric labels along the left edge, major gridlines when enabled, display-unit scaling, reversed orientation and logarithmic clamping
- Series assigned to the secondary value axis plot against their own scale, so combo charts keep independent primary and secondary magnitudes
- Bubble charts render area-scaled bubbles derived from the bubble size column rather than fixed marker dots
- In-memory charts resolve their value, category and bubble ranges against the owning sheet when caches are empty, so freshly created charts render identically to loaded ones
- The chart model gains editable doughnut hole size, first slice angle, radar style and of-pie type, split position, split mode, secondary plot size and gap width, all persisted through save and load
Fixed
- Category charts whose points carry values but no numeric categories no longer abort rendering with a placeholder, which previously suppressed tick marks, gridlines and series output for every column, bar and line chart
Version 2.337.0
Added
- Paginated output can render cell comments as an at-end listing through the new
PrintCommentsmode on the SVG exporter and pagination model: cell address, author and text appear below the sheet's last data row - Named drawing objects are exported as PNG images at the configured DPI and scale through
ExportObjectAsPNG, with a measure-onlyGetObjectSizecounterpart returning the object's point dimensions without any rendering - Text-shape anchors outside the used range now widen the printed surface like charts and pictures already did
Changed
- The pagination renderer caches resolved cell fonts per pass and memoises repeated text measurements, removing redundant font-pool reads and GDI measure calls from shrink-to-fit loops and word wrap
Version 2.336.0
Added
- Cell text rotation now renders in page image, SVG, print, and preview output: 1-90 degree counter-clockwise and clockwise angles rotate around the cell centre and the 255 stacked form emits one letter per line
- Subscript and superscript cells render with a shifted baseline and reduced glyph size rather than losing their vertical alignment
- Header and footer sections honour their
&nnpoint-size and&Kcolour format codes in every pagination-driven output - Column widths in paginated output derive from the measured maximum digit width of the workbook's Normal font, so workbooks based on fonts other than Calibri 11 paginate with Excel-faithful column boundaries
- Worksheets with a custom classic grid colour render their grid lines in that palette entry instead of the fixed grey default
Version 2.335.0
Added
- About seventy classic worksheet functions now evaluate as well as being parsed: the math and trigonometry group
ATAN2 ASIN ACOS SINH COSH TANH ASINH ACOSH ATANH EVEN ODD, the date and time groupTIME HOUR MINUTE SECOND DATEVALUE TIMEVALUE DAYS360, the finance groupMIRR IRR IPMT PPMT DB,TRANSPOSE TYPE N ADDRESS ROMAN HYPERLINK MAXA MINAand the pre-2010 spellings of the distribution and statistics family such asNORMSDIST TDIST CHIDIST FDIST POISSON QUARTILE PERCENTILE PERCENTRANK COVAR CHITEST GAMMALNthat forward to the dotted implementations sharing the same argument lists
Fixed
- Legacy one-argument normal CDF forms such as
NORMSDISTcomputed an incorrectly scaled error-function approximation MIRRcompounded positive cash flows with an off-by-one period exponent, pushing results away from Excel's values
Version 2.334.0
Added
- Report band placeholders that consist of a single value field now write the raw data type into the target cell: numbers stay numeric, dates stay date cells and receive the default date format when the cell is General and booleans keep their cell type, so downstream SUM, sorting and chart references work on generated reports
- Custom table styles gained the full section set including pivot subtotal, subheading, blank-row and page-field sections, per-section font name, size, italic, stripe size and four-edge borders through
SetSectionEx, pluspivot/tableflags,DefaultTableStyleName/DefaultPivotStyleNameworkbook properties and full load-side round-trip of styles, sections and dxf attributes - Opening an encrypted XLSX workbook without a password now fires
TXLSXWorkbook.OnPasswordwith the same retry contract as the classic engine, enabling GUI password prompts without knowing beforehand that the file is encrypted - Saving classic BIFF5 workbooks with a password now gets XOR obfuscation and BIFF8 workbooks can select standard RC4 through
EncryptionType, completing the classic encryption matrix alongside the existing RC4 CryptoAPI default - Worksheet text rendering in page image, SVG, print, and preview output now honours vertical alignment and WrapText word wrap with greedy line breaking, instead of clipping wrapped cells to a single centred line
Fixed
- Error cells now display their Excel error literal such as #DIV/0! or #REF! in every rendering path rather than an undefined empty text
- Custom table-style sections are written in the schema
tableStyleElementform so Excel recognises the style, and a section font colour no longer discards its bold setting - Report band snapshots keep all bound column values when a band grows past its initial capacity
Version 2.333.0
Added
TXLSPDFSignature.CertificationPolicycan create a DocMDP certification signature that permits no changes, form filling and signing, or form filling, signing and annotations; certified catalogues reference the signature through/Perms, ordinary certified output uses PDF 1.5 and incompatible PDF/A-1 certification is rejected before the destination stream is changed
Version 2.332.0
Changed
- Automatic tagged PDF now emits a complete table structure with rows, semantic header and data cells, dense per-page marked-content identifiers, exact parent-tree mappings, merged-cell row and column spans, and artefact isolation for page decoration, charts, images, headers, and footers
Fixed
- Reusing one PDF exporter now clears binary object slots between documents, preventing an ICC profile, image or other stream from an earlier export from replacing a newly allocated object when object numbering changes
Version 2.331.0
Added
- A unified XLSX drawing facade exposes mixed image, chart, text-box, preserved-anchor and group order, with forward, backward, front, back, transform-aware group and save-reopen-ungroup operations that retain drawing relationships
- Named styles support automatic or explicit linked format parts while preserving local overrides, and all 60 built-in light, medium and dark table styles resolve through the shared HTML, PDF, image, preview and viewer formatting paths
TXLSPDFBookmarksupports hierarchical Unicode bookmarks, sibling and child relationships, colours, bold or italic titles, and expanded or collapsed descendantsTXLSPageImageExporter.ExportAllAsTiffwrites selected pages to a stream or file as one LZW-compressed multipage TIFF with progress, cancellation and atomic file replacement- Classic XLS opens can halt after global metadata or seek directly to selected worksheets by validated
BOUNDSHEEToffsets, including encrypted-stream repositioning TXLSFormatSnapshotcaptures a full classic cell format independently of its source workbook andIXLSRange.ApplyFormatapplies it to cell, row or column ranges- Compatible row-major typed XLSX bulk writes use packed RLE storage, with public packed-cell and byte statistics plus transparent one-time materialisation for stable object handles
Changed
- Style-only blank XLSX cells share reference-counted payloads with copy-on-write local edits, automatic compaction across bulk formatting, named-style updates, copy, sort, format-patch, save and load paths, and measurable avoided payload bytes
- Dynamic arrays stream directly into scalar aggregates, repeated exact lookups reuse typed incremental range caches and immutable stateless formula tokens are shared across compilations
- Elliptical arcs use flatness-driven adaptive cubic Bezier subdivision shared by PDF, SVG and bitmap output, increasing precision only where scale or eccentricity requires it
- XLSX package output now stabilises shared strings, hyperlinks, relationships, and part ordering so reverse construction produces byte-identical deterministic packages
- The unified XLS, XLSX, CSV and TSV forward reader keeps memory bounded; BIFF8 shared-string continuations spill beyond a configurable threshold while retaining projection, selected-sheet, encryption and malformed-input safeguards
Fixed
- C++Builder Win64 package linking no longer writes duplicate Delphi generic object-list vtables from workbook comparison and import-check units
Version 2.330.0
Added
TXLSXWorksheet.Subtotalinserts grouped subtotal rows, a configurable grand-total row, formulas, inherited visible formatting and Excel-compatible outline levels for sorted data rangesGetCellVisibleFormatresolves worksheet, row, column, range-overlay, and explicit cell formatting without materialising an empty cellCheckDataValidationtests a candidate value against the rules covering one cell and can commit it atomically when valid
Changed
- Lookup scan memos use compact exact binary keys and a single payload lookup per cache hit, cutting recalculation allocation and hash-table work without changing lookup comparisons
- Fixed-width CSV export pads each field in one operation, holding padding time linear in the configured output width
Fixed
- Backward
ReplaceTextInscans now invoke replacement callbacks in the requested reverse scan order - Styled cells with no value or formula no longer block neighbouring text overflow in SVG, image and preview rendering
- Classic XLS numeric output normalises negative zero in addition to non-finite and subnormal values before writing BIFF numeric records
Version 2.329.0
Added
A1ToR1C1converts A1-style formulas to R1C1 notation (relative offsets, absolute$forms, ranges, and round-trips throughR1C1ToA1), completing both directions of reference-style conversion
Changed
- The recalculation lookup memo skips scan vectors of fewer than five cells in
VLOOKUP,XLOOKUP/XMATCH, andMATCH, where a raw scan is cheaper than the dictionary round-trip
Version 2.328.0
Added
- The shared page renderer behind SVG, image and preview output now paints XLSX cell styles: solid fills (with alpha), per-cell fonts and colours, horizontal alignment with Excel's numeric-right default, Excel-style border collapsing where the heavier shared edge wins, shrink-to-fit that scales the font to the column, and overflow of long text into consecutive empty neighbour cells
Version 2.327.0
Added
- The CSV/TSV loader gains per-column import directives (
cctText,cctNumber,cctDate,cctBoolean,cctSkip) mirroring Excel's Text Import wizard, so individual columns can be forced to text to keep leading zeros, coerced to a type or dropped from the import - Fixed-width text import: assigning field widths switches the loader from separator parsing to character-position slicing and the saver can emit space-padded fixed-width columns with truncation
Version 2.326.0
Added
- XLSX worksheet search gains windowed
FindTextInandReplaceTextInmethods that pin the scan to a rectangular cell range, plus a column-major scan order flag that mirrors the Search: By Columns mode of Excel's Find and Replace dialog; the backward scan now accepts a zero anchor to begin from the bottom-right corner - Saving now guards against formulas longer than Excel's 8192-character limit, failing fast with the offending cell identified rather than writing a workbook Excel would open in repair mode
Fixed
- Non-finite numeric cell values (NaN and positive or negative infinity) can no longer leak unparseable tokens into saved XLSX parts; they now serialise as
#NUM!error cells and subnormal doubles flush to zero in both the XLSX and BIFF8 writers, matching what Excel can store and display
Version 2.325.0
Added
- Workbook-format APIs now include editable XML Maps and schema bindings, ordered multiple workbook windows, multi-area and per-pane selections, and caller-owned lossless formula-token inspection, reconstruction, reference replacement and atomic writeback for XLS and XLSX
- Workbook processing now includes stable horizontal or vertical sorting with custom comparers and explicit formula movement, BIFF2 through BIFF4 style and formula conversion, one projected forward-reader facade for XLS, XLSX, CSV and TSV, typed custom views, and editable OLAP, web-table, fixed-text and parameter connection submodels
- Calculation and inspection now include structured missing-function, external-reference and circular-dependency diagnostics, global and workbook-local UDF registries, Unicode bidirectional visual ordering, merged-cell AutoFit strategies, typed Excel 4 macro-sheet preservation and command scanning, and the
ISOMITTED,ARRAYTOTEXT,VALUETOTEXT,PDURATION, andRRIfunctions - Compiled reporting now covers whole-workbook placeholders, named row, column and cross-tab bands, expandable Excel-table bands, one table and cursor abstraction, exact compound-key relationship indexes, lazy data contexts, streaming table combinators, controlled named query providers, per-record sheet bands, overflow continuation sheets, and immutable recursive includes
- Report authoring now includes compiled conditions, lookup, regular expressions, dynamic formulas and formats, image fields, chart-series rebinding, reusable runners with stream or atomic file output, dependency-aware range cloning, fixed-footer and balanced pagination planning, addressed diagnostics, strict execution, template checking and safe migration of supported legacy placeholders
- PDF output now includes automatic tagged structure trees, visible or invisible host-signed fields, explicit PDF/A-1, PDF/A-2 and PDF/A-3 conformance profiles at levels a and b, atomic progress and cancellation, style-aware cached font fallback, contextual complex-text shaping, native multi-stop gradients, per-stop alpha, cell fill patterns, shadows and positioned comment annotations
- Shared rendering now includes native range, page, workbook and named-object SVG, incremental PNG and JPEG pages, backend-neutral layout geometry, inline vector charts and shapes in HTML, stateful partial HTML sessions with shared CSS, rendered picture effects, vector preset-shape and WordArt geometry, advanced scientific and financial chart details, and deterministic data-label collision and leader-line layout
Changed
- All 55 audited capability items F01 through F18, R01 through R19 and V01 through V18 now have completed supported implementations with explicit ownership, format-safety, cancellation and output boundaries
- Large report templates compile object targets and expressions once, materialise only bound axis fields, consume data cursors once, hash relationship and join keys, freeze source collection prefixes for repeated disjoint cloning, and avoid rescanning generated workbook objects
- Rendering paths share pagination, geometry, object placement, effect state and document resource caches while PDF, SVG, HTML, bitmap, metafile, preview and print outputs retain only their format-specific encoders
Fixed
- XLSX cell-write events now serialise their effective replacement values without retaining stale rich-text runs, BIFF external-name tokens preserve the complete 4-byte name index, and top-level connection sources round-trip independently from text-import sources while retaining the legacy source fallback
- Legacy BIFF style and formula meaning, workbook-window and selection remapping, mixed absolute formula references, formula-token ownership, and invalid token writeback now retain deterministic lossless behaviour across load, edit, and save
- Report expansion now rejects deterministic table, filter, name, overlap, partial-object, grid and query-backed conflicts before structural writes, preserves zero-row table cardinality where representable, keeps exact integer join keys beyond 2^53, and reports deterministic applied counts after cancellation or failure
- PDF and vector export now preserve fallback-font Unicode mappings, grapheme and shaping clusters, archival profile restrictions, gradient alpha, image effects, chart decorations, dense label placement and output atomicity without resource growth from repeated content
Version 2.324.0
Added
- Lossless formula-token inspection with guarded writeback for XLS and XLSX through
TXLSFormulaTokenStream,ParseFormulaTokens,GetFormulaTokens,FormulaTokensToText, andSetFormulaTokensexpose RPN token kinds and classes, raw BIFF token and extra payloads, independent reference flags, cloning, reference replacement, context provenance and exact compatible BIFF reuse while rejecting malformed, incompatible, array-owned or unsupported streams before cell mutation - Expandable Excel-table report bands through
TXLSCompiledTableReportBanduse one bounded cursor snapshot to expand a single data-template row while preserving headers, totals, table and AutoFilter ranges, filter and sort state, column metadata, calculated and totals formulas, styles, structured references and dependent worksheet objects; representable zero-row results remove the template data row, while query-backed, conflicting, invalid and overflowing layouts fail before writes - Style-aware PDF font fallback chains through
SetFontFallbackChain,AddFontFallback, andClearFontFallbackChainsresolve source-family and style tiers by glyph coverage, cache loaded faces and selections, preserve supplementary scalars and cross-run grapheme clusters, assign distinct CIDs to shared-glyph Unicode sequences, embed standalone TTC faces and reject PDF/A output atomically when no embedded glyph is available
Version 2.323.0
Added
- Reusable workbook report templates through
TXLSCompiledReportTemplate: placeholders are compiled once and can be applied repeatedly without rescanning the workbook, using a sorted value lookup and pre-split text fragments across cells, rich text, comments, threaded comments, hyperlinks, text boxes, chart titles and series names, headers and footers, worksheet names, defined names and document properties - Report data binding through
IXLSReportTable,IXLSReportCursor, lazyIXLSReportTableProviderloading, random-access memory tables, andTXLSReportRelationIndex, which builds a compound-key child hash once and retains row numbers rather than copying row payloads for repeated master-detail lookup - Formula calculation now evaluates
PDURATIONfor the number of periods required to reach a target investment value andRRIfor the equivalent periodic growth rate, covering Excel-compatible numeric error boundaries and the required OOXML_xlfn.storage prefix - Formula calculation now evaluates
ISOMITTED,ARRAYTOTEXT, andVALUETOTEXT, including a dedicated omitted-argument value that remains distinct from a blank cell, BIFF missing-argument token round trips, one- and two-dimensional arrays, strict string escaping, localised separators, error conversion rules, and OOXML future-function prefixes - Structured formula preflight through
TXLSXWorkbook.AnalyzeFormulaIssuesreports missing functions, external workbook references and exact circular dependency components with cell coordinates and bounded member lists, while string literals and local structured references are excluded from false matches - Dependency-aware range cloning through
TXLSXWorksheet.CloneRangeTocopies selected cells, merged ranges, conditional formats, data validations, hyperlinks, comments, images and charts in a single operation, relocates applied ranges and anchors, and translates formula payloads with mixed relative and absolute reference semantics; report bands use the same path for dependent objects - PDF export progress and cancellation through
TXLSPDFExport.OnProgress,OnProgressEx, andCancel: begin, page and end notifications add negligible callback overhead, cancellation is checked between row passes and page objects, cancelled streams receive no partial PDF and the exporter remains reusable - Compiled report diagnostics through
TXLSCompiledReportTemplate.Analyze, strict execution, andWriteDiagnosticsidentify missing values, empty placeholders and unclosed placeholders with target type plus worksheet and cell coordinates before mutation, or write the same findings to a diagnostic worksheet - Reusable report execution through
TXLSCompiledReportRunnerprovides begin, target and end progress with completed, cancelled and failed states, supports cancellation before the first write or between compiled targets, reports the exact applied count and remains reusable after cancellation or exceptions without rescanning the workbook - Merged-cell AutoFit strategies for classic XLS and XLSX allow the first or last row or column to absorb the required growth, or distribute it evenly across the merged span, while preserving legacy overload behaviour, hidden states, explicit bounds, and deterministic repeated calls
- Optional PDF comment annotations through
TXLSPDFExport.ExportCommentsAsAnnotationsplace Unicode author and comment text on the originating cell rectangle whilst preserving the existing comments-at-end page; per-sheet comment indexes build in approximately O(C log C) time and support O(log C) cell lookup - Hierarchical user-defined function registries let XLS and XLSX workbooks share process-wide handlers while retaining workbook-local overrides, replacement, removal, clearing and the existing workbook event fallback; average lookup is O(1), local matches mask global names and handlers run outside registry locks for safe parallel recalculation and self-removal
- Lazy report-table combinators through
TXLSReportTableFactoryprovide top rows, column projection, row count, minimum and multiple aggregate definitions, schema-mapped union, contiguous split partitions, and duplicate-preserving inner or left hash joins without materialising complete intermediate row payloads - Incremental PNG and JPEG page export through
TXLSPageImageExportersupports XLS and XLSX ranges, worksheets and workbooks with page selection, DPI, scale, JPEG quality, progress, cancellation and reusable sessions; one pagination model is built per session and bitmap memory is released after every page - Multiple XLSX workbook windows through
TXLSXWorkbook.WorkbookViewspreserve independent active tabs, first visible sheets, visibility, minimised state, geometry, tab display, scrolling, unknown attributes, extensions, and correctly remapped worksheet view bindings while the existing single-window properties continue to address the first view - Named row, column, and cross-tab report bands through
TXLSCompiledReportBandexpand a defined-name template structurally from one-pass bounded data snapshots, preserve formulas and dependent worksheet objects, tile explicit row and column metadata without creating zero-sized defaults and reuse fixed source collection boundaries so repeated same-sheet cloning does not rescan generated payloads - PDF export now writes two-stop and multi-stop axial or radial gradients as native PDF shadings, reuses identical function, shading and transparency resources, clips each fill to its cell and applies solid or uniform gradient alpha without the former banded rectangle approximation
Fixed
- Custom point-based paper width and height overrides now participate in the pagination band calculation alongside the final page object, so page breaks and rendered dimensions use the same available area
Version 2.322.0
Added
- Formula calculation now evaluates the Bessel functions of the first kind
BESSELJ(oscillating) andBESSELI(modified), computed by the power series with term recurrence for numerical stability across the practical argument range
Version 2.321.0
Fixed
- XLSX RTF export now builds a real font table rather than hardcoding Calibri: the pre-scan collects every distinct cell font name, the
\fonttbllists each with its own\fNindex, and each cell’s text references its actual font — workbooks styled in Times New Roman, Courier New or any other font no longer visually re-flow to Calibri when opened in Word or WordPad
Version 2.320.0
Fixed
- PDF export now renders text rotation on the classic XLS engine path: cells with 90-degree or 270-degree orientation draw their text vertically by way of a PDF text matrix pivoting around the cell centre, matching the existing XLSX-path behaviour; previously vertical headers and rotated labels rendered horizontally in PDFs produced from
.xlsworkbooks
Version 2.319.0
Added
- Formula calculation now evaluates Excel 365's LAMBDA-dependent array combinators
MAP(element-wise transform),REDUCE(fold to a single value),SCAN(fold spilling each intermediate step),MAKEARRAY(build from row and column indices),BYROW(row-wise aggregate spilling a column andBYCOL(column-wise aggregate spilling a row), rounding out the LAMBDA functional-programming family alongside the existingLAMBDAandLETsupport
Version 2.318.0
Added
- Formula calculation now covers the bond and treasury finance functions:
COUPDAYBS,COUPDAYS,COUPDAYSNC,COUPNCD,COUPPCD,COUPNUM(coupon day-count primitives),PRICE/YIELD(standard bond pricing with bisection yield solver),PRICEDISC/YIELDDISC(discounted securities),PRICEMAT/YIELDMAT(maturity-based),DURATION/MDURATION(Macaulay and modified),TBILLEQ/TBILLPRICE/TBILLYIELD(treasury bills),DISC/INTRATE/RECEIVED(discount and interest),ACCRINTM(accrued interest at maturity),DOLLARDE/DOLLARFR(fractional-dollar conversion),EFFECT/NOMINAL(effective and nominal rates),CUMIPMT/CUMPRINC(cumulative interest and principal),FVSCHEDULE(variable-rate future value), andAMORDEGRC/AMORLINC(French depreciation); all rest on a self-contained nested coupon-date engine with the five standard day-count bases
Version 2.317.0
Added
- Encrypted-workbook loading now accepts Agile Encryption files that declare the SHA-256 hash algorithm (produced by some third-party writers): the password key derivation, spin loop, password verifier, and the data-integrity key/value IVs and HMAC all honour the declared hash, while files declaring mismatched hashes between the key data and key encryptor are still rejected; saving continues to write Excel’s default SHA-512 variant
Version 2.316.0
Added
SortRangepreserves formulas on both workbook engines: formula cells travel with their rows and their relative references re-anchor with Excel's sort semantics ($-absolute parts stay, references shifted off the grid clamp in place), so sorted tables keep computing rather than collapsing to values- Sheet background images:
SetBackgroundImagetiles a picture behind an XLSX worksheet's cells (display-only, like Excel), round-tripping through the worksheetpictureelement, its media relationship and the package content types
Fixed
- Recalculating an arithmetic formula that references a never-touched empty cell no longer aborts with a conversion error — empty operands contribute 0 as Excel does
Version 2.315.0
Added
CopyToClipboardpublishes the native Biff8 clipboard format alongside text and HTML on both workbook engines, so ranges pasted into Excel or other HotXLS workbooks carry values, formulas, number formats, fonts, fills, borders, alignment and merged cells instead of plain textPasteFromClipboardprefers the Biff8 payload when present: text pasted from Excel keeps its original values without locale-dependent date and number re-parsing, formulas re-anchor their relative references to the paste target and merged areas rebuild at the destination; both engines also paste each other's blocks with full formatting
Changed
- Formulas pasted into Excel arrive as their computed values (a limitation of Excel's third-party Biff8 clipboard parsing); everything else — text, numbers with formats, fills, borders and merges — pastes losslessly into Excel and formulas survive fully in Excel-to-HotXLS and HotXLS-to-HotXLS directions
Version 2.314.0
Added
- Camera objects on XLSX worksheets:
AddCameraplaces a live snapshot picture bound to a cell range — the Excel camera tool's linked picture — with the range binding written to the documented drawing extension and a placeholder image scaled to the anchor; camera objects created by Excel reopen with their range binding preserved
Version 2.313.0
Added
- In-place worksheet patching for XLSX packages:
BeginPatchon the streaming writer opens an existing workbook and rewrites exactly one worksheet — every other part (styles, drawings, charts, pivot tables, custom parts) is copied across with its compressed bytes verbatim, without decompressing or re-authoring anything, so a large template has its data sheet refreshed in a fraction of a full rebuild - Patch mode can also append a new worksheet: the sheet is registered in the workbook part list, relationships and content types with numbering that never clashes with existing parts, following the package's own strict or transitional relationship convention
- Patched packages drop the stale calculation chain automatically (Excel rebuilds it on load) and features that would need new package parts (tables, charts, images, comments, defined names) report a clear error instead of writing an invalid package
Version 2.312.0
Added
- Strict Open XML output: setting
StrictOOXMLon an XLSX workbook saves the package in ISO/IEC 29500 strict conformance — every namespace declaration and relationship type flips from the transitional vocabularies to the strictpurl.oclc.orgones across worksheets, shared strings, styles, theme, drawings, charts, comments, document properties and preserved parts, whilst content types, part names and the VML vocabularies stay as both conformance classes share them - Reading strict-conformance workbooks is now complete: relationship types written in strict form resolve to the same targets as their transitional equivalents, complementing the strict element-namespace acceptance so files saved in Excel's "Strict Open XML Spreadsheet" mode open as any other workbook would
- Saving with strict output enabled reports a clear error for features that exist only as Microsoft extensions (VBA projects, form controls, threaded comments, dynamic-array metadata) rather than writing a package that would not validate
Fixed
- Custom document properties declared a misspelled value-types namespace, which could stop the properties part passing validation in external tools
Version 2.311.0
Added
- Reading an XLS workbook preserves unrecognised worksheet records: any record the typed parser does not model is captured verbatim and replayed on save, so files carrying vendor-specific or newer-spec records round-trip through HotXLS without losing them
Version 2.310.0
Added
- Preset-geometry shapes on XLSX worksheets:
AddPresetShapewrites any of the 187 OOXMLST_ShapeTypepreset tokens (rightArrow,flowChartDecision,star5, …) into the drawing's<a:prstGeom>verbatim, and thePrstTokenproperty lets existing shapes swap geometry — tokens round-trip through save and reopen
Version 2.309.0
Added
- Template processing on worksheets:
ApplyTemplatereplaces{{key}}placeholders throughout all cells — values keep their native types, formula placeholders substitute before parsing — andFillTemplateBandclones a template block once per record with per-clone formula row translation, merged-range cloning and a#skipfield for row-level conditionals, turning any hand-built sheet into a data-driven report generator
Version 2.308.0
Added
- PDF export can attach files:
AddAttachmentcarries raw documents into the exported PDF as/EmbeddedFilesentries (file specification, embedded stream with optional MIME subtype, and the catalogue name tree), so reports ship together with their supporting data in one self-contained file
Changed
- Reading an XLS workbook with an unrecognised BIFF version word no longer rejects the whole stream: the reader falls back to the BIFF8 layout so files from writers that emit unusual version numbers still load when their records parse
Version 2.307.0
Added
- Central scratch-file management: every temporary file the library creates is registered and swept, so an aborted export or an exception between create and delete no longer leaves stray temp files behind
VerifyEncryptedSavere-opens a just-written encrypted container through the full decrypt pipeline and fails the save when the password cannot unlock it — broken containers surface immediately rather than at the user's next open- Dataset export raises an
OnExportLimitevent when row-splitting kicks in and workbook grid limits per format version are exposed as constants (65536×256 for BIFF8, 1048576×16384 for the 2007+ formats) for capability negotiation
Version 2.306.0
Added
- XLSX worksheets gain form-control authoring:
AddFormButton,AddFormCheckBox,AddFormRadioButton,AddFormComboBox, andAddFormListBoxwrite button / check box / radio / drop-down / list controls with captions, linked cells, checked state and macro binding — the save path emits the VML shapes, the per-controlctrlPropsparts, their relationships and the content-type entries and files carrying controls round-trip their parts verbatim on reopen
Version 2.305.0
Added
- PDF export gains an opt-in
UsePDFAmode producing documents identified as PDF/A-2b: the sRGB IEC61966-2.1 profile is embedded as the GTS_PDFA1 output intent, the XMP metadata carries thepdfaidpart/conformance identification and the header announces PDF 1.7 — pair it with an embedded TrueType font (UnicodeFontFileor the auto-selected installed font) for archivable output
Version 2.304.0
Added
- Live cross-workbook evaluation:
RegisterExternalWorkbooklinks a workbook object to a book name so formulas like[Book.xlsx]Sheet!A1compile (the[Book]Sheet!Refprefix now parses into a real external reference) and read the registered object's current state on every recalculation; unregistering cuts the live link and falls back to the external-link cache
Version 2.303.0
Added
- Workbook comparison through
TXLSXWorkbookCompare: pairs sheets by name and reports added/removed sheets, added/removed cells, changed values, changed formulas and added/removed merged ranges — as a structured diff list for tooling and as one human-readable line per difference throughReport
Version 2.302.0
Added
- The streaming direct writer gains a pull-mode row supply:
OnNeedRowfires once per prospective row and the supplier writes that row straight through the writer, declaring end-of-data to stop — data pipelines can steer an export without pre-buffering row lists
Version 2.301.0
Added
- ODS export writes cell formulas: same-sheet references map to the standard
of:=OpenFormula spelling (bracketed refs, semicolon argument separators, string literals untouched), whilst sheet-qualified and structured references ride themsoxl:passthrough Excel itself uses for cross-suite round trips — saved packages reopen holding the original Excel formula text
Version 2.300.0
Added
- Right-to-left worksheets now render mirrored everywhere: PDF export mirrors the column geometry across the printable width (column A on the right, cell content untouched) and both HTML exporters emit
dir="rtl"on the table so the browser reverses the column order — the sheet flag already round-trips through XLSX and BIFF
Version 2.299.0
Added
- Dataset export (
TDataToXLS) gains a title band and a footer band:Titlerenders one merged, boldly styled row above the header (ownTitleFontand optionalTitleColor), andFooterappends a line under the last data or summary row ForEachFormattedCellon a worksheet visits every populated cell in row/column order and delivers its display text — number format applied — through a callback, ready for indexing and text extraction
Version 2.298.0
Added
- The ApiTour example now lands straight in a live showcase: an in-memory sales dashboard with KPI tiles, cross-sheet
SUMIF/COUNTIFformulas, data bars, a colour scale, an icon set and two charts renders inside the embedded workbook viewer the moment the sample starts, every grid cell stays editable with instant recalculation and refreshed conditional formats and one-click actions export the showcase to PDF, HTML and CSV or hand it to Excel with live build and export timings - The C++Builder ApiTour sample mirrors the new Delphi showcase, embedded viewer, formula bar, export actions and activity log
Changed
- The ApiTour examples replace modal result dialogs with an in-window activity log while the classic create, modify, and export walkthrough keeps its behaviour
Version 2.297.0
Added
- PDF export gains an opt-in
UseXRefStreammode producing PDF 1.5 files with compressed object streams and a binary cross-reference stream: small dictionary objects travel inside one Flate-compressed container and the classic xref table and trailer are replaced by a compact stream, shrinking exported documents whilst page content stays byte-identical
Version 2.296.0
Added
- The streaming direct writer gains an opt-in
AutoSplitRowsmode: a row past the worksheet limit (1048576) closes the current sheet and continues on a freshly created<name>_2,<name>_3… sheet, so unbounded exports never produce an illegal row index FillTableCalculatedColumnon a worksheet pushes a table column's calculated-column formula down into every data row, row-translated per cell as Excel's own authoring does, then recalculates naturally
Version 2.295.0
Changed
- XLSX HTML export centralises cell styling: identical style combinations go out once as
td.cNclasses in a style sheet rather than a repeated inlinestyleattribute on every cell, shrinking HTML output for uniformly-styled tables; conditional-format visual overlays stay inline so they retain their per-cell character
Version 2.294.0
Fixed
- Structured references in current-row form (
Table[@Col]) now evaluate against the formula cell's own row during recalculation, in both the serial and the parallel evaluation paths; previously every such formula read row 1 of the column — typically the header text — and recalculation broke outright with a type-cast error when that row held text
Version 2.293.0
Changed
- The opt-in
RecalcAggregateCachememo now also takes in unconditional single-range aggregates —SUM,AVERAGE,MIN,MAX,COUNT, andCOUNTAover one plain single-sheet range — so repeated totals over the same block reuse the first pass's result under the same reference-stability gate the conditional family uses
Version 2.292.0
Added
- Workbook-to-code generator (
TXLSCodeGen): walks a workbook and emits the source statements that rebuild it — sheet creation, cell values, formulas, number formats, column widths and merged ranges — in Delphi or C++Builder dialects, so a hand-crafted file becomes a ready-made API example - Column-rule import validator (
TXLSImportCheck): per-column required, text-length, regex-pattern and uniqueness rules plus a caller callback run over a worksheet's data rows; violations can be annotated back with a red font and a reason comment, andKeepOnlyViolationscompacts the sheet down to the header plus failing rows for a "please fix and return" workbook
Version 2.291.0
Added
- CSV import accepts an options record:
OpenCSVoverloads take leading-line skipping (SkipRows, for title banners above the grid) and whitespace trimming (AutoTrim) alongside the separator and type-detection switches FillMergedCellValueson a worksheet copies each merged range's anchor value into every covered member cell, so report-style sheets with merged labels read like one flat gridAddListValidationgains an array-of-strings overload that folds the items into one dropdown list in a single call- Dataset export (
TDataToXLS) gains zebra striping (AlternatingColor, painted on odd detail rows) and a totals row (SummaryRow) that appends realSUMformulas for the exported numeric fields or a caller-chosen field list, with a bold caption cell
Fixed
- Dataset export now applies the configured
DetailColorbackground to detail cells; previously the property existed but was never painted
Version 2.290.0
Changed
- The opt-in
RecalcLookupCachememo now also coversVLOOKUPexact and approximate scans,HLOOKUP, andMATCHmatch types 0 and 1, so workbooks that repeat these classic lookups over the same range reuse the first pass's outcome during a recalculation pass under the same reference-stability safety gate asXLOOKUP/XMATCH
Version 2.289.0
Added
- The streaming direct writer gains an opt-in
TrackColumnWidthsmode: the worksheet is staged in memory whilst rows stream so the saved file carries the<dimension>used-range hint and per-column widths sized to the longest display text seen (characters plus padding, capped at 255), approximating autofit for exports whose data only becomes known as it streams; explicitly set column widths always win
Version 2.288.0
Added
- Opening XLSX packages tolerates non-canonical namespace prefixes: worksheets, charts, drawings, and document-property parts that bind their elements to a differently prefixed (or ISO 29500 strict) namespace are normalised onto the standard vocabulary while parsing, so files from third-party generators and strict-mode savers load correctly
- Worksheets whose cells omit the
rposition attribute place each cell after its predecessor in scan order and rows without anrattribute continue the row sequence — the convention several streaming writers use
Version 2.287.0
Added
Openreads Excel 2.0/3.0/4.0 workbooks (BIFF2-4): raw BIFF streams without an OLE wrapper load with their numbers, text, booleans, errors and formula cached results; string results of formulas arrive through the BIFF2-4 String record, and the stream's code page record drives text decoding
Changed
- BIFF2-4 documents are read for values — number formats and styles of those generations are not modelled, so dates surface as raw serial numbers and formulas as their last computed values
Version 2.286.0
Added
- Number formats with comparison sections (
[>=100],[<0], …) pick the section by value everywhere display text renders, matching Excel's conditional-format behaviour - Number-format text sections (
"ID:"@) template string values instead of ignoring the format SetCellFromHtmlfills a cell from a light HTML fragment:<b>/<strong>,<i>/<em>,<u>,<br>, and<font color=...>become rich runs; other tags drop while their text is kept- The
TaggedTextmarkup accepts<br>line breaks,<strong>/<em>aliases, the<font color=...>attribute form, and"/ entities - Column keep-together blocks (
KeepColumnsTogether) stop vertical page breaks inside a column group, mirroring the row-level feature in pagination, preview and PDF output - Classic Spinner and ScrollBar form controls can now be authored into XLS files with Min/Max/Inc/Page settings and a linked cell, emitted through the OBJ FtSbs subrecord
WriteAutoValuerecognisesm/d/yyyyandd.m.yyyydates with optional times (AM/PM included) beyond ISO form, rejecting invalid calendar datesConvertFormulasToValuesgains anOnlyExternalmode that freezes only formulas referencing other workbooks and the classic XLS facade gains the whole-sheet method- Row auto-fit measures merged cells against their combined column width and spreads the needed height across the merged rows
Version 2.285.0
Added
- PDF export draws worksheet charts as native vector graphics: clustered, stacked and percent-stacked columns and bars, line charts with markers, area charts, pie and doughnut charts with percentage labels, scatter plots, and radar charts — each with a titled frame, auto-scaled axes, tick labels, gridlines, a legend, optional per-point data labels, per-series solid fills and Excel's default accent palette; 3D chart types render as their 2D projection
- Charts anchored beyond the last cell now extend the printed surface, so a chart placed below the data rows still appears in PDF and preview output rather than being clipped away
Version 2.284.0
Added
- PDF headers and footers render Excel's style codes:
&Bbold,&Iitalic,&U/&Esingle/double underline,&Sstrikethrough,&X/&Ysuper/subscript,&nnfont size,&Kcolour, and&"Font,Style"weight keywords - PDF export honours the worksheet's black-and-white print mode by collapsing fills, fonts, borders, data bars, and icons to luminance grey
- Printed row and column headings (row numbers and column letters) render alongside the grid when the sheet requests them
- Print centring:
CenterHorizontally/CenterVerticallytranslate the printed grid between the margins whilst header and footer bands stay in place - Cell comments print either as a red corner indicator (as-displayed mode) or as a comment listing page following the sheet through the new
PrintCommentsAtEndworksheet property, which carries Excel'scellComments="atEnd"page-setup value - Internal hyperlinks (
Sheet!Celltargets) become clickable in-document GoTo links that go to the target sheet's page - The exporter exposes a viewer
PageLayoutpreference and emits an XMP metadata packet alongside the document information dictionary - TrueType collection (
.ttc) fonts can serve as the embedded Unicode font; the bold and italic cuts of the embedded face are synthesised when only a regular face exists
Changed
- Column widths convert through Excel's maximum-digit-width formula (Calibri 11 metrics) rather than a fixed per-character estimate, so PDF and preview widths match Excel's stored pixel widths
- Wrapped lines re-measure from each line's own first character, mending wrapped lines that ignored the width of words moved down by an earlier break
Version 2.283.0
Added
- PDF export wraps
WrapTextcells with real word breaking, line-by-line horizontal alignment, vertical block alignment and justified or distributed spacing - PDF export renders rotated cell text through PDF text matrices, including vertical stacked text, and honours
ShrinkToFitby stepping the font size down until the value fits - PDF text that overflows a cell now extends across empty neighbouring cells and clips at the first occupied cell, mirroring Excel print behaviour; general alignment right-aligns numbers like Excel
- PDF export draws rich-text runs with per-run font style, size, colour, underline, strikethrough, superscript and subscript; wrapped lines keep the per-run styling
- PDF export draws diagonal cell borders and true double-line borders
- Text spanning merged cells now draws, aligns, wraps and anchors hyperlinks across the whole merged rectangle, and covered merge members no longer paint their own background
Changed
- PDF text widths come from calibrated per-character advance tables instead of a fixed average character width, so alignment, wrapping and shrinking match the printed page
- Cell indentation shifts text like Excel and icon-set cells indent their value next to the icon
Version 2.282.0
Added
- PDF export preserves PNG transparency: images with an alpha channel now emit a soft-mask plane rather than losing transparency, including palette images with a tRNS chunk
Changed
- PDF page content streams are now Flate-compressed, slimming exported documents substantially with no viewer requirements beyond PDF 1.4
- PDF export batches consecutive text operations into shared text blocks and skips redundant font, size and colour selection, reducing both output size and generation time
- Adjacent cells with the same solid fill render as one merged rectangle and collinear border segments with the same style stroke as a single run instead of per-cell edges
- PNG images are embedded in PDF without decoding and re-encoding, retaining the original compressed stream and exact pixels
- Images with identical byte content are embedded once and shared, however many image objects reference them
Fixed
- Hyperlink annotations are now also written for link cells whose text renders through the embedded Unicode font path
- PDF content bytes no longer depend on the active system code page, so Western text renders the same on any Windows locale
Version 2.281.0
Fixed
- Clipboard readers no longer truncate the data handle to 32 bits, which made
XLSGetClipboardBiff8and the XML Spreadsheet paste path return empty on 64-bit applications - Clipboard operations retry opening the clipboard for up to half a second when another application holds it, rather than failing on the first contention
Changed
- Conditional-format rule lookups (
FindAt/IndexOfCellpaths) read each rule’s cell range once instead of on every queried cell, matching the data-validation cache - PDF export builds a per-sheet hyperlink index, superseding the linear per-cell scan with a binary search
Version 2.280.0
Added
- User-defined functions can be registered by name:
RegisterUserFunctionroutes formulas calling that name straight to its handler (no global if-chain in oneOnUserFunction), with the workbook event still handling unregistered names ScanUnknownFunctionsaudits a workbook for formula functions the calculation engine cannot evaluate, reporting every cell and name — ideal before enabling recalculation on foreign filesRecoveryMode: a structurally damaged worksheet part is skipped with a warning diagnostic rather than aborting the whole open- Native BIFF8 clipboard format:
XLSSetClipboardBiff8/XLSGetClipboardBiff8publish and read theBiff8stream Excel itself uses, so clipboard exchange keeps values, formulas and formatting
Changed
- Data-validation auditing reads each rule’s cell range once instead of on every cell, speeding
CheckDataValidationsover large sheets
Version 2.279.0
Added
- PDF export embeds worksheet images: PNG/GIF/BMP bitmaps are converted to Flate-compressed RGB XObjects and JPEG files pass through untouched via DCTDecode (no recompression); identical images on several pages share one object and images added without an explicit size now default to their pixel dimensions at 96 DPI
- Keep-together blocks:
KeepRowsTogetherstops print/PDF pagination from splitting a row block that fits one page, andXlsxAutoPageBreaksturns the natural (keep-aware) page boundaries into explicit row breaks so Excel paginates as the export does - Configurable XLSX compression:
ZipCompressionLevelselects the deflate level for saves (-1 default through 9) - Reproducible saves:
DeterministicOutputpins zip entry timestamps so saving the same workbook twice yields byte-identical files
Fixed
- Corrupt compound files with cyclic FAT chains no longer stall the classic .xls loader — directory and stream chain walks carry cycle guards
Version 2.278.0
Added
- PDF export emits clickable link annotations for worksheet hyperlinks: cells carrying a URL are given an invisible /Link rectangle with a URI action over the cell area
- PDF export writes a document outline (bookmarks): each exported worksheet becomes a bookmark targeting its first rendered page
Version 2.277.0
Added
- Data validation gets an audit API:
CheckDataValidationssweeps populated cells against the sheet’s rules (list membership, whole/decimal/date/time bounds, text length, custom formulas through the calculator) and reports every violating cell with the rule index and a reason - Typed custom document properties round-trip through
docProps/custom.xml: text, number, date, and boolean entries onWorkbook.CustomProperties - Custom XML data parts round-trip through
Workbook.CustomXmlPartswith workbook-level relationships and content types - Images accept an SVG companion:
AddImagePairstores the SVG bytes next to the raster fallback, writes thesvgBlipextension and the extra media part Excel 2016+ consumes - Charts can take data-label text from a cell range (“Value From Cells”) through
DataLabelsRange, emitted as the chart extension and recovered on open - Custom table styles:
Workbook.CustomTableStylesdefines named styles with coloured/bold sections (header row, total row, stripes, edge columns), written totableStyleswith their own differential styles so tables can reference them by name
Version 2.276.0
Added
- Cell gradient fills: linear sweeps by degree and path gradients with per-stop colours round-trip through
gradientFill, render as CSS gradients in HTML export, band-interpolated fills in PDF export and the workbook viewer and are offered through theTXLSXFills.AddLinearGradientconvenience - Elapsed-time number formats (
[h]:mm:ss,[mm]:ss,[s]) now render running totals rather than wrapping like a clock, in every display path (FormattedText, HTML, PDF, conditional-format values) - Fraction number formats (
# ?/?,# ??/??, fixed denominators like0/8) render with Excel’s best rational approximation, covering zero-integer hiding and alignment spacing [Red]-style colour brackets now surface throughTXLSXCell.GetFormattedTextColorand repaint the cell text in PDF exportTXLSXWorkbook.ValidateNumberFormatchecks a custom format string the way Excel’s Custom Format dialog does — section count, quote balance, and bracket content (colours, conditions, elapsed units, locale directives)- Frozen pane state can be read back through
GetFrozenPanes, and the bottom-right pane scroll position round-trips throughSetPaneScroll/GetPaneScroll(written astopLeftCell) - The row/column heading display toggle
DisplayRowColHeadersround-trips throughshowRowColHeaders - Charts expose
DispBlanksAs(gap / span / zero) andPlotVisibleOnlyinstead of hardcoding them, and recover both from preserved ChartML on open - Comments carry editable box geometry (
WidthPt/HeightPt, VML points) plus a text-drivenAutoSizeFromTextheuristic
Version 2.275.0
Added
- Find & replace understands Excel wildcards:
*(any run of characters),?(exactly one character), and~as the escape for a literal*,?, or~— the same semantics Excel itself applies in Find & Replace,COUNTIF-family criteria, and autofilters - The XLSX worksheet
FindTextgains an options overload: match case, match entire cell contents, search formula text as well as values, wildcard mode and backward scanning, with a start anchor so repeated calls walk through matches ReplaceTextgains the same option set plus an optional per-match callback that can accept, rewrite, skip or abort each replacement cell by cell- The classic XLS worksheet
FindText/ReplaceTextgain wildcard and entire-cell overloads, so both facades follow Excel search semantics GetRangeStatisticsscans a rectangle and reports minimum, maximum, sum, average, numeric value count and populated cell count in one passWriteAutoValuewrites text the way Excel's own cell entry interprets it:TRUE/FALSEbecome booleans, error literals such as#N/Abecome error values, unambiguous ISO dates become dates, plain invariant-format numbers become numbers, with everything else — including leading zeros and thousands separators — stays text (both facades)GetHtmlFromCellrenders one cell as a styled HTML fragment with escaped markup, alongside the whole-sheet HTML exportSortRangeaccepts a case-insensitive flag so text keys sort alphabetically regardless of case (XLSX facade)
Version 2.274.0
Added
- Excel tables now round-trip header-less tables and also per-table comments through the new
HasHeaderRowandCommenttable properties, written asheaderRowCount="0"and thecommentattribute - Charts can select an Excel gallery style through the new
ChartStyleproperty (1–48 or the extended 101–148 range), round-tripped by the chart part’s style element - Combination charts can govern plot-area layering through a new
ZOrderproperty on each plot group, so a column series can draw behind or in front of a line series - Worksheets and single cells can set formulas into their calculated values through
ConvertFormulasToValuesandConvertFormulaToValue, keeping the cached result whilst dropping the formula, shared-formula link and array metadata - Defined names now take an optional comment through the new
Commentname property, round-tripped by the classic name-comment record and the XLSX defined-namecommentattribute - PDF export accepts custom paper dimensions in points through the new
PaperWidthandPaperHeightproperties, overriding the paper-size enum for every rendered worksheet - PDF export can suppress the header or footer band through the new
HidePrintObjectsset - PDF header and footer field codes
&F(file name) and&Z(path) now expand using the source workbook path captured by file-based exports - Data bars support an independent negative-value border colour through the new
NegativeBorderColorandNegativeBarBorderColorSameAsPositivesettings, emitted in the Excel 2010+ data-bar extension - Built-in cell styles whose identifiers have no legacy record slot (Hyperlink, Title, Headings, Accents, Good/Bad/Neutral, …) now resolve their canonical display names when saving, so the Excel Styles gallery survives a round-trip
- Agile-encrypted workbooks now carry a real
dataIntegrityblock: the writer emits a spec-conformant HMAC over the complete encrypted package and opening verifies it, detecting a wrong password or a tampered package; files from writers without the block still open unchanged - Classic workbooks honour Excel's “password to modify” write reservation through
SetModifyPassword(recommend read-only flag, legacy password hash and reserving user name emitted as the WRITEPROT + FILESHARING record pair);IsWriteReservedreports the state and an empty password clears it - An opt-in
RecalcLookupCachememo speeds up lookup-heavy recalculation: repeatedXLOOKUP/XMATCHscans over the same range reuse the first pass's result. The memo engages only when the dependency graph is provably reference-stable (noOFFSET/INDIRECTor unresolvable references, no circular chains, no What-If data tables) and stays silently off otherwise, so results always match - A companion
RecalcAggregateCachememo speeds up conditional-aggregate recalculation: repeatedSUMIF/COUNTIF/AVERAGEIFscans over the same range and criteria reuse the first result under the same reference-stability gate and with identical results LAMBDAexpressions evaluate with full closures: a defined name whose RefersTo is aLAMBDAcan be called by name with arguments (=MyFunc(5)), closures bind lexically insideLET(=LET(f, LAMBDA(x, x*2), f(21))), parameters shadow same-spelling column references and the formula text round-trips verbatim; a bareLAMBDAstored as a cell result retains the skip-without-value behaviourLETnow has complete semantics: each binding is visible to the later bindings and to the body expression, including nestedLETcomposition — replacing the former partial implementation- Formula text now accepts the comma as an argument separator alongside the classic semicolon, mirroring Excel's canonical syntax for pasted and imported formulas
- Structured references in formulas now evaluate:
Table[Column],Table[[Column]], column spans and the[#Data]/[#All]/[#Headers]/[#Totals]item forms resolve to the workbook's Excel tables at parse time, so=SUM(Table1[Amount])calculates whilst the original formula text still round-trips verbatim; unresolvable references keep the previous skip-without-value behaviour and current-row forms ([@Column]) remain unsupported
Changed
- When a workbook disables full precision, recalculated results are now stored rounded to the count of decimal places shown by each cell’s number format, matching Excel’s “precision as displayed” behaviour for HotXLS-computed values
- Conditional-formatting rules written to XLSX now receive sheet-unique priorities, removing duplicate-priority files that made Excel prompt for repair
- Conditional formats flagged as PivotTable-scoped through the new
IsPivotproperty are routed to the extension bucket rather than the worksheet’s main conditional-formatting block, where Excel would drop or misplace them
Version 2.273.0
Changed
TXLSXWorkbook.PreserveRawPartsnow copies unchanged worksheet images, header and footer images, and chart parts with their original compressed payloads, while image data edits and chart model edits take the serialisation path- A successful file SaveAs now accepts the committed package as the next raw-copy baseline, allowing subsequent saves to reuse newly serialised opaque data, VBA, connections, external links, images, charts, themes, and pivot payloads without re-opening the previous source package
Fixed
- Unknown worksheet and drawing relationships from packages with nonstandard part locations are now re-anchored against their generated canonical owners, including drawing-only packages whose only anchors are preserved unsupported shapes
- A failed compressed-member copy now rolls back its partial local header, payload bytes, parent folder entries, and central-directory count before safe serialisation fallback, preventing unreachable data from accumulating in the output archive
Version 2.272.0
Changed
- XLSX SaveAs now opens one validated source archive for the complete save operation and copies every unchanged relationship-reachable opaque part with its original compressed payload, avoiding repeated central-directory scans plus decompression and recompression while modified payloads still take the serialisation path
Fixed
- Unknown workbook relationships from packages whose workbook uses a nonstandard part name are now rebased against the generated workbook location, so their preserved target parts cannot become unreachable after SaveAs
- Projected direct reads now retain shared-formula master definitions outside the selected row or column set, so selected follower cells still get their correctly translated formulas without rebuilding unselected values or rich text
- Editing a chart no longer removes an unmodelled axis number format simply because data-label number-format authoring uses an element with the same local name
Version 2.271.0
Fixed
- The classic HTML exporter now writes UTF-8 and declares it with a
<meta charset>plus an HTML5 doctype; previously the stream was written in the system ANSI code page, corrupting any non-ASCII cell value, and the absent charset declaration left the page at the browser’s mercy
Version 2.270.0
Added
- Chart data labels can now take an explicit number format and a placement through the new
LabelNumFmtandLabelPosseries properties (with their*Setflags), emitted as<c:numFmt>and<c:dLblPos>in both the standard and combination-chart writers — enabling percentage or currency label text and label positions such as outside-end or centre; either setting alone also turns on the label block and unset series stay byte-identical
Version 2.269.0
Added
- Line and scatter chart series can now take an explicit marker symbol and size through the new
MarkerSymbol,MarkerSize, andMarkerSetproperties, emitted as the series’<c:marker>block in both the standard and combination-chart writers; unset series retain automatic markers - Value axes with display units can now display the unit label (“Thousands”, “Millions”, …) via the new
ShowDispUnitsLabelaxis property
Version 2.268.0
Added
- XLSX chart trendlines now take a fixed intercept plus forward and backward forecast periods through the new
Intercept/InterceptSet,Forward, andBackwardproperties, emitted as<c:intercept>/<c:forward>/<c:backward>; previously only the classic BIFF chart builder offered these controls and unset trendlines stay byte-identical
Version 2.267.0
Added
- Formula calculation now evaluates the complex-number functions
IMCOS,IMSIN,IMTAN,IMSEC,IMCSC,IMCOT,IMLOG2, andIMLOG10, completing theIM*engineering family with trigonometric, reciprocal and base-2/base-10 logarithm coverage over complex string operands
Version 2.266.0
Changed
- The streaming direct reader now applies column projection before accumulating cell values: when a projected column set is configured, cells outside it skip the value, formula and rich-text string building that previously ran for every cell and was discarded at cell end, speeding up wide-sheet reads that project only a few columns
Version 2.265.0
Added
- Bar and column chart plot groups now expose a configurable grouping mode (
clustered,stacked,percentStacked), a cluster gap width and a series overlap through the newBarGrouping,GapWidth, andOverlapproperties; previously every bar/column chart was hard-coded toclusteredwith no gap or overlap control and unset groups stay byte-identical while the edit-after-open merge list treats the new elements as owned
Version 2.264.0
Fixed
- PDF cell borders now reflect the worksheet’s border style and weight rather than every border drawing as an identical 0.75 pt solid line: XLSX cells render thin, medium, thick, hair, and double weights and dashed, dotted, dash-dot, dash-dot-dot, and slant-dash-dot patterns, and BIFF cells render thin, medium, and dashed/dotted styles
Version 2.263.0
Added
- PDF export can now embed document metadata through the new
DocumentTitle,DocumentAuthor,DocumentSubject, andDocumentKeywordsproperties; when any is set, the PDF carries a/Infodictionary with those fields plus aCreator/Produceridentity and aCreationDate, while default exports with no metadata stay byte-identical
Version 2.262.0
Fixed
- CSV export no longer over-quotes fields: an inner space no longer forces quoting, so values like
John Smithare written unquoted, matching RFC 4180 and Excel; fields with the delimiter, a double quote, a line break or leading or trailing whitespace are still quoted as before
Version 2.261.0
Added
- Each chart series can now carry a solid fill colour through the new
SolidFillHexproperty, emitted as the series’<c:spPr>shape properties; assigning a hex colour stamps the series with a brand or palette colour instead of Excel’s automatic theme colour, while unset series stay byte-identical and the edit-after-open merge list treatsspPras owned so it replaces rather than duplicates
Version 2.260.0
Changed
- The sparse cell-storage back end now grows each 256-row block buffer geometrically (doubling) rather than reallocating on every appended cell, removing the quadratic copy cost when loading dense worksheets
Version 2.259.0
Fixed
- BIFF8 worksheet object-protection (
OBJECTPROTECT) and scenario-protection (SCENARIOPROTECT) records are now read back into the sheet protection state, so the lock flags survive a round-trip rather than being written but lost on reload - BIFF8 workbook-globals
MMS,RefreshAll, andUseSelFSrecords are now preserved through round-trip instead of being silently dropped
Version 2.258.0
Added
- Formatted display text now recognises
[Cyan]and[Magenta]colour directives and the indexed palette directives[Color1]through[Color8], so HTML-style formatted output applies those colours instead of dropping them
Version 2.257.0
Added
- Formula calculation now evaluates the engineering and mathematical functions
FACTDOUBLE,SQRTPI,DELTA,GESTEP,SERIESSUM, andCONVERT, withCONVERTcovering mass, distance, time, pressure, force, energy, power, magnetism, temperature and volume units and rejecting mismatched unit categories
Version 2.256.0
Fixed
- Formatted display text now renders minutes correctly in time masks such as
hh:mm,mm:ss, and[h]:mm:ss; previously Delphi’smm(month) was used, so minute fields showed the month number - Locale and currency directives such as
[$-409]and[$$-1009]are now stripped from formatted output instead of leaking as a literal$-409prefix, while a currency symbol present in the directive is preserved
Version 2.255.0
Added
- ZIP package reading now understands ZIP64 archives, parsing the extended-information extra field and the ZIP64 end-of-central-directory record and locator so workbooks whose parts or offsets exceed the 4 GB / 65535-entry classic limits open correctly rather than failing the end-of-central-directory sanity check
Version 2.254.0
Security
- Encrypted-workbook password verification now compares the verifier hash in constant time for both Agile and Standard Encryption, sealing a timing side-channel that could reveal how many leading bytes of the password hash match
- Agile encryption no longer falls back to a time-seeded pseudorandom generator for salts, verifiers and intermediate keys when the system CSPRNG is unavailable; it now fails closed rather than emitting predictable key material
Version 2.253.0
Added
- Formula calculation now evaluates the Excel 365 array-shaping functions
VSTACK,HSTACK,TOROW,TOCOL,WRAPROWS,WRAPCOLS,TAKE,DROP,CHOOSECOLS,CHOOSEROWS,EXPAND,RANDARRAY, andTEXTSPLIT, spilling their results through the existing dynamic-array machinery - Formula calculation now evaluates the modern text functions
TEXTBEFOREandTEXTAFTERwith instance-number, case-insensitivity, match-end, and not-found handling - Formula calculation now evaluates
RANDBETWEEN,ISEVEN,ISODD, and theFORECAST.LINEARalias ofFORECAST
Version 2.252.0
Added
- Defined names take an optional comment, round-tripped as the BIFF8 NAMECMT record and the OOXML
definedNamecommentattribute - Local-file hyperlink targets are normalised (backslash-to-slash conversion,
file://andfile:///prefixes, percent-encoding of reserved characters) so Excel keeps them verbatim - Shape, picture and text-box fill kinds (solid, picture, gradient, none, automatic) are now typed over the raw fill-type property and round-trip faithfully
- Conditional-format data bars support Excel 2010+ independent negative-value bar border colours
- Pivot cache fields round-trip multi-level date and numeric grouping linkage
- User-function callbacks receive an argument-kind descriptor so handlers can distinguish literal values, cell or range references and array constants
- Formula compilation accepts localised function names (German, French, Spanish), rewritten to canonical English before lexing
- Password and encryption helpers expose named return-code constants
Changed
- Package and XLSX saves now flow through larger deflate buffers with a higher compression memory level and omit a redundant checksum pass over already-compressed bytes, reducing save CPU and wall-clock time
- Internal string-builder, list and hash-table growth now uses geometric (doubling) allocation together with an earlier hash resize point, lowering allocation churn and lookup cost when a workbook carries many styles, names, defined ranges or shared strings
- Shared-string table lookups now compare the stored bytes directly before materialising a full string, cutting lookup allocations on large shared-string tables
Version 2.251.0
Fixed
- XLSX open and save now keep foreign workbook-root namespace declarations, markup-compatibility attributes, complete workbook-level
<extLst>payloads and their unknown relationships whilst regenerating typed workbook state; preservedr:idreferences follow relationship-ID reassignment rather than becoming stale when they conflict with generated worksheet or workbook relationships
Version 2.250.0
Changed
- XLSX sparse row entries now store only their column and stable cell handle, eliminating unused payload tags plus redundant classification and a second row-index lookup whenever a cell value, formula or rich-text object changes
Version 2.249.0
Added
TXLSRTFImport.LoadFromRTFandTXLSWorksheet.OpenRTFoverloads can import tables or paragraph lists at an explicit one-based target row and column whilst the original overloads continue to start at A1
Changed
- XLSX typed row writers now append strictly forward batches directly to pre-sized sparse row vectors and sparse cell lookup resolves first-column and last-column hits without binary search while overlap writes retain their existing replacement path and stable cell handles
Fixed
- File-backed XLSX raw-part copying and selective sheet loading now rely on a private source-archive identity with size and timestamp validation, so a later stream open or a public
FileNameassignment cannot divert preserved parts to another workbook RefreshPivotCachenow switches refreshed caches to typed serialisation so rebuilt records cannot be overwritten by stale raw package bytes during save- Raw compressed ZIP copying now requires the source stream to contain exactly the declared compressed byte count, refusing both truncated and overlong entries before central-directory registration
- Reusing one RTF importer now resets code-page and character-format parser state between documents so bold, italic, underline, strikeout and font size cannot leak into the next import
MetadataOnlyXLSX opens now avoid shared-string, person, worksheet-relationship, comment, drawing, chart, table, query-table, pivot and worksheet-reachable opaque payloads while retaining workbook properties, names, sheet states, styles, theme, connections, and external links
Version 2.248.0
Changed
- XLSX SaveAs now raw-copies unchanged
connections.xmlparts from the source package when the parsed connection model is unchanged, preserving source XML fidelity and avoiding unnecessary decompression and recompression whilst still rewriting edited connections from the typed model
Version 2.247.0
Changed
- XLSX SaveAs now raw-copies unchanged external-link XML and relationship parts from the source package when the parsed model is unchanged, preserving unknown extension XML and avoiding unnecessary decompression and recompression whilst still rewriting edited links from the typed model
Version 2.246.0
Added
TXLSHTMLImport.LoadFromHTMLoverloads can import at a one-based target row and column, select one zero-based top-level table or all tables and parse numbers with an explicit decimal separator without changing global format settings
Changed
- XLSX style loading now resolves each cell style through a shared immutable cellXf array rather than repeated string-key construction and linear map searches, reducing styled-workbook open time and temporary allocations
Fixed
- Modified VBA project bytes now bypass preserved raw-part copying so saving an edited macro-enabled workbook cannot reinstate the original
vbaProject.binpayload - Raw ZIP-member copying now rejects compression methods other than STORE and DEFLATE rather than emitting a mismatched compression header, allowing callers to use safe decompression and rewrite fallback paths
- HTML import now ignores row and cell tags outside top-level tables and preserves the established all-table behaviour of the original overloads
Version 2.245.0
Added
- Editable
TXLSWorkbookViewercells with protected-cell-aware input, formula entry and recalculation, rectangular range selection, formula-reference picking and bounded circular undo and redo history TXLSPivotDesignerprovides a reusable non-visual field-list model with row, column, filter and value zones, deterministic field movement, aggregation selection, layout validation, and result application- Classic XLS workbooks now provide
CalculateAndVerifydiagnostics with shared mismatch records containing worksheet identity, one-based cell coordinates, cached and freshly calculated values and formula text - Classic XLS and XLSX worksheets now provide typed numeric, string and variant row and column writers with one-based coordinates, grid-boundary clipping, direct cell-model writes and a returned write count
Changed
- XLSX viewer painting now preserves sparse worksheets by avoiding blank-cell materialisation during repaint and style resolution
TXLSXWorksheet.ReplaceTextnow visits stored cells directly in linear time without copying and sorting the entire cell collection
Fixed
- Classic XLS RC4 and RC4 CryptoAPI read and write now protect every plaintext record body required by
[MS-XLS], keepBoundSheet8.lbPlyPosunencrypted, consume matching keystream positions and activate decryption before reading the first encrypted record afterFILEPASS - SpreadsheetML serialisation now applies the symmetric
_xHHHH_codec only to Xstring fields, whilst formulas and reference syntax use ordinary XML escaping so token-shaped literals retain their exact formula meaning
Version 2.244.0
Added
- Multi-format clipboard import:
XLSPasteFromClipboardRichprefers the XML Spreadsheet clipboard format (carrying formulas, styles and merges) over plain Unicode text, withXLSClipboardHasXmlSpreadsheet,XLSGetClipboardXmlSpreadsheet, andXLSParseXmlSpreadsheetfor format detection, extraction and SpreadsheetML 2003 parsing
Version 2.243.0
Added
- External defined names:
TXLSXExternalLinknow parses, stores, and round-trips<definedNames>entries (name + refersTo) from external workbook links, withAddDefinedName,FindDefinedName, and indexedDefinedNames[]access - Per-sheet refresh failure state: each
TXLSXExternalSheetDatacarries aRefreshErrorflag that records whether the most recent refresh attempt failed, parsed from and emitted to therefreshErrorattribute
Version 2.242.0
Added
TXLSXWorkbook.PreserveRawPartscopies the compressed representation of unchanged parts (theme, VBA project, pivot tables and pivot caches) directly from the source archive during SaveAs, avoiding decompression and recompression of preserved opaque entries
Version 2.241.0
Added
TXLSXWorkbook.SelectedSheetsproperty enables selective worksheet loading: Open parses cell XML only for sheets named in the list, whilst other sheets keep their names and visibility states with zero cells. CallLoadSheet(Index)to materialise a skipped sheet on demand from the original archive
Version 2.240.0
Added
TXLSXWorkbook.MetadataOnlyopen mode parses workbook properties, defined names, sheet names and visibility states, styles, theme, connections and external links, but skips all worksheet cell XML and satellite parts for fast property and name discovery from large workbooks
Version 2.239.0
Added
- Compact 256-row block cell storage with stable public handles, row-major cache-friendly serialisation, and style compaction across all workbook pools before every save
- Interval style overlays let row, column, and rectangle formatting stay compact without materialising empty cell objects, resolve lazily on cell access, survive structural edits, and round-trip as compact column, row, and style-only cell entries
Changed
- Normal workbook save now streams each worksheet row directly into the package deflate stream, so peak memory tracks the largest single row rather than the complete worksheet XML
- Shared strings and auxiliary XML parts now stream one entry at a time through a single reusable UTF-8 serialiser, bounding peak memory by the largest entry instead of the whole part
Version 2.238.0
Added
TXLSPaginationModelbuilds reusable logical pages for XLS and XLSX ranges, worksheets and workbooks with paper geometry, margins, headers, footers, row and column bands, repeated titles, page order, gridline policy and drawing placementsTXLSWorkbookViewernow offers shared-model print preview, keyboard and scroll-wheel page navigation, cachedPaginationModelaccess, explicitRefreshPagination, and selected-page EMF outputTXLSPDFExport.CreatePaginationModelreveals the exact owned page model used by PDF counting and rendering for all six XLS and XLSX input types
Changed
- PDF export and page counting now consume one pagination engine rather than maintaining separate XLS and XLSX page loops
- Fit-to-width and fit-to-height scaling now works against actual page bands, including manual breaks and repeated titles, within Excel's 10% through 400% scale range
Version 2.237.0
Added
TXLSFormulaDebuggercreates an owned interactive session containing the parsed expression tree, source spans, operators, operand nodes and values, intermediate results, deterministic evaluation order and navigable current-step state- Formula-debug sessions surface cell and range dependencies with resolved sheet coordinates, report selected and skipped branches for
IF,IFERROR,IFNA,CHOOSE,IFS, andSWITCHand preserve recovered inner errors with their originating node
Changed
- Workbook and worksheet
Calculatenow return Excel formula failures as standardVarianterror values instead of converting them toNull TXLSFormulaTracernow records exact before-and-after operand stacks for push and reduction steps
Version 2.236.0
Added
TXLSXWorksheet.StructuralEditRegistrynow has application-owned worksheet metadata participate in row and column insertions or deletions throughIXLSXStructuralEditParticipant
Changed
- XLSX structural edits now complete their reference-sensitive work in one guarded transaction covering formulas, names, validations, conditional formats, comments, hyperlinks, drawings, tables, queries, scenarios, data tables, print settings, sparklines, pivot caches and views and worksheet extensions
Fixed
- Inserted or deleted rows and columns now update protected ranges, threaded-comment anchors, reopened classic-comment VML, local and cross-sheet sparkline references, typed pivot sources and anchors, calculated pivot formulas, and recognisable references inside preserved worksheet extension XML
Version 2.235.0
Added
TXLSDirectWriternow adds classic comments, anchored worksheet images, formula-backed column, bar, line, area, pie, doughnut and scatter charts and complete caller-supplied ChartML without constructing a full workbook object model- Images can be supplied as bytes, seekable streams with optional ownership transfer, or file paths and can use PNG, JPEG, GIF, BMP, EMF or WMF content
Changed
- Rich direct-writer parts use current-sheet side-channel descriptors, assign worksheet relationship identifiers before the sheet closes and stream media and related XML parts after worksheet XML to keep row memory independent of sheet size
Version 2.234.0
Added
TXLSDirectReadernow exposes opt-in dimension, sheet-format, column, row, pane and merged-range events with typed layout records- Column and row events report widths or heights, hidden and collapsed state, outline levels and source style indexes without constructing worksheet cell objects
Changed
- Assigned layout callbacks use a bounded-memory metadata pass before cell delivery, ensuring merged ranges and other layout facts arrive before cells that depend on them whilst ordinary cell-only scans retain the original single-pass path
- Parallel direct reads keep layout callbacks on the calling thread and complete selected-sheet metadata before draining ordered worker cell queues
Version 2.233.0
Added
TXLSXChartTextStylenow provides typed chart-title, legend, axis-title, and axis-label font names, point sizes, RGB colours, emphasis and text rotationTXLSXChartLayoutnow provides normalised manual plot-area, chart-title, axis-title, and legend positioning with explicit edge or factor modes and inner or outer plot targets- Charts now expose typed legend visibility, position, overlay, text style and layout controls together with chart-title overlay settings
Changed
- Manual layouts always serialise complete x, y, width, and height groups using Office-compatible default modes so Excel does not discard partial or conflicting coordinates
Fixed
- Editing typed chart fonts or layouts preserves unrelated extension lists and custom namespace content whilst clearing a known colour or emphasis property no longer restores the imported value during structural merge
Version 2.232.0
Added
TXLSXImagenow exposes percentage-based crop edges, transparency, brightness, contrast, rotation in degrees and stretch or tile fill modesTXLSXImage.HasPreservedXmlreports whether imported DrawingML is available, whileClearPreservedXmlopts one picture into clean typed-model regeneration
Changed
- Image effect values use compact fixed-point storage and write native DrawingML units without creating per-effect helper objects
Fixed
- Editing a supported property on an imported image now preserves unrelated extensions, markup-compatibility choices, custom attributes, shape effects and namespace-qualified content
Version 2.231.0
Added
- Imported XLSX charts now preserve their original ChartML while
TXLSXWorkbook.PreserveUnsupportedPartsis enabled, retaining unknown namespaces, markup-compatibility alternatives, extension lists, custom styles and unmodelled formatting TXLSXChart.HasPreservedXmlreports whether original ChartML is available, andClearPreservedXmllets applications opt one chart into clean typed-model regeneration
Changed
- Saving an untouched imported chart replays its original ChartML, whilst edits to supported properties structurally overlay only the modelled chart nodes and keep unrelated content in place
Fixed
- Editing a chart title, series, axis or other supported property no longer discards unrelated Excel-authored extensions, alternate content, styles or formatting from the chart part
Version 2.230.0
Added
TXLSXChart.AddPlotGroupnow builds ordered combination charts whose chart families and series keep independent primary or secondary axis assignments- Charts now expose primary and secondary category and value axes plus a series axis, with typed category, value, date and series-axis settings including positions, identifiers, crossings, date units, label intervals and visibility
- Column, bar, line, pie and area charts now have dedicated 3D chart types with configurable rotation, height, depth, perspective, right-angle axes and gap depth
- Series now expose typed string and numeric caches for names, categories, values and bubble sizes, including sparse point indexes and numeric format codes
Changed
- The compatibility
ChartType,AddSeries, and flatSeriesAPIs continue to address the primary plot group whilst the chart model retains every ordered plot group
Fixed
- Opening and resaving combination charts no longer collapses them into one chart family or loses secondary, date or series axes
- Chart formula references and cached series values now survive workbook copies and open/save cycles instead of being flattened or discarded
- Chart anchors are now paired with their chart parts by relationship identifier, so applications that reorder relationship entries no longer swap chart contents between worksheet positions
Version 2.229.0
Added
TXLSXWorksheet.HeaderFooterImagesnow creates, finds, replaces, and removes typed image slots for each left, centre, and right header or footer position across odd, even, and first pages- Header and footer images expose their raw bytes, format, caption, point dimensions, and point margins, with direct loading from PNG, JPEG, GIF, BMP, EMF, and WMF files
Changed
- Even-page and first-page images automatically switch on the matching page variants and uphold the required picture field codes whenever header or footer text is edited
Fixed
- Worksheet comments alongside header or footer images now keep independent VML relationships whenever they share a single worksheet
- Excel-authored header and footer image slots now retain their image bytes, formats, captions, dimensions, margins, and relationships across open and save cycles
Version 2.228.0
Added
- Classic XLS worksheets and shape collections now create and discover typed
TXLSButtonandTXLSRadioButtoncontrols alongside tick boxes, combo boxes, and list boxes - Form controls now expose macro names, linked cells, input ranges, tick states, flat or 3D appearance, and radio-group links through typed properties
- Defined names expose
IsMacroso that macro bindings retain the required workbook-name metadata
Fixed
- Editing and resaving classic form controls no longer discards tick states, macro bindings, linked-cell formulae, source ranges, or supported radio-group metadata
- Clearing a combo-box or list-box source range now removes the serialised input formula instead of restoring the previous range on the next open
Version 2.227.0
Added
LINESTandLOGESTnow return full multivariable coefficient arrays and optional five-row statistics matricesTRENDandGROWTHnow return shaped prediction arrays for both single-variable and multivariable inputs
Changed
- Array arithmetic, comparisons, concatenation, unary negation, and per-cent operations now broadcast scalars and singleton rows or columns whilst retaining per-cell results
- Calculation dependencies now unfold nested workbook and worksheet names, formula-defined names, and multi-area references with scope-aware cycle protection
Fixed
- A single array-element error no longer collapses the complete result or incorrectly falls back to scalar evaluation
- Formula-defined names whose dependencies can be resolved statically no longer force an unnecessary volatile full recalculation
Version 2.226.0
Added
- Existing XLSX pivot caches and pivot-table views now load into the typed model through package relationships, encompassing cache records, fields, shared items, grouping, filters, formats, calculated definitions, and extensions
TXLSPivotTable.Makenow appraises calculated cache fields, calculated items, and data calculated members with dependency-aware name binding- The extended
ShowDataAsmodes add parent percentages, running totals in percent, and ascending or descending rank with valid XLSX extension markup
Changed
- Pivot result generation now applies item visibility, page selections, and caption, date, aggregate, and value filters before building grouped domains
- Numeric, date, and discrete groups, label or data-value sorting, configured subtotals, and optional materialised grand-total rows or columns now take part in result generation
Fixed
- Pivot filters now use schema-valid root-level filter markup and symbolic filter types rather than ambiguous numeric values
- Relationship-driven loading no longer presumes conventional or sequential pivot cache, cache-record, or pivot-table part names
Version 2.225.0
Added
TXLSXWorkbook.ConnectionsandTXLSXWorksheet.QueryTablesnow offer typed authoring and editing for external database, web, text, and query-result metadata- Connection parameters now keep their precise Boolean, integer, floating-point, string, or cell-reference kind, covering explicit zero, false, and empty-string values
Changed
- Opening and saving XLSX now resolves and writes the connection and query-table parts through their owning relationships, lines up result tables with defined names, and retains unknown attributes, child nodes, and extension lists
- Row and column edits keep query-result ranges aligned, whilst copies of worksheets within the same workbook and across workbooks keep query ownership and remap connection identifiers alongside clashing names
Fixed
- Query tables can sit alongside standard tables, threaded comments, and pivot tables without worksheet or workbook relationship identifier collisions
Version 2.224.0
Added
- Both classic XLS and modern XLSX worksheets now surface
AddDataTableandDataTablesfor one-variable row, one-variable column and two-variable What-If data tables
Changed
- Workbook recalculation now evaluates every data-table result within an isolated input context, covering indirect formula dependencies as well, and carries definitions alongside cached results through open, save, worksheet copy and structural row or column edits
Fixed
- Deleted What-If input cells now yield
#REF!results, and classic workbook recalculation walks every worksheet rather than skipping the first sheet - Inserting rows at the head of a classic worksheet no longer risks an access violation under Win64
Version 2.223.0
Changed
- Parallel direct-reader cancellation now flows through active ZIP member reads and every decompression step rather than waiting for the next XML pull
Fixed
- Aborting a parallel worksheet scan no longer blocks on a large compressed XML read finishing before blocked workers are released
Version 2.222.0
Added
TXLSDirectReader.ParallelBufferMemoryLimitcaps the aggregate raw-cell queue payload for parallel worksheet scanning, whilstParallelPeakBufferedBytessurfaces the measured peak for diagnostics and capacity tests
Changed
- Parallel direct reads now stream worksheet ZIP entries into worker-local XML readers and bounded producer-consumer queues rather than retaining the complete inflated worksheet XML and the complete per-sheet cell buffers
- Active worksheets are given independent queue budgets and are processed in worker-sized windows, keeping callback order without letting later worksheets starve the worksheet currently being emitted
Fixed
- Cell aborts, callback failures and worker errors now wake blocked producers and consumers, halt XML pulls cooperatively, join all workers and leave the direct reader reusable
Version 2.221.0
Changed
- Multi-sheet XLSX opening now streams each worksheet ZIP entry straight into its worker-local inflater and XML reader rather than holding inflated worksheet XML before parsing
- Concurrent worksheet readers serialise only short positioned reads from the package source, so decompression and XML parsing stay parallel whilst transient worksheet input memory is bounded by the active worker count
Version 2.220.0
Added
- PivotTable result generation now executes all nine classic
ShowDataAsmodes, namely difference, percent of a base item, percent difference, running total, percent of row, percent of column, percent of total and index calculations xlPivotBaseItemPreviousandxlPivotBaseItemNextprovide typed selectors for adjacent base items in comparison calculations
Changed
- Pivot percentages and index values draw on row, column and grand totals aggregated straight from the source records, preserving correct Average, Product, Count, variance and standard-deviation semantics without a rescan of the source
- Running totals track pivot-item order, reset on their own for each peer group, and keep sparse result storage for high-cardinality pivots
Fixed
- BIFF8
SXDIrecords now use the standard 14-byte fixed layout and preserveShowDataAs, base field, base item, number format and display name via typed reads, whilst legacy HotXLS records stay readable - XLSX data fields now record pivot-field indexes, map previous and next selectors to the required OOXML values, and emit base attributes solely for modes that use them
- Missing comparison cells remain blank, while present zero denominators return
#DIV/0!instead of being confused with missing data
Version 2.219.0
Fixed
VDBnow applies variable declining-balance depreciation across fractional periods, shifts to straight-line depreciation where advantageous, and honoursno_switch- Zero factors, salvage boundaries, fractional starting periods and invalid period ranges now yield Excel-compatible results, rather than rounding periods and returning a simplified declining-balance approximation
Version 2.218.0
Added
TXLSXWorksheet.Scenariosnow offers typed What-If Scenario Manager authoring with named scenarios, active and shown indexes, changing-cell ranges, user and comment metadata, locked and hidden states plus owned input-cell values- Scenario definitions now track worksheet copies alongside row or column structural edits, whilst Excel compatibility limits are validated before invalid metadata can be written
Fixed
- Opening and saving Excel-authored scenarios now keeps root attributes and nested input cells intact, rather than flattening the hierarchy into lossy raw XML
- Scenario, AutoFilter, data-consolidation, merged-cell and phonetic worksheet elements now follow schema order, so strict spreadsheet consumers need no repair pass
Version 2.217.0
Added
TXLSXWorksheet.IgnoredErrorsnow offers typed authoring for every standard ignored-error category with multi-area references, worksheet-copy support, structural-edit updates, and open/save round tripsTXLSXWorkbooknow surfaces reference mode, recalculate-on-save, full-precision, concurrent-calculation, and manual concurrency settings alongside its existing calculation options
Fixed
- Every non-default workbook calculation setting now on its own produces and round-trips a schema-ordered
calcPrelement, covering iteration limits configured before iteration is enabled - Calculation modes, reference modes, iteration caps, calculation identifiers, and manual concurrency counts now refuse or normalise invalid values in place of writing ambiguous workbook state
Version 2.216.0
Changed
XMATCHandXLOOKUPnow bear out logarithmic ascending or descending binary searches when requested, covering Excel-compatible duplicate and approximate-match boundariesXIRRnow honours its guess with a safeguarded solver that can find high and guess-sensitive roots, whilstXNPVuses compensated summation and validated date and rate inputs- High-cardinality XLSX defined-name lookup now relies on a lazy scope-aware hash index whilst retaining serialised order, local-name precedence, and first-match behaviour
- Preserved XLSX package parts now allocate their declared uncompressed size once whilst retaining complete length and CRC verification
Fixed
- Invalid lookup modes, wildcard binary searches, two-dimensional lookup areas, and mismatched
XLOOKUPreturn vectors now surface formula errors in place of producing ambiguous results XIRRandXNPVnow refuse invalid cash-flow signs, rates, guesses, and dates, truncate fractional date serials, and report non-convergence in place of returning an unverified midpoint
Version 2.215.0
Added
FREQUENCYnow returns a vertical array with one result per bin plus the overflow bucket
Changed
SORTnow relies on a stable scalable ordering for rows or columns, preserving the source order of equal keysUNIQUEnow relies on stable hash-indexed matching for rows or columns, coveringexactly_onceresults and case-insensitive textPERCENTRANK.INC,PERCENTRANK.EXC, andMODE.MULTnow grow with little overhead on high-cardinality input in place of relying on quadratic scans
Fixed
- The
by_coloption ofSORTandUNIQUEnow operates on columns in place of falling back to row behaviour
Version 2.214.0
Added
- XLSX opening now takes streaming UTF-16 little-endian and big-endian XML parts with a byte-order mark or the required endian-specific declaration, covering characters outside the Basic Multilingual Plane
Changed
- High-cardinality PivotTable cache refreshes now rely on deterministic hash indexes for shared values and allocate the record matrix once, preserving first-seen item order whilst avoiding repeated linear searches and row-by-row growth
- Projected direct ingests drop cells outside the selected rows and columns before copying raw values, formulas, and rich text into per-sheet buffers
Fixed
- Malformed XML with duplicate byte-order marks, unsupported or contradictory encoding declarations, UTF-32 signatures, odd UTF-16 byte lengths, or invalid surrogate pairs is now refused
- Parallel direct-reader workers now initialise all job state before starting, halt taking new sheet jobs after a failure, re-fire the lowest-index job error deterministically, and clean up every created worker if pool construction fails
Version 2.213.0
Added
T.TESTnow assesses independent samples with either pooled equal variance or Welch unequal variance alongside paired samples, covering one-tailed and two-tailed probabilities
Changed
- XLSX opening now chases workbook, worksheet, and drawing relationship targets for worksheets, shared strings, styles, themes, macros, external links, comments, threaded comments, VML, drawings, images, charts, tables, and PivotTables, covering valid packages that use renamed or non-contiguous part paths
Fixed
- Malformed packages with duplicate relationship identifiers no longer permit a later unsupported relationship to replace the first usable target during compatibility recovery
Version 2.212.0
Changed
- Formula dependency tracking now grows better on large worksheets by indexing cell and range dependencies before reconstructs and dirty-cell invalidation
- Large statistical and regression formulas now assess every numeric value in the supplied ranges in place of stopping at the previous fixed-size buffer
Fixed
- XLSX cells outside the worksheet grid are refused uniformly so invalid coordinates can no longer alias valid cells
- Editing formulas no longer clears workbook calculation mode, iteration limits, full-calculation flags, or other calculation settings
- Blob-list ingests now validate requested ranges in an explicit manner and allow valid empty slices at the end of the stream
Security
- Classic XLS encryption now covers pivot cache streams along with worksheet data
- Malformed SST extension tails and ZIP central-directory records are refused before oversized allocation, truncated ingests, or comment-embedded fake directory records can affect loading
Version 2.211.0
Added
TXLSPivotTable.Makenow materialises every configured data field with its own aggregation and unfolds the values on rows or columns according toDataFieldAxisIsRow
Changed
- Pivot result generation re-uses hash-indexed row and column key domains across all data fields, selects dense or sparse accumulator storage from the result shape, preserves cache item order beyond nine keys, and emits readable combined labels for multi-field axes
Fixed
Countnow incorporates non-empty text, Boolean, error, date, and numeric cache values whilstCountNumsincludes only numeric and date values,Productreturns zero for intersections without numeric values, blanks are no longer counted as entries, and values-only pivots can materialise their grand totals without row or column fields
Version 2.210.0
Added
TXLSWorkbookViewernow renders XLSX conditional fills, font colour and emphasis, number formats, directional positive and negative data bars, gradients, borders, axes, hidden values, and all built-in icon-set familiesTXLSWorkbookViewer.RefreshConditionalFormatsreconstructs prepared aggregate and threshold state after callers modify an attached XLSX workbook in place
Changed
- The viewer stores one prepared conditional-format evaluator per active worksheet, re-uses it across scrolling, selection, and repaint operations, and releases it whenever the workbook or worksheet changes
Fixed
- Data-bar axes at the rightmost boundary are now clipped inside the owning cell in place of drawing into the adjacent cell
Version 2.209.0
Added
- XLSX worksheets now surface a prepared conditional-format evaluator that resolves rule priority,
StopIfTrue, relative formulas, differential styles, Top/Bottom ranking, above/below-average tests, duplicate and unique values, relative date periods, two- and three-colour scales, data bars, and icon sets for any cell
Changed
- HTML and PDF exports now render matching conditional fills, font emphasis and colour, number formats, colour scales, directional positive and negative data bars, explicit axes, icon-family glyphs, hidden values, and theme colours with tint resolution
- Large conditional-format domains now re-use compiled relative formulas without a per-cell syntax-tree allocation, stream mean, deviation, minimum, and maximum statistics, retain ordered values only for ranking or percentile rules, batch-sort Unicode duplicate keys, and use row-band candidate indexes to avoid scanning unrelated rules
Fixed
- Classic conditional rules now open expression types as expected and evaluate reversed between caps, case-insensitive text predicates, blank cells, and error predicates uniformly
Version 2.208.0
Changed
- The packed cell storage engine now records native tagged string, Boolean, error, and blank payloads, iterates cells in row-major order, and run-length encodes consecutive equal-typed cells for lower memory use and faster sequential output
- Classic workbook shared strings now keep character bytes in one allocation and create decoded string values lazily, reducing allocation overhead on large unique-string tables
Added
- Pivot tables can now calculate a complete result matrix from cache records with row and column key grouping and all 11 supported aggregate functions
- Classic workbook charts now surface typed series, axis, legend, and chart-group information for conversion and inspection workflows
Version 2.207.0
Added
TXLSPivotCache.RefreshFromSourceconstructs a pivot cache from a source worksheet range: it ingests the header row to name the fields, distils each data row’s distinct values into the per-field shared-item domain, locks the field type from the first non-empty value, and records the shared-item index for every (record, field) — so a pivot table can be created by code from a data range in place of relying on Excel’srefreshOnLoad. A callback-driven value reader leaves the pivot unit free of any direct worksheet dependency
Version 2.206.0
Added
- New
TlxCellMMU(lxCellMMUunit) realises a packed, row-major cell storage engine with run-length encoding of equal-typed and empty cell runs, and a tagged-byte type code that doubles as the data width selector — so a column of small integers costs one byte per cell in place of eight. The engine encodes numbers in the smallest width that preserves the value (int8 / int16 / int32 / 2-decimal / 4-decimal scaled integers / IEEE double), stores string-index, boolean, error, and blank cells compactly, and surfaces aGetValue/SetNumber/SetStringAPI plus a forward iterator, which is the next-generation backend behind a feature flag for the existingTXLSXCellsAPI, targeting a 10–25× working-set reduction on dense sheets
Version 2.205.0
Added
TXLSCustomChart.GetChartInfonow unravels a semantic summary from the raw BIFF chart record stream — chart type family (bar, line, pie, area, scatter, radar, doughnut, surface, bubble), the series count, and legend presence — so a BIFF chart’s type can be read by code and a BIGH-to-XLSX chart conversion can pick the right target family. The byte-passthrough storage that guarantees round-trip fidelity is unchanged
Version 2.204.0
Changed
- The classic
.xlsshared-string table now records ASCII-only strings in the compressed Latin-1 encoding ([MS-XLS] §2.5.294fHighByte=0, one byte per character) in place of always using UTF-16, roughly halving the SST size — and therefore the.xlsfile — for ASCII-heavy workbooks
Version 2.203.0
Added
- New
TlxCompoundFilereads back and writes out the Compound File Binary (OLE2) container format directly in pure Pascal, with noole32.dll/ COMIStoragedependency — opening the door to in-memory and cross-platform.xlshandling. The reader handles the v3 layout HotXLS meets in the wild (header + in-header DIFAT + FAT chain walk + MiniFAT and the mini-stream for streams under 4096 bytes + the directory tree); the writer emits a minimal-but-valid v3 container sufficient for HotXLS’s output
Version 2.202.0
Added
- The autofilter sort state now has a typed model (
TXLSXSortStatewithTXLSXSortConditionchildren) covering sort-by value / cell colour / font colour / icon, sort method (none / stroke / pinYin), case sensitivity, column sort, and per-condition custom lists — such that applications can build sort states by code in place of editing raw XML, whilst the legacy opaqueSortStateXmlpassthrough still wins for files HotXLS did not author - Dynamic filters are now read in and written as a typed
TXLSXDynamicFilterType(above/below average and std-dev, today/yesterday/tomorrow, this/last/next week, month, quarter or year, year-to-date, Q1–Q4, M1–M12) with optionalval/maxValcaps — on opening a workbook that uses a dynamic filter no longer drops it on save
Version 2.201.0
Added
- Surface and 3-D surface charts (
xlsxChartSurface/xlsxChartSurface3D) are now first-class chart types — written, read, and round-tripped alongside the other chart families - The autoshape authoring API spans a practical subset of the OOXML preset-geometry list — triangles, diamonds, parallelograms, hexagons, octagons, arrows, chevrons, callouts, flowchart nodes, stars, hearts, sun, moon, brackets and braces — each mapping to its correct
prsttoken and[MS-ODRAW]shape id, so authored shapes render as expected in Excel (the full 187-preset list was already preserved on round-trip via raw-anchor passthrough)
Version 2.200.0
Fixed
- Opening a workbook whose autofilter uses a colour filter or an icon filter no longer drops that filter on save —
colorFilterandiconFilterare now ingest into typed columns (TXLSXAutoFilterColumn.SetColorFilter/SetIconFilter) and re-emitted verbatim, in place of being lost as unrecognised filter-column children
Version 2.199.0
Added
TCondFormatRule.Evaluatetells whether a conditional-formatting rule fires for a given cell, spanning cell-value comparisons, formula expressions, text contains/begins/ends, blanks, and error rules — the foundation for querying which cells a rule currently highlights and for rendering CF results outside Excel
Changed
FACTand the internal factorial helpers now rely on a precomputed 0!..170! table in place of recomputing an O(n) product on every call, speeding upFACT, the multinomial coefficients, and the Poisson/Binomial/chi-square distribution paths
Version 2.198.0
Changed
- Saving a worksheet now groups cells into rows with a single count-then-fill pass in place of growing each row’s index with a realloc-per-cell, removing a hidden O(cells × cells-per-row) copy on large sheets
- The formula dependency graph now indexes its reference ranges by (sheet, row) so seeding a dirty cell binary-searches the candidate band in place of scanning every formula on every changed cell — the bigger the workbook and the more sheets it has, the larger the speedup on recalculation
- Row-major, column-sorted cell traversal is now exposed as
TXLSXWorksheet.BuildRowMajorCellOrderso save, clipboard, autofilter and other row-ordered consumers share one traversal in place of re-deriving it
Version 2.197.0
Fixed
- Radar, stock, and pie-of-pie/bar-of-pie charts are no longer lost when an
.xlsxworkbook that contains them is opened and re-saved — the chart reader now identifies thec:radarChart,c:stockChart, andc:ofPieChartcontainer elements it already records, restoring symmetric read/write coverage SUBTOTALwith function codes 101–111 now excludes values on hidden rows, andAGGREGATEnow honours its ignore-hidden-row option codes (2, 3, 6, 7), matching Excel in place of treating the include-hidden and ignore-hidden variants identically- Calling a fixed-arity built-in function with more arguments than declared (for instance
=SIN(1,2)) now fires#VALUE!centrally in place of being accepted by the dispatcher
Version 2.196.0
Fixed
- Row and column insertion or deletion now partitions cell-value and expression conditional formats plus data validations when edited target areas require different relative formula anchors, whilst preserving rule settings, assigning unique conditional-format priorities, and keeping aggregate conditional-format domains intact
Version 2.195.2
Changed
- PDF export now subsets the embedded TrueType font via the Windows
fontsub.dllCreateFontPackageAPI, keeping only the glyphs the document actually rendered in place of embedding the whole.ttf— typically shrinking the PDF by 8–20× for Unicode-heavy sheets; it falls back to full embedding when subsetting is unavailable
Version 2.195.1
Fixed
- Inserting or deleting rows and columns on the classic
.xlsengine now rewrites every affected formula reference (cell formulas and defined names) in line with Excel semantics — references below an insertion shift, references fully inside a deletion become#REF!, and partially overlapping areas shrink — in place of leaving stale coordinates
Version 2.195.0
Changed
- Deleting table columns now translates every affected structured-reference token to
#REF!across worksheet formulas, table formulas, defined names, and chart series whilst preserving unrelated references and string literals
Fixed
- Removing an entire table no longer leaves qualified structured references aimed at a table that no longer exists
- Cloned data validations now keep their IME input mode
Version 2.194.0
Changed
- Row and column edits now keep Excel table column identifiers, names, calculated formulas, totals formulas, filter columns, filter ranges, and sort conditions in step with the edited table
Fixed
- Conditional-format and data-validation formulas now re-anchor relative and mixed references when deletion removes their first target area
- Worksheet and table sort states now record valid attributes and drop conditions whose ranges were deleted
Version 2.193.0
Changed
- Row and column edits now refresh complex and cross-scope defined-name formulas, bubble-chart data ranges, and formula-based visual conditional-format thresholds
- Bubble and scatter charts now re-establish their X-axis, Y-axis, and bubble-size series ranges when reopened
Fixed
- Multi-area conditional-format and data-validation targets now shift each surviving area on its own in place of leaving the complete target list unchanged
- Text box and WordArt anchors now shift or resize with inserted and deleted rows and columns
Version 2.192.0
Added
- Streaming direct ingests and row-cursor traversal can opt into structured rich strings with complete run formatting, phonetic runs, and phonetic properties whilst retaining bounded shared-string storage
TXLSDirectWriter.WriteRichStringrecords formatted and phonetic text as inline or deduplicated shared strings
Changed
- Rich shared-string deduplication now distinguishes run formatting and phonetic metadata whilst keeping ordinary string interning on its existing fast path
Fixed
- Phonetic text in inline strings is no longer counted in the displayed cell value
Version 2.191.0
Added
TXLSXRange.SetDynamicArrayFormulanow establishes native dynamic-array formulas with the complete Excel XLDAPR metadata chain
Changed
- Dynamic-array roots now pool one deduplicated workbook metadata record and cross-workbook worksheet or range copies remap that record into the destination workbook
- Supported dynamic-array metadata remains available when unsupported package-part preservation is disabled, whilst unrelated value metadata is still removed
Fixed
- Dynamic-array spill cells are no longer treated as legacy CSE followers, and replacing or clearing the root no longer leaves stale metadata indexes
- Removing the final dynamic-array root now strips out the unused metadata part, workbook relationship, and content-type entry
Version 2.190.0
Changed
- Streaming direct ingests and row-cursor traversal now expand shared-formula followers into complete cell-relative formulas whilst retaining projection and bounded-memory behaviour
Fixed
- Dynamic-array workbooks now keep cell and value metadata indexes, formula recalculation attributes, metadata package relationships, and unchanged future-function prefixes during open and save cycles
- Disabling unsupported-part preservation no longer leaves dangling worksheet metadata indexes once the metadata part is removed
Version 2.189.0
Added
- Opening XLSX workbooks now unfolds shared-formula followers into complete per-cell formulas with correct relative, absolute, mixed, range, and sheet-qualified references
Fixed
- Self-closing shared-formula followers no longer capture later value or formula XML, and their cached results withstand open and save cycles
- CSE array formulas now keep their anchor and follower relationships through row or column structure edits, complete-range copies, worksheet duplication, and cross-workbook sheet copies
- Assigning a normal formula or clearing a cell now strips out stale CSE array membership so calculation cannot be redirected to an old array anchor
- Copying only part of a CSE array no longer yields dangling follower references in the destination
- Range copies now capture overlapping sources and shift relative formula references, preventing source cells or array anchors from being overwritten before they are copied
- Row or column edits that intersect only part of a CSE array are refused in place of quietly resizing or detaching the array
Version 2.188.0
Added
TXLSDirectReader.SharedStringMemoryLimitcaps decoded shared-string memory and automatically migrates larger tables to delete-on-close indexed temporary storage with a fixed-size value cacheTXLSRowCursor.SharedStringMemoryLimitsurfaces the same bounded shared-string storage control for forward-only row traversal
Changed
- Direct shared-string parsing now keeps whitespace-only values, CDATA, XML entities, non-BMP characters, empty items, and rich-text run order whilst excluding phonetic guide text from the displayed value
Fixed
- Opening XLSX workbooks now keeps every shared-string item in document order, preventing duplicate text or differently formatted rich strings from collapsing later cell indexes
- Saving XLSX workbooks now de-duplicates rich strings by run boundaries and formatting properties in place of visible text alone, preserving distinct formatting for cells with the same displayed value
Version 2.187.0
Added
TXLSDirectReader.FirstRowandLastRowlimit streaming ingests to a 1-based row range and halt worksheet parsing after the requested rangeTXLSDirectReader.IncludeColumnandClearColumnProjectionoffer constant-time column projection that omits unselected cells before value decoding and callback dispatch
Version 2.186.0
Added
TXLSDirectWriter.UseSharedStringscan de-duplicate repeated text into an OOXML shared-strings part with accurate total and unique counts, reducing package size for repetition-heavy dataTSimpleDomReaderoffers a compact single-pass XML tree for random-access queries of workbook metadata and package parts, with case-sensitive QName and local-name lookup
Changed
- Direct XLSX reading now relies on hash-assisted exact element dispatch, single-pass attribute harvesting, and constant-time current-row column lookup whilst preserving streaming memory behaviour
- Shared-string XML generation now relies on a linear-growth buffer to avoid repeated whole-string copies on large distinct-string tables
Fixed
- CSV formula export no longer appends a second equals sign when formula text already includes one
- XLSX PDF export no longer cuts off cell text using a character-count estimate before layout
- XML reader name hashes now follow processing instructions, attributes, and moves back to their owning elements without exposing stale element state
Version 2.185.1
Fixed
- Inserting or deleting rows and columns now tweaks local and cross-sheet formula references exactly once whilst preserving function names and text literals
Version 2.185.0
Added
TXLSPDFExportnow offers one-basedFirstPageandLastPageoutput selection, a complete logicalPageCount, and sixCalculatePageCountoverloads for classic and XLSX ranges, worksheets, and workbooks without building PDF page objectsTXLSXWorkbook.SaveWorkbookAsHTMLissues visible worksheets in one navigable HTML document with stable per-sheet anchors, escaped titles and sheet names, and an option to include hidden or very hidden sheetsTDataToXLS.BeforeRecordcan omit records before row output andBeforeValuecan alter or hold back field values with dataset, detail-level, source-field, and export-column contextTXLSWorkbookViewersurfaces selected-cell comments and hyperlinks, fires an application-controlled hyperlink event, renders comment indicators and XLSX fonts, fills, and alignment, and normalises selection and rendering across merged ranges
Changed
- The ConversionWorkbench example can now produce PDF output and issues all visible XLSX worksheets for HTML targets, whilst the WorkbookViewer example showcases merged-cell navigation, comments, and hyperlink activation
Version 2.184.0
Added
- Classic XLS and XLSX ranges can place Unicode tabular text and styled HTML to the Windows clipboard through
CopyToClipboard, preserving formulas, merged cells, links, display formatting, and without risk quoted embedded tabs, line breaks, and quotation marks TXLSXWorkbooknow keeps custom package parts reachable from unknown package-root, workbook, worksheet, or drawing relationships, covering relationship-ID collision handling, content types, child relationships, compression choice, and exact payload bytes;PreserveUnsupportedParts,UnsupportedPartCount,UnsupportedPartBytes, andClearUnsupportedPartssurface control and diagnostics- Classic XLS saves surface begin, work, and end callbacks with cancellation through
OnProgressEx, whilstIXLSWorkbookProgressoffers structured diagnostics with stable codes, severity, operation, sheet context, native return values, and exception details TXLSXWorkbooknow surfaces the same structuredDiagnostics,LastDiagnostic, andOnDiagnosticsurfaces for save, open, recalculation, cancellation, and exception reporting- Parsed VBA modules now cater for editing
SourceCodeand writing the updated compressed module stream back through classic XLS, standalone VBA storage, and macro-enabled OOXML saves whilst preserving stream prefixes and untouched project content - Classic worksheets and shape collections now surface typed
TXLSCheckBox,TXLSComboBox, andTXLSListBoxform controls with creation helpers, labels, control-kind inspection, cell anchors, removal, and open/save discovery TXLSXRange.ApplyFormatPatchcan selectively copy font, fill, border, number-format, alignment, and protection components with source-pattern tiling whilst preserving destination values and unselected formattingTDataToXLScan recursively emit linked master-detail datasets throughReadDetailTablesandIndentDetailTables, keeping active data links intact, appending each detail table beneath its master record, and inheriting field, title, and formatting options at every levelTXLSXWorksheet.AddWordArtcreates cell-anchored DrawingML text with preset warping plus configurable text and outline colours, and the raw drawing-anchor preservation path keeps the complete WordArt shape on later open/save cyclesTXLSWorkbookViewerintroduces a VCL worksheet viewer for classic and modern workbook objects with XLS, XLSX, XLSM, template, and ODS file loading, formatted cell text, classic styles, row and column sizing, headers, gridline and selection rendering, scrollbars, mouse selection, keyboard navigation, cell positioning, worksheet switching, and selection or worksheet events- New Delphi
FeatureShowcaseandWorkbookViewerexamples showcase styled PDF printing, print titles, manual breaks, classic form controls, selective format patches, WordArt, diagnostics, run-time viewer creation, file loading, cell navigation, worksheet switching, and viewer events, with matching English guides and developer-reference topics
Changed
- Classic XLS and modern XLSX workbook, worksheet, and range PDF export now records every visible worksheet into one document, omits hidden and chart sheets, renders solid fills, font colours, font sizes, bold and italic emphasis, horizontal and vertical alignment, explicit cell borders, and optional worksheet gridlines, follows each worksheet's print area, paper size, orientation, margins, zoom, fit-to-width setting, column widths, actual row heights, manual row and column page breaks, repeated title rows and columns, and three-part headers and footers with page, total-page, sheet-name, date, and time fields, paginates wide and tall ranges across both axes, emits locale-independent PDF numeric syntax, and embeds an eligible TrueType font plus a ToUnicode map for text outside WinAnsi
- XLSX extended progress callbacks now receive reliable begin, work, and end states for save, open, and recalculation, whilst the legacy callback remains work-only and every operation resets prior cancellation state
- Classic XLS serialisation now propagates worksheet, chart, style-extension, VBA, control-stream, storage, and output commit failures in place of reporting success, and file saves stage the complete compound file before atomically replacing the destination
- XLSX and ODS file saves now build a complete sibling temporary package and atomically replace the destination only after successful finalisation, leaving existing files unchanged after cancellation or failure
Version 2.183.0
Added
TXLSDirectWriternow caters for reusable package-level cell-style handles and style cloning without buffering worksheet rows; the same style index can be applied to any number of cells or reused across worksheets- Direct cell styles offer 30 formatting capabilities spanning font name, size, BGR colour, bold, italic, strikeout, outline, shadow, five underline modes, 19 fill patterns with foreground/background colours, five on its own coloured border edges with 14 line styles and diagonal directions, built-in or custom number formats, horizontal and vertical alignment, wrapping, shrink-to-fit, indentation, text rotation, quote prefixes, and locked/hidden protection
- Styled overloads ship for strings, numbers, booleans, dates, formulas, errors, and every cached formula result type, permitting high-volume exporters to select a prebuilt style by integer index during sequential records
Changed
- The direct writer de-duplicates equal font, fill, border, and number-format components when building
styles.xml, whilst preserving stable cell-style indexes already written into worksheet streams - Generated direct-writer style tables now incorporate the standard
noneandgray125default fills before custom fills for stricter OOXML compatibility
Version 2.182.0
Added
TXLSDirectWriternow records conditional formatting whilst retaining its row-count-independent memory profile, with eight cell-value operators, expression rules, contains/not-contains/begins-with/ends-with text rules, top or bottom value and percentage rules, above or below average rules, duplicate and unique values, blank and nonblank cells, error and nonerror cells, data bars, two- and three-colour scales, and all 17 baseline icon-set families- Direct conditional-format rules support explicit priorities, halt-if-true evaluation, average standard-deviation and equality options, icon threshold replacement, icon-only and reverse display, data-bar value visibility, BGR colours, and differential fill, font-colour, bold, and italic styles
Changed
- The direct writer de-duplicates equivalent differential styles across worksheets and stores only conditional-format rules and styles, such that memory use scales with the rule count in place of the number of worksheet rows
- Automatic data-bar minimum and maximum threshold kinds are normalised to the standard
minandmaxtokens in the base OOXML element for broad spreadsheet compatibility
Version 2.181.0
Added
TXLSDirectWriternow records worksheet and workbook protection without buffering worksheet data, covering 15 fine-grained worksheet permissions, legacy password verifiers, modern hash metadata, editable protected ranges with optional passwords or security descriptors, workbook structure and window locks, raw verifier assignment, and protection clearing
Fixed
- Unsupported drawing anchors now keep every closing element when reconstructed for round-trip output, so shape-only drawings remain well-formed after open and save
- XLSX worksheet protection permissions now track the OOXML locked-flag definition, so allowed actions write
0, forbidden actions write1, and omitted attributes reopen with their schema defaults - Legacy XLSX worksheet, protected-range, and workbook passwords now rely on the Excel-compatible 16-bit verifier algorithm with ANSI conversion and the 15-byte limit
Version 2.180.0
Added
- The XLSX worksheet model now round-trips the What-If Scenario Manager (
<scenarios>) and Data Consolidation (<dataConsolidate>) elements. NewScenariosXmlandConsolidateXmlraw-XML properties onTXLSXWorksheetcarry the inner content verbatim — the writer emits the wrapper elements, the reader parses scenario/data-consolidation children back. Financial-modelling files that define scenarios or consolidation definitions no longer lose them on round-trip
Version 2.179.0
Added
- A new
XlsxBuildNumFmthelper function constructs OOXML number-format codes from semantic properties —Decimals,Thousands(separator),NegativeRed(red negatives),CurrencySymbol, andPercent. Callers no longer need to hand-write format strings like"$#,##0.00;[Red]-$#,##0.00"— the builder produces them from simple parameters. Designed for use withCell.NumberFormatorWorkbook.NumberFormats.Add
Version 2.178.0
Added
- The XLSX worksheet model now round-trips the VBA code name (
<sheetPr codeName="..."/>), essential for VBA interop in which the VBA project references worksheets by code name. NewCodeNameproperty onTXLSXWorksheet - Comments now cater for an
AlwaysShowvisibility toggle onTXLSXComment— when True the comment balloon stays visible at all times (Excel's per-comment "Show/Hide Comment" toggle), rather than only on hover - Data validation now round-trips the IME mode attribute (
imeMode) onTXLSXDataValidation. The 11-value enum governs CJK input-method behaviour when a cell is entered (noControl / off / on / hiragana / fullKatakana / etc.). Indispensable for Japanese/Korean/Chinese-locale files - The worksheet model gains a
PaneStateproperty for the pane-state attribute on<pane>beyond the existing frozen-mode handling — supportsfrozenSplit(frozen-then-scrollable) andsplitstates
Version 2.177.0
Added
- Three formerly-registered-but-unimplemented worksheet functions now hold full dispatch:
DOLLAR(currency-formatted text),FIXED(fixed-decimal text with optional comma suppression), andAREAS(count of areas in a reference). Previously these were registered inInitFuncHashbut had no calc-engine case — evaluating=DOLLAR(...)quietly returned wrong results - The XLSX worksheet model now round-trips per-view-type zoom scales (
zoomScaleNormal/zoomScalePageLayoutView/zoomScaleSheetLayoutView), gridline colour (sheetView color), and sheet-view display flags (showFormulas/showZeros). New properties onTXLSXWorksheet:ZoomNormal,ZoomPageLayout,ZoomSheetLayout,GridColor,ShowFormulas,ShowZeros - Outline summary direction now round-trips. New
SummaryBelow,SummaryRight, andShowOutlineSymbolsproperties onTXLSXWorksheetgovern whether summary rows/columns sit below/right of the detail and whether outline symbols are shown. The writer emits<outlinePr>inside<sheetPr>; the reader parses it back - The workbook calcPr now bears
forceFullCalcandcalcCompletedattributes alongside the existingcalcId/fullCalcOnLoad/calcMode/iteratetrio
Version 2.176.0
Added
- The XLSX formula engine now settles structured table references before compilation. A new
ResolveStructuredRefsmethod onTXLSXWorkbookscans formula text forTableName[ColumnSpec]patterns and swaps them for concrete A1 range references using the workbook'sTXLSXTablecollection. Supported specs include column data range (Sales[Qty]), current-row column (Sales[@Total]), full data (Sales[#Data]/Sales[#All]), headers (Sales[#Headers]), and totals row (Sales[#Totals]). The resolution runs automatically insideGetCompiledFormula— existing formulas stay unaffected because non-table identifiers are left verbatim. Formerly structured references caused formula compilation to fail
Version 2.175.0
Added
- The formula engine now caters for R1C1 reference-style formula compilation. A new
GetCompiledFormulaR1C1method onTXLSCalculator(andGetCompiledR1C1onTXLSFormula) accepts a formula written in R1C1 notation (R2C3for absolute,R[-1]C[2]for relative,RCfor the current cell) and compiles it by first translating to A1 notation using the formula cell's row/col. A standaloneR1C1ToA1function performs the conversion — it detectsR/Cmarkers standing alone (not part of a function name such as ROUND), parses the optional bracketed offsets, and yields the equivalent A1 reference. String literals and identifiers are ignored. Before this only A1-style formulas could be compiled
Version 2.174.0
Added
TXLSDirectWriterAutoFilter output now caters for worksheet and table filter columns, value filters, blank filters, date-group filters, custom comparison filters, dynamic filters, top/bottom filters, filter button flags, sort states, sort conditions, XML escaping, and duplicate worksheet/table filter range suppression whilst streaming XLSX files
Version 2.173.0
Added
TXLSDirectWritertable output now caters for table comments, totals row counts, column totals-row labels, column totals-row functions, calculated-column formulas, totals-row formulas, and XML escaping for table-column metadata whilst streaming XLSX files
Version 2.172.0
Added
TXLSDirectWriternow records Excel table parts whilst streaming XLSX files, covering worksheet table relationships, table part content types, table ranges, column names, header-row and totals-row flags, and built-in table style display flags without building a full workbook object model
Version 2.171.0
Added
TXLSDirectWriternow records worksheet data validations whilst streaming XLSX files, covering list, whole-number, decimal, date, time, text-length, custom-formula, arbitrarysqref, prompt, error-alert, allow-blank, dropdown, and input/error message flags without assembling a full workbook object model
Version 2.170.0
Added
TXLSDirectWriternow records workbook and sheet-local defined names whilst streaming XLSX files, covering hidden names, comments, generated absolute ranges, print areas, print title rows, print title columns, combined print titles, quoted sheet-name references, XML escaping, and replacement semantics for repeated print-name setters without building a full workbook object model
Version 2.169.0
Added
TXLSDirectWriternow records worksheet hyperlinks whilst streaming XLSX files, covering external URL, mailto, and file relationships, internal sheet locations, display text, tooltips, single-cell or multi-cell hyperlink ranges, barewww.URL normalisation, XML escaping, and percent-encoded relationship targets without building a full workbook object model
Version 2.168.0
Added
TXLSDirectWriternow records print and sheet-view metadata whilst streaming XLSX files, covering gridline and row/column header display toggles, page margins, odd header/footer text, print gridlines and headings, page centreing, paper size and landscape orientation, fit-to-page dimensions, and manual row or column page breaks without building a full workbook object model
Version 2.167.0
Added
TXLSDirectWriternow records worksheet layout metadata whilst streaming XLSX files, covering default column and row sizes, custom column widths, hidden rows and columns, merged ranges, AutoFilter ranges, frozen panes, sheet tab colours, and right-to-left sheet views without building a full workbook object model
Version 2.166.0
Added
- Streaming XLSX workflows now incorporate sheet-name listing without worksheet scans, name-based row-cursor sheet selection, raw numeric date streaming, direct writer re-use, error-cell writing, and cached formula-result writers for number, string, Boolean, date, and error values
Version 2.165.0
Fixed
TXLSDirectReader.ReadStreamnow re-establishes the caller's stream position after direct scanning, in line with the documented stream contract and allowing applications to re-use the same stream after a direct read pass
Version 2.164.0
Added
TDataToXLSdataset exports now cater forIncludeFieldsandExcludeFieldsstring lists. Applications can whitelist exported fields, omit sensitive columns, and keep headers, data rows, column widths, and export callbacks in step with the selected field set
Version 2.163.0
Added
- CSV export gains configurable text quoting across the XLS and XLSX engines
TXLSWorkbooknow surfacesCSVEmitFormulasandCSVQuoteAllStrings, andTXLSXWorkbookintroducesCSVQuoteAllStrings. When enabled, formula export records formula text and string fields are quoted whilst numeric, date, Boolean, Null, and Empty fields keep the normal quoting rules
Version 2.162.0
Added
- The XLSX engine gains an abortable progress event system. A new
OnProgressExcallback onTXLSXWorkbookfires alongside the existingOnProgresswith three enhancements: (1) aTXLSXProgressStateparameter (ppsBegin/ppsWork/ppsEnd) that brackets each phase so UIs know when an operation begins and ends; (2) anAbort: Booleanvar parameter that lets the callback halt the current operation mid-stream — the read/write/calc loops checkWorkbook.Abortedand break out without issue; (3) a newxlsxProgressExportingphase for export operations (HTML/RTF/CSV/ODS). AFireProgresshelper method pools the dual-callback dispatch. TheFAbortedflag is cleared at the outset of every top-level operation (Open / SaveAs / Recalculate)
Version 2.161.0
Added
- The XLSX chart model now caters for four new chart elements for stronger Excel compatibilityChart data table (
c:dTable):TXLSXChartgainsShowDataTable+ShowDataTableKeystoggles — when enabled the writer emits the data-table element inside the plot area so Excel renders the source data as a grid below the chart axisUp/down bars + hi-low lines (stock/OHLC chart elements):TXLSXChartgainsHasUpDownBars+UpDownGapWidthandHasHiLowLines— the writer emitsc:upDownBarsandc:hiLowLinesinside the chart element (line/stock charts)3D view controls:TXLSXChartgainsRotation3DX/Rotation3DY/Elevation3D/Perspective3D/RightAngleAxes3D— the writer emitsc:view3Dat the chart level whenever any 3D property deviates from the default. Formerly none of these elements were emitted, so charts constructed with data tables, stock-chart elements or 3D views shed them on round-trip
Version 2.160.0
Added
- Formula references now tweak automatically when rows or columns are inserted or deleted in the XLSX engine. The
ShiftSheetGeometrymethod — called byInsertRows/DeleteRows/InsertCols/DeleteCols— now walks every surviving formula cell and rewrites its A1 references to mirror the structural change. A newXlsxAdjustFormulaRowColRefstext-scanner detects single-cell refs (A1,$B$2) and range refs (A1:B3), moves their row/column components past the insertion point, and converts deleted references to#REF!. Both relative and absolute references are shifted (matching Excel's behaviour). Previously formulas were quietly left pointing at the wrong cells after a structural edit
Version 2.159.0
Added
- Autofilter sort state now round-trips via the XLSX engine
TXLSXWorksheetgains aSortStateXmlproperty that carries the raw inner XML of the OOXML<sortState>element (column sort direction, case sensitivity, sort method, and each<sortCondition>with its descending flag + ref). The writer emits the element after<autoFilter>; the reader parses the attributes and sort conditions back. Previously sort state was quietly dropped on read and never written - CJK phonetic/ruby settings now round-trip via the XLSX engine
TXLSXWorksheetgainsPhoneticFontId,PhoneticType(hiragana / katakana / fullWidthKatakana / noConversion), andPhoneticAlignment(left / centre / distributed). The writer emits<phoneticPr>after<sheetData>; the reader parses the attributes back. Previously the phonetic element was quietly dropped on read — Japanese-market files lost their furigana reading-aid settings
Version 2.158.0
Added
- The XLSX engine now round-trips the named cell-style table (
<cellStyles>). A newTXLSXNamedStyleclass +TXLSXNamedStylescollection onTXLSXWorkbookcarries the full surface:Name,XfId,BuiltInId,CustomBuiltIn,Hidden,BuiltinLevel. The writer emits one<cellStyle>per entry when the collection is non-empty; the reader parses them back again. Previously the writer hardcoded a single"Normal"entry and the reader threw away all named styles, so files carrying "Good"/"Bad"/"Total"/custom-named styles dropped those names on round-trip
Version 2.157.0
Added
- The XLSX engine now round-trips the full
<calcPr>element, not just the iterative-calculation togglesTXLSXWorkbookgainsCalcId(the calc engine identifier Excel uses to decide if cached values are stale),FullCalcOnLoad(compels Excel to do a full recalc on open — critical for workbooks produced by a non-Excel engine), andCalcMode(auto / manual / autoNoTable). The writer emits the matching attributes on<calcPr>; the reader parses them back. Previously onlyiterate/iterateCount/iterateDeltawere handled, and the rest were quietly dropped
Version 2.156.0
Added
- The formula evaluator now realises 37 worksheet functions that were formerly registered (ptg assigned in InitFuncHash) but had no dispatch implementation — they fell through to
#NAME?. The new implementations span five function families: Regression (FORECAST,LINEST,TREND,GROWTH,LOGEST,CORREL,PEARSON,SLOPE,INTERCEPT,RSQ,STEYX), Depreciation (SLN,SYD,DB,DDB,VDB), Descriptive Statistics (AVEDEV,DEVSQ,KURT,SKEW,GEOMEAN,HARMEAN,TRIMMEAN,FREQUENCY), Array Pairwise (SUMXMY2,SUMX2MY2,SUMX2PY2), and Combinatorial/Maths (COMBIN,PERMUT,FACT,QUOTIENT,ROMAN,DEGREES,RADIANS,STANDARDIZE). The regression functions use a least-squares solver; the depreciation functions realise straight-line, sum-of-years'-digits, and declining-balance methods; the descriptive-statistics functions compute mean absolute deviation, kurtosis, skewness, geometric/harmonic/trimmed means; and the pairwise functions compute sum of squared differences between two equal-sized ranges. A newCollectRangeValueshelper onTXLSCalculatorextracts numeric values from range arguments for the stat functions
Version 2.155.0
Added
- The formula evaluator now caters for five additional statistical and engineering compatibility names:
ERFC,ERFC.PRECISE,BINOM.INV,CHI.INV.RT, andF.TESTERFCcomplements the existing error-function series,BINOM.INVsearches the binomial CDF threshold,CHI.INV.RTaliases the right-tail chi-square inverse, andF.TESTreturns the two-tailed sample-variance p-value
Version 2.154.0
Added
- The formula evaluator now settles cross-workbook references via a new
OnGetExternalValuecallback onTXLSCalculator. When a 3D range reference points into an external workbook ([1]Sheet1!A1), the evaluator routes via the callback in place of returning#REF!. The XLSX engine wires this callback toGetExternalCellValue, which maps the SupBook index + sheet index to the matchingTXLSXExternalLink's<sheetDataSet>cache and decodes the cached cell value by its OOXML type attribute (numeric / boolean / string / error). Previously, cross-workbook formulas returned#REF!unconditionally; the callback infrastructure now allows any engine (BIFF8, XLSX, or a bespoke calculator host) to supply external values - The formula evaluator now bears out element-wise array broadcasting on binary operators (
+/-/*///^). When either operand is a 1D or 2D variant array (e.g. a matrix-function result, a spilt range, or a CSE array operand), the operator is set element-by-element; a scalar operand is broadcast to every element of the array operand. The newApplyArrayBinaryOphelper takes care of shape validation, scalar broadcast and division-by-zero propagation. Legacy scalar arithmetic is untouched — the array path solely engages whenever at least one operand is a variant array - The formula evaluator now identifies the
TABLEfunction (What-If Analysis DataTable). Excel stores data tables as CSE array formulas whose body holdsTABLE(rowRef, colRef); formerlyTABLEwas unrecognised and fell through to#NAME?. The function is registered with a synthetic ptg (ftabTABLE = 4232) such that it round-trips through BIFF8 formula encoding, and at eval time returns a placeholder value (0) — the real results are pre-computed by Excel and stored as cached cell values, so HotXLS doesn't re-evaluate the substitution logic
Version 2.153.0
Added
- The PivotTable typed model now bears the page-axis typed properties (Hier / Caption / Name), the auto-sort scope, and the raw-XML round-trip hooks for
<formats>and<extLst>needed for fuller Excel compatibilityTXLSPivotFieldgainsPageHier/PageCaption/PageName(F16 — OLAP hierarchy name + page-axis caption + display name) andAutoSortScope(F20 — an A1 range reference pinning the cells Excel uses to auto-sort the field's items);TXLSPivotTablegainsFormatsXml/ExtLstXml(F17 — raw inner-XML round-trip for the<formats>CF / number-format overrides block and the<extLst>slicer / timeline / x14 block, emitted verbatim when set, so round-trip is safe even across engine versions). The XLSX writer emits the matching<pageField hier=... cap=... name=.../>attributes, the<autoSortScope>child of<pivotField>, and the<formats>+<extLst>blocks ahead of the closing sentinel - The formula tracer now records per-step operand-stack captures, enabling a true step-through "Evaluate Formula" debugger
TXLSFormulaStepgainsStepKind(push / reduce / function),StackBefore/StackAfter(comma-separated captures of the operand stack at the moment each step started / finished), andTokenStart/TokenEnd(1-based character span pinning the step back to the source formula)TXLSFormulaTracergainsTraceReversed(returns the same steps in reverse evaluation order — useful for a step-back UI that walks from the final result towards the original operands) and aStepCountproperty. Hitherto the tracer recorded only Depth / Source / Expression / Value and carried no stack state - HTML export now embeds per-cell images via a new
OnCellImagecallback onTXLSHTMLExportand a newxhImagesoption. When the option is set and the callback is wired, the exporter asks the implementer for each cell's<img>fragment (typically a Base64 data-URI) and appends it after the cell text. This decouples the exporter from the XLS engine's BIFF8 image storage (which lives in the per-sheet MsoDrawing record) such that the exporter doesn't have to parse anchors itself. The XLSX engine's HTML export already embedded images; this closes the gap for the XLS engine - RTF import now applies character properties (bold / italic / underline / strikethrough / size) from the RTF control words to the destination cell's font
TXLSRTFImporttracks\b/\i/\ul/\strike/\fsacross the document and pushes the dominant run's formatting into the cell's XF at commit time. A freshImportCharFormatproperty (default True) switches the behaviour; set False to reinstate the legacy text-only import. Multi-run cells collapse to a single XF (the last active run wins) because the XLS engine's cell API operates at cell level rather than per-fragment — yet this is far better than discarding all formatting, as the legacy importer did - A new
TXLSHTMLImportclass parses HTML tables into worksheet cells. Walks the first<table>in the source, emitting one worksheet row per<tr>and one cell per<td>/<th>. Honourscolspan/rowspan(an Excel-style merge), strips tags inside a cell (collapsing nested formatting to plain text), decodes the five standard character entities (&/</>/"/'/ ) and the numeric&#NNN;/&#xNN;forms, and coerces clean numeric strings to Double such that imported tables stay computable. Designed for the output HotXLS itself produces (SaveAsHTML) plus general copy-paste-quality HTML tables; not a full HTML5 parser
Version 2.152.0
Added
- XLSX tables now keep column-level totals metadata and table formulas
TXLSXTablesurfacesColumnTotalsRowFunctions[],ColumnTotalsRowLabels[],ColumnCalculatedColumnFormulas[], andColumnTotalsRowFormulas[];SaveAsemits the matchingtotalsRowFunction,totalsRowLabel,calculatedColumnFormula, andtotalsRowFormulatable-column XML,Openingests them back, and table clones preserve them
Version 2.151.0
Added
- The PivotTable typed model now bears the per-field filter collection, the multi-select toggle, the fieldGroup discretePr + groupItems surface, and the calculated items / calculated members model needed for fuller PivotTable compatibility
TXLSPivotFieldgains a typedTXLSPivotFilterscollection (each entry carriesFilterTypeacross the 80-member OOXMLST_FilterTypeenum — count / percent / sum / caption / value / date families — plusValue1/Value2/StrValue1/StrValue2,EvalOrder,DataField,MemberPropertyId,Name,Description), aMultipleItemSelectionAllowedtoggle (F9), and aTXLSPivotCalculatedItemcollection (F14)TXLSPivotCacheFieldgainsDiscreteIndices[]+AddDiscreteIndexandGroupItemLabels[]+AddGroupItemfor the fieldGroup discretePr + groupItems blocks (F13)TXLSPivotTablegains aTXLSPivotCalculatedMembercollection (F14). The XLSX writer emits the matching<pivotField multipleItemSelectionAllowed="1">, the per-field<filters><filter .../>block, the<fieldGroup><discretePr>...</discretePr><groupItems>...</groupItems></fieldGroup>element, the per-field<calculatedItems>block, and the table-level<calculatedMembers>block — so by code built pivots with filters / multi-select / grouping / calculated items round-trip
Version 2.150.0
Added
- Defined names now keep their formula text valid whenever the worksheet they reference is deleted or renamed. Deleting a sheet rewrites every
SheetN!qualifier inside a defined name's formula to#REF!(in line with Excel's behaviour); renaming a sheet updates the qualifier to the new name. Before this fix the formula text still pointed at a no-longer-existent sheet name, which Excel subsequently flagged as a broken link on reopen - The PivotTable typed model now bears the field-level sort order and layout toggles, plus the table-level layout / display attributes needed for fuller PivotTable layout compatibility
TXLSPivotFieldgainsSortType(manual / ascending / descending),Compact,Outline,SubtotalTop,DragToRow/DragToCol/DragToPage/DragToData,ShowAll,InsertBlankRow,NumFmtId;TXLSPivotTablegainsCompact/CompactData/Outline/OutlineData/Indent/ShowEmptyRow/ShowEmptyCol/ShowHeaders/ShowDrill/EnableDrill/FieldListSortAscending/GridDropZonesplusRowHeaderCaption/ColHeaderCaption/ErrorCaption/MissingCaption/ShowError/ShowMissingand the page-axis layout pairRowPageCount/ColPageCount. The XLSX writer emits the matching<pivotField sortType=... compact=... outline=...>and<pivotTableDefinition indent=... outline=... showEmptyRow=...>attributes and the<location rowPageCount=... colPageCount=.../>element so by code built pivots carry the user-set layout in place of Excel's defaults - A new
FormulaIsVolatilemethod onTXLSWorkbookreports whether a formula would force a recalculation on every calc pass — i.e. it calls a volatile function (NOW / RAND / TODAY / OFFSET / INDIRECT) or carries an unresolvable reference. The probe shares the same dependency extractor the recalc engine uses, such that the answer matches whatRecalculateactually does. Callers can use it to flag cells for a verification UI, to populate a calc-chain volatile set on a brand-new workbook, or to omit caching the result of a freshly-entered formula
Version 2.149.0
Added
- PivotTable stores can now stand refreshed from their source range by code. A new
RefreshPivotCache(ACacheId)method onTXLSXWorkbookre-scans the cache's source range, reconstructs the shared-items domain per field (re-deduplicating values and re-deriving the per-type caps), and rewrites the per-record item indices. Previously HotXLS relied on the hardcodedrefreshOnLoad="1"flag and put off all refresh work until Excel's next open; programmatic pipelines may now refresh in-process
Version 2.148.0
Added
InsertColson the XLSX engine now takes its column width from the left-hand neighbour, in line with Excel's default behaviour for "insert column". Before this the inserted column picked up the workbook's default width, producing a visible fidelity gap after a reopen- The XLSX engine gains convenience outline-collapse helpers
ToggleColGrouped/ToggleRowGroupedonTXLSXWorksheet, which walk the outline tree and collapse or expand the group at a given level. The collapse flags themselves already round-tripped; this introduces the missing walk-the-tree convenience API
Version 2.147.0
Added
- HTML export now emits
<a name>anchors at cells that are internal-hyperlink targets, so#SubAddresshyperlinks resolve as expected when the reader clicks them. Previously the links were emitted but the targets had no anchors, so internal jumps resolved to nothing - CSV export gained a
CSVEmitFormulasproperty onTXLSXWorkbook. When True, formula cells export their formula text (=SUM(A1:A2)) in place of the calculated value — useful for debugging and for pipelines that re-import into a different engine - External hyperlink URLs are now percent-encoded on write (
XlsxEncodeHyperlinkUrl): space, angle brackets, quotes, braces, pipes, backslashes, carets, and backticks are written as%XXin the<Relationship Target="..."/>attribute such that the file opens as expected in every browser. Existing percent-encoded sequences (%20) are retained as-is - PivotTable style info now bears the full
pivotTableStyleInfosurface:StyleName,ShowRowHeaders,ShowColHeaders,ShowRowStripes,ShowColStripes,ShowLastColumnonTXLSPivotTable. The XLSX writer emits the matching element so by code built pivots carry the user-chosen banding style in place of the hardcoded default - A new
CalculateAndVerifymethod onTXLSXWorkbookre-evaluates each formula cell and compares the computed result with the cell's cached value. It returns the count of mismatches (0 = every cached value matches the engine's fresh computation; volatile formulas are excluded). Handy for QA when porting workbooks between engines or confirming that a writer did not corrupt cached values
Version 2.146.0
Added
- The XLSX engine now caters for iterative circular-reference calculation (Excel's iterative calc mode). A new
Iterate/IterateCount/IterateDeltaproperty triple onTXLSXWorkbookcontrols the behaviour: whenIterate=Trueand a reference cycle is detected duringRecalculate, the engine re-evaluates cycle-member cells up toIterateCounttimes (default 100) or until every cell's change is< IterateDelta(default 0.001), in place of returning#REF!. The settings round-trip through OOXML's<calcPr iterate="1" iterateCount="N" iterateDelta="X"/>element. Financial models with intentional circular references (interest-on-interest, circular allocations) now converge in place of erroring - PivotTable cache fields now bear a grouping model for numeric-range and date-hierarchy grouping
TXLSPivotCacheFieldgainsHasGroup+GroupStartNum/GroupEndNum/GroupInterval(numeric range) andGroupByDate/GroupDays/GroupMonths/GroupQuarters/GroupYears/GroupHours/GroupMinutes/GroupSeconds/GroupStartDate/GroupEndDate(date). The XLSX writer emits the<fieldGroup><rangePr groupBy="range|days|months|..."/>element so by code built pivots with grouped fields match Excel's output - HTML export now emits comment endnotes. When
xhCommentsis in the export options, each commented cell gets a[n]superscript link, and the full comment text (author + body) is listed as an endnote section after the table with a back-anchor pointing to the cell. Previously, comments were only available via the cell'stitle=attribute, which is invisible when printed or copy-pasted
Version 2.145.0
Added
- BIFF8 formula error literals (
tErrtoken) now decode into a typedSA_ERRORsyntax item in place of failing the formula parse. A cell storing=#N/A(or any of the seven Excel error constants) formerly caused the whole formula to be dropped on read; the error byte now round-trips through read → evaluate → write and reconstructs to its text form (#NULL!,#DIV/0!,#VALUE!,#REF!,#NAME?,#NUM!,#N/A) via a newXlsErrorToStringhelper - The BIFF8
tIsect $0Ftoken (implicit intersection operator) now unravels in the binary-formula translator, building the sameSA_ISECTnode the text parser produces for@. Previously a binary formula containingtIsectwould fail to parse - Data bar conditional formatting now emits the Excel 2010+
x14extension block in the worksheetextLstwhen the model carries any non-default x14 field (negative fill colour, gradient off, axis colour, direction, border). A newBuildDataBarExtXmlconstructs the<x14:conditionalFormattings>extelement bearing the matching priority, cfvo pair, fill + negative + axis colours, plus the gradient/border/direction/negativeBarColorSameAsPositive attributes
Version 2.144.0
Added
- The XLSX engine can now write Agile-encrypted workbooks (
TXLSXWorkbook.SaveAsEncryptedAgile), closing a high-value read/write compatibility gap. Agile is what Excel 2010+ records by default for password-protected .xlsx files; HotXLS could formerly read Agile but only write Standard Encryption (AES-128). The new write pipeline mirrors the existing decrypt path: SHA-512 password hashing with a 100000-iteration spin count, AES-256-CBC per-segment package encryption, a randomly generated intermediate key wrapped per the three spec-pinned block keys, and a complete<encryption>descriptor XML carrying the encrypted verifier + key blobs. The output is byte-faithful to what Excel produces and round-trips without issue throughXlsLoadAgileEncryptedFile(verified by test: correct password decrypts, wrong password rejected) - New cryptographic primitives underpin the Agile write path:
XlsHMACSHA512(RFC 2104, needed for thedataIntegrityelement),XlsBase64Encode(RFC 4648 encoder mirroring the existing decoder), andAESEncryptCBC(AES-CBC encrypt for any key size 128/192/256, the inverse of the existingAESDecryptCBC). The AES unit now brings inaes_encrypt_key192/aes_encrypt_key256from the Gladman obj (formerly only 128-bit encrypt was available)
Version 2.143.0
Added
- The formula evaluator now interprets and evaluates the explicit intersection operator
@(Excel 365 dynamic-array syntax, e.g=A2:A4 @ B2:B4). The lexer emits a newLT_ISECTtoken for the@symbol, the precedence parser constructs anSA_ISECTnode (binding tighter than^, looser than%), and a newIntersectRangesevaluator resolves both operands as ranges and returns the value of the single crossing cell — Excel's implicit-intersection rule. The BIFF token serialiser emitstIsect $0Fsuch that the operator round-trips through XLS, and the formula-text reconstruction path emits the implicit-space form. Previously such formulas failed to parse - A standard Base64 encoder (
XlsBase64Encode) is now available, mirroring the existingXlsBase64Decode. It is the prerequisite for the Agile-encryption write path, which writes out saltValue / encryptedVerifierHashInput / encryptedKeyValue / encryptedHmacValue as Base64 attribute values - The workbook's
OnProgressevent now, in addition, fires during full recalculation (Recalculate), with a newxlsxProgressCalculatingphase. Beforehand the event fired only during reading and writing, so lengthy full-recalcs gave the UI no heartbeat. The event fires roughly every 4% of cells so as to avoid flooding - The extended document properties (
docProps/app.xml) now round-trip three more fields Excel records for password-protected / template-based documents:Manager,Template, andDocSecurity(a bitmask: 1=password-protected, 2=read-only recommended, 4=read-only enforced, 8=annotation-locked)
Version 2.142.0
Added
- The PivotTable typed model now bears the metadata, source, calculated-field, "show values as", and shared-items-caps surface that the previous round of analysis flagged as gaps
TXLSPivotCachegainsRefreshOnLoad/RefreshedBy/RefreshedDate/MissingItemsLimit/CreatedVersion/RefreshedVersion/MinRefreshableVersion/EnableRefresh/BackgroundQuery/SaveDataplus a typed worksheet-source shape (SourceName/SourceRelId/SourceIsNamedRange);TXLSPivotCacheFieldgainsFormula/DatabaseField/MemberPropertyField(calculated fields) and the shared-items caps (ContainsBlank/ContainsInteger/ContainsString/ContainsNumber/ContainsDate/MinValue/MaxValue/MinDate/MaxDate/HasBounds);TXLSPivotDataFieldgainsShowDataAs/BaseField/BaseItemfor the "show values as" transforms (percent-of / difference / running-total / index). The XLSX writer, (BuildPivotCacheDefinitionXml/BuildPivotTableXml) honours all of these so a by code built pivot (AddPivotTable) emits a richerpivotCacheDefinition+pivotTableDefinition— refreshOnLoad / version triple / refreshedBy / named-range source / calculated cacheField formula / sharedItems caps / dataField subtotal + showDataAs. Pivot tables read from a file continue to round-trip their raw XML verbatim - Image anchor behaviour now round-trips via a new
AnchorTypeproperty onTXLSXImage(xaTwoCell= move and size with cells,xaOneCell= move but don't size,xaAbsolute= don't move or size). The writer picks the anchor element (xdr:oneCellAnchor/xdr:twoCellAnchor editAs=.../xdr:absoluteAnchor) to match; the reader parses the element name +editAsattribute back. Maps to Excel's right-click → Size and Properties → Properties dialogue - Header/footer now round-trips even/first-page differentiation
TXLSXWorksheetgainsEvenHeaderText/EvenFooterText/FirstHeaderText/FirstFooterTextplus the four<headerFooter>toggles (DifferentOddEven,DifferentFirst,ScaleWithDoc,AlignWithMargins). Files in which the user enabled "Different odd and even pages" or "Different first page" no longer lose the even/first-page sections on round-trip - Page setup now round-trips the extended
<pageSetup>attributes Excel records for non-default print setups:Copies,FirstPageNumber+UseFirstPageNumber,HorizontalDpi,VerticalDpi,PrintErrors(displayed/blank/dash/NA),UsePrinterDefaults <sheetFormatPr>now round-tripscustomHeight,zeroHeight,outlineLevelRowandoutlineLevelCol, so files in which the user set a user-pinned default row height, hidden-default rows, or a default outline level no longer lose that behaviour- Data bar conditional formatting round-trips the standard
gradientattribute (gradient vs. solid fill), andTXLSDataBarSpecgains the Excel 2010+x14extension fields (NegativeBarColor,NegativeBarColorSameAsPositive,GradientFill,AxisColorwith theme/tint,Direction,Border) on the model so API consumers can set them - Comment balloons round-trip their VML drawing verbatim. The reader captures
xl/drawings/vmlDrawingN.vmlas-is and the writer replays it on save (in place of the built-in yellow-balloon template), such that each balloon's user-set position / size / fill colour / visibility withstands - Comment bodies round-trip per-run formatting
TXLSXCommentgains a lazyRichText: TXLSXRichTextpayload (reusing the shared-strings run model); the writer emits one<r><rPr>...</rPr><t>...</t></r>per run when RichText carries formatting, and the reader parses<b/>,<i/>,<sz val=N/>,<color rgb=.../>back so bold / italic / size / colour withstand - The formula evaluator now realises
SUBTOTAL(all eleven aggregators: AVERAGE / COUNT / COUNTA / MAX / MIN / PRODUCT / STDEV / STDEVP / SUM / VAR / VARP, alongside the 101–111 ignore-hidden variants) andAGGREGATE(nineteen aggregators with the option-code 0–7 flags that select error/hidden skipping, spanning the LARGE / SMALL / MEDIAN / PERCENTILE / QUARTILE family with theirkargument). Both formerly fell through to the unsupported-function path;SUBTOTALwas registered but had no implementation,AGGREGATEwas not registered at all - The
CELLandINFOworksheet functions are now evaluated:CELLsupportsaddress,col,row,type,contents,filename,format, and the GUI-stateinfo_types (color,parentheses,prefix,protect,width) return neutral defaults;INFOsupportsosversion,system,recalc,memavail,numfile,release,origin. Both were registered but fell through to#NAME? - Conditional formatting now round-trips the
stopIfTrue,stdDev,equalAverageandtimePeriodcfRuleattributes, plus the full ten-membertimePeriodfamily (yesterday / today / tomorrow / last7Days / lastWeek / thisWeek / nextWeek / lastMonth / thisMonth / nextMonth). These were quietly dropped on read; Excel records them routinely on the above-average and date-band rules, and dropping them changed how the rule re-evaluated on reopen - CSV export gained a
TXLSCsvEncodingproperty onTXLSCSVSaverwith three modes:ceSystemAnsi(legacy default),ceUtf16(the historical Unicode mode), andceUtf8which records a UTF-8 file with the EF BB BF byte-order mark — the modern Excel-friendly default that reopens without the text-import wizard on any locale - CSV import gained a
LocaleTolerantNumbersproperty onTXLSCSVLoader. When enabled, a numeric field that fails to parse with.as the decimal separator is retried with,(and vice versa), such that a European3,14imports as the number 3.14 on a US machine. Strict mode (the default) is unaffected, so leading-zero text, postal codes and other comma-bearing tokens remain text
Fixed
- The XLSX engine's strict-mode number inference no longer coerces comma-bearing text fields (e.g
3,14) into numbers via Delphi'sTryStrToFloat, which tolerates a comma as a thousand separator even whenThousandSeparatoris set to#0. Such fields now stay text unless the newLocaleTolerantNumbersoption is enabled
Version 2.140.0
Changed
- The XLSX engine now compacts its six per-attribute style pools (Fonts / Fills / Borders / NumberFormats / Alignments / Protections) prior to every save: a new
CompactStylePoolspass scans every cell's style indices and drops pool entries that are no longer referenced by any cell — the entries that accumulate when cells are cleared, deleted, or re-styled after the pool entry was first added. The compacted pools produce a smaller<cellXfs>table in the output file (typically 30–70% smaller for documents that have been through several edit cycles), in line with the compaction the XLS engine already does viaCreateAllReferredList
Version 2.139.0
Added
- Drawing-layer shapes, connectors, group shapes, and non-chart graphic frames now round-trip verbatim: whenever the XLSX reader encounters a
<xdr:sp>,<xdr:cxnSp>,<xdr:grpSp>, or non-chart<xdr:graphicFrame>anchor that the typed model (images / charts / text boxes) does not cover, it captures the complete anchor XML and replays it unchanged on save — such that drawings authored in Excel (arrows, callouts, grouped shapes, smart art frames) withstand a read→write cycle without loss. Each worksheet surfacesRawDrawingAnchorCount/RawDrawingAnchor(i)for inspection
Version 2.138.0
Added
- External link cached cell values now round-trip on the XLSX engine: a new
TXLSXExternalCell/TXLSXExternalRow/TXLSXExternalSheetDatamodel hangs off eachTXLSXExternalLinkviaAddSheetData/AddRow/AddCell, the writer emits the matching<sheetDataSet>block insideexternalLinkN.xml, and reopening restores every cached valueFindCachedCell(sheetIdx, row, col)looks up the last-known value of an externally referenced cell — the data Excel itself displays when the remote workbook is offline
Version 2.137.0
Added
- The OOXML cellXf
quotePrefixflag — Excel's mechanism for marking stored text as a literal such that it withstands numeric coercion (CSV-imported codes like00123, long account numbers, or anything the user prefixed with an apostrophe) — now round-trips on the XLSX engine:TXLSXAlignmentgains aQuotePrefixproperty, the alignment pool dedup counts it, the writer emitsquotePrefix="1"on the matching<xf>, and reopening restores it whether the cellXf carried a child<alignment/>or was a bare self-closing<xf quotePrefix="1"/>
Version 2.136.0
Added
- Chart axes are now fully programmable: a new
TXLSXChartAxismodel on each chart'sCategoryAxisandValueAxissurfacesLogBase(logarithmic scale, e.g. 10 for base-10 log),Orientation(normal / reversed),MajorGridlines/MinorGridlines,MinValue/MaxValue(NaN = auto),MajorUnit/MinorUnit,CrossesAt,TickLblPos, andDispUnits(display units: hundreds / thousands / millions / billions / trillions). All default to Excel's auto behaviour, so existing charts emit the same XML as before; the writer introduces<c:logBase>,<c:orientation>,<c:majorGridlines>,<c:majorUnit>,<c:crossesAt>,<c:tickLblPos>, and<c:dispUnits>only when the caller sets a non-default value, and reopening such a chart brings back every setting
Version 2.135.0
Added
- Chart error bars are now programmable and round-trip on the XLSX engine: each
TXLSXChartSeriesgainsAddErrorBar(dir)returning aTXLSXChartErrBarwithValueType(fixed / percentage / stdDev / stdErr / custom),Value,PlusValue/MinusValue(custom), andNoEndCap; one error-bar slot per direction (X / Y) is held, the writer emits the matching<c:errBars>block, and reopening restores the direction, type, and magnitude such that scientific / engineering charts keep their uncertainty indicators
Version 2.134.0
Added
- Chart data labels are now programmable and round-trip on the XLSX engine: each
TXLSXChartSeriesgainsShowValue,ShowCategoryName,ShowSeriesName,ShowLegendKey,ShowPercent,ShowBubbleSize, andSeparatorproperties that emit the matching<c:dLbls>block with its<c:show*/>children; reopening such a chart restores the switches so 'show value' / 'show percent' settings withstand a save-edit-save cycle
Version 2.133.0
Added
- Vector image formats EMF and WMF are now first-class image types within the XLSX engine:
TXLSXImageFormatgainsxlsxImageEmf/xlsxImageWmf, the writer emits the matchingimage/x-emf/image/x-wmfcontent types and.emf/.wmfextensions, and the format sniffer recognises EMF (01 00 00 73), placeable WMF (D7 CD C6 9A), and standard WMF headers — such that images pasted from Word or PowerPoint that Excel embeds as vector data now round-trip in place of being dropped
Fixed
- BIFF8 chart substreams whose GELFRAME record (
$1066) spans the 8224-byte continuation boundary no longer lose fill/line geometry: the reader now takes GELFRAME self-continuation (Excel records another$1066in place of the standard$003CCONTINUE) and also lets standard CONTINUE records stitch inside chart context, in line with the writer's existing multi-chunk dispatch - BIFF8 header/footer background pictures (
$0866) whose payload spans continuation records no longer corrupt: each continuation segment repeats a 14-byte MSO header that the reader now strips before concatenating, such that the embedded image data is no longer shifted by 14 bytes per segment
Version 2.132.19
Fixed
- Legacy XLS and encrypted XLSX storage cleanup now releases compound-file streams deterministically, preventing temporary files from staying locked after save, open, VBA, or encrypted-package operations
- Formatted display of extended integer variant values now applies the requested number format uniformly, in line with the existing behaviour for standard integer values
- Shared strings, data validation, chart sheets, ZIP archives, PNG drawing, and repeated text formulas now release temporary buffers more defensively on error paths and large text operations
Version 2.132.18
Fixed
- Internal string-builder value assignment now clears prior text when handed an empty string, preventing reused XML and text buffers from holding stale content
Version 2.132.17
Fixed
- XLS chart sheet creation now takes quoted source sheet names that contain an exclamation mark, refuses oversized row references before they can wrap into a valid BIFF row, and caps trendline legend names to the BIFF short-text limit so generated chart records stay well formed
Version 2.132.16
Fixed
- Internal string-key and object-key lists now strip out stale lookup keys when an existing slot is overwritten, preventing old keys from resolving to replacement entries
- Internal object-list replacements and transformed unique-key stores now release owned entries on overwrite, clear, and destruction, preventing leaks during repeated workbook and style operations
Version 2.132.15
Fixed
- Direct XLSX streaming ingests now decode boolean cells that store OOXML literal values such as true and false
- Internal string-list index updates now strip out stale keys when an existing slot is overwritten, preventing old names from resolving to the new value
Version 2.132.14
Fixed
- BIFF8 data-validation prompt and error messages whose first character is NUL now keep record boundaries in place of writing a mismatched DV length
Version 2.132.13
Fixed
- XML text parsing now refuses nested entity starts such as && in place of quietly dropping the unfinished entity
- Decompiled formulas now record numeric constants with an invariant dot decimal separator so formula text remains portable across regional settings
Version 2.132.12
Fixed
- Palette PNG transparency now ignores transparent colours that are not surface in the image palette in place of marking an arbitrary palette index as transparent
- SUMPRODUCT formulas now halt scanning remaining rows after the first out-of-used-range row in long range arguments, avoiding unnecessary cell ingests whilst preserving the calculated result
Version 2.132.11
Fixed
- TEXT formulas now return #VALUE! when an invalid or oversized number format cannot be applied in place of being swallowed as a blank successful result
- Shared-string table truncation now releases the correct tail blocks and leaves the table reusable after large delete cycles
Version 2.132.10
Fixed
- MATCH exact lookups now honour Excel wildcards, and classic XLS row-offset metadata now ignores out-of-block rows in place of corrupting saved workbook structure
- PNG compressed text metadata now releases temporary buffers without risk if chunk processing fires
Version 2.132.9
Fixed
- PNG compressed-text metadata, chunk-list insertion, and CRC byte-order handling now stay stable across supported Windows platforms
Version 2.132.8
Fixed
- LEFT and RIGHT formulas now surface #VALUE! when num_chars cannot be converted to a valid integer
Version 2.132.7
Fixed
- SEARCH formulas now cater for Excel-style ?, *, and ~ wildcards
- Worksheet name validation now refuses invalid Excel sheet-name characters when renaming sheets
- Manual page-break deletion now works once a break is inserted ahead of existing breaks
Version 2.132.6
Fixed
- DATE formulas now mirror Excel-compatible month and day rollover behaviour, covering calls such as DATE(2008,14,2)
- Column-range Hidden ingests now surface each column's visibility in place of mixing in row visibility state
- BIFF row metadata at the Excel 97-2003 row limit now ingests as expected so settings for row 65536 are retained
Version 2.132.5
Fixed
- BIFF workbook loading now tolerates malformed worksheet tab colours, truncated pivot labels, and invalid pivot-cache date fragments without raising exceptions
- Workbook package and stream loading now cleans up failed archive and storage setup paths more uniformly, avoiding leaked resources on malformed input or failed stream-backed storage opens
Version 2.132.4
Fixed
- ZIP archive handling now finalises the current package before reusing the same archive object for another package, and file-based archive opening now permits concurrent shared readers
Version 2.132.3
Fixed
- Workbook package writing now keeps non-ASCII ZIP entry names with UTF-8 metadata, preventing mojibake when package part names contain Unicode text
- XML output now records raw text and attribute values as UTF-8 bytes when escaping is disabled, in line with the declared document encoding
- Formula evaluation now clears its in-progress state after callback exceptions and as expected handles large-number cancellation on Unicode Delphi constructs
- Array-formula matrix extraction now respects non-zero Variant array lower caps in place of raising for valid one-based arrays
Version 2.132.2
Changed
- Range sorting now relies on a stable O(n log n) ordering pass on large sorted ranges, whilst preserving existing row content round-trip behaviour
- ODS and XLSX numeric parsing and formatting now re-use invariant formatting state in place of creating it repeatedly in hot paths
Fixed
- XML parsing now takes valid CDATA blocks and UTF-8 processing instructions without corrupting text or failing on valid markup
- Formula parsing now takes signed scientific notation and refuses malformed or truncated formula bytes without issue
- Classic workbook open and save paths now release streams and storages dependably after errors, preventing temporary files from remaining locked
- Binary buffer handling now validates copy and read caps, grows destination buffers before copying, and refuses malformed VBA compression back-references without issue
Version 2.132.1
Fixed
- Corrected the error message raised when an encrypted workbook uses an unsupported encryption scheme: it formerly claimed ECMA-376 Agile Encryption could not be read, although Agile decryption (AES-128/192/256) has been supported since 2.119.0. The message now lists the actually supported schemes
- Open now points callers at TXLSXWorkbook.OpenEncrypted when it refuses an encrypted OOXML package, in place of stating that encrypted workbooks are not supported
Version 2.132.0
Changed
- XLSX loading is substantially faster: the XML reader now interns repeated element names and converts text and attribute values straight from its scan buffer, cutting per-cell memory allocations by more than half. Multi-threaded opening (2.128.0) benefits the most — the allocations removed were the ones serialising the worker threads — with multi-sheet workbooks now opening close to twice as fast as the single-threaded path on multi-core machines; single-threaded opening also gains a few percent
Version 2.131.0
Added
- Worksheet extension blocks that HotXLS does not model —
<ext>entries in a worksheet's<extLst>other than sparklines, as written by Excel for features like x14 conditional formatting or slicers — are now preserved verbatim when a workbook is opened and written back on save, such that opening and resaving a file no longer strips those extensions. The captured blocks are visible read-only throughWorksheet.RawWorksheetExtsand travel with the sheet when it is copied to another workbook
Version 2.130.0
Added
- Saved workbooks that contain formulas now bear the
xl/calcChain.xmlcalculation-chain part, letting Excel seed its dependency engine from the recorded order in place of rebuilding it on open. After aRecalculatecall the chain follows the dependency graph's topological order; otherwise formula cells are listed in document order (a valid hint Excel refines on the fly). The part, its content type, and its workbook relationship are output together and withstand open/save round-trips
Version 2.129.0
Added
- New
Workbook.ParallelParseThreadsproperty tunes the worker count for the multi-threaded Open path introduced in 2.128.0 (0 = automatic, one worker per CPU core). Worksheet parsing allocates heavily and memory allocation is serialised across threads, so on some workloads a small explicit cap performs alongside — or better than — the full core count; the property lets integrators pick what measures best for their files
Version 2.128.0
Added
- Multi-threaded XLSX loading: on opening a workbook now interprets each worksheet's XML — the dominant cost on large files — on worker threads, so multi-sheet workbooks open faster on multi-core machines. Sheet parts are extracted from the package up front and each worker touches only its own sheet, such that the loaded workbook is identical to the serial result
- New
Workbook.ParallelParseproperty (defaultTrue) switches back to single-threaded parsing when set toFalsebeforeOpen— a one-line opt-out for constrained environments
Changed
- The
OnProgressreading callback still fires once per worksheet on the calling thread, now as each sheet is dispatched for parsing in place of strictly between sheets
Version 2.127.0
Added
- Incremental recalculation on the XLSX engine: the new
Workbook.Recalculatemethod constructs a formula dependency graph, evaluates every formula cell once in dependency order, and stores each result in the cell's cached value. Subsequent calls re-evaluate only the cells affected by value changes since the last pass — on chained models (financial sheets, report cascades) editing one input recomputes just its downstream formulas in place of the whole workbook - Volatile functions (
NOW,TODAY,RAND,OFFSET,INDIRECT) recalculate on every pass, as do formulas whose references cannot be resolved statically (multi-area names, external workbooks) — the engine over-recalculates in place of risk a stale result - Reference cycles are detected in place of looping:
Recalculatereturns an error code when formulas form a circular chain, omits the cycle members, and still evaluates every formula outside the cycle. Cross-sheet references, named ranges, and CSE array formulas (results spilt across the anchored range) participate fully in the dependency graph
Changed
- The existing on-demand
Calculatepath is unchanged;Recalculateis a separate opt-in API, and workbooks that never call it behave exactly as they did before
Version 2.126.0
Added
- Sparklines on the XLSX engine: worksheets now bear sparkline groups — the in-cell mini charts Excel renders from a data range — with the three Excel types (line, column, win/loss stacked). Create one with
Worksheet.AddSparklineGroupor build groups manually via the newWorksheet.SparklineGroupscollection, adding as many sparklines per group as needed, each with a source range and a display cell - Sparkline groups surface the full option set Excel offers: line weight, data-point markers, high/low/negative/first/last point emphasis toggles, eight ARGB colour slots (series, negative, axis, markers, first, last, high, low), per-group or per-sparkline vertical-axis scaling, and gap/zero/span handling for empty source cells
- Sparklines withstand a full save→open round-trip: saving emits the worksheet
extLstextension block ([MS-XLSX] §2.3.6) so Excel 2010 and later render the sparklines, and opening such a workbook — whether written by HotXLS or Excel — reconstructs every group, option, and range so they persist through edit cycles. Copying a sheet to another workbook clones its sparkline groups as well
Version 2.125.0
Added
- Seven DBCS byte-counting text functions now assess on both engines:
LEFTB,RIGHTB,MIDB,LENB,FINDB,SEARCHB, andREPLACEB. Each treats its input as a byte string under the system ANSI code page so CJK (Chinese/Japanese/Korean) characters occupy 2 bytes whilst ASCII occupies 1; operations that would split a DBCS lead/trail byte pair snap back to the nearest character boundary, matching Excel's behaviour
Version 2.124.0
Added
- Five hypothesis-testing and distribution functions now assess on both engines:
Z.TEST(one-tailed right-tail probability that the sample mean is at leastxunder the null hypothesis),T.TEST(paired two-sample t-test p-value; the unpaired equal/unequal-variance types are deferred),CHISQ.TEST(goodness-of-fit p-value via the upper-tail chi-square CDF),HYPGEOM.DIST(hypergeometric PMF/CDF with the cumulative flag), andNEGBINOM.DIST(negative-binomial PMF/CDF). The p-value maths re-uses the engine's existing normal/Student-t/chi-square CDF helpers via self-contained nested routines, so no existing Calc method changes
Version 2.123.0
Added
- Fourteen formula functions from a compatibility gap review now assess on both engines:
AVERAGEIF(single-criterion average, the SUMIF/COUNTIF sibling the engine was missing),WORKDAY.INTLandNETWORKDAYS.INTL(custom weekend masks via the 1-17 numeric codes or a 7-character Mon-Sun string),XIRRandXNPV(internal-rate-of-return and net surface value for irregular-date cash flows, solved by bracketing bisection),CEILING.PRECISE/FLOOR.PRECISE/ISO.CEILING(sign-agnostic rounding),PERCENTRANK.INC/PERCENTRANK.EXC(percentile rank with the matching inclusive/exclusive interpolation),MODE.MULT(spills every value tied for the highest frequency),ERF.PRECISE(Gauss error function via its alternating series),ACCRINT(accrued interest), andISPMT(period interest for constant-principal amortisation)
Version 2.122.0
Added
- Threaded comments (Excel 365) now round-trip on the XLSX engine:
AddThreadedCommentandAddThreadedReplyon a worksheet build a parent→child reply tree anchored at a cell, auto-registering every author on a fresh workbook-levelPersonslist, and emit the dedicatedxl/threadedComments/threadedCommentN.xmlpart per sheet plus the workbook-scopedxl/person/person.xml; reopening such a package reconstructs the conversation tree and participant list from those parts, such that reply chains, identifiers, and display names withstand a full read→write cycle
Version 2.121.0
Added
- The formula evaluator now calculates the Excel 365 dynamic-array functions
XMATCH,SORT,UNIQUE, andSEQUENCE, joining the already-supportedXLOOKUPandFILTER; results spill as 2-D arrays soSEQUENCE(3;2;1;1)returns a 3×2 grid,SORTreorders rows by any key column ascending or descending,UNIQUEcollapses duplicate rows keeping the first occurrence, andXMATCHreturns the 1-based position of a lookup value with the same exact/wildcard/next-smaller/next-larger match modes asXLOOKUP
Version 2.120.0
Added
- New
PasteFromClipboardmethod on both engines' worksheets ingests tab-delimited text off the Windows clipboard — the payload Excel places there when a range is copied, or a plain selection from any other application — and records it into cells starting at the given row and column, with the same number/date/boolean type promotion the CSV loader already uses; leading=text becomes a live formula, matching how Excel itself pastes
Version 2.119.0
Added
- Reading of ECMA-376 Agile Encryption — the password protection that Excel 2010 and later apply by default:
OpenEncryptednow interprets the XML encryption descriptor, derives the keys with SHA-512 spin-count hashing, verifies the password, and decrypts the AES-CBC segmented package (AES-128/192/256), such that workbooks password-protected directly in Excel open without Excel installed OpenEncryptedhandles all three cases through one entry point: plain unencrypted.xlsx, Standard Encryption (ourSaveAsEncryptedround trip), and Agile Encryption; a wrong password fires the same clear error in every scheme
Fixed
- Saving an
.xlsxworkbook whose worksheet XML topped roughly 116 KB — about 3,000 rows of typical string data — crashed with a stack overflow; the ZIP writer's CRC-32 checksum now processes data in 64 KB slices, which keeps the compression backend off its large-input code path that allocates an oversized scratch buffer on the stack. The checksum result is unchanged
Changed
- Shared-string deduplication now runs via a hash table in place of scanning the string list, and the
sharedStrings.xmlpart is assembled via the pre-grown string builder in place of repeated concatenation — together with the constant-time cell index this brings saving 120,000 string cells from tens of seconds down to about a third of a second
Version 2.117.0
Changed
- XLSX cell access is now constant-time: the worksheet cell collection carries a hash index over (row, column), replacing the previous linear scan — so populating, reading back, or loading a large sheet scales linearly with the cell count in place of quadratically; filling 100,000 cells now takes well under a second where it formerly took minutes
- The speedup applies across the engine:
Cells[r, c],HasCell, workbook loading, saving, cross-workbook copies, auto-fit, and every helper that touches cells by position all benefit; row and column insertion or deletion reconstructs the index in a single pass
Version 2.116.0
Added
- PDF export in the classic XLS engine: new
SaveAsPDFmethods on the worksheet and workbook render the used range (or a caller-supplied range viaTXLSPDFExport) as a paginated grid — cell display text via the number format, gridlines, column widths derived from the Excel widths and scaled to fit the page, and automatic multi-page pagination - The output is a self-contained PDF 1.4 file with no external dependencies, using the built-in Helvetica font with WinAnsi text encoding; portrait or landscape A4 orientation, page margin, and font size are all configurable on the exporter
- This is a data-presentation export alongside HTML and RTF: it reproduces tabular content and layout for reports and document handoff in place of full per-cell styling
Version 2.115.0
Added
- One-call chart creation from a data range in the XLSX engine: new
AddChartFromRangeconstructs a complete chart and derives its series automatically from a rectangular data block — the equivalent of Excel's "insert chart from selection" — with a series-in-columns or transposed series-in-rows layout - Named shortcuts
AddColumnChart,AddBarChart,AddLineChart,AddPieChart, andAddAreaChartchoose a chart type by name over the same one-call flow, reading series names from the header row and category labels from the first column - Series references are qualified with the source sheet's quoted name, such that a generated chart keeps working when placed on any sheet and withstands save and reload
Version 2.114.0
Added
- RTF import in the classic XLS engine, the inverse of the existing
SaveAsRTFexport: newOpenRTFmethods on the worksheet and workbook read an RTF document's table into worksheet cells, with\celladvances the column,\rowadvances the row — starting at A1 - Recovers tabular data from files produced by
SaveAsRTF, Word, or WordPad: numeric text is held as numbers so formulas keep working, hex (\'hh) and Unicode (\uN) escapes decode as expected, and header groups (font table, colour table, stylesheet, info) are skipped - Documents with no table fall back to paragraph mode, importing each
\paras the next row in column A
Version 2.113.0
Added
- Reading of encrypted
.xlsxworkbooks:OpenEncryptednow decrypts ECMA-376 Standard Encryption (AES-128) packages, completing the round trip alongside the existingSaveAsEncrypted— it ingests the compound-file container, derives the key from the password, verifies it, and opens the recovered workbook - A wrong password fires a clear "password is incorrect" error, and
OpenEncryptedon a plain unencrypted.xlsxcontinues to open it directly, such that callers can route every file through one entry point
Changed
- The unsupported-encryption message now cites ECMA-376 Agile Encryption specifically as the remaining unsupported scheme, since Standard Encryption reading and writing are both on offer
Version 2.112.0
Added
- New
TaggedTextproperty on XLSX cells converts between rich text and lightweight markup:<b>,<i>,<u>,<s>,<sub>,<sup>,<color=#RRGGBB>,<font=Name>, and<size=N>, with</>/&escapes — so multi-format cell content can be produced from a template string in place of assembling run objects by hand - Writing markup constructs the run list and keeps
Valueas the concatenated plain text; markup without tags stores a plain string with no rich payload; reading serialises each run's attributes as complete tag sets; unknown tags pass through as literal text
Fixed
- A rich-text run consisting entirely of whitespace (for instance a single styled space between words) now withstands save and reload; formerly the space was dropped when the file was reopened
Version 2.111.0
Added
- New
OnProgressevent on the XLSX workbook reports open and save progress: it fires once per worksheet as it is parsed duringOpenor emitted duringSaveAs, carrying the phase (reading or writing), the current 1-based sheet number, and the total — such that applications can drive a progress bar over long multi-sheet operations at negligible callback cost
Version 2.110.0
Added
- New
TXLSRowCursordataset-style row cursor for.xlsx/.xlsmfiles:Open,SelectSheet, thenFindFirst/FindNextwalk a worksheet one row at a time with only the current row's cells held in memory — a pull-driven alternative toTXLSDirectReader's callbacks for sequentially processing multi-million-row sheets - Each row surfaces its 1-based worksheet row number, the populated cells in document order (typed value, formula text, style index), and a
ValueByCollookup that returnsNullfor columns not populated on that row; rows with no populated cells are skipped - Sheet names and count ship after
Open(file and stream overloads), with shared strings and date-format detection dealt with in the same way as the streaming reader
Version 2.109.0
Added
- New
TXLSXCellFormat"format brush" for the XLSX engine: set out font, fill, border, alignment, number format, and protection once, then stamp any number of targets withApply(single cell),ApplyRange,ApplyRows,ApplyCols, orApplySheet - Only the aspects actually touched are set — a brush that sets just
Font.Boldleaves the targets' fills, borders, and number formats alone — so brushes compose with existing formatting like Excel's format painter - Each apply resolves the touched aspects into the workbook style pools once and then records only pool indices per cell, so formatting large ranges costs one pool lookup per aspect in place of per cell;
ApplyRangematerialises missing cells whilst the row/column/sheet forms stamp existing cells only
Version 2.108.0
Added
- Localisable boolean display text: the new
XLSBooleanTrueText/XLSBooleanFalseTextvariables govern how boolean cell values render wherever display text is produced —FormattedText, HTML export, and auto-fit measurement — such that localised applications can show for instance WAHR/FALSCH or VRAI/FAUX
Changed
- Boolean cells now display as
TRUE/FALSEby default, matching Excel's grid, in place of the runtime'sTrue/Falsecapitalisation
Version 2.107.0
Added
- New
OnPasswordevent on the classic XLS workbook: whenOpenmeets an encrypted workbook and the supplied password is missing or wrong, the event asks the application for a password and retries the open (up to three attempts) — so interactive tools can prompt the user in place of pre-loading passwords or inspecting error codes - The event receives the current password by reference and a
Retryflag; leavingRetryatFalsegives up and returns the original password error
Version 2.106.0
Added
- New
TXLSFileMonitorclass watches a workbook file on disk and firesOnFileChangedwhen another process — typically Excel — saves over it, such that applications can reload and refresh their view automatically - Polling-based (last-write time plus size,
IntervalMsconfigurable, 1 s default), such that it works on local disks and network shares alike without a message loop;SynchronizeEventpicks between main-thread delivery for UI handlers (default) and direct watcher-thread delivery for console or service code - A file that briefly vanishes mid save cycle does not fire a false event; the change is reported once the new content is in place
Version 2.105.0
Added
- Bounded auto-fit in the classic XLS engine, in line with the limits the XLSX engine already offers: new
AutoFit(Columns, AMin, AMax),ColumnsAutoFit(AMinWidth, AMaxWidth), andRowsAutoFit(AMinHeight, AMaxHeight)overloads clamp every fitted column width (Excel width units) or row height (points) to the given range — 0 leaves a side unbounded, and an all-empty column or row still gets the requested minimum
Version 2.104.0
Added
- New read-only
FormattedTextproperty returns a cell's display text — the stored value rendered through its number format, the way Excel renders it on the grid — covering thousands separators, decimals, percentages, date and time masks, multi-section positive/negative/zero masks, and boolean formats - Available in both engines: on
IXLSRangein the classic XLS engine (multi-cell ranges render their anchor cell) and onTXLSXCellin the XLSX engine (rich-text cells return their concatenated run text)
Version 2.103.0
Added
- New
DetectExcelContentFormatfunction (file name and stream overloads) identifies a workbook's container from its leading bytes in place of the file extension — reporting a BIFF/OLE compound file, an OOXML.xlsxpackage, an OpenDocument.odspackage, or plain delimited text — such that applications can route renamed or extension-less files to the right loader
Changed
TXLSWorkbook.Opennow sniffs the content signature and refuses ZIP-based packages (an.xlsxor.odsrenamed to.xls) with a clear message naming the right loader, in place of failing with an opaque error codeTXLSXWorkbook.Opennow identifies OLE compound-file content (a legacy.xlsrenamed to.xlsx, or an encrypted package) and reports what the file actually is, in place of surfacing a ZIP parser error
Version 2.102.0
Added
- Cross-workbook worksheet copy in the classic XLS (BIFF8) engine now brings the workbook-level defined names a formula uses over to the destination — the same thing Excel does when a sheet moves between workbooks: a name the destination already has is bound as-is (no duplicate is created), a missing name is registered with its original definition and visibility such that the formula recompiles against it, and a name whose definition cannot resolve in the destination (for instance, it points at a sheet that does not exist there) leaves the formula on its computed value as before
Version 2.101.0
Added
- Cross-workbook worksheet copy in the classic XLS (BIFF8) engine now re-points formulas at the source workbook as an external link when the destination has no sheet of the referenced name and the source has been saved to a file: the copied cell stays a live formula (its references switch to the [SourceBook]Sheet form), the source's computed value is kept as the cached result so ingests keep working until the link is refreshed, and the external workbook reference round-trips through save and reload; formulas carrying defined-name references, and copies from unsaved source workbooks, keep the computed value as before
Version 2.100.0
Added
- Array formulas now withstand worksheet copies in the classic XLS (BIFF8) engine: each array range is rebuilt as a whole in the copy — within the same workbook and across workbooks alike — with the root formula recompiled against the destination's sheet names; an array the destination cannot recompile keeps its computed values instead
Fixed
- Copying a range that holds array-formula cells between classic XLS worksheets no longer risks a crash on the spill cells (which carry no formula tree of their own); such cells now carry their computed value across
Version 2.99.0
Added
- Chart sheets can now stand copied between classic XLS (BIFF8) workbooks: the chart record stream is cloned into the destination, series category / value / name references are recompiled against the destination's sheet names (a series whose sheet has no same-name counterpart falls back to an empty reference such that the file still opens), chart font references migrate by value into the destination font table, and the page setup, tab colour, zoom, and visibility of the chart sheet come along; this removes the last documented limitation of the cross-workbook worksheet copy
Version 2.98.0
Added
- Cross-workbook worksheet copy in the classic XLS (BIFF8) engine now keeps rich-text formatting inside cells: each formatting run's font is migrated by value into the destination workbook's font table and the run is rewritten to point at it, so mixed-font strings keep their appearance in place of falling back to plain text; phonetic (Far-East) auxiliary data travels with the string as well
Fixed
- Fonts referenced only by rich-text runs (and not by any cell format) are no longer dropped from the FONT table when saving a classic XLS workbook, and the runs now follow the same font reordering as cell formats on save, such that rich-text strings keep the correct fonts after a save/reload cycle
Version 2.97.0
Added
- Cross-workbook worksheet copy in the classic XLS (BIFF8) engine now, in addition, clones embedded pictures: the image bytes migrate into the destination workbook's picture store (identical images are shared in place of duplicated), and each picture frame keeps its cell anchor, size, visibility, and transparent colour; a new CrossWorkbookCopyXls sample project showcases the classic-engine copy end to end
Changed
- Classic XLS cross-workbook copy limitations are now documented: chart sheets are not copied (AddCopy returns nil for them), and a formula whose sheet reference has no same-name sheet in the destination keeps the source's computed value in place of becoming an external reference
Version 2.96.0
Added
- Cross-workbook worksheet copy in the classic XLS (BIFF8) engine now, in addition, clones conditional formats (cell-is and expression rules, data bars, colour scales, icon sets, and their differential styles), data validations (list, numeric, date, text-length, and custom rules with prompt and error boxes), the AutoFilter definition with its per-column criteria (the dropdown buttons are rebuilt in the copy), and tables (ids and names are re-issued so they stay unique in the destination workbook); rule formulas are recompiled against the destination's sheet names, in line with the behaviour of cell formulas
Version 2.95.0
Added
- Classic XLS (BIFF8) worksheets can now stand copied from one workbook into another: TXLSWorksheets.AddCopy introduces a new sheet to the destination workbook and copies the source sheet's cell values, formulas (re-encoded as text such that the destination recompiles them against its own sheet names, keeping same-name 3D references live), merged cells, comments, hyperlinks, row heights, column widths, outline levels, frozen panes, sheet protection, page setup, manual page breaks, tab colour, and view settings; cell, row, and column formats are migrated by value into the destination workbook's format table, such that a styled source produces an on its own styled copy
- Cross-workbook format migration in the classic XLS engine now bears the full-precision RGB and theme colours alongside each format entry, so fills, fonts, and borders keep their exact colours in place of falling back to palette approximations; this also applies to range-level paste between workbooks
Version 2.94.0
Added
- Cross-workbook worksheet copy now clones conditional formats (with their differential styles and the dataBar / colorScale / iconSet visual payloads), tables, data validations, and charts (with every series); each sub-object deep-copies its own state into the target worksheet
- Cross-workbook formula references are rewritten: a reference whose sheet name exists in the destination resolves as-is, otherwise it becomes an external reference back to the source workbook (which is registered as an external link) or #REF! whenever the source has no file identity; the rewrite applies to cell formulas, conditional-format rules, data-validation formulas, and chart series ranges alike
Version 2.93.0
Added
- A worksheet can now stand copied from one workbook into another: TXLSXSheets.AddCopy introduces a new sheet to the destination workbook and copies the source sheet's cells, formulas, merged ranges, column/row sizing, hidden/collapsed/outline flags, freeze panes, view state, protection, page setup, AutoFilter range, and tab colour onto it; the six per-cell style indices are remapped into the destination workbook's own Font/Fill/Border/NumberFormat/Alignment/Protection pools via value-equality lookup, such that a styled source produces an on its own-styled copy in place of indices pointing at the wrong pool
- The six per-attribute style pools (Fonts, Fills, Borders, NumberFormats, Alignments, Protections) each surface a 1-based LookupOrAdd that de-duplicates by value; a new CrossWorkbookCopy sample project showcases the cross-workbook copy with style preservation
Version 2.92.0
Added
- XLSX workbooks now cater for pivot tables: TXLSXWorksheet.AddPivotTable scans a flat source range, auto-constructs a pivot cache, and returns a typed pivot table for row / column / page / data-axis wiring, mirroring the long-standing BIFF8 (XLS) engine API such that the same code targets either format; PivotSetDataFieldFormat assigns a number format to each aggregated value field
- Excel-created pivot tables round-trip without loss through Open then Save: the XLSX engine preserves each pivot cache definition, cache records, and pivot table part verbatim and replays the original bytes on save, so re-saving a workbook never drops or alters its pivots even when they use features the typed model does not surface
Version 2.91.0
Added
- A worksheet AutoFilter can now stand applied to the data such that the saved workbook opens with the non-matching rows already hidden, mirroring what Excel does when a value is picked from the filter dropdown
- Embedded images surface their geometry in real units (centimetres, inches, points) alongside the EMU values, and can be resized by a scale factor with optional aspect-ratio locking
- Page-setup margins can be set in centimetres directly, as a metric convenience alongside the inch-based margins
- Protected XLSX worksheets now surface fifteen fine-grained permission toggles (format cells, insert/delete rows and columns, sort, AutoFilter, select locked/unlocked cells, and more) via a new AllowOption property, matching Excel's Review > Protect Sheet checkbox list; the per-action settings round-trip via the file
- XLSX worksheets can now stand duplicated (TXLSXSheets.Duplicate): a new sheet is added and the source's cells, merged ranges, column/row sizing, freeze panes, view state, protection, page setup, and tab colour are copied onto it, mirroring Excel's right-click > Move or Copy > Create a copy
- Twenty-two new sample projects span the capabilities the library supports: workbook encryption, cell comments, hyperlinks, defined names, AutoFilter evaluation, embedded pictures, an invoice template, advanced XLSX conditional formatting, merged cells, row/column outlining, freeze panes, multi-sheet layout, array formulas, range copy/move, find/replace, date systems, rich text, advanced CSV, HTML export options, custom number formats, hidden rows/columns, and worksheet protection
Version 2.90.29
Changed
- The streaming direct reader now counts every populated cell even when no per-cell handler is attached, such that a plain ReadFile call can be used to size a worksheet quickly; the returned count and the CellCount property report the number of populated cells scanned
Version 2.90.28
Added
- Formulas can now stand evaluated step by step, the equivalent of Excel's Evaluate Formula command: a new tracer reduces an expression one sub-step at a time, innermost first, and reports each reduction with its source sub-expression, the same sub-expression after its operands are substituted by their values, and the resulting value, such that applications can show how a result is built up; it respects operator precedence, keeps range references intact for functions such as SUM, and re-uses the worksheet calculation engine so every step agrees with a full recalculation
Version 2.90.27
Added
- XLSX workbooks can now stand produced cell by cell via a new streaming direct writer that emits each worksheet straight into the package as rows arrive, without building a full in-memory cell tree, so very large files can be generated with a near-constant memory footprint; the writer handles inline strings, numbers, booleans, dates, and formulas across multiple sheets and round-trips with the streaming direct reader
Version 2.90.26
Added
- XLSX workbooks can now stand scanned cell by cell via a new streaming direct reader that fires per-cell and per-sheet events without building a full in-memory cell tree, keeping the memory footprint near constant for very large files; each reported cell carries its value, kind (number, string, boolean, date, or error), formula text, and style index, with optional date detection and early-abort support
Version 2.90.25
Added
- Classic XLS worksheets can now introduce hyperlinks from A1-style cell references whilst preserving URL normalisation, workbook-target subaddresses, display text, and screen tips
Version 2.90.24
Added
- Classic XLS page breaks can now stand added from one-based row or column positions and A1-style cell references through page-break collection and worksheet helper overloads
Version 2.90.23
Added
- Classic XLS worksheets and shape collections can now establish rectangle, oval, line, and typed autoshape drawing objects from A1-style range strings
Version 2.90.22
Added
- Classic XLS shape collections can now establish text boxes from A1-style range strings via an AddTextBox overload
Version 2.90.21
Added
- Classic XLS text boxes can now stand repositioned from A1-style range strings via a new SetArea overload
Version 2.90.20
Added
- Classic XLS worksheet text boxes can now stand created from A1-style range strings via an AddTextBox overload
Version 2.90.19
Added
- Classic XLS worksheets can now establish drawing text boxes directly from row and column anchors via a new AddTextBox method
Version 2.90.18
Added
- Classic XLS worksheets can now establish cell comments directly from row and column coordinates through new AddComment overloads