HotXLS Sürüm Notları
HotXLS kullanıcıya görünen özellikleri, düzeltmeleri, XLS/XLSX geliştirmeleri, dışa aktarma güncellemeleri, uyumluluk değişiklikleri ve dokümantasyon güncellemeleri için sürüm geçmişi.
[Unreleased]
Sürüm 2.88.111
- Classic XLS çalışma sayfaları artık bağımsız çizim TextBox nesnelerini destekler.
TXLSShapes.AddTextBoxile kendi satır/sütun bağlantısı, metin, text runs, çizgi/dolgu biçimi ve hücre yorumu oluşturmadan normal shape silme desteği olan birTXLSTextBoxoluşturabilirsiniz.
Sürüm 2.88.110
- ApiTour demoları artık daha fazla workbook otomasyon desenini kapsıyor. Delphi ve C++Builder ApiTour örnekleri
WriteCellsile callback tabanlı aralık yazmayı,ForEachCellile yüklenen hücreleri taramayı,FindTextveReplaceTextile şablon güncellemelerini, seçili aralığıApiTour-Range.htmldosyasına HTML olarak dışa aktarmayı ve Delphi'deOnUserFunctionüzerinden özel formül callback'lerini gösterir.
Sürüm 2.88.109
- QuickStart demoları artık daha eksiksiz bir ilk çalışma kitabı gösteriyor. Delphi ve C++Builder QuickStart örnekleri satır ve sütun toplam formülleri, dondurulmuş bölmeler ve eşleşen XLS/XLSX işlemleri içeren biçimlendirilmiş bir çarpım tablosu oluşturur; demo ağacında artık her örnek için düzenli HTML readme sayfaları da bulunur.
Sürüm 2.88.108
- XLSX aralıklar artık sahiptir doğrudan HTML dışa aktarma yardımcıları.
TXLSXRange.SaveAsHTML(FileName)andTXLSXRange.SaveAsHTML(Stream)dışa aktarma only the seçili XLSX aralık as a UTF-8 HTML tablo, sharing the çalışma kitabı HTML renderer's escaping, basic stil output, and merged-hücre span handling.
Sürüm 2.88.107
- XLSX çalışma sayfaları now include metin arama ve değiştirme yardımcıları.
TXLSXWorksheet.FindTextandTXLSXWorksheet.ReplaceTextscan yüklenmiş text hücreler in row-major order, skip formüller and non-text values, and destek optional case-sensitive matching for template workflows.
Sürüm 2.88.106
- BIFF8 Window2 görünüm bayrakları artık korur özel kılavuz çizgisi and donmuş bölme durumu. HotXLS now clears
fDefaultHdrwhenWindow2.icvHdrstores a özel kılavuz çizgisi color, korur Excel-authoredfFrozenNoSplitduring açma/kaydetme, and yazarfFrozenNoSplitforFreezePanesoutput.
Sürüm 2.88.105
- CF12 formül eşikleri now round-trip through BIFF8 Data Bar, Color Scale, and Icon Set rules. formül-based threshold values compile to CF12 formül token bytes on kaydetme and are restored to
TXLSCfValue.Valuewhen a çalışma kitabı is reopened.
Sürüm 2.88.104
- Classic XLS formüller and icon-set thresholds now emit tighter BIFF8 records. Integer constants in formüller use the compact
tInttoken when they fit the BIFF unsigned-integer aralık, andTXLSIconSetSpec.ThresholdEqualsInclude[Index]now controls the CF12 icon-set threshold equals byte so callers can choose include or exclude comparison semantics.
Sürüm 2.88.103
- Classic XLS çalışma sayfaları now include a text find yardımcı.
IXLSWorksheet.FindText(SearchText, Row, Col[, MatchCase])locates the first matching yüklenmiş text hücre, skips formüller and non-text hücreler, and clears the returned coordinates when no match is found.
Sürüm 2.88.102
- Classic XLS çalışma sayfaları now include a text replacement yardımcı.
IXLSWorksheet.ReplaceText(SearchText, ReplacementText[, MatchCase])replaces matches in yüklenmiş text hücreler, skips formüller and non-text hücreler, and reports the changed hücre count for template-filling workflows.
Sürüm 2.88.101
- aralıklar artık sahiptir doğrudan HTML dışa aktarma yardımcıları.
IXLSRange.SaveAsHTML(FileName)andIXLSRange.SaveAsHTML(Stream)dışa aktarma the seçili aralık through the existing HTML renderer, so callers no longer need to create aTXLSHTMLExportinstance or passxlHTMLexplicitly for common aralık fragments.
Sürüm 2.88.100
TXLSWorkbook.GetSheetNames(Stream, AList)now okur XLSX package streams as well as classic XLS streams. Applications can pass memory streams, database BLOB streams, or downloaded XLSX streams to the classic facade and receive ordered çalışma sayfası names without first saving to a file.
Sürüm 2.88.99
- çalışma sayfası lookup, hyperlink creation, and multi-area selection APIs are now easier to use. Classic XLS and XLSX sheet collections add
TryGetSheetByName, classic XLS çalışma sayfaları addAddHyperlinkconvenience overloads, andIXLSWorksheet.SelectAreascan yazmak active multi-aralık selections.
Sürüm 2.88.98
- Classic XLS çalışma kitapları now expose a
UserNamealias for the saved-by field.IXLSWorkbook.UserNamemaps to the same WRITEACCESS value asLastSavedBy, so code that uses theUserNamenaming convention can okumak and update the çalışma kitabı audit name directly.
Sürüm 2.88.97
- XLSX çalışma sayfaları now share the callback hücre scan and aralık yazmak yardımcılar.
TXLSXWorksheet.ForEachCellenumerates yüklenmiş hücreler in row order with value and formül text, whileTXLSXWorksheet.WriteCellsfills numeric or A1-stil aralıklar from a callback with per-hücre skip and cancellation.
Sürüm 2.88.96
- Classic XLS çalışma sayfaları now destek callback-driven aralık writing.
IXLSWorksheet.WriteCellsfills a 1-based numeric aralık or A1-stil aralık in row order, lets the callback provide each hücre value, destekler per-hücre skip, and can cancel long yazmak loops early.
Sürüm 2.88.95
- Classic XLS çalışma sayfaları artık yapabilir enumerate yüklenmiş hücreler through a callback.
IXLSWorksheet.ForEachCellwalks existing çalışma sayfası hücreler in row order, passes 1-based sheet, row, and column coordinates with value and formül text, and lets the callback cancel long scans early.
Sürüm 2.88.94
- formül calculation artık yapabilir call application-defined functions.
TXLSWorkbook.OnUserFunctionandTXLSXWorkbook.OnUserFunctionletCalculatedelegate özel or unsupported çalışma sayfası functions to application code, passing evaluated arguments and using the returnedVariantresult when handled.
Sürüm 2.88.93
- Classic XLS çalışma sayfası protection now exposes per-action permission flags.
IXLSWorksheeteklerAllowDeleteRows,AllowInsertRows,AllowFormatCells,AllowSort,AllowAutoFilter, and the remaining SheetProtect permission özellikler, with BIFF8 options written and okumak back through the existing protection records.
Sürüm 2.88.92
- Classic XLS VBA payloads artık sahiptir explicit load/kaydetme/clear yardımcılar.
IXLSWorkbook.LoadVBAProjectFromFile,SaveVBAProjectToFile,HasVBAProject, andClearVBAProjectexpose the preserved OLE VBA storage payload whileVBAProjectremains the parsed okumak-only module view.
Sürüm 2.88.91
- Classic XLS AutoFilter criteria artık yapabilir be inspected through a field collection.
IXLSWorksheet.AutoFilterColumnsexposes the current BIFF8 AutoFilter field count and 1-based field items, including active state, operator, and storedCriteria1/Criteria2DOPER values.
Sürüm 2.88.90
- Classic XLS çalışma sayfaları artık sahiptir one-call AutoFilter criteria setup.
IXLSWorksheet.ApplyAutoFiltersets a çalışma sayfası AutoFilter aralık and yazar a field criterion in the same call, with A1-stil and 1-based numeric aralık overloads plus optional two-criterion operators.
Sürüm 2.88.89
- Classic XLS shapes artık yapabilir be removed by hücre aralık.
TXLSShapes.DeleteInRangedeletes anchored pictures or shapes whose OfficeArt client anchors intersect a 1-based çalışma sayfası aralık, returning the number of shapes removed.
Sürüm 2.88.88
- Classic HTML dışa aktarma tablo layout attributes are now configurable.
TXLSHTMLExport.TableBorderWidth,CellPadding, andCellSpacingcontrol the generated<table>attributes for both styled and simple HTML output while defaulting to the previous zero values.
Sürüm 2.88.87
- Classic HTML dışa aktarma artık destekler minimal tablo output.
TXLSHTMLExport.SimpleExportyazar a plain HTML tablo without generated CSS classes, hyperlink anchors, or comment title attributes while preserving escaped display text and merged-hücre spans.
Sürüm 2.88.86
- Classic HTML dışa aktarma artık yapabilir yazmak a document title.
TXLSHTMLExport.Titleyazar an escaped HTML<title>element before the generated stil block, while the default empty value keeps existing output unchanged.
Sürüm 2.88.85
- Classic HTML dışa aktarma now carries hücre comments as tooltips.
TXLSHTMLExport.Optionsartık içerirxhCommentsby default, writing hücre comment text as escapedtitleattributes while still allowing callers to remove the option for plain hücre output.
Sürüm 2.88.84
- Classic HTML dışa aktarma hyperlink output is now configurable.
TXLSHTMLExport.Optionsdefaults to[xhHyperlinks]for existing behavior, and callers can removexhHyperlinksto dışa aktarma linked hücreler as plain escaped text.
Sürüm 2.88.83
- Classic HTML dışa aktarma artık korur hücre hyperlinks.
SaveAsHTMLwraps linked hücreler in HTML anchor tags, emits hyperlink addresses as escapedhrefvalues, carries ScreenTip text as escapedtitleattributes, and keeps the displayed hücre text escaped inside the link.
Sürüm 2.88.82
- Classic XLS çalışma kitapları artık yapabilir control the saved-by user name.
IXLSWorkbook.LastSavedByexposes the WRITEACCESS saved-by field so generated or edited çalışma kitapları can store an explicit audit name while unedited source çalışma kitapları continue preserving their original metadata.
Sürüm 2.88.81
- Classic XLS çalışma sayfaları artık yapabilir control the displayed gridline color index.
IXLSWorksheet.GridlineColorIndexexposes the Window2icvHdrfield so saved çalışma sayfaları can reopen with a chosen gridline color while leaving gridline visibility and print gridline settings unchanged.
Sürüm 2.88.80
- Classic XLS çalışma kitapları artık yapabilir set the active sheet by index.
IXLSWorkbook.ActiveSheetIndexexposes a 1-based active-tab özellik backed by the WINDOW1 active sheet field, allowing saved çalışma kitapları to reopen on a chosen çalışma sayfası without changing the first visible tab.
Sürüm 2.88.79
- Classic XLS çalışma sayfası outlines artık yapabilir control automatic outline stiller.
TXLSOutline.ApplyStylesexposes the WSBool outline stil flag, allowing saved çalışma sayfaları to korumak or explicitly enable Excel outline stil application without changing outline levels or summary placement.
Sürüm 2.88.78
- Classic XLS page setup artık yapabilir control automatic page breaks.
IXLSPageSetup.AutoPageBreaksexposes the çalışma sayfası WSBool automatic page-break flag, allowing saved çalışma sayfaları to keep automatic page breaks enabled or disable them explicitly while preserving manual page breaks.
Sürüm 2.88.77
- Classic XLS çalışma kitapları artık yapabilir control AutoFilter date grouping.
IXLSWorkbook.AutoFilterDateGroupingexposes the Window1 date-grouping flag with a positive Boolean API, allowing saved çalışma kitapları to keep Excel's date filter grouping enabled or disable it explicitly.
Sürüm 2.88.76
- Classic XLS çalışma kitapları artık yapabilir set çalışma kitabı window position and size directly.
IXLSWorkbook.XWindow,YWindow,WindowWidth, andWindowHeightexpose the Window1 geometry fields so saved çalışma kitapları can reopen with a chosen window rectangle.
Sürüm 2.88.75
- Classic XLS çalışma kitapları artık yapabilir kaydetme the çalışma kitabı window hidden state directly.
IXLSWorkbook.WindowHiddenmaps to the Window1 hidden flag, allowing saved çalışma kitapları to reopen with the çalışma kitabı window hidden without changing çalışma sayfası visibility.
Sürüm 2.88.74
- Classic XLS çalışma kitapları artık yapabilir kaydetme the çalışma kitabı window minimized state directly.
IXLSWorkbook.Minimizedmaps to the Window1 minimized flag, allowing saved çalışma kitapları to reopen with the çalışma kitabı window minimized.
Sürüm 2.88.73
- Classic XLS çalışma kitapları artık yapabilir hide or show the vertical scrollbar directly.
IXLSWorkbook.ShowVerticalScrollmaps to the Window1fDspVScrollflag, allowing saved çalışma kitapları to açma with the vertical scrollbar hidden or visible.
Sürüm 2.88.72
- Classic XLS çalışma kitapları artık yapabilir hide or show the horizontal scrollbar directly.
IXLSWorkbook.ShowHorizontalScrollmaps to the Window1fDspHScrollflag, allowing saved çalışma kitapları to açma with the horizontal scrollbar hidden or visible.
Sürüm 2.88.71
- Classic XLS çalışma kitapları artık yapabilir hide or show the sheet tab bar directly.
IXLSWorkbook.ShowSheetTabsmaps to the Window1fDspTabsflag, letting saved çalışma kitapları açma with sheet tabs hidden or visible without changing çalışma sayfası visibility.
Sürüm 2.88.70
- Classic XLS çalışma kitapları artık yapabilir set the çalışma kitabı tab bar ratio directly.
IXLSWorkbook.TabRatioexposes the Window1wTabRatiovalue so callers can adjust the space reserved for sheet tabs versus the horizontal scrollbar.
Sürüm 2.88.69
- Classic XLS çalışma kitapları artık yapabilir set the first visible sheet tab directly.
IXLSWorkbook.FirstSheetexposes the Window1itabFirstvalue as a 1-based özellik, so callers can choose which sheet tab appears at the left edge when Excel opens the çalışma kitabı.
Sürüm 2.88.68
- Classic XLS çalışma sayfaları can artık korur and set outline symbol visibility.
IXLSWorksheet.DisplayOutlineSymbolsmaps to the BIFF WINDOW2fDspGutsflag, allowing saved sheets to hide outline and grouping symbols in the window view.
Sürüm 2.88.67
- Classic XLS çalışma sayfaları can artık korur and set row and column heading visibility.
IXLSWorksheet.DisplayHeadingsmaps to the BIFF WINDOW2fDspRwColflag, allowing saved sheets to hide row numbers and column letters in the window view.
Sürüm 2.88.66
- Classic XLS çalışma sayfaları can artık korur and set the show-formüller view.
IXLSWorksheet.DisplayFormulasmaps to the BIFF WINDOW2fDspFmlaflag so Excel can açma a sheet showing formül text instead of calculated results.
Sürüm 2.88.65
- Classic XLS çalışma sayfaları artık yapabilir set Normal view zoom independently.
IXLSWorksheet.NormalViewZoomexposes the cached WINDOW2 Normal zoom so callers can kaydetme distinct zoom levels while a sheet is in Page Break Preview.
Sürüm 2.88.64
- Classic XLS çalışma sayfaları artık yapabilir set Page Break Preview zoom directly.
IXLSWorksheet.PageBreakPreviewZoomexposes the cached WINDOW2 preview zoom so callers can kaydetme different Normal and Page Break Preview zoom levels.
Sürüm 2.88.63
- Classic XLS çalışma sayfaları now expose split-pane yardımcılar.
IXLSWorksheet.SplitPanes(Width, Height)creates a movable pane split using the existing BIFF pane writer, andUnsplitPanesclears the pane record before saving.
Sürüm 2.88.62
- Classic XLS çalışma sayfaları artık sahiptir simpler frozen-pane yardımcılar.
IXLSWorksheet.FreezePanes(Cols, Rows)freezes the requested left columns and top rows, whileUnfreezePanesremoves the pane record before saving.
Sürüm 2.88.61
- Classic XLS sheet-name discovery now accepts streams.
TXLSWorkbook.GetSheetNames(Stream, List)okur BIFF sheet names from a caller-provided XLS stream without loading çalışma sayfası contents, matching the file-name yardımcı for in-memory çalışma kitabı data.
Sürüm 2.88.60
- çalışma sayfası collections now expose direct by-name lookup yardımcılar.
IXLSWorkSheets.SheetByName(Name)andTXLSXSheets.SheetByName(Name)return the matching çalışma sayfası object ornil, so callers no longer need to resolve an index before accessing a sheet.
Sürüm 2.88.59
- The XLSX facade now okur sheet names directly from streams.
TXLSXWorkbook.GetSheetNames(Stream, List)okur ordered names fromxl/workbook.xmlwithout loading çalışma sayfası XML, matching the file-name overload for in-memory and BLOB-backed çalışma kitapları.
Sürüm 2.88.58
- The XLSX facade now exposes quick sheet-name discovery.
TXLSXWorkbook.GetSheetNames(FileName, List)okur ordered names fromxl/workbook.xmlwithout loading çalışma sayfası XML.
Sürüm 2.88.57
TXLSWorkbook.GetSheetNamesartık destekler XLSX packages. The yöntem okurxl/workbook.xmlfrom.xlsx,.xlsm,.xltx, and.xltmfiles and returns ordered sheet names without loading çalışma sayfası XML.
Sürüm 2.88.56
- Classic XLS çalışma kitapları artık yapabilir okumak sheet names without loading çalışma sayfaları.
TXLSWorkbook.GetSheetNames(FileName, List)scans the çalışma kitabı globals stream and returns ordered sheet names from Excel 97-2003.xlsfiles.
Sürüm 2.88.55
- Classic XLS aralık AutoFilter criteria now yazmak BIFF8 filter records.
TXLSRange.Autofilter(Field, Criteria)creates the filter aralık when needed and emitsAUTOFILTERconditions for simple string, numeric, Boolean, blank, nonblank, and comparison-prefixed criteria.
Sürüm 2.88.54
- Classic XLS çalışma sayfaları artık sahiptir çalışma sayfası-level AutoFilter yardımcılar.
IXLSWorksheet.SetAutoFilter,ClearAutoFilter, andAutoFilterRangemanage BIFF8 filter dropdown aralıklar directly while reusing the existingAUTOFILTERINFOand filter database name writer.
Sürüm 2.88.53
- Classic XLS çalışma sayfaları now expose list data-validation creation.
IXLSWorksheet.AddListValidation(Range, Items)yazar BIFF8DVALandDVrecords, keeps the dropdown visible by default, destekler comma-separated inline lists, and korur the rules throughOpen/SaveAsround-trips.
Sürüm 2.88.52
- formül calculation now works consistently across XLS and XLSX entry points.
TXLSWorkbook.Calculatenow accepts Excel-stil leading-equals formüller such as=SUM(A1:B1)+C1, and the XLSX facade eklerTXLSXWorkbook.CalculateplusTXLSXWorksheet.Calculate. The XLSX path shares the HotXLS formül token parser and evaluator for hücre and aralık references, referenced formül hücreler, cross-sheet references, and çalışma kitabı or sheet scoped defined-name aralıklar.
Sürüm 2.88.51
- XLSX aralıklar now destek Excel-stil merge across.
TXLSXRange.Merge(True)yazar one<mergeCell>entry per row, matching the classic XLSRange.Merge(True)behavior, while no-argumentMergeandMerge(False)continue to create one full-aralık merged rectangle.
Sürüm 2.88.50
- BIFF8 HeaderFooter and HFPicture placement now match the current MS-XLS rules. HotXLS korur Excel-authored
HeaderFooter($089C) records for even / first page header and footer text, and replaysHFPicture($0866) records after çalışma sayfası dimensions and drawing objects per the çalışma sayfası ABNF, so page-layout details survive .xls açma/kaydetme round-trips.
Sürüm 2.88.49
- Comment rich-text runs artık sahiptir a typed API.
TXLSComment.TextRunsexposes BIFF8TXOFormatRunentries so callers can inspect or set per-character font boundaries in .xls comments while HotXLS still korur the underlying run bytes for safe round-trips.
Sürüm 2.88.48
- Pivot-tablo supplemental SX records are now exposed through the typed API. HotXLS now attaches yüklenmiş BIFF8 pivot records such as
SXIVD,SXLI,SXFormat,SXEx,SXVDEx,SXRule,SXFilt, andSXAddltoTXLSPivotTable.SupplementalRecordsfor inspection while still preserving the original raw bytes for kaydetme round-trips.
Sürüm 2.88.47
- External çalışma kitabı cached values now survive .xls açma/kaydetme round-trips. HotXLS artık korur BIFF8
XCTandCRNrecords attached to yüklenmişSUPBOOKentries, so cached hücre values for external çalışma kitabı links are no longer dropped during kaydetme.
Sürüm 2.88.46
- Built-in stil outline levels now survive .xls açma/kaydetme round-trips. HotXLS now okur and korur the BIFF8
STYLEiLevelbyte for built-in stiller, so Excel RowLevel_1..7 and ColLevel_1..7 stil metadata is no longer reset to the default during kaydetme.
Sürüm 2.88.45
- Defined name metadata now survives .xls açma/kaydetme round-trips. HotXLS artık korur yüklenmiş BIFF8
NAMErecord option bits and shortcut bytes unless the defined name is edited, so Excel-authored function, object, procedure, calculated-expression, and binary-name metadata is no longer cleared during kaydetme.
Sürüm 2.88.44
- ObProj çalışma kitabı markers now survive .xls açma/kaydetme round-trips. HotXLS artık korur yüklenmiş BIFF8
ObProjrecords even when no VBA storage is exposed through the object model, so çalışma kitabı-level VBA project markers and third-party metadata are no longer dropped during kaydetme.
Sürüm 2.88.43
- çalışma sayfası option flags now survive .xls açma/kaydetme round-trips. HotXLS artık korur unmodeled BIFF8
WSBOOLbits such as dialog-sheet, automatic page-break, stil-application, and outline-gutter display flags while still updating the existing fit-to-page and outline summary settings through the public API.
Sürüm 2.88.42
- Additional çalışma kitabı metadata records now survive .xls açma/kaydetme round-trips. HotXLS artık korur yüklenmiş BIFF8
COUNTRY,BOOKBOOL,BACKUP,FNGROUPCOUNT,USESELFS, andRECALCIDrecord bodies instead of rewriting them with defaults, keeping çalışma kitabı-level uyumluluk and calculation metadata stable.
Sürüm 2.88.41
- Multi-area selections and active pane focus now survive .xls açma/kaydetme round-trips. HotXLS artık korur yüklenmiş BIFF8
SELECTIONrecords and thePANESactive-pane value unless the sheet selection or panes are changed through the API, so Excel split/frozen pane focus and multi-aralık selections are no longer collapsed during kaydetme.
Sürüm 2.88.40
- External çalışma kitabı names now survive .xls açma/kaydetme round-trips. HotXLS artık korur yüklenmiş BIFF8
EXTERNALNAMErecords attached to externalSUPBOOKentries, including DDE/OLE/link metadata and formül tails, so external names and link definitions are no longer dropped when saving.
Sürüm 2.88.39
- Password-protected BIFF8 .xls files now use and okumak RC4 CryptoAPI FILEPASS records. HotXLS now yazar Excel 2007/2010-stil
FILEPASSvMajor=2 metadata for encrypted .xls çalışma kitapları and okur both legacy RC4 vMajor=1 and RC4 CryptoAPI vMajor=2/3/4 files, so password-protected çalışma kitapları no longer fail or downgrade to the older encryption header.
Sürüm 2.88.38
- Excel-authored .xls hyperlink metadata now survives açma/kaydetme round-trips. HotXLS artık korur the BIFF8
HLinkrecord body for yüklenmiş hyperlinks unless the hyperlink is edited, keeping sourcestreamVersion,hlstmfoption bits such asfIcon, moniker data, and related target metadata stable across saves.
Sürüm 2.88.37
- çalışma kitabı window state now survives .xls açma/kaydetme round-trips. HotXLS now okur and korur the BIFF8
WINDOW1record's window position, size, visibility/iconic flags, first displayed sheet tab, seçili-tab count, and tab-scrollbar ratio instead of rewriting them with defaults on every kaydetme.
Sürüm 2.88.36
- BIFF8 WriteAccess saved-by users now survive .xls açma/kaydetme round-trips. HotXLS now okur and korur the
$005C WRITEACCESSrecord body instead of replacing Excel's saved-by user withHotXLS, so çalışma kitabı audit metadata remains stable after saving.
Sürüm 2.88.35
- Excel comment authors now survive .xls açma/kaydetme round-trips. The BIFF8
Noterecord'sstAuthorfield is now parsed and passed into the drawing note model instead of being replaced with an empty string, so the comment "Created by" author written by Excel is preserved when HotXLS saves the çalışma kitabı again.
Sürüm 2.88.34
- Shape OfficeArt FOPT options are now exposed through a low-level option bag.
TXLSShape.OfficeArtOptionslets advanced callers inspect, set, and delete any stored FOPT PID as aLongWordorWideString, while the existing high-levelLine,Fill, color, and visibility APIs remain unchanged.
Sürüm 2.88.33
- Additional OfficeArt solver-container rule records now round-trip. Beyond typed
msofbtConnectorRule($F012), HotXLS artık korur non-folder solver children such asOfficeArtFArcRule($F014) andOfficeArtFCalloutRule($F017) as raw OfficeArt records insidemsofbtSolverContainer($F005), so advanced Excel drawings no longer lose non-connector solver relationships during kaydetme.
Sürüm 2.88.32
- OfficeArt ClientData markers are no longer duplicated after unknown-record preservation. MS-XLS defines
OfficeArtClientData($F011) as a zero-length marker whose followingObjrecord remains a separate BIFF record. v2.88.32 recognises that marker instead of capturing it as an unknown SpContainer leaf, so parsed shapes emit exactly one $F011 marker during kaydetme while malformed container-stil assumptions remain out of the XLS path.
Sürüm 2.88.31
- OfficeArt connector rules now round-trip. Excel-authored .xls drawings store connector-line bindings in
msofbtSolverContainer($F005) with childmsofbtConnectorRule($F012) records. v2.88.31 parses and emits that $F005/$F012 pair throughTMsoConnectorRules, preserving the start shape, end shape, connector shape, and connection sites across kaydetme/reload. The earlier audit note listed $F121, but MS-ODRAW definesOfficeArtFConnectorRuleas $F012.
Sürüm 2.88.30
- Unrecognised OfficeArt SpContainer leaf records now round-trip. Excel-authored .xls files commonly embed leaf Fbts such as
msofbtClientTextbox($F00D),OfficeArtFPSPL($F11D), andOfficeArtUDefProp($F122) inside each shape SpContainer. v2.88.30 captures unknown shape-level leaves asTMsoFbtUnknownand re-emits them in parse order between the shapeClientAnchorand the trailing zero-bodymsofbtClientDatamarker. - Scope and follow-up. Other drawing-level unknown leaves remain deferred; the connector-rule solver-container case is handled by v2.88.31. Container-form unknowns, such as
msofbtClientData($F011) used as a container instead of a sibling marker, remain audit-round Slice 3.
Sürüm 2.88.29
- ComboBox and ListBox OBJ unknown subrecords now round-trip. TMSOShapeComboBox.ParseObj and TMSOShapeListBox.ParseObj already typed-parsed FtSbs ($000C), FtSbsFmla ($000E), and FtLbsData ($0013) into dedicated fields, but any other source-file subrecord (FtMacro $0004, ObjLinkFmla, FtNts $000D, etc.) appearing between CMO and FtLbsData was silently dropped at case fall-through. v2.88.29 ekler the same else-branch as v2.88.28 Picture, capturing the unknown subrecord's 4-byte header + body into
FObjTailRaw. Both AddObj yöntemler emit the captured bytes between the CMO body and the FtSbs subrecord to match the BIFF8 spec's subrecord ordering. - FtLbsData's swallow-all behaviour limits the scope. The existing
$0013case overridesRecLen := Len - offsto absorb all bytes after the FtLbsData header intoFObjRec_LBSData's blob, so subrecords appearing AFTER FtLbsData (typically just FtEnd) are still round-tripped through that mechanism unchanged. The new FObjTailRaw integration specifically targets the gap before FtLbsData where FtMacro and ObjLinkFmla typically live. Freshly authored combo / list boxes via the Drawing API have emptyFObjTailRaw→ byte-identical output to v2.88.28.
Sürüm 2.88.28
- Picture-shape OBJ unknown subrecords now round-trip. TMSOShapePicture.ParseObj already typed-parsed FtCf ($0007), FtPioGrbit ($0008), and FtPictFmla ($0009) into dedicated fields, but any other source-file subrecord (FtMacro $0004, FtNts $000D, etc.) was silently dropped at the case fall-through. v2.88.28 ekler an else-branch that appends the full 4-byte header + body of unrecognised subrecords into
FObjTailRaw; TMSOShapePicture.AddObj then emits those bytes verbatim after its typed subrecord output and before the FtEnd marker. Source-file picture objects with macro hooks survive the resave. - typed + raw coexistence pattern. Unlike PictureFrame (v2.88.27) which used an if/else swap between typed and raw emit, Picture combines both: the typed fields korumak the API surface (callers can still adjust
ftCfValueetc.), while the raw tail korur only the unknown bytes. Newly authored pictures via the Drawing API have emptyFObjTailRaw, so output is byte-identical to v2.88.27.
Sürüm 2.88.27
- OBJ trailing-subrecord round-trip extended to PictureFrame shapes. TMSOShapePictureFrame.AddObj previously emitted only the legacy hardcoded FtCf ($0007, body $FFFF) and FtPioGrbit ($0008, body $0000) subrecords between CMO and FtEnd. For freshly authored picture frames the new code still emits those defaults; for picture frames parsed from a source .xls the captured
FObjTailRawbytes are emitted verbatim instead, preserving any source-file FtPictFmla / non-default FtCf / non-default FtPioGrbit content across the kaydetme cycle. - Investigation note — Flush auto-corrects sz.
TMsoShapeContainer.Flushrewrites the Obj record's size header at commit time viaData.SetWord(Data.DataLength - 4, 2), which means the hardcodedsz := $1Avalues that have lived in HotXLS AddObj implementations for years were not spec bugs after all — Flush corrects them automatically. v2.88.27 still computes sz accurately for source-code clarity, but the runtime behaviour is unchanged from that perspective.
Sürüm 2.88.26
- OBJ trailing-subrecord round-trip extended to Chart and CheckBox shapes. v2.88.25 introduced raw-byte preservation for the bytes between an Obj record's CMO ($0015) and its FtEnd ($0000) marker, but only TMSOShapeTextBox.AddObj emitted the captured tail. This release applies the same pattern to TMSOShapeChart.AddObj and TMSOShapeCheckBox.AddObj — both share the simple "CMO + FtEnd" emit structure of TextBox, so the change is a one-line variable substitution (
sz := $1A + Word(Length(FObjTailRaw))) plus a verbatim byte loop before the FtEnd marker. - Chart trailing subrecords (e.g. FtMacro for embedded chart object macros) and checkbox state subrecords (FtCbls + FtCblsData + ObjLinkFmla, MS-XLS §2.5.140-141 / §2.5.149) now survive HotXLS kaydetme/reload. Freshly authored charts and checkboxes via the Drawing API still emit a default 26-byte CMO+FtEnd (byte-identical to v2.88.25), so existing callers see no behaviour change. Picture / ComboBox / ListBox / PictureFrame shapes have their own dynamic typed-subrecord emit that conflicts with FObjTailRaw — their integration is deferred to future commits.
Sürüm 2.88.25
- OBJ record trailing subrecords now preserved across the kaydetme cycle for comments. The BIFF8 Obj record ($005D) chains a sequence of typed subrecords after the mandatory CMO ($0015), terminated by an FtEnd ($0000) marker, per MS-XLS §2.4.181. For Note (comment) shapes the trailing block is typically a 26-byte FtNts (§2.5.149) carrying a GUID and the fSharedNote flag — both essential when Excel later merges comments across users in shared çalışma kitapları. HotXLS previously discarded every byte after CMO on okumak and emitted only an empty FtEnd on yazmak, so any source-file FtNts was lost on every HotXLS resave.
- Generic-base capture, TextBox-only emit (R5-3 first slice). TMsoShapeContainer.ParseObj now captures the byte aralık between CMO body end and FtEnd marker into a new internal
FObjTailRaw: TBytesfield; TMSOShapeTextBox.AddObj inserts those bytes between its CMO emit and the FtEnd marker, with the Obj record header size adjusted accordingly. Newly authored comments (no source bytes) keep byte-identical output to v2.88.24. Other shape classes (Picture / CheckBox / ComboBox / ListBox / Chart) inherit the capture but their typed AddObj overrides keep the legacy "synthesise from scratch" behaviour — raw-bytes emit for those shape types is deferred to future commits.
Sürüm 2.88.24
- Multi-font and multi-color hücre comments now round-trip. The BIFF8 TXO record's formatting-runs block (
rgTxoRuns+TxOLastRunper MS-XLS §2.5.272) carries the per-run font and color overrides that give a comment its rich-text styling. HotXLS previously discarded the entire block on okumak and emitted a single empty default run + LastRun on yazmak — flattening any "Important!" highlighted in red, any bold word inside the comment text, into uniform default formatting on every HotXLS resave. - Raw-byte preservation in TMSOShapeTextBox. ParseTXO captures the post-text Continue bytes verbatim into a new internal
FFormatRunsRaw: TBytesfield; Store emits them back as the formatting-runs Continue and adjusts the base record'scbRunsheader to match. Newly authored comments (viaAddComment) keep the legacy single-default-run output unchanged, so byte-identical output is preserved for default çalışma kitapları. Typed Excel-API access to individual format runs is still deferred — the existing single-WideString comment API is unchanged.
Sürüm 2.88.23
- Print resolution and copy count now round-trip — Setup record now fully covered. Three Setup-record Word fields (
iResat offset 12,iVResat offset 14,iCopiesat offset 32, per MS-XLS §2.4.257) carry Excel's "Page Setup → Page → Print quality" and "Number of copies" choices. HotXLS previously dropped all three on okumak and emitted hardcoded values (600 DPI / 600 DPI / 1 copy), so any user-tweaked resolution or copy count silently reverted on every HotXLS resave. - Three new TXLSPageSetup özellikler.
PrintResolution: LongWord,PrintVResolution: LongWord, andCopies: LongWord— all default to the values the writer previously hardcoded (600 / 600 / 1) so çalışma kitapları that never touch them produce byte-identical output to v2.88.22. Setters clamp atHigh(Word)so an over-large caller value cannot wrap on emit. - Setup record round-trip work complete. With this fix every kullanıcıya görünen field of the BIFF8 Setup record ($00A1) round-trips end to end — paper size / scale / first page number / fit-to-page width and height / orientation / print order / black-and-white / draft / print comments / hücre errors / resolution / copies. Only the two spec-hint grbit bits (
fNoPls,fNoOrient) remain unexposed, both of which HotXLS yazar as zero matching Excel's default behaviour.
Sürüm 2.88.22
- özel Page Setup "First page number" now round-trips. The BIFF8 Setup record carries the çalışma kitabı's Page Setup → Page → "First page number" choice as two related fields: grbit bit 7 (
fUsePage) selects between Excel's "Auto" default and an explicit starting page number, and the signed Word at offset 4 (iPageStart) holds that özel value, per MS-XLS §2.4.257. HotXLS previously dropped both on okumak and emittediPageStart = 1with the bit clear, so a user-typed "First page number: 100" silently snapped back to "Auto" on every HotXLS resave. - Two new TXLSPageSetup özellikler.
UseFirstPageNumber: Booleanmirrors the bit (False = "Auto", default);FirstPageNumber: Integercarries the iPageStart value (default 1, clamped to the spec's signed-Word aralık -32768..32767 by the setter). HotXLS round-tripsiPageStartverbatim even whenUseFirstPageNumberis False, so toggling between Auto and özel in Excel korur the last user-typed value.
Sürüm 2.88.21
- "Print comments at end of sheet" choice now survives the kaydetme cycle. The BIFF8 Setup record's grbit bit 9 (
fEndNotesper MS-XLS §2.4.257) carries the Page Setup → Sheet → Comments dropdown's distinction between "As displayed on sheet" (the default) and "At end of sheet". HotXLS already round-tripped PrintNotes (bit 5) to control whether comments print, but bit 9 was dropped on okumak and emitted as zero on yazmak — so a user-chosen "At end of sheet" silently reverted to "As displayed on sheet" on every HotXLS resave. - New TXLSPageSetup.PrintNotesAtEnd Boolean özellik. Defaults to
Falsematching Excel's UI default. The reader and writer round-trip the bit verbatim (even whenPrintNotes = False), so a çalışma kitabı with comments temporarily disabled retains the "at end of sheet" preference for when the user re-enables them — mirroring Excel's own behaviour.
Sürüm 2.88.20
- çalışma kitabı "Set precision as displayed" choice now round-trips. The BIFF8 CalcPrecision record ($000E) carries the çalışma kitabı-wide File → Options → Advanced → "Set precision as displayed" checkbox per MS-XLS §2.4.35. HotXLS previously had no dispatcher case for $000E and TXLSWorkbook.StorePrecision emitted a hardcoded
1(= full precision retained). A user-checked "Set precision as displayed" silently reverted to "full precision" on every HotXLS resave — hiding the user's deliberate intent that any subsequent recalc should permanently truncate hücre values to their formatted decimal places. - New TXLSWorkbook.UseFullPrecision Boolean özellik. Defaults to
True(matches the BIFF8 default and Excel's UI default of unchecked). Setting it toFalsemirrors checking the destructive "precision as displayed" option — HotXLS itself does not truncate any hücre value on the round-trip, but the flag is now faithfully written back so Excel's next recalc respects it. With this fix, every BIFF8 calc record (CalcCount / CalcMode / CalcPrecision / CalcDelta / CalcIter / CalcSaveRecalc) round-trips end to end.
Sürüm 2.88.19
- "Recalculate çalışma kitabı before saving" checkbox now round-trips. The BIFF8 CalcSaveRecalc record ($005F) carries the çalışma kitabı's File → Options → kaydetme → "Recalculate çalışma kitabı before saving" boolean, per MS-XLS §2.4.37. HotXLS previously had no dispatcher case for $005F and StoreCalculationSettings emitted a hardcoded
1— so a user-disabled "recalc on kaydetme" silently re-enabled itself on every HotXLS resave, which actually mattered for manual-calc çalışma kitapları where the user had deliberately frozen the on-disk hücre values. - New TXLSWorkbook.RecalcOnSave Boolean özellik. Defaults to
True(matches both Excel's UI default and the legacy hardcoded value), so çalışma kitapları that never touch the özellik keep byte-identical output to v2.88.18. Setter accepts any Boolean; the reader normalises arbitrary non-zero source bytes toTrue.
Sürüm 2.88.18
- Iterative calculation settings (enable + max iterations + max change) now round-trip. The BIFF8 CalcIter ($0011), CalcCount ($000C), and CalcDelta ($0010) records together carry Excel's "Enable iterative calculation" trio of options (File → Options → formüller), per MS-XLS §2.4.33 / §2.4.31 / §2.4.32. None of the three had a dispatcher case before, and StoreCalculationSettings emitted them with hardcoded values (off / 100 / 0.001). A user-configured 1000-iteration loop with a 0.0001 convergence delta silently reset to "iteration off, 100, 0.001" on every HotXLS resave — breaking circular-reference formüller and convergence-sensitive financial models.
- Three new TXLSWorkbook özellikler.
EnableIteration: Booleanmirrors the checkbox;MaxIterations: LongWordis the iteration cap (clamped to the spec-legal 1..32767 aralık by the setter);MaxIterationChange: Doubleis the convergence delta (negative input snaps to the spec default 0.001). Defaults match the values the writer used to hardcode, so çalışma kitapları that never touch the new özellikler produce byte-identical output to v2.88.17.
Sürüm 2.88.17
- çalışma kitabı calculation mode (Manual / Automatic / Auto except tablolar) now round-trips. The BIFF8 CalcMode record ($000D) carries the çalışma kitabı-level "formüller → Calculation Options" choice per MS-XLS §2.4.36. HotXLS previously had no dispatcher case for $000D at all, so the source file's value was discarded on load, and the writer always emitted a hardcoded
$0001(Automatic). A user-seçili Manual mode silently reverted to Automatic on every HotXLS resave — bad for large çalışma kitapları where Manual is set deliberately for performance. The new ParseCalcMode handler stores the source value on the çalışma kitabı and StoreCalculationSettings now emits the stored value instead of the constant. - New TXLSWorkbook.CalculationMode özellik. okumak-yazmak
LongWordözellik acceptingxlCalcManual(0),xlCalcAutomatic(1, default), orxlCalcAutomaticExceptTables(0xFFFF) — three new constants exported fromlxTNC.inc. The setter clamps unknown values to the spec default so a corrupt source file cannot leave the çalışma kitabı in an undefined state. Existing code that never touches the özellik keeps the legacy "Automatic" default, so previous output is byte-identical for default çalışma kitapları.
Sürüm 2.88.16
- Page Setup "hücre errors as" choice now survives the kaydetme cycle. The BIFF8 Setup record ($00A1) packs the Page Setup → Sheet tab "hücre errors as: displayed / <blank> / <dash> / <N/A>" dropdown into bits 10-11 of its grbit word as
iErrors, per MS-XLS §2.4.257. HotXLS previously dropped these bits on okumak and emitted them as zero on yazmak, so a çalışma kitabı the user had configured to print#DIV/0!as#N/Asilently reverted to "displayed" after every HotXLS resave. The reader now decodesiErrorsinto a newTXLSPageSetup.PrintCellErrorsözellik and the writer rebuilds the field from it. - New TXLSPageSetup.PrintCellErrors özellik. okumak-yazmak
LongWordözellik acceptingxlPrintErrorsDisplayed(0, default),xlPrintErrorsBlank(1),xlPrintErrorsDash(2), orxlPrintErrorsNA(3) — four new constants exported fromlxTNC.inc. Existing PageSetup callers that never touch the özellik keep the default ("displayed"), so the legacy print output is unchanged.
Sürüm 2.88.15
- hücre comment alignment and orientation now round-trip. The BIFF8 TXO base record ($01B6) carries five typed flags in its
grbitword (hAlignment, vAlignment, fLockText, fJustLast, fSecretEdit) plus a separaterotword for text orientation, per MS-XLS §2.4.329. The reader previously dropped all of these and the writer pinnedgrbitto a hardcoded0x0012(left + top) with rotation always 0, so every kaydetme reset a centered or rotated comment back to left+top+horizontal regardless of source. The reader now decodes the typed fields on load and the writer composesgrbitfrom them, so the layout survives the kaydetme/reload trip. - Six new TMSOShapeTextBox özellikler for explicit comment styling.
HAlignment,VAlignment,Rotation,LockText,JustLastLine, andSecretEditare exposed as okumak-yazmak özellikler on each comment shape;AddCommentdefaults to left+top+horizontal+unlocked so callers that do not touch them keep the previous appearance. - TXO writer now lays out reserved4 / reserved5 along spec field boundaries. Previous code emitted offsets 2-9 of the base record as two long yazar (rot + reserved4 then reserved5); the writer now splits them into
Wordrot,Wordreserved4,Longreserved5 — the byte content is unchanged (still all-zero for Note shapes) but the source structure now matches MS-XLS §2.4.329 field offsets, making future TXO düzeltir harder to misalign.
Sürüm 2.88.14
- TXO cchText offset corrected — the v2.88.13 comment-length fix now actually fires. The previous release introduced a sanity check for the TXO base record by reading
cchTextat offset 8, but MS-XLS §2.4.329 putscchTextat offset 10 (after grbit, rot and the 6 reserved / controlInfo bytes). Offset 8 falls inside the reserved5 long, which is always zero on Note-shaped objects, so every comment quietly slid into the defensive fallback that simply restored the pre-v2.88.13 behaviour. The fix corrects the offset to 10 — long comments now genuinely stitch across Continue records and short comments no longer pick up trailing padding. No further behavioural change beyond what v2.88.13 was always supposed to ship.
Sürüm 2.88.13
- Long hücre comments now okumak back at full length. The BIFF8 TXO record ($01B6) splits its text body across the base record and one or more Continue records, with the character count published in the base record at offset 8 as
cchText. The previous comment reader skipped the base record entirely, treated DataList[1] as the entire text, and stopped there — so a comment longer than about 4100 wide characters was silently truncated, and a shorter comment whose Continue record carried trailing padding picked up junk at the end. The reader now consumescchTextas the authoritative character count, walks each Continue segment per MS-XLS §2.4.329 (the rgb break sits on a character boundary so no partial-character bookkeeping is needed), and stops as soon as the budget is satisfied so the formatting-runs block that follows the text never bleeds into the string. Comments with corrupted / missing base records still fall back to the legacy "all remaining bytes" path.
Sürüm 2.88.12
- Cached strings longer than ~4100 characters from string-returning formüller now round-trip across Continue records. v2.88.11 wired up the okumak side of the BIFF8 String record ($0207) but only consumed the first record body, so a cached string whose UCS-2 bytes overflowed the 8224-byte BIFF limit and spilled into one or more Continue records ($003C) was silently truncated. The handler now walks the entire dispatch-level DataList: it okur cch and fHighByte from the base record, copies the body that fits there, then concatenates every following Continue segment as raw bytes per the MS-XLS §2.5.293 character-boundary guarantee — XLUnicodeString never re-emits fHighByte mid-string. Each segment is bounded by the remaining character budget so a stray oversized Continue cannot make the result longer than cch. Single-record strings (the common case) take the exact same fast path as before.
Sürüm 2.88.11
- String-returning formüller now round-trip the cached text Excel computed. The previous release covered the number, boolean, error and empty variants of the BIFF8 FormulaValue cache (MS-XLS §2.5.133), but left the string variant on the to-do list because its cached value lives in a separate String record ($0207) that immediately follows the formül record. ParseFormula now remembers the hücre coordinates when it sees a string-variant formül, and the new ParseString handler decodes the trailing $0207 record per MS-XLS §2.4.268 and routes the WideString into
FCachedFormulaValue.GetCellValueartık yapabilir fall back to the Excel-computed text whenever the HotXLS evaluator cannot reproduce it. A defensive reset at the top of ParseFormula drops any stale pending anchor so a malformed source file with a missing String record cannot misroute a later one. Records longer than 8224 bytes that overflow into Continue chunks still fall back to evaluator output as a known limitation.
Sürüm 2.88.10
- BIFF8 formül records now round-trip the cached value Excel computed. ParseFormula used to skip the 8-byte FormulaValue payload at offset 6 entirely, so the cached result of every formül in a yüklenmiş .xls (numbers, booleans, errors, empty) was thrown away and HotXLS had to re-evaluate every hücre through its own formül engine. When that engine could not match Excel (unsupported XLM functions, broken external links, formüller the engine has not yet implemented) the hücre silently became blank or zero. The reader now decodes the four numeric / boolean / error / empty variants per MS-XLS §2.5.133 and stores them on a new
TXLSCellRef.FCachedFormulaValuefield;GetCellValuefalls back to that cache only when the evaluator fails, so freshly-authored formüller still go through evaluation as before. The string variant continues to defer to the evaluator because the trailing String record ($0207) parser is not yet wired up.
Sürüm 2.88.9
- BIFF8 formül records with unresolvable values now flag fAlwaysCalc instead of the reserved1 bit. When the HotXLS evaluator could not calculate a formül at kaydetme time, the writer used to set
grbit = 0x0002— bit 1, which MS-XLS §2.4.127 reserves and tells readers to ignore. Excel duly ignored it, treated the placeholder cached value of 0 as authoritative, and silently displayed 0 instead of recalculating. The writer now setsgrbit = 0x0001(fAlwaysCalc, bit 0), so Excel re-runs the formül on next recalc and the hücre shows the correct result.
Sürüm 2.88.8
- PageSetup.PrintTitleColumns / PrintTitleRows now raise on bad input. Setting either özellik with a malformed aralık string (anything
ColDiapasonToValues/RowDiapasonToValuescould not parse) previously dropped the assignment silently — the çalışma kitabı kept whatever Print_Titles aralık was already set, or no aralık at all, and the caller had no way to find out something went wrong. The setters now raiseException.Createwith a descriptive message naming the offending value, matching the existing raise stil onTXLSRangeinvalid-index paths.
Sürüm 2.88.7
- Row miyRw field now stays within the MS-XLS spec aralık. Pre-BIFF8 versions of Excel encoded "use the çalışma kitabı default row height" by OR-ing bit 15 into miyRw, and HotXLS carried that idiom forward in the BIFF8 writer even though MS-XLS §2.4.221 caps miyRw at 8192 twips. Modern Excel emits a plain 255 (12.75 pt default) in the same case and uses the fUnsynced grbit bit to signal manual overrides, so the bit-15 hack made HotXLS output diverge from authoritative .xls files (a value of 32 959 = 0x80FF for "default" was technically out-of-spec). The writer now drops the OR and yazar 255 directly; the reader still strips bit 15 on the way in for backwards uyumluluk with HotXLS v2.88.6 and earlier files plus rare third-party generators that copied the BIFF5 idiom.
- BIFF8 spec audit round 2 errata note eklendi. Re-checking the [MS-XLS] field boundaries clarified two findings flagged as P2 in the original report (
dev-notes/XLS-BIFF8-Spec-Audit-Round2.md) are not actual bugs: the bit-15 set in the BOF history flag $000080C9 belongs to the verXLHigh field (bits 14-17, value 2 = "Excel 2002"), not the reserved1 tail (bits 19-31); and ParseFormula's use of a leading PtgExp token to detect shared / array formüller matches what the spec implies and disambiguates correctly via the following ShrFmla / Array record. Both items are now annotated as retracted.
Sürüm 2.88.6
- Macro sheets and VBA modules now keep their BoundSheet8 ordinal slot. The reader previously dropped BoundSheet8 records whose
dtfield was 1 (macro sheet) or 6 (VBA module), so the HotXLS Sheets collection ran short by those entries. Any XTI cross-reference in ExternSheet that pointed at a sheet position past a macro sheet by file order then resolved to the wrong HotXLS çalışma sayfası after a SaveAs. The reader now ekler a placeholder sheet for every BoundSheet8 record and stores the rawdtbyte on a newSheet.SheetTypeRawözellik; the writer emits the original byte back. Macro substream BOF records ($0040) are also treated as çalışma sayfası substreams during parsing so hücreler inside macro sheets are preserved rather than silently absorbed into the previous sheet.
Sürüm 2.88.5
- BIFF8 Row record now round-trips fCollapsed, fExAsc, fExDes and fPhonetic. Previously the reader dropped fCollapsed (grbit bit 4) — the writer inferred it from outline-level transitions on neighbouring rows, which misclassified rows the source file had explicitly collapsed or marked as boundaries. The high three bits (fExAsc at 28, fExDes at 29, fPhonetic at 30) were never okumak either, and were always emitted as zero because the writer truncated the 4-byte grbit to a single 16-bit ixfe slot. The reader now consumes all four bits per MS-XLS §2.4.221 and pins fCollapsed as explicit so the writer-side inference no longer overwrites Excel-asserted values. The writer packs ExAsc / ExDes / Phonetic into bits 12-14 of the ixfe Word, masking ixfe to the spec-allowed 12-bit aralık to prevent an XF index ever colliding with the new flags. round-trip side effects: thick-top / medium-bottom borders driven by ExAsc / ExDes hints now survive HotXLS SaveAs, and phonetic info visibility on Japanese sheets stops resetting on every kaydetme.
Sürüm 2.88.4
- BIFF8 Window2 fPaged bit now flags only the active sheet. Previous releases set
fPaged(MS-XLS §2.4.346 bit 10) on every visible sheet, which made HotXLS output diverge from what Excel itself yazar (per spec the bit means "this sheet is currently displayed in the çalışma kitabı window", so only the active-sheet substream should carry it). Excel readers fell through toWindow1.itabCurto identify the real active sheet anyway, so the misuse was tolerated, but Apache POI strict mode and other tooling that trustsfPagedas a primary signal now see the correct sheet flagged.
Sürüm 2.88.3
- BIFF8 Window2 zoom and gridline color now round-trip. Previous releases dropped the WINDOW2 record fields past offset 6 on okumak and emitted hard-coded zeros on yazmak, so any Excel-saved sheet zoom (75 percent, 125 percent, etc.) and gridline color customisation reverted to defaults after a HotXLS SaveAs. The reader now consumes
icvHdr,wScaleSLVandwScaleNormalper MS-XLS §2.4.346: the active-view zoom feedsSheet.Zoomand the opposite-view value lands in a cached slot so switching between Normal and Page Break Preview in Excel restores the previous zoom. The writer emits the activeSheet.Zoomin the matching view slot and the cached value in the other, plus the preserved gridline color index.
Sürüm 2.88.2
- Fixed BIFF8 HFPicture record opcode. Saved .xls files now emit header / footer background-image records with the correct
rt = 0x0866per MS-XLS §2.4.138. Previous releases used0x086C— the opcode for CellWatch — so Excel tried to parse the embedded OfficeArt BLIP as a watched-hücre reference and silently dropped the picture (sometimes refusing to açma the çalışma kitabı when the embedded image bytes happened to violate CellWatch’s expected 16-byte structure). çalışma kitapları that round-trip a header / footer image through HotXLS now keep the image intact.
Sürüm 2.88.1
- Fixed BIFF8 Theme record opcode. Saved .xls files now emit the Theme record with the correct
frtHeader.rt = 0x0896per MS-XLS §2.4.326. Previous releases used0x0892— the opcode for StyleExt — so Excel interpreted the embedded OOXML theme payload as a hücre-stil extension and silently fell back to the built-in Office theme, losing any customised theme colors when round-tripping a çalışma kitabı through HotXLS.
Sürüm 2.88.0
- [MS-XLSX] cross-audit round 4 — theme part + sheet-name setter. Two follow-up düzeltir targeting issues left after rounds 1–3 (v2.51.0 / v2.52.0 / v2.54.1). Neither breaks an existing call site; one extends behavior at a setter, the other ekler a new always-emitted part.
- Saved .xlsx packages now include an
xl/theme/theme1.xmlpart. stiller.xml has always emitted<color theme="N"/>references for any font / fill / border / tab color set through the theme-index path (and for theme colors carried through from a parsed input .xlsx), but no theme part was written, so the references dangled. Excel tolerated the omission by falling back to its built-in “Office” theme silently, but Office File Validation flagged every reference as “theme part missing” and Apache POI strict mode rejected the çalışma kitabı on first lookup.SaveAsnow emits the canonical Office (2007+) theme: 12-slot color scheme (systemwindowText/window, four Excel default colors, six accents, two hyperlink colors), Calibri Light / Calibri font scheme, minimum-valid format scheme (three fill / line / effect / background-fill entries each perCT_StyleMatrix).[Content_Types].xmlgains a matchingOverride;xl/_rels/workbook.xml.relsgains atheme/theme1.xmlrelationship that lands at the tail of the rid aralık, so existingXlsxFirstExternalLinkRidoffsets for sheets / sst / stiller / vba / externalLinks are unchanged. - Direct
Sheet.Name := '...'assignment now sanitises and dedupes too. Round 3 (v2.54.1) eklendi Excel naming-rule enforcement inTXLSXSheets.Add(AName), but theTXLSXWorksheet.Nameözellik setter was a rawwrite FName, so the most common mutation path that round didn’t cover —lxXlsxExport.pas:122 Target.Name := Source.Namein the XLS → XLSX round-trip — let through any name the BIFF8 source happened to carry (forbidden chars: \ / ? * [ ], length > 31, surrounding single quotes, reservedHistory, case-insensitive duplicates of an existing sheet). The özellik setter now routes through a newSetNameyöntem that replays the sameXlsxSanitizeSheetName+' (N)'-suffix dedup logic (case-insensitive, exclude-self) against the parent çalışma kitabı’s sheet collection. Detached çalışma sayfaları (noFWorkbookback-pointer yet) skip the dedup step and just sanitise —TXLSXSheets.Addwill enforce uniqueness when the sheet attaches. Idempotent on already-valid names so reader-sideFSheets.Add(names[i])stays a pure round-trip.
Sürüm 2.87.4
- XLS shared formüller now yazmak a valid
ShrFmlabody. BIFF8 shared-formül output artık içerir the requiredcUsebyte before the shared parsed formül, so çalışma kitapları saved withUseSharedFormulasno longer shift the formül token stream by one byte. - XLS tablo stil and filter metadata now matches the latest MS-XLS layout.
AddTablenow yazarLIST12asList12TableStyleClientInfo, sets tablo and field AutoFilter flags inFeature11, and emits the empty per-columnFeat11FdaAutoFilterblocks Excel expects. - BIFF8 CF12 Data Bar / Color Scale / Icon Set rules now omit forbidden DXF payloads. HotXLS follows the MS-XLS rule that these CF12 types must carry an empty DXF block, while preserving their actual rule settings in the CF12 kind-specific tail.
Sürüm 2.87.3
- XLS çalışma sayfası tablo metadata now follows the MS-XLS
Feature11tablo layout.AddTableoutput for .xls files now yazar aFeatHdr11tablo header plusFeature11TableFeatureType/Feat11FieldDataItempayloads, removes the legacy$0867 FeatHdrtablo marker, and stores tablo and column names asXLUnicodeStringvalues. - XLS tablo readback now understands the spec-correct field layout. HotXLS parses
TableFeatureTypetablo names, aralıklar, totals-row state, and field captions, while keeping a fallback for older HotXLS-generated tablo records.
Sürüm 2.87.2
- XLS BIFF8 continuation records now carry correct base lengths. Oversize XLS records split by the writer now update the first record length to 8224 bytes instead of leaving the original oversized length in the BIFF header.
- Large XLS çalışma sayfası tablolar now use spec-correct
ContinueFrt11chunks. WideAddTableoutputs with largeFeature11payloads now kaydetme with$0875 ContinueFrt11continuation records and reopen with tablo metadata preserved, matching the [MS-XLS]Feature11/ContinueFrt11layout.
Sürüm 2.87.1
- XLSX çalışma sayfası grid limit artık içerir the last Excel row and column.
TXLSXRange,RCRange,EntireRow, andEntireColumnnow allow row 1048576 and column 16384 (XFD), matching [MS-XLSX] row-number and column-number bounds. Earlier the internal clamp used zero-based maxima, soXFD1048576and aralıklar touching the last row or last column were silently clipped to the previous row/column. - XLSX encryption docs and tests now match the implemented yazmak path. Help pages and the regression suite now state that
SaveAsEncryptedyazar ECMA-376 Standard Encryption output for non-empty passwords, whileOpenEncryptedstill raises for encrypted packages and falls back for plain .xlsx files.
Sürüm 2.87.0
- XLSX password-protected kaydetme now works (wave J phase 2, backlog #29).
TXLSXWorkbook.SaveAsEncrypted(FileName, Password)now yazar a real ECMA-376 Standard Encryption-protected .xlsx file (Office 2007+ format). The complete [MS-OFFCRYPTO] §2.3.4 pipeline is in place: phase 1's SHA-1 50000-iteration password derivation + AES-128 verifier blocks + AES-CBC package body encryption + binaryEncryptionInfoserializer is now joined by phase 2's four\005DataSpacesmetadata streams (Version / DataSpaceMap / DataSpaceInfo / TransformInfo) and the OLE Compound File Binary writer that drops everything into a CFB container Excel opens with the user password. Workflow: caller invokesSaveAsEncryptedwith a non-empty password → HotXLS serialises the çalışma kitabı into an in-memory plaintext .xlsx zip → encrypts via AES-128 CBC with a fresh random 16-byte salt and verifier → yazar the CFB output viaStgCreateDocfile. açma in Excel 2007+: enters password → content opens. Wrong password: rejected.OpenEncrypted(decrypt side) is still a separate backlog item and continues to raiseEXlsxEncryptionNotImplementedwhen handed an encrypted file.
Sürüm 2.86.1
- XLSX Standard Encryption — cryptographic foundation (wave J phase 1, backlog #29). Two new internal units land the cipher and key-derivation half of the ECMA-376 Standard Encryption yazmak path.
lxAES.paswraps Brian Gladman's AES (linked fromthirdparty/Win32/aes*.obj+thirdparty/Win64/aes*.obj) and exposes AES-128 ECB single-block and AES-128 CBC encryption entry points.lxXlsxStdEncrypt.pasimplements pure-Pascal SHA-1 (FIPS-180-4), the [MS-OFFCRYPTO] §2.3.4.10 50000-iteration password derivation, the §2.3.4.7 verifier blocks (EncryptedVerifier+EncryptedVerifierHash), AES-CBC package body encryption (8-byte LE size prefix + zero-pad to 16-byte boundary + IV-of-zeros), and the §2.3.4.6 binaryEncryptionInfoserializer.TXLSXWorkbook.SaveAsEncryptedstill raisesEXlsxEncryptionNotImplemented— wave J phase 2 will add the OLE Compound File Binary writer (\005DataSpacescontainer streams) and wire the pipeline toSaveAsEncrypted. Until then, the new units are library-internal scaffolding callers should not depend on.
Sürüm 2.86.0
- QueryTable and External Data Connection round-trip (wave I, backlog #28). Excel-created QueryTables and external data connections (Data → Get External Data from Web / SQL / OLEDB) now survive a HotXLS kaydetme/açma cycle. Earlier the BIFF8 reader silently skipped
QsiSXTag($0802),QsiSXTagExt($0810), andDConn($0876), so the metadata that describes the upstream query was dropped on kaydetme and the tablo degraded to plain hücre values. The reader now captures these records as opaque bytes and the writer emits them back into the çalışma sayfası substream (alongside the PIVOTVIEW block per [MS-XLS] §2.1.7.20.5) and the çalışma kitabı globals (alongside the late globals block before EOF per §2.1.7.20.3). HotXLS still does not model the typed QSI / DConn structure programmatically — creating new QueryTables from caller code is deferred to a later wave — but çalışma kitapları that already contain them no longer lose refresh metadata. BIFF8 (.xls) only; BIFF5 unaffected.
Sürüm 2.85.1
- Restore Win32 / Win64 library build. Two pivot-line-item yardımcı variables in the wave H5.3 multi-data-field SXLI emitter were declared as separate
array of array of Wordanonymous types, which the Delphi compiler treats as distinct unnamed types and rejects on direct assignment withE2008 Incompatible types. The HotXLS library has not built since v2.84.1 on RAD Studio 12.0 through 37.0. The two variables are now declared together so they share a single anonymous type, fixing the assignment and restoring the .dcu / .bpl output for both Win32 and Win64 targets. No runtime behaviour change — the emitted SXLI bytes are identical to v2.85.0.
Sürüm 2.85.0
- Typed pivot subtotal API (wave H5.4). The typed
TXLSPivotFieldnow exposes aSubtotals: TXLSPivotSubtotalsset özellik alongside the existing rawSubtotalMask: Word. Callers can assign e.g.Field.Subtotals := [xlpsSum, xlpsAverage];instead of bit-packing the SXVDgrbitSubfield by hand. Twelve subtotal types are exposed (xlpsDefault, xlpsSum, xlpsCount/CountA, xlpsAverage, xlpsMax, xlpsMin, xlpsProduct, xlpsCountNums, xlpsStdDev, xlpsStdDevP, xlpsVar, xlpsVarP), each mapping to a single bit per [MS-XLS] §2.4.279. The rawSubtotalMaskstays the round-trip source of truth — reserved bits 12-15 are preserved on okumak/yazmak. Closes the wave H4.3 known limit “row field subtotal SXVD.grbitSub configuration unavailable from API” and finishes the wave H5 pivot follow-ups.
Sürüm 2.84.1
- Multi data-field SXLI expansion (wave H5.3). When a pivot tablo has more than one data field AND the data-field axis matches a given SXLI axis (
DataFieldAxisIsRow = True&& row axis, orDataFieldAxisIsRow = False&& column axis), the writer now replicates each cartesian-product combinationDataFieldCounttimes withiData = 0 .. DataFieldCount - 1, plusDataFieldCountgrand-total lines so each data field gets its own total. The non-hosting axis is unchanged. Excel and other readers now render multi-data-field pivots in the layout the caller intended instead of falling back on the previous “singleiData = 0per combination” approximation. Single-data-field pivots emit bit-identical output to v2.84.0. Delta compression (H5.1) folds the repeated combinations down to ~8 bytes per replica, so the expansion ekler minimal byte overhead. Closes the wave H4.3 known limit “multi-data-field SXLI not correctly expanded”.
Sürüm 2.84.0
- Pivot page-axis pre-selection API (wave H5.2). The typed
TXLSPivotFieldnow carries aPageItemIndexözellik that programmatically-built pivots can set to pre-select a specific cache item on the page-axis filter. DefaultxlPageItemAll(= $7FFD) leaves the filter at “(All)” so callers that never assignPageItemIndexbehave bit-identically to v2.83.2. The SXPI ($00B6) writer okurField.PageItemIndexinstead of hardcoding $7FFD, and the typed reader now populatesPageItemIndexfrom SXPI on açma so callers can inspect the saved page selection. Closes the wave H4.3 known limit “page filter caller-pre-selection unavailable from API”.
Sürüm 2.83.2
- Smaller pivot SXLI records via delta compression (wave H5.1). The pivot writer now delta-compresses SXLI line items using the spec's cSic field — each line's leading cache-item indices that match the previous line in the same SXLI record are folded into a shared-prefix count, and only the trailing indices are emitted. Typical row-axis SXLI records (a few row fields × dozens of items) shrink by 30–60% with no change in semantics. Output is still chunked to stay under the 8224-byte BIFF record limit. The first line of every SXLI record always emits cSic = 0 (record-local, no cross-record back-reference), and the grand-total line is never delta-compressed.
Sürüm 2.83.1
- hücre fill, font, and border colors set via RGB now round-trip through .xls kaydetme/açma. The BIFF8 XFExt ($087D) writer was emitting each record's ixfe field using the in-memory XF array position, but the matching hücre records on disk yazmak ixfe using the post-pruning SaveIndex order. Whenever any XF earlier in the tablo was pruned during kaydetme (typical when one hücre migrates from a transient XF to a final XF), every XFExt's ixfe ended up off by the number of pruned slots, and the rich color associated with each hücre shifted to a neighbouring hücre on reload. The writer now resolves SaveIndex for each rich-slot XF and emits the matching on-disk ixfe, so RGB hücre colors saved by HotXLS — interior fill, font color, border colors — survive a kaydetme / reload round-trip cleanly. XFExt records for XFs that got pruned entirely are now skipped rather than emitted with a dangling ixfe.
Sürüm 2.83.0
- Pivot line items + page item state (wave H4.3). Programmatically-built pivot tablolar now emit SXLI ([MS-XLS] §2.4.275, $00B5) for both row and column axes, plus SXPI ($00B6) for the page axis. This gives the pivot view layout-fidelity: non-Excel readers see the exact display order the writer intended, large pivots açma faster (Excel doesn't have to recompute line layout from scratch), and page filters persist with a default "(All)" selection per page field.
- Row + column SXLI enumeration. The writer enumerates the cartesian product of axis fields' cache items (innermost field varies fastest, matching Excel's nested-row layout) and emits one line per combination plus a trailing grand-total line marked with the SXLI nTypes fGrandTotal bit. Each line uses cSic = 0 (no delta-compression — simpler at the cost of a few extra bytes per line). Output is chunked into multiple SXLI records when the line count overflows the 8224-byte BIFF limit; a 16384-line safety cap prevents runaway expansion on pathological inputs.
- SXPI page-axis state. Emitted only when at least one field has Axis = xlpfaPageField. Each entry is 10 bytes (isxvd + iCache + ipos + objId) with iCache = $7FFD signalling "(All)" — the API surface for pre-selecting specific page items is deferred to wave H5. Pivots without page fields emit no SXPI (the çalışma sayfası ABNF lists it as optional).
- Closes wave H3 known limit "SXLI / SXPI not emitted". Combined with H4.1 (DataField number formats) and H4.2 (SXDBB per-record stream), wave H4 closes all three known limits in the H3 pivot-tablo writer. Pivot tablolar built via
IXLSWorksheet.AddPivotTablenow ship self-contained caches with full layout metadata.
Sürüm 2.82.0
- Pivot cache self-contained per-record stream (wave H4.2). Programmatically-built pivot caches now emit SXDBB records ([MS-XLS] §2.4.272, $00C5 in cache context) carrying the per-record field-value indices in the spec's bit-packed encoding. Without SXDBB, Excel had to refresh the cache from the source aralık on açma — which worked when the source data was present and unchanged, but broke when the source was renamed / deleted or had drifted since the pivot was built. The cache is now self-contained.
- Bit-packed encoding per spec. Each field uses
ceil(log2(itemCount + 1))bits per record (sentinel space included). Records are byte-aligned — every new record starts on a fresh byte boundary. The writer chunks the stream into multiple SXDBB records to stay under the 8224-byte BIFF size limit, so caches with tens of thousands of source rows still serialise cleanly. - round-trip path unchanged. Pivot caches okumak from disk (FromRawBlobs = True) continue to round-trip via the wave H1 raw-byte path — the new SXDBB writer only fires for typed caches built by
IXLSWorksheet.AddPivotTable. Mixed çalışma kitapları (one round-tripped cache + one new cache) emit both paths cleanly.
Sürüm 2.81.0
- Pivot data field number formats (wave H4.1). Pivot data fields artık yapabilir carry an Excel number format string so currency / percentage / date data renders with the right glyphs on açma instead of showing raw General-format values. New
IXLSWorksheet.PivotSetDataFieldFormat(DataField, FormatStr): Wordregisters the format in the çalışma kitabı's NumFormats tablo (auto-add or reuse) and yazar the resulting ifmt index toTXLSPivotDataField.NumberFormat. The typed writer already emits SXDI.ifmt, so this closes the loop. - Public NumFormats yardımcı on TXLSWorkbook.
Workbook.RegisterNumFormat(FormatStr): Wordexposes the same auto-add behavior at çalışma kitabı level for callers who need ifmt indices in non-pivot contexts. Empty FormatStr short-circuits to index 0 ('General'). - Caller usage.
df := pivot.AddDataFieldByName('Revenue', xlpaSum); Sheet.PivotSetDataFieldFormat(df, '$#,##0.00'); df := pivot.AddDataFieldByName('GrowthPct', xlpaAverage); Sheet.PivotSetDataFieldFormat(df, '0.00%');
Sürüm 2.80.1
- Icon Set conditional formats round-trip cleanly through HotXLS kaydetme/açma. The v2.49.0 audit changed the CF12 writer to emit
ct=$06for Icon Set rules per [MS-XLS] §2.4.43 (the spec-correct value;$05is reserved for Filter rules), but the matching reader path still only recognised the legacy$05value. As a result, .xls files written by HotXLS v2.49.0..v2.80.0 lost their Icon Set rules on reload — the rule kind degraded to a plain hücre-is rule and the icon-set type / Reverse / ShowOnly flags reset to defaults. The reader now accepts both$05(legacy HotXLS pre-v2.49.0) and$06(spec / v2.49.0+) so çalışma kitapları from either generation re-açma cleanly.
Sürüm 2.80.0
- Programmatic pivot tablo creation API (wave H3). New
IXLSWorksheet.AddPivotTable(SourceRangeA1, DestRow, DestCol, Name): TXLSPivotTableyöntem walks the supplied source aralık, infers each column's data type from the hücre values, auto-builds aTXLSPivotCache(or reuses an existing one bound to the same aralık), and creates a typed pivot tablo on the destination sheet with one TXLSPivotField per cache field (axes initially unset). - Caller wires axes / data via convenience yöntemler.
pivot.AddRowField('Region'),pivot.AddColumnField('Quarter'),pivot.AddPageField('Year'),pivot.AddDataFieldByName('Revenue', xlpaSum).SetFieldAxis+AddDataFieldare exposed for finer control. Field axis enum: xlpfaRowField / xlpfaColumnField / xlpfaPageField / xlpfaDataField / xlpfaNone. Eleven aggregation functions: Sum, Count, Average, Max, Min, Product, CountNums, StdDev, StdDevP, Var, VarP. - Typed writer emits SX* records + cache substream. When
pivot.FromRawBlobs = False(the default for programmatically created tablolar), the writer serialises the typed model into SXView ($00B0) + SXVD ($00B1) per field + SXVI ($00B2) per item + SXIVD ($00B4) row/col index arrays + SXDI ($00C5) per data field + SXEx ($00C6) into the çalışma sayfası footer. The matching pivot cache (cache.FromRawBlobs = False) emits a fresh BOF (dt=$0006) + SXDB ($00C6) header + SXFDB ($00C8) + SXFDBType ($00FB) + per-item SXSTRING / SXNUM / SXBOOLEAN / SXERR / SXDATETIME / SXEMPTY + EOF substream appended after the çalışma sayfası bodies. - round-trip safety preserved. Pivot tablolar and caches okumak from disk keep their wave H1
FromRawBlobs = Trueflag and continue to round-trip via the raw-byte path. Only the new programmatically created pivots flow through the typed writer. Mixed çalışma kitapları (one round-tripped pivot + one new pivot via AddPivotTable) emit both paths cleanly. - Wave H3 limitations. Source aralık types other than rectangular A1 (named aralıklar, external çalışma kitabı refs) are out of scope. SXLI / SXPI (line items / page items) are not emitted for typed pivots — Excel computes them on açma. Formatting customisation (data field number format beyond per-field NumberFormat) is exposed as a field but the writer treats it as 0 (general). Multiple pivots sharing a cache are supported but caller must wire the same source aralık string each time.
Sürüm 2.70.0
- Pivot tablo typed okumak model (wave H2). Building on the wave H1 raw-byte preservation, the reader now also populates a typed object model so callers can introspect pivot tablo structure without bytecode parsing. New types —
TXLSPivotTable,TXLSPivotField,TXLSPivotItem,TXLSPivotDataField,TXLSPivotCache,TXLSPivotCacheField,TXLSPivotCacheItem,TXLSPivotCaches,TXLSPivotTables— surface via the newIXLSWorksheet.PivotTablesandTXLSWorkbook.PivotCachesözellikler. - What the model captures. Per pivot tablo: position (FirstRow / Col / LastRow / Col / FirstDataRow / FirstDataCol), Name, DataCaption, CacheId, and an ordered list of
Fields(each with Name, Axis ∈ {xlpfaRowField,xlpfaColumnField,xlpfaPageField,xlpfaDataField,xlpfaNone}, Items[], SubtotalMask, CacheFieldIndex). Data axis emits a parallelDataFieldslist, each carrying anAggregationfrom the 11-valueTXLSPivotAggregationenum (xlpaSum / Count / Average / Max / Min / Product / CountNums / StdDev / StdDevP / Var / VarP). - Cache model. Each
TXLSPivotCacheholds CacheId, SourceRange (Sheet + 0-based row/col bounds), RecordCount, and a list ofFields. Each cache field carries its data type (xlpcftNumber / String / Boolean / Error / Empty / DateTime / Mixed), Name, NumberFormat index, and the unique-value Items[]. Per-record indices into each field's Items[] are exposed viaCache.RecordIndices[Record, Field]for programmatically-built caches; round-tripped caches okumak from disk leave per-record indices unpopulated and rely on the raw-byte path for fidelity. - round-trip safety. Pivot tablolar that came from raw bytes have
FromRawBlobs = True— the writer continues to replay the wave H1 raw blobs verbatim. The typed model is populated as a best-effort projection for caller introspection. The typed-model writer that produces wire bytes from the model is scoped to wave H3 (programmatic AddPivotTable API). - New lxPivot.pas unit. All pivot types live in their own unit alongside lxChart / lxFormula / lxNames. lxHandle re-dışa aktarır the public types so existing imports keep working.
Sürüm 2.69.0
- Pivot tablo round-trip preservation (wave H1). HotXLS now keeps every record that makes up a pivot tablo when an Excel-created .xls travels through açma → kaydetme. Before this release, the reader silently dropped unrecognised SX* records (SXView, SXVD, SXVI, SXIVD, SXLI, SXPI, SXDI, SXAddl, etc.) and skipped the entire Pivot Cache substream, so re-saving an Excel pivot file left Excel with broken pivot tablolar on next açma. The reader now captures all of these as opaque bytes and the writer replays them verbatim, so the pivot tablo on the cover sheet still renders correctly in Excel after a kaydetme / reload cycle.
- çalışma sayfası PIVOTVIEW block. SX* view records ($00B0–$00B2, $00B4–$00B6, $00C5–$00C8, $00D0–$00D2, $00D5, $00E3, $00F0, $00FB, $0100, $0864) are captured in stream order and emitted in the writer's per-sheet footer (between the tablolar block and the trailing EOF), matching the [MS-XLS] §2.1.7.20.1 çalışma sayfası ABNF position for PIVOTVIEW. Oversize SXAddl payloads ride through the existing Continue ($003C) splitter the same way HFPicture does.
- Pivot Cache substreams. BOF (dt=$0006) followed by SXDB / SXFDB / SXFDBType / SXSTRING / SXNUM / SXBOOLEAN / SXERR records up to the matching EOF is captured as one cache bucket; multiple caches in the same çalışma kitabı each get their own bucket. On kaydetme the writer rebuilds the full BOF / records / EOF substream for each captured cache and appends them to the çalışma kitabı OLE stream after the per-sheet bodies, where [MS-XLS] §2.1.7.20 expects them.
- Scope: raw-byte preservation only (H1). Wave H1 deliberately does not parse pivot data into a typed model — TXLSPivotTable / TXLSPivotField / TXLSPivotCache and a programmatic AddPivotTable API are scoped to future waves H2 / H3. Until then HotXLS callers can't introspect or modify pivot tablo structure, but the existing Excel-built pivot tablolar round-trip through HotXLS without loss.
Sürüm 2.68.0
- Chart backlog wave F sub-feature 3: Series error bars.
TXLSChartSeriesInfogrew anErrorBars: array of TXLSChartErrorBarsInfofield. Each entry produces a SerErrBar record ([MS-XLS] §2.4.105, $105B) inside the parent Series block, after Trendlines and before the Series End, in caller order. A typical column chart with Y error bars uses two entries (Sertm=1 Y+ and Sertm=2 Y-); scatter / bubble charts add X+/X- pairs (Sertm=3 / 4). - Five value sources.
Ebsrcselects 1=percent, 2=fixed value, 3=stddev, 4=stderr, 5=özel.NumValuecarries the magnitude (10.0 = 10% when Ebsrc=1, raw scalar for fixed value, multiplier for stddev). For özel (Ebsrc=5) theCnumfield carries the count of özel data points; spec says MUST=0 for the other sources, so the builder forces non-özel entries to Cnum=0 regardless of caller input. - T-cap rendering toggle.
FTeeTopcontrols whether Excel renders T-shaped caps on the bar ends (Excel's visual default = on). Useful when caller wants the more minimal "tick-only" stil. - özel value series (Ebsrc=5) caveat. The minimal builder emits the SerErrBar record with the chosen Cnum but does not yet emit the supporting BRAI cluster that points at the özel value array. özel error bars therefore render with default magnitude until a future phase wires up the BRAI follower. Percent / fixed / stddev / stderr (Ebsrc 1..4) are fully functional in this release.
Sürüm 2.67.0
- Chart backlog wave F sub-feature 2: Series trendlines.
TXLSChartSeriesInfogrew aTrendlines: array of TXLSChartTrendlineInfofield. Each entry produces a Trendline record ([MS-XLS] §2.4.328, $2050) inside the parent Series block, after SerToCrt and before the Series End, in caller order. Multiple trendlines on a single series are legal and Excel renders them all. - Six regression types.
Regtselects 0=polynomial, 1=exponential, 2=logarithmic, 3=power, 4=moving-average, 5=linear. For polynomial theNOrderfield sets the degree (2..6); for moving-average it sets the period (2..N). For the other typesNOrderis ignored but spec requires 1..6, so the builder defaults zero/out-of-aralık values to 1 / 6 respectively. - Equation and R² display + forecasting.
FDispEq/FDispRSqrtoggle the on-chart equation and R² labels.NumForecast/NumBackcastset the forward / backward extrapolation periods (Double, ≥ 0).NumInterceptsets the y-intercept; pass NaN ($7FF8000000000000) for "automatic". - Trendline label as inline LPWideString. The
Namefield is written into the Trendline record's sName slot ([MS-XLS] XLUnicodeString: cch:2 + grbit:1 + UTF-16 body). Empty Name leaves Excel to auto-generate a legend entry like "Linear (Series1)". - AddSeries internal refactor. The internal
AddSeriesyardımcı now takes a singleTPreparedSeriesInforather than the previous (Name, CatArea, ValArea) triple, so future Series-attached records (next phase: error bars) can flow through one parameter without further signature churn.
Sürüm 2.66.0
- Chart backlog wave F sub-feature 1: 3D chart types. Programmatically built chart sheets artık yapabilir request
xlsChartType3DColumn,xlsChartType3DBar,xlsChartType3DLine, orxlsChartType3DPieviaAddChartSheet(Name, ChartType, ...). The 3D variants reuse the same on-the-wire BARCHART / LINECHART / PIECHART chart-type record as the 2D variants but the surrounding CHARTFORMAT block now also emits a Chart3d record per [MS-XLS] §2.4.46 to switch Excel into its 3D rendering pipeline. - Default 3D geometry mirrors Excel's "Insert > 3D Column". 20° rotation, 15° elevation, perspective off, cluster on, autoscale on, height and depth both 100% of width, gap 150%. Walls and right-angle axes match Excel's default. The geometry is hard-coded for now (no caller knob); the next phase can promote it to a record-stil override.
- Chart3DBarShape ($105F) restored conditionally. v2.55.0 removed the unconditional Chart3DBarShape emission because [MS-XLS] §2.4.47 mandates "MUST be ignored if the current substream does not contain a Chart3d record" and 2D charts don't have one. Wave F restores it for 3D Bar / 3D Column only (riser=rectangle, taper=none), emitted adjacent to Chart3d inside CHARTFORMAT so the spec relationship is visible from the wire layout. 3D Line and 3D Pie still skip it (no riser/taper concept).
- 3D Pie skips both axes. The axes-used count and axis emission paths now treat
xlsChartType3DPiethe same asxlsChartTypePie— axes-used = 0, no category / value axis emitted. Without this gate Excel rendered a 3D pie with stray axis lines bleeding through the chart.
Sürüm 2.65.0
- formül array constants round-trip with their data.
PtgArraytokens ($20 / $40 / $60 — V / R / A class) in formül streams now carry theirPtgExtraArraypayload through both okumak and yazmak paths.SUM({1,2,3}),=MMULT(...),{=COUNTIF(...)}and other array-literal formüller korumak the literal values in.xlsfiles written by HotXLS instead of round-tripping with empty rgcb sections. - Array data hangs off the syntax tree.
TXLSSyntaxItemgrewArrayCols/ArrayRows/ArrayValuesözellikler (with the matchingTXLSArraySerValrecord describing num / str / bool / err / empty hücreler per [MS-XLS] §2.5.198.122 SerAr). Tools that walk the syntax tree can introspect array constants directly without needing the separate external-data container. - Programmatic array-literal construction. Code that builds
TXLSSyntaxItemtrees via the API can populateSA_ARRAYitems withSetArrayDimensions+ArrayValues[i]and HotXLS emits the matching PtgExtraArray in the rgcb section automatically. The wire ordering matches the [MS-XLS] §2.5.198.59 rule that PtgExtraArray entries are sequenced by the position of their PtgArray token in the rgce stream. - Existing okumak path stays correct for mixed rgcb. The new code only consumes PtgExtraArray entries that correspond to PtgArray tokens it parsed; any other extra data (e.g. PtgExtraMem from PtgMemArea / PtgMemFunc, still unsupported) is left alone for downstream handling, and a malformed rgcb falls back to leaving array values empty rather than discarding the parsed tree.
Sürüm 2.64.0
- Chart backlog wave D phase 7: drawing theme color get / set round-trip within a process. Phase 5 introduced
XlsApplyThemeColorToDrawingas a set-only yardımcı because BIFF8 OfficeArt is a pre-Office-2007 binary format with no theme color slot on disk. The setter still down-casts to RGB for the on-disk OfficeArt opt blob, but the çalışma kitabı now also keeps an in-memory side-tablo that remembers the original theme idx + tint per(TMsoShapeContainer, OfficeArt property id)pair. A newXlsGetDrawingThemeColorreader consults that side-tablo so the same process can pull back the theme intent it just wrote — useful for in-app render code that wants to highlight theme-driven colors or expose them in özellik panes. After kaydetme / açma the side-tablo starts empty again and the getter returns False, falling through toColorFormat.RGB. - New caller API.
XlsGetDrawingThemeColor(ColorFormat, Workbook, out ThemeIdx, out Tint): Booleanjoins the existingXlsApplyThemeColorToDrawing. The setter signature is unchanged; it now also records the entry intoTXLSWorkbook.FDrawingThemeColors(a dynamic array of records keyed by container pointer + özellik id). SubsequentXlsApplyThemeColorToDrawingcalls on the same slot overwrite the entry, so the tablo tracks the latest intent rather than accumulating history. - Stable identity through new internal özellikler.
TXLSColorFormatgrew okumak-only_Containerand_Pidaccessors so the yardımcılar can compose the side-tablo key without the caller fishing private fields out of the class. Underscore prefix marks them as the same internal-API tier as_StringTable/_XFList/_BiffTheme: stable enough for library glue code, not part of the public contract. - Why this is "single-process round-trip" only. The BIFF8 OfficeArt format only stores indexed / RGB / scheme / sysColor in its 4-byte ColorRef; there's no extension record analogous to XFExt $087D where the theme idx + tint could live. So the disk round-trip cap is structural, not a HotXLS gap. The Phase 7 side-tablo bridges the in-process gap so app-internal code can pretend the format destekler theme colors as long as it lives within one çalışma kitabı session.
Sürüm 2.63.0
- Chart backlog wave D phase 6: compound border selectors round-trip RGB / theme through XFExt. The last theme-color known-limit is closed:
Border[xlAround],Border[xlInsideVertical],Border[xlInsideHorizontal], andBorder[xlInsideAll]now register the same RGB or theme color against every physical edge slot they target instead of falling back to the indexed-palette path. The newTXLSXfRichSlotSet(set ofTXLSXfRichSlotID) lifts the pending-rich stash from a single slot to a set, so one hücre-loop pass onSetRangeXFBordersPropertyregisters up to four XFExt slots in one go. - Compound selector mapping. The new
BorderEdgeSlotSet(BorderIndex): TXLSXfRichSlotSetyardımcı centralises the selector → slot translation:xlEdgeLeft / Right / Top / Bottom→ singleton sets (unchanged from phase 2).xlDiagonalDown / Up→[rsDiag](BIFF8 FullColorExt only carries a single diagonal color).xlAround→[rsTop, rsBottom, rsLeft, rsRight](outer border).xlInsideVertical→[rsLeft, rsRight](hücre-to-hücre vertical separators).xlInsideHorizontal→[rsTop, rsBottom](horizontal separators).xlInsideAll→[rsTop, rsBottom, rsLeft, rsRight].
Border.SetColorandBorder.SetThemeColorshare the same mapping, so RGB and theme paths behave identically across all selectors. - TXLSBorders.SetColor restored to a single dispatch. Phase 2 had to fan
Borders.Color := Vout to four per-edgeGetBorder(edge).Color := Vcalls because the pending-rich stash only carried one slot at a time. With the set form,Borders.SetColornow stashes the full{rsTop, rsBottom, rsLeft, rsRight}set and callsSetColorIndexonce —SetBordersColorIndextakes the optimal wire path (single hücreler loop with BorderMask=15), andConsumePendingRichSlotregisters all four XFExt slots on each touched XF in the same pass. ~4x fewer hücre-loop iterations than the phase-2 fan-out, byte-identical XFExt result. - ConsumePendingRichSlot iterates the set. The slot-registration loop walks the eight enum members and dispatches each one present in
FPendingRichSlotthroughRegisterXFExtSlot. Boundary hücreler whose XF didn't actually change during a compound-selector update still fire the callback — that's harmless because the XFExt slot is only visually relevant when the hücre genuinely has the matching border line, and the indexed wire is set by the per-hücreBorderMaskExcel already understands.
Sürüm 2.62.0
- Chart backlog wave D phase 5: özel theme XML round-trip + drawing theme yardımcı. Three pieces close the last theme-color gaps that phase 4 left açma. özel theme palettes set in Excel via Page Layout → Colors now survive the load cycle: the parser walks the OOXML
<a:clrScheme>embedded in the BIFF8$0892Theme record and güncellemeler the çalışma kitabı's 12-slotFBiffThemein place. The matching writer emits the same record when the palette has drifted from the default Office scheme, so caller-customised themes round-trip through HotXLS without falling back to defaults. A newXlsApplyThemeColorToDrawingyardımcı lets chart / shape callers address drawing colors with the same theme idx + tint vocabulary that hücreler already use. - Reader: OOXML theme XML parsing.
ParseThemestitches the record body (frtRefHeaderU + dwThemeVersion + variable-length XML payload, may span Continue records) into a single byte buffer and runs a targeted substring scan for the twelve<a:clrScheme>children (dk1, lt1, dk2, lt2, accent1..6, hlink, folHlink). For each slot it prefers<a:srgbClr val="RRGGBB"/>and falls back to<a:sysClr ... lastClr="RRGGBB"/>, then convertsRRGGBBto the HotXLS COLORREF layout and callsFBiffTheme.SetThemeRGBColor. Bodies that don't look like OOXML (missing<a:clrScheme>sentinel, ZIP-compressed variants, etc.) leave the palette at its default scheme so common renderings stay correct. - Writer: Theme record emission with skip-when-default.
TXLSWorkbook.StoreThemeemits a$0892record only whenIsBiffThemeDefaultreports the palette has drifted from the Office default scheme. The OOXML body is built from a deterministic template: twelve<a:srgbClr>entries (chosen over the Excel-native sysClr form for dk1/lt1 because it round-trips through the same parser without needing a sysColor name resolver), plus the minimal legal<a:fontScheme>/<a:fmtScheme>stanzas the schema requires. Untouched çalışma kitapları emit no record and stay byte-compatible with pre-Phase-5 output. - Drawing theme color yardımcı. The new free function
XlsApplyThemeColorToDrawing(ColorFormat, Workbook, ThemeIdx, Tint)resolves a theme idx + tint through the çalışma kitabı palette and yazar the resulting RGB onto aTXLSColorFormat(shape fill / line / chart color). BIFF8 OfficeArt is a pre-Office-2007 binary format with no native theme color encoding, so this is set-only: okumak-back returns the resolved RGB rather than the theme slot, and the round-trip theme reference is lost on disk. For full theme round-trip useIXLSInterior.SetThemeColor/IXLSFont.SetThemeColor/IXLSBorder.SetThemeColoron hücreler, which leverage XFExt $087D. - Wave D fully closed in five phases. Phase 1 (v2.58.1) eklendi the case-tablo acknowledgement, Phase 2 (v2.59.0) wrote XFExt for RGB hücre colors, Phase 3 (v2.60.0) closed the RGB reader loop, Phase 4 (v2.61.0) shipped the theme color path on hücreler, and Phase 5 (this) completes the picture with özel theme XML round-trip plus the drawing-side yardımcı. hücreler now match Excel's rendering pixel-for-pixel when round-tripping any combination of palette / RGB / theme colors that the BIFF8 spec can express; drawings carry the visual intent forward through the yardımcı but pay the OfficeArt format's RGB-only price on okumak-back.
Sürüm 2.61.0
- Chart backlog wave D phase 4: BIFF8 theme color destek (theme idx + tint via XFExt $087D). Office's 12-slot theme palette (lt1, dk1, lt2, dk2, accent1..6, hlink, foHlink) now round-trips on the .xls side: callers can address theme colors directly with the new
Interior.SetThemeColor(themeIdx, tint)/Interior.SetPatternThemeColor/Font.SetThemeColor/ per-edgeBorder.SetThemeColorAPIs, and the hücre color getters resolve the same theme idx + tint back through the çalışma kitabı's BIFF theme palette when reading. The XF record still receives a best-match indexed icv (so legacy readers like Excel 2003 keep rendering an approximate color), while Excel 2007+ recovers the exact theme intent through the XFExt FullColorExt (xclrType=3) future-extension record — same backward-uyumluluk trick Microsoft uses when "kaydetme As" downgrades a theme-styled .xlsx to .xls. - New caller API. Five new
SetThemeColorentry points join the existing RGB / index setters:IXLSInterior.SetThemeColor(ThemeIdx, Tint),IXLSInterior.SetPatternThemeColor(ThemeIdx, Tint),IXLSFont.SetThemeColor(ThemeIdx, Tint), andIXLSBorder.SetThemeColor(ThemeIdx, Tint)on each border edge.ThemeIdxis the 0-based theme slot (0=lt1, 1=dk1, 2=lt2, 3=dk2, 4..9=accent1..6, 10=hlink, 11=foHlink);Tintis the spec-stil -1.0..+1.0 lighter/darker adjustment that gets encoded into FullColorExt.nTintShade as Q15 signed integer. - çalışma kitabı BIFF theme palette.
TXLSWorkbooknow carries anFBiffTheme: TXLSThemeColorsinitialised to the default Office theme scheme that the XLSX side has used for years throughTXLSColorManager.FTheme. hücre color getters resolve theme idx + tint through this palette viaGetThemeRGBColor(idx, tint)(which already applies HSL-based tint adjustment inlxRgb.GetRGBTInt). Internal_BiffThemeözellik exposes the palette for parser-side güncellemeler. - Theme record ($0892) acknowledged on okumak.
lxRead.ParseThemetakes$0892out of the default-skip path so the çalışma kitabı-globals case tablo treats it as a known record. The embedded OOXML theme XML body itself is left unparsed for now — the 12 default Office theme colors already match the most common source and Excel-set theme hücreler render correctly through them. çalışma kitapları with a fully customised theme will surface theme hücreler through the default palette here (documented known limit; XML-based theme parsing is a follow-up wave). - Why no Theme record on yazmak. HotXLS-saved .xls files don't emit a Theme record. Excel 2007+ falls back to the default Office theme when no $0892 is present, which exactly matches HotXLS's
FBiffThemedefault scheme, so hücreler usingSetThemeColorrender with the right color in Excel without us having to ship the embedded XML. Files therefore stay smaller and the writer side has no XML-emit dependency.
Sürüm 2.60.0
- Chart backlog wave D phase 3: XFExt ($087D) okumak-side RGB / theme recovery closes the round-trip. The Phase 1 acknowledgement and Phase 2 emitter are now joined by a parser that actually consumes each
$087Drecord into the çalışma kitabı XF rich-color side-tablo. Files saved by Excel with RGB hücre colors (fill, font, individual borders) now surface throughcell.Interior.Color/Interior.PatternColor/Font.Color/ per-edgeBorder.Colorat the exact RGB Excel wrote, instead of the indexed-palette approximation HotXLS used to return for the same hücreler. Wave D is now fully closed in both directions. - Reader:
ParseXFExtwalks ixfe + cexts + rgExt. The parser handles the eight color ExtProp extTypes ($0004 fillFg, $0005 fillBg, $000D font, $0007/$0008/$0009/$000A/$000B for top / bottom / left / right / diagonal borders) and decodes each one's FullColorExt body (xclrType, nTintShade as signed Q15, xclrValue). xclrType 2 (RGB) and 3 (theme) get registered on the çalışma kitabı side-tablo against the record'sixfe; other extTypes ($0006 FillGradient, $000E FontScheme, $000F TextIndent) skip cleanly so a future wave can add them without disturbing this code path. Defensive bounds checks oncbmean a malformed record terminates parsing of its tail without reading past the declared length. - hücre color getters consult the side-tablo first. The eight color getters that previously routed straight through the indexed-palette path (
GetCustomColor(GetColorIndex)) now resolve their XF index, queryTlxFormatList.TryGetRichSlotfor the matching rich-color slot, and applynTintShadevia the existingGetRGBTIntyardımcı when the slot carries an RGB value. xclrType=3 (theme) falls through to the indexed path: the BIFF çalışma kitabı has no theme model on this call chain, so the palette approximation remains the best available answer for theme hücreler. hücreler whose XF was never touched by a Phase 2 setter or a parsed XFExt produce the same byte-identical okumak result as before. - Wave D is closed. kaydetme korur caller-set RGB (Phase 2). Load korur Excel-set RGB (Phase 3). çalışma kitapları with no rich color information emit the same byte stream as before. The only remaining caveats stay documented as known limits: theme colors still down-grade through the BIFF palette because there is no theme color manager on this side of the codebase, and compound border selectors (
xlAround/xlInside*) tag a single ambiguous side-tablo slot rather than per-edge — both rare enough to leave for a future wave.
Sürüm 2.59.0
- Chart backlog wave D phase 2: XFExt ($087D) emission for BIFF8 hücre colors. When application code sets
cell.Interior.Color := $00FF6633(or any other RGB) on the BIFF8 path, the writer now emits a$087DXFExt record alongside the indexed-palette XF entry so Excel reopens the çalışma kitabı with the exact RGB the caller passed in, rather than the closest 56-color palette approximation HotXLS used to fall back to. Covers all four hücre color surfaces:Interior.Color/Interior.PatternColor/Font.Color/ per-edgeBorder.Color(top / bottom / left / right / diagonal) and the convenienceBorders.Colorwhich now distributes to the four primary edges so each gets its own XFExt slot. - How the round-trip stays safe. The BIFF8 hücre setter chain still produces the indexed-palette XF wire output it always did — readers (HotXLS or anything else) that ignore
$087Dsee the legacy approximation. The XFExt record sits next to the XF and carries the original RGB as a 16-byte FullColorExt (xclrType=2, xclrValue=$00BBGGRR, nTintShade=0) wrapped in an ExtProp with the spec-correct extType for each slot ($0004 fillFg, $0005 fillBg, $000D font, $0007/$0008/$0009/$000A/$000B for top/bottom/left/right/diagonal borders). hücreler that never took the color-setter path still emit no XFExt — çalışma kitapları with no rich colors produce the same byte stream as before. - Storage and bookkeeping. A new per-XF rich-color side-tablo in
TlxFormatListholds the original RGB / theme info the hücre setter passed in, keyed by the çalışma kitabı's hash-resolved XF index.TXLSRange.SetXFProperty/SetRangeXFBordersPropertygrew an optionalOnNewIndexcallback so the hücre setter can register the rich color against every XF index the hücre ends up on (multi-hücre aralıklar that hash to multiple distinct XFs all get tagged). The side-tablo is consulted inStoreWorkbookright after stiller and before PALETTE, matching the*XFExtposition in [MS-XLS] §2.1.7.20.3 çalışma kitabı Globals ABNF. xlExcel5 output is untouched (BIFF5 has no XFExt record). - Known limit. The reader side stays at the wave-D-phase-1 acknowledgement:
ParseXFExtconsumes$087Drecords from the input stream but does not yet feed the recovered RGB back into the çalışma kitabı's stil objects, because doing so in the hash-keyed stil model risks invalidating existing XF entries. Files saved by HotXLS now look correct in Excel; files coming in from Excel still surface the indexed-palette approximation when okumak back throughcell.Interior.Color. Closing that okumak-side gap is a separate follow-up (Phase 3) that requires reworking the stil hash to admit per-XF rich color before the first hash anchor.
Sürüm 2.58.1
- Chart backlog wave D (okumak-side acknowledgement only): XFExt ($087D) no longer routed through the default-skip path. A new
ParseXFExtbranch in the BIFF8 çalışma kitabı-globals case tablo consumes$087Drecords that Excel yazar alongside RGB and theme-colored hücre stiller. The reader still leaves the indexed-color XF record unchanged — full RGB / theme precision recovery onto the çalışma kitabı's hash-key stil model is deferred to a separate wave because it would require the BIFF writer-side stil classes to grow an RGB / theme color field that doesn't exist today. Files coming from Excel with rich colors continue to load with the indexed approximation HotXLS has always produced, but the spec-conformance gap of "treating$087Das unknown" is closed. - Why not the full wave-D scope. The plan envisioned a paired yazmak + okumak implementation, but exploration found that the BIFF yazmak pipeline (
TXLSWorkbook.FXFList: TlxFormatList) encodes XF stil data as a string-key with hex-packed indexed color slots and has no analogue of the XLSX-sideTXLSStyleColor(which carriesColorType/ColorValue/TintAndShade). Adding XFExt emission would mean either bridging the two stil models or extendingTlxFormatListwith per-XF rich color side-tablolar, both of which are larger refactors than a single wave can absorb. The change here therefore stays surgical: lxRead recognises the record, lxStyleXf and lxHandle are unchanged.
Sürüm 2.58.0
- Chart backlog wave C: SST rich-text and phonetic round-trip (BIFF8 XLUnicodeRichExtendedString). Rich-text formatting set in Excel (a hücre whose individual characters carry their own font / color, the "two colors in one hücre" effect from the Format hücreler dialog) sits in the shared string tablo as an
XLUnicodeRichExtendedStringwith an attachedrgRunFormatRun array. Far-East phonetic info (the furigana / hiragana annotation above kanji) attaches as anrgExtRstblock on the same record. HotXLS previously dropped both on load and re-emitted the string as plain text on kaydetme, so opening then resaving a çalışma kitabı flattened every multi-format hücre to a single font / color. The shared-string parser artık korur both trailing blocks per unique string, and the writer re-attaches them when the string fits a single SST record. - Reader walks Continue boundaries without re-reading flag bytes. A new
CollectRawTailyardımcı insideParseSSTpulls the rawrgRunbytes (cRun × 4 bytes per FormatRun) followed by the rawrgExtRstbytes, spilling across Continue ($003C) records as needed — neither block is re-prefixed with the string’s flag byte at a Continue boundary per [MS-XLS] §2.4.58, which the old per-byte skip logic could not korumak correctly whenrtorszovershot the current record. The preserved tails are registered against the çalışma kitabı SST through the newTXLSStringTable.AddWithExtras, which deliberately does not bump the hücre-reference counter so subsequentLabelSSTparsing still produces correctcstTotalon kaydetme. - Writer attaches fRichSt / fExtSt + cRun / cbExtRst + rgRun + rgExtRst when the whole record fits in one BIFF chunk.
AddSSTItemnow factors the rich / phonetic tail size into its overflow check; strings whose body + tails fit a single 8224-byte SST chunk emit the full preserved layout, and Excel re-opens the çalışma kitabı with the original formatting intact. Strings that overflow fall back to plain text without formatting (the splitter would otherwise need to interleave Continue flag bytes with the still-running rgRun byte stream, a state machine the current writer doesn't have); this is the explicit known limitation documented in the wave-C plan and affects only very long rich-formatted strings (> ~4000 wide chars). - Continue flag byte corner case fix (carried over from the v2.54.0 SST audit). Per [MS-XLS] §2.4.58 the leading flag byte of an SST Continue record carries only the
fHighBytebit (bit 0); bitsfExtSt(bit 2) andfRichSt(bit 3) MUST be ignored because those structures exist exactly once at the head of the first record.ParseSSTnow masks the Continue flag byte with$01, preventing a stray high bit from making the reader skip ahead 2 or 4 bytes looking for cRun / cbExtRst fields that aren’t there and misaligning every byte that follows.
Sürüm 2.57.0
- Chart backlog wave G: Header / Footer pictures survive the round-trip (BIFF8 HFPicture). When Excel saves a çalışma sayfası with a header or footer background image (Insert → Header & Footer → Picture, then the company logo stil), the picture sits in an
HFPicture($086C) record that embeds an OfficeArt BLIP. HotXLS previously had no case branch for this record so the entire payload was dropped on load; saving the çalışma kitabı again therefore lost the header/footer image. The reader artık korur the full record body (every Continue chunk concatenated) per sheet, and the writer re-emits it in the spec-correct position so Excel reopens the file with the original images intact. - Reader concatenates all Continue chunks before storing the payload. The new
ParseHFPicturebranch inParseWorksheetRecordwalks every entry of the collatedDataList(the $086C body in slot 0 plus any number of $003C bodies that follow) and stores the joined bytes as a singleTByteson the çalışma sayfası. A sheet may carry several entries — up to six in Excel's UI (default / first / even pages × left / center / right) — so the storage is an array rather than a single field. - Writer emits HFPicture records right after PageSetup, then lets the existing Continue splitter handle the BLIP overflow. A new
StoreHFPicturesstep inserts itself into the per-sheet store sequence immediately afterStoreSetup, matching the*HFPictureposition in [MS-XLS] §2.1.7.20.2 çalışma sayfası ABNF. Each preserved body is wrapped in a fresh $086C header and routed throughAppendData— the existingAddContinueyardımcı takes over when the BLIP exceeds the 8224-byte BIFF limit, so a 30-50 KB JPEG ends up spread across one $086C plus four to six $003C records exactly the way Excel yazar it. - No new public API surface. Wave G is a round-trip preservation feature; HFPicture content is opaque to application code (no caller-facing setter to inject a new header image). çalışma kitapları that never carried an HFPicture record produce byte-identical output as before. The internal yardımcı
TXLSWorksheet._AddHFPictureBlobis reserved for the reader; the underscore prefix flags it the same way as_Drawing/_Autofilter.
Sürüm 2.56.0
- Chart backlog wave B: çalışma sayfası tab color round-trip (BIFF8 SheetExt). Sheet tab colors set in Excel via right-click Tab Color are now both readable and writable through the BIFF8 path.
TXLSWorksheet.TabColoris a new public özellik that takes a HotXLSLongWordcolor (low byte=R, mid=G, high=B, top byte=0, same convention asFont.Color/Interior.Color); the default value0means "automatic / no tab color" and suppresses the record entirely. - Writer emits a per-sheet
SheetExt($0862) record. One 48-byte record is appended to the çalışma kitabı globals stream just before EOF for every sheet whoseTabColoris non-zero. Layout follows [MS-XLS] §2.4.282 SheetExt v1 + §2.5.108 FullColorExt: the 12-bytefrtRefHeaderU+ 4-bytecb+ 4-byte reservedflagsTab1+ 16-byte FullColorExt block (xclrType=2 RGB, nTintShade=0, xclrValue=tab color) + 4-byteiTabId(0-based stream order of the matching BoundSheet8) + 4-byte reservedflagsTab2.iTabIduses the same iteration order as the BoundSheet block so the two stay aligned across multi-sheet çalışma kitapları. xlExcel5 output is untouched (no SheetExt record in BIFF5). - Reader restores the tab color on açma. A new
ParseSheetExtbranch inParseWorkbookRecord's case tablo okuriTabIdand the FullColorExt block and yazar the resolved RGB value back toSheets[iTabId + 1].TabColor.xclrType=2(RGB) stores the raw value;xclrType=1(indexed icv) resolves through the çalışma kitabı palette (Colors[icv, 0]) so the application sees a concrete RGB regardless of how Excel happened to encode it;xclrType=0(auto) andxclrType=3(theme) leaveTabColorat its default0, matching the writer-side "no tab color" semantics. - round-trip example. Setting
Workbook.Sheets[1].TabColor := $00FF00(green: B=0, G=$FF, R=$00) before SaveAs to .xls produces a çalışma kitabı that opens in Excel with a green tab; saving that same çalışma kitabı back out and re-opening it returns the özellik to$00FF00. Files coming from Excel with one or more tab colors are now opened without losing the colors, instead of having every tab default to automatic.
Sürüm 2.55.1
- Restore main-branch build. Two pre-existing identifier errors that left HotXLS unable to compile on RAD Studio 12+ are now fixed. Both came in with earlier bug-fix releases but had no compile gate, so the regressions only surfaced when the next contributor tried to rebuild the package.
- Shared-formül multi-column writer no longer references a missing record field. The v2.50.0 SHRFMLA wire-format fix eklendi
Data.AddByte(Group.LastCol)inWriteShrfmlabut did not extendTXLSShrfmlaGroupwith the new field, so the package failed to compile with "Undeclared identifier: LastCol". The record now carriesLastColalongside the existingFirstCol, andCollectSharedFormulas.OpenGrouppopulates it with the group's anchor column. Behaviour on single-column shared-formül groups (the only kind the collector currently produces) is unchanged; the spec-correctcolLastbyte is now real instead of an alias ofcolFirst. - XLSX hücre writer references
XlsxFloatToStrthrough a forward declaration. The v2.51.0 locale-safety fix introduced an XlsxFloatToStr call in the hücre-value branch (line 2718) but the yardımcı is defined a few hundred lines below (line 2910). Without a forward declaration, Delphi's single-pass compiler reported "Undeclared identifier: XlsxFloatToStr". A forward declaration is now placed at the top oflxHandleX's implementation block so both the early call site and the existing definition compile cleanly.
Sürüm 2.55.0
- Chart backlog wave A: multi-series cache wiring + chart / axis title captions. Two long-standing chart-builder limitations are now fixed; both come from the v2.54.0 audit backlog. The first emit-side change is wire-format only (no API change); the second wires through existing
AddChartSheetTitle / CatAxisTitle / ValAxisTitle parameters that previously had no effect. - Per-series values cache, no longer truncated to Series[0]. [MS-XLS] §2.1.7.20.1 chart-sheet ABNF allows
*(SIIndex *NUMBER)— oneSIIndex(1) + N×NUMBERblock per series. The Phase-1 builder emitted only one cache block sized bySeries[0].ValArea, so any later series with a longer value aralık had its cache slots silently cut short. The builder now (a) computes the maximum point count across all series for theDIMENSIONSrow aralık, and (b) loops over every prepared series emitting an individualSIIndex(1)block whose NUMBER count matches that series'AreaPointCount(ValArea). Cache slots stay zero-valued (BRAIPtgArea3dreferences still resolve to the live source hücreler at draw time); the change is purely about giving Excel's strict parser a complete cache footprint. - Chart Title / CatAxisTitle / ValAxisTitle captions are written through. The Phase-1 implementation accepted three Title parameters on
AddChartSheetoverloads and silently discarded them ("Junk := Length(...)" placeholder). They now emit a proper attached-label block —TEXT($1025) +POS+BRAI-literal-tStr +SeriesText($100D) +OBJECTLINK($1027) + End — at the spec-correct position just before theCHARTcontainer's End record per [MS-XLS] §2.1.7.20.1 CHARTTITLES ABNF.OBJECTLINK.wLinkObjuses 1 for chart title, 2 for value-axis title, 3 for category-axis title per [MS-XLS] §2.4.182. Callers passingTitle := 'Quarterly Sales'finally see "Quarterly Sales" rendered above the plot area in Excel.
Sürüm 2.54.1
- [MS-XLSX] cross-audit follow-up. Two targeted düzeltir from the v2.52.0 audit’s "deferred" list. Both are user-observable; neither breaks existing call sites.
- Date hücreler keep their date format when combined with any single non-numFmt stil. A
TDateTimehücre withFontIndex/FillIndex/BorderIndex/AlignmentIndex/ProtectionIndexset but no explicitNumberFormatIndexused to route through a single-dim cellXf whosenumFmtIdwas 0 (General), so Excel rendered the hücre as a raw serial number (e.g.46038) instead of1/15/2026. The XLSX stil engine now treats the implicit date as a virtual dim: any other styled dim promotes the hücre into a composite cellXf that carriesnumFmtId=14alongside the real dim. Pure-date hücreler with no other styling still route toXlsxXfIndexDateas before. New public surface:TXLSXWorkbook.RegisterCompositeXf/GetCompositeXfgain 7-arg overloads that accept an OOXML built-innumFmtIdoverride (the existing 6-arg signatures are unchanged and forward to the new variant with the override disabled). - Sheet names that violate Excel’s naming rules are auto-sanitised. Excel rejects sheet names that exceed 31 characters, contain
: \ / ? * [ ], start or end with a single quote, equal the reserved nameHistory(case-insensitive), or collide with another sheet name (case-insensitive). HotXLS used to pass the raw user input straight through, so calls likeWorkbook.Sheets.Add('Q1:Q2 Sales')produced a çalışma kitabı that failed to açma with the “The name you entered is not valid” dialog.TXLSXSheets.Addnow normalises the name via the newXlsxSanitizeSheetNameyardımcı (forbidden chars become_, surrounding single quotes drop, length caps at 31, empty / reserved fall back to'Sheet') and appends a' (2)'/' (3)'suffix on case-insensitive collisions. Idempotent on already-valid names, so sheets parsed out of conforming .xlsx files round-trip unchanged.
Sürüm 2.54.0
- Deep spec-audit round 2 against [MS-XLS] v20250520 / [MS-OFFCRYPTO] v20240820. Eight independent corner-case / wire-format defects found by eight parallel code-reviewer agents auditing çalışma sayfası shell records, SST/Continue edges, formül PTG depth, encryption padding, chart records, drawing/comment writer, and Pivot/tablo destek. Public API unchanged; existing code recompiles untouched.
- Comment Note record now spec-conformant. Two distinct düzeltir in
TMsoDrawing.StoreNotes(per [MS-XLS] §2.4.179 Note): (1)idObjis now written as a Word (2 bytes) instead of a LongWord (4 bytes), correcting a 2-byte offset slide that misaligned every byte after idObj; (2) the previously absentstAuthorXLUnicodeString field is now serialized (cch + flags + UTF-16 body) fromFAuthorinstead of being replaced by a bareWord(0). Excel's strict reader terminates Note parsing atstAuthor, so omitting it corrupted comment metadata on round-trip even when Excel still opened the file. - Comment
Visibleözellik no longer inverts intent.TMSOShapeTextBox.GetVisible/SetVisiblereturned True whenfHiddenwas set and storedfHiddenwhen callers asked for the comment to be visible — the bit's meaning is the inverse ([MS-XLS] §2.4.179 grbit bit1: 1 = hidden). Callers usingComment.Visible := Truepreviously got hidden comments; now the özellik matches its name in both directions. - RC4 password derivation correct for 16-character or longer passwords. [MS-OFFCRYPTO] §2.3.6.1 stores the MD5 single-block message-length field as a 64-bit little-endian bit count in bytes 56–63. The previous reader (
lxDecryption) and writer (lxEncrypter) both wrote only the low byte viaSetByte, silently dropping the high byte for passwords of 16+ characters (length-in-bits ≥ 256). Long-password files now derive the same ValDigest on both sides; previously long passwords were rejected even when correct, and HotXLS-encrypted files with long passwords could not be re-opened. - formül
tFuncVartoken now masks thefCeFuncbit out of the function-name lookup. [MS-XLS] §2.5.198.63 splits the trailing Word intotab(15 low)+fCeFunc(1 high); the reader stored the full Word intoItem.IntValueas the hash-tablo key, so functions emitted with the user-prompt flag (macro/UDF callers) hashed to$8000 | iftaband produced an empty function name, killing the entire formül. Now masked with$7FFF. - Multiple FILEPASS records are now ignored after the first. [MS-XLS] §2.4.117 allows at most one FILEPASS; a hostile or malformed çalışma kitabı with a second FILEPASS used to free the live decrypter and re-derive a fresh keystream mid-stream, putting it out of sync with the data already consumed. Subsequent FILEPASS records are now silently dropped while encryption stays armed.
- PtgArray V-class opcode emitted correctly.
GetArrayData(aClass=0)previously fell through to the A-class opcode ($60); per [MS-XLS] §2.5.198.32 the opcode is$20for V-class,$40for R-class,$60for A-class.aClass=0now correctly maps to$20. - Chart3DBarShape no longer emitted on 2D charts. [MS-XLS] §2.4.47 specifies that Chart3DBarShape "MUST be ignored if the current substream does not contain a Chart3d record". HotXLS doesn't yet destek 3D chart types (no Chart3d record emitted), so writing an empty Chart3DBarShape inside every DataFormat block was both redundant and non-spec (the empty payload also failed the 2-byte riser+taper layout). The record is now omitted entirely.
- Audit backlog captured in
TechnicalNotes.md. Larger spec gaps surfaced by the round 2 audit (XFExt records not emitted, PtgArray constant data not serialized, Chart Title/CatAxisTitle/ValAxisTitle parameters dropped, per-series chart cache, Pivot tablo / QueryTable / DConn unsupported) are documented as known gaps for future feature work rather than silent omissions.
Sürüm 2.53.0
- OpenOffice excelfileformat.pdf cross-audit round 2. Three additional BIFF8 wire-format düzeltir uncovered by re-running the spec sweep after v2.50.0, this time targeting modules the first pass had touched only lightly: the formül token decoder, the XF alignment byte, and the ROW outline-collapse boundary check. Public API unchanged.
- Macro-command formüller with the user-prompt flag no longer corrupt the parser (§3.7.2 tFuncVar). The reader pulled the byte at offset+1 of a
tFuncVartoken straight into the argument count, but bits 6-0 ($7F) carry the argument count and bit 7 ($80) is the "user prompt for macro commands" flag. Any tFuncVar with the prompt bit set was okumak as 128 + N arguments, blowing the formül stack and yielding nil for the whole expression. The reader now masks with$7Fper spec. - JustifyLastLine alignment flag round-trips correctly (§5.115 XF). The XF BIFF8 body's alignment byte (offset 6) packs HorAlign + WrapText + VerAlign + JustifyLastLine. Previous code wrote three of those four fields but omitted bit 7 (
$80, JustifyLastLine). hücreler withJustifyLastLine = Truekaydetme with the bit cleared, so the distributed / justified last-line rendering reverts to the Excel default after a kaydetme / reopen. - Row 0 / row 65535 no longer mis-flagged as outline-group boundaries (§5.88 ROW). The fCollapsed (
$10) bit is set when a row's outline level differs from its neighbours. For the boundary rows the "neighbour" doesn't exist, butOutlineLevel[-1]andOutlineLevel[65536]returned the default level 1, which made every row 0 / row 65535 with an explicit outline level > 1 falsely register as a collapsed outline group edge. The check now treats absent neighbours as matching the row's own level so the transition fires only for genuine outline boundaries.
Sürüm 2.52.0
- [MS-XLSX] cross-audit — round 2. Three follow-up refinements to the XLSX writer after the v2.51.0 audit. Each item is independently grounded in an ECMA-376 or W3C XML clause; combined effect is better OOXML consumer interop and quieter validation output.
- hücre strings with leading / trailing whitespace round-trip. The inline-string fallback in
XlsxFormatCellValueemitted<is><t>...</t></is>withoutxml:space="preserve"; XML 1.0 §3.3.3 normalization stripped the surrounding spaces on load, so a hücre whose value was “ Pending ” came back as “Pending”. The SST, rich-text run, and comment-text paths already carried the attribute; the inline-string fallback now matches. - Every çalışma sayfası now carries a
<dimension>hint. ECMA-376 §18.3.1.35 marks the<dimension ref="..."/>element optional but every Excel-written .xlsx contains it; consumers that okumak it (Apache POI / NPOI / OOXML SDK) pre-size their hücre buffers from the hint instead of growing dynamically. The writer now computes the bounding rectangle of populated hücreler during the row-grouping pass and emits the element as the second child of<worksheet>(after<sheetPr>if present, before<sheetViews>). Empty çalışma sayfaları collapse to<dimension ref="A1"/>. <sst count="...">reports total hücre references, not unique strings. ECMA-376 §18.4.8 definescountas the total reference count anduniqueCountas the distinct-string count; the writer used to emit both asFStrings.Count(always equal), misleading OOXML consumers about reference density.TXLSXSharedStringsnow tracks a separateRefCountthat increments on everyAdd/AddRichcall regardless of dedup, and the attribute reports the real reference total.
Sürüm 2.51.0
- [MS-XLSX] cross-audit pass. Five wire-format and locale-safety düzeltir across the XLSX writer uncovered by validating against the Microsoft [MS-XLSX] — Excel (.xlsx) Extensions to the Office açma XML SpreadsheetML File Format dokümantasyon (v20260108) and the underlying XML 1.0 / OOXML schema requirements. Public API is unchanged; existing applications recompile and re-kaydetme without modification.
- Saved .xlsx files now açma on every Windows region. Page margins, column widths, row heights, font sizes, color tints, theme tints, özel-font rich-text run sizes, and the
<v>-wrapped numeric value of every hücre were being serialised through Delphi’s locale-awareFloatToStr. On Windows configured for a region whose decimal separator is ',' (most of continental Europe and parts of Asia / Latin America) the writer emitted attribute values likewidth="8,43"andtop="0,75", which the OOXML schema rejects — Excel surfaced “We found a problem with some content in <file>.xlsx” and offered a recovery pass that wiped page setup, column widths, and the numeric hücre values. Every double-valued OOXML attribute now uses an invariant '.' separator regardless of the active region. The same fix also patches the in-memory column-width / row-height cache that previously stored locale-formatted strings;GetColWidth/GetRowHeightreturned0.0right after aSetColWidth/SetRowHeightcall on the same çalışma kitabı in those regions. - hücreler containing control characters no longer break the çalışma kitabı. XML 1.0 §2.2 forbids ASCII codes 0x00–0x08, 0x0B, 0x0C, 0x0E–0x1F (and U+FFFE / U+FFFF) anywhere in an XML document — they cannot be encoded as numeric character references either. hücre values that happened to contain those bytes (legacy data feeds, log dumps, escape-key sentinels) used to be written into
<t>...</t>verbatim, producing an .xlsx Excel refuses to açma with no path back to the data. The writer now silently strips the forbidden code points; valid whitespace (TAB / LF / CR) is preserved. - Newlines inside attribute values round-trip correctly. XML §3.3.3 normalises raw TAB / LF / CR inside an attribute value to a single space before handing the value to the application. Multi-line headers / footers, defined-name comments, multi-line data-validation prompts, hyperlink display strings, and any other attribute that carried a newline used to collapse to a single space on load.
XlsxEscapeAttrnow emits those characters as	/
/
numeric character references so Excel okur them back as the original whitespace. - <col> entries emitted in ascending column order. ECMA-376 18.3.1.4 / 18.3.1.13 expects every
<col min="..."/>entry to appear in ascendingminorder. The previous TStringList(Sorted=True) dedup sorted the integer column indices lexically ("10" before "2"), so a sheet that customised both column 2 and column 10 produced<col min="10"/>before<col min="2"/>. Excel tolerated the layout but Office File Validation flagged the file and strict OOXML consumers (Apache POI strict mode, LibreOffice with strict-validation enabled) rejected it. Column entries are now sorted numerically before emission.
Sürüm 2.50.0
- OpenOffice excelfileformat.pdf cross-audit pass. Eight follow-up wire-format and lifetime düzeltir uncovered by re-validating the BIFF8 writer / reader against the OpenOffice Microsoft Excel File Format dokümantasyon after the v2.49.0 [MS-XLS] pass. Public API is unchanged; existing applications recompile and re-kaydetme without modification.
- Shared formüller now span the full column aralık (§5.94 SHAREDFMLA). The
SHRFMLArecord body wrotecolFirstinto thecolLastbyte, collapsing every multi-column shared formül group to a single-column group in Excel. Fill-down formüller across two or more columns now expand to the correct hücreler when the çalışma kitabı is reopened. The reader-sidecolLastwidth was also corrected (was reading a 16-bit value that pulled in the adjacent reserved byte). - Shared formül Boolean / Error results round-trip correctly (§5.50 formül). The same
FormulaValuebyte-layout bug fixed in v2.49.0 for standalone formüller was still present in the shared-formül writer (hücreler that carry atExptoken pointing at aSHRFMLAmaster). CachedTRUE/FALSEand#REF!/#DIV/0!/etc. values now appear as written instead of always reading back asFALSE/#NULL!. - formül option flags identify shared-formül members (§5.50 formül). hücreler inside a shared-formül group now set the
fShrFmlabit (0x0008) in the formül record option flags so strict parsers recognise thetExptoken as a back-reference instead of attempting to evaluate it as an opaque opcode. - Bold and underlined fonts identified correctly by strict readers (§5.45 FONT). The FONT option-flags word now sets bit 0 (bold) and bit 2 (underlined) in addition to the dedicated
bls/ulsfields. LibreOffice içe aktarma paths and Office File Validation that check the option flags rather than the standalone fields no longer mis-classify bold or underlined fonts as plain. - CFRULE option flags carry spec-mandated constant bits (§5.16 CFRULE). When at least one formatting block is present the option-flags DWORD now ORs in bit 7 (
0x00000080, "Always 1") and bits 21-19 (0x00380000, "Always 111"). Conditional-formatting rules survive a kaydetme / load round-trip on strict CFRULE parsers; the "no format blocks" special case (all-zero option flags) is preserved. - CHOOSE() formüller okumak back correctly (§3.10.5 tAttrChoose). The
tAttrparser previously skipped a fixed 4 bytes for every subtype;tAttrChoose($04) is variable-length (header + per-choice jump tablo + error jump), so the decoder walked into the jump-tablo contents and corrupted every following token. The decoder now okurncand advances by6 + 2·ncbytes, matching the spec layout. - Data-validation and conditional-formatting teardown no longer dereferences past the tail. Two
Destroydestructors (TDataValidator,TCondFormatter) walked0..cnton lists whose valid indices are0..cnt-1, accessing one element past the end during çalışma kitabı teardown. Long-running applications that build and discard many CF / DV containers no longer occasionally AV at shutdown.
Sürüm 2.49.0
- Spec-audit pass against [MS-XLS] v20250520. Sixteen wire-format and behaviour düzeltir across the BIFF8 writer, formül decoder, encryption path, chart builder, conditional-format and data-validation runtime, SST/ExtSST index, VBA storage reader and OLE stream açma path. Public API unchanged; existing code recompiles untouched. Highlights below.
- BIFF8
Formularecord Boolean and Error results now round-trip correctly. [MS-XLS] §2.5.133FormulaValuepacks the type tag into byte[0] and the bool/error code into byte[1]; the writer used to emit$0001/$0002as a Word and put the value into byte[2], so cached Boolean formüller okumak back as False and Error formüller as #NULL! in every consuming application. - hücre colours set via
SetColorRGBrender correctly. The colour manager wrote ColorType=1 (theme) for RGB values and ColorType=2 (RGB) for theme values, swapping the two code paths. Both setters now route through the matching ColorType bucket so RGB values feed the RGB resolver and theme indices feed the theme resolver. - XOR Obfuscation and RC4 decryption fixed. The XOR yöntem-1 decrypt loop now matches [MS-OFFCRYPTO] §2.3.7.3 (XOR first, then rotate-right 5; seed XorArray index from the entry stream position, not the post-process position). RC4
Skipnow walks every 1024-byte boundary continuously instead of jumping straight to the destination block, keeping the keystream state aligned with the file position for every subsequentDecryptcall. - Chart sheet wire format aligned with the spec. SIIndex records emit in numIndex=1 → 2 → 3 order ([MS-XLS] §2.4.262; was 2 → 1 → 3, which strict parsers reject), DEFAULTTEXT count clamped to the spec maximum of 2 ([MS-XLS] §2.1.7.20.1; was 4), Chart3DBarShape placeholder uses the correct id
$105F(was$1066). - HLink tooltip records load correctly. The
HLinkTooltip($0800) body decoder used to okumak FrtRefHeader anchor fields at offsets 2/4/6/8 instead of 4/6/8/10, so the anchor-aralık comparison never matched and per-hücre tooltips were silently discarded; tooltips now associate with their hyperlinks. BIFF8 aralık-reference decoder also fixed aFFirstColRel/FLastColReltypo in the BIFF5/7 fallback sign-extension path that mis-decoded aralıklar with negative last-column relative offsets. - Conditional formatting and data validation runtime düzeltir.
IsContainRowin bothTCondRangeandTDVRangereturned true only when the aralık degenerated to a single row (the comparison was inverted); per-row clearing of CF / DV rules now works on multi-row aralıklar. Three destructors (CondFormat, formatter, DVRangeList) usedfor i := 0 to cnton lists whose valid indices are 0..cnt-1; the off-by-one is fixed and long-running workloads no longer occasionally AV during teardown. CF12 icon-set rules emit ct=$06(IconSet per [MS-XLS] §2.4.43) instead of ct=$05(Filter), so çalışma kitapları containing icon-set rules açma with the rules intact. - ExtSST quick-find index spec-conformant for large çalışma kitapları. The
dsstfield is now computed asmax((cstUnique / 128) + 1, 8)per [MS-XLS] §2.4.107 instead of the static default of 8; çalışma kitapları with more than ~900 unique strings now build a correctrgISSTInfbucket array and Excel's quick-find SST lookup works. - WriteAccess record honours [MS-XLS] §2.4.349 cch <= 54. The
userName.cchfield now carries the actual user-name length (6 for "HotXLS") with the remaining bytes filled by the spec-defined "unused" trailer. Previously the field carried cch=109, which Office File Validation flags as a hard format violation. - BIFF8 çalışma kitabı stream açma path matches the spec spelling. The first OLE
OpenStreamattempt uses 'çalışma kitabı' (capital W per [MS-XLS] §2.1.7.20) instead of all-lowercase, so compound-file containers on case-sensitive OLE implementations açma the stream on the first try. - VBA module reader no longer drops the last byte of each stream. The seek-to-end length used
trunc(l) - 1instead oftrunc(l), truncating the compressed-source tail and causing the RLE container decompressor to terminate early on certain modules.
Sürüm 2.48.10
- HotXLS-saved .xls files now include the two OLE compound-file özellik-set streams Excel expects on every çalışma kitabı:
\005SummaryInformationand\005DocumentSummaryInformation. Pre-v2.48.10 only TRIAL builds wrote them (as a banner-stamping mechanism); release builds produced .xls files whose çalışma kitabı stream was valid BIFF8 but whose OLE container was missing the standard Office metadata streams. Excel 2003's strict parser treats this as the "File error: data may have been lost" condition (modern Excel keeps the Protected View "this file has problems" banner). Adding the streams resolves the dialog on chart çalışma kitapları without changing any BIFF8 record. - The two streams are emitted via Win32's
StgCreatePropSetStg+IPropertySetStorage.Create+IPropertyStorage.WriteMultiplepath — the same code Microsoft Office uses, so Office File Validation accepts the byte layout. The SummaryInformation stream is created with defaultAppName="HotXLS"and empty Author; TRIAL builds still overwrite the Author / AppName values with the trial banner vialxTrial.XlsTrialStampXlsSummaryafter the default stamp, so trial files remain identifiable in Excel's File > Info > özellikler pane. The DocumentSummaryInformation stream is created empty (Win32 still emits the özellik-set header + CODEPAGE özellik — enough for Excel's strict parser to consider the metadata "present and well-formed"). - This fix is universal — every HotXLS-saved .xls now carries the standard OLE metadata, not just chart çalışma kitapları. çalışma sayfası-only outputs from earlier releases happened to escape the symptom because Excel is more lenient with metadata-less çalışma sayfası çalışma kitapları than with chart-sheet çalışma kitapları, but they were also technically missing the streams. New
Lib/lxXlsSummary.pasunit holds the two yardımcı procedures; lxHandle.pas calls them unconditionally insideTXLSWorkbook.SaveWorkbookafterStoreWorkbookpopulates the çalışma kitabı stream and beforeFDocStorage.Commit. - This release closes the eight-version chart-Phase-2 follow-up sequence (v2.47.0 — v2.48.10): from
tArea3Dseries binding, through BRAI id realignment, sdtX/cValx Excel-observed values, SERIESTEXT placement, çalışma kitabı stream padding removal, sheet-level shell records, and now OLE metadata streams. The result is a chart .xls that opens in Excel 2003 and modern Excel without any "file has problems" warnings, byte-aligned with what Excel itself yazar for the same data.
Sürüm 2.48.9
- BIFF8 chart sheets now carry the full set of sheet-level shell records that Excel 2003+ requires. v2.48.8's chart_phase2_demo.xls rendered the column chart correctly but Excel 2003 still surfaced a "File error: data may have been lost" dialog (newer Excel versions kept the Protected View banner) because the chart substream was missing the same sheet-level records a çalışma sayfası substream carries. Real Excel files (both from-scratch and re-saved variants of HotXLS output) wrap the chart records in this shell:
- Before the chart records (between BOF and UNITS):
HEADER($0014, empty),FOOTER($0015, empty),HCENTER($0083, value 0),VCENTER($0084, value 0),SETUP($00A1, 34-byte page setup),PRINTSIZE($0033, value 3). - After the chart records (after the outermost CHART END, before EOF):
DIMENSIONS($0200, 14 bytes) declaring the cached data aralık, threeSERIESINDEX($1065) markers for categories / values / bubble-size cache slots, aNUMBER($0203, 14 bytes) per cached value point, andWINDOW2($023E, 10-byte chart-sheet variant) at the end.
dev-notes/biffview-refs/excel_column_chart_resaved.xls(the Excel-saved column-chart reference, kept local). - Before the chart records (between BOF and UNITS):
- The values cache currently emits zero placeholders (
0.0for every data point), matching what Excel itself yazar when re-saving a chart whose source cache wasn't pre-populated. The chart still plots the real data because the BRAIPtgArea3dreferences resolve to the source çalışma sayfası hücreler at draw time — the cache is what lets Excel parse the chart sheet without warnings, not what feeds the plot. A future release can populate the cache with the actualValuesaralık numbers; the wire format is in place. - End-to-end smoke test: açma the regenerated
Demo/Delphi/XlsCreateChart/chart_phase2_demo.xlsin Excel 2003 — the "File error: data may have been lost" prompt no longer appears, and the column chart renders identically to before. The same file opens cleanly in modern Excel without the Protected View banner.
Sürüm 2.48.8
- BIFF8 (.xls) writer no longer pads the çalışma kitabı stream with trailing zero bytes.
TXLSWorkbook.StoreOleFileused to callStoreExtraSpace(Book)after the last sheet's records, padding the stream length up to the next 512-byte (OLE sector) boundary. Excel's strict parser treats those trailing zero bytes as a bogus stream of0x0000-id records and surfaces a "this file has problems" Protected-View prompt — visible on the v2.48.7 chart_phase2_demo.xls even after the BRAI / sdtX / SERIESTEXT wire format was fixed and the chart itself rendered correctly. Removing the call drops the padding from the çalışma kitabı stream content; OLE sector padding still happens, but in the CFB container layer below the stream where Excel itself puts it (every Excel-saved .xls has a non-sector-aligned çalışma kitabı stream length). - Symptom history: any HotXLS-saved .xls whose total valid-record byte length didn't already happen to land on a 512-byte boundary carried the trailing-zero stream. The bug existed from the repository bootstrap commit forward but rarely surfaced — most çalışma kitapları happen to have enough records that the padding ended up small (≤ 4 zero bytes that Excel tolerated). Chart-sheet çalışma kitapları happen to land far short of a sector boundary (the v2.47.0 — v2.48.7 demo padded 420 zero bytes), so this is where the Protected-View prompt became consistent.
StoreExtraSpacethe yöntem survives as private dead code inlxHandle.pasin case a future code path legitimately needs sector-rounded streams; the call site inStoreOleFileis removed. çalışma kitabı stream length now equals exactly the byte length of all valid records (chart demo: 3164 bytes; Excel from-scratch reference: 4419 bytes — both non-sector-aligned). Reader code paths are unaffected — HotXLS has always okumak non-sector-aligned çalışma kitabı streams from Excel-saved files correctly.
Sürüm 2.48.7
- BIFF8 chart series records finally render correctly in Excel. The fix is realigning BRAI id assignments with [MS-XLS] §2.4.51 — the parent implementation plan documented them inverted, propagating the bug through every chart release from v2.41.0 to v2.48.6. The correct id semantics are:
id = 0— series name / legend label (plan said: categories)id = 1— values (correct)id = 2— categories (plan said: name)id = 3— bubble sizes (plan said: errBars)
- Also realigned to match Excel-saved column-chart wire format:
SERIES.sdtXis now0x0003(Excel's observed value for text categories, not the [MS-XLS] §2.4.252 documented0x0001), andcValxcarries the actual category count instead of0. The "cValx MUST = 0whensdtX∈ {1, 3}" spec rule is contradicted by every Excel-saved sample examined. - The
SERIESTEXT($100D) literal-name carrier returns, but in the right place: immediately after theid = 0BRAI, still inside the SERIES BEGIN/END block. This is what real Excel files do — the v2.48.5 emit point (after the whole BRAI cluster, beforeDataFormat) was wrong and broke chart parsing; the correct position is right next to the series-name BRAI. - v2.41.0 — v2.48.6 saved chart files all carry the inverted-BRAI wire format. They açma in Excel without error but show the legend / X-axis symptoms above. Re-kaydetme through v2.48.7+ to migrate; no API change — the same
AddChartSheetcall now produces a chart that renders identically to what Excel itself would yazmak for the same data. - New byte-level inspection tool
dev-notes/biffview-refs/dump_chart_substream.pydumps the chart substream of any BIFF8 .xls with per-record decoding (SERIES / BRAI / SERIESTEXT / AXIS / CATSERRANGE / LEGEND / OBJECTLINK / POS / TEXT). Used during this release to byte-diff HotXLS output against the Excel-saved reference samples; available for future chart-spec follow-ups.
Sürüm 2.48.6
- BIFF8 chart-sheet substream retracts the v2.48.5 changes. Excel testing on the regenerated v2.48.5 demo did not render the chart at all — worse than the v2.47.0 baseline (where the chart drew but with wrong X-axis labels). The two v2.48.5 changes were the cause:
SERIES.sdtX = 4is not actually accepted by Excel even though Apache POI exposesCATEGORY_DATA_TYPE_TEXT = 4. [MS-XLS] §2.4.252 strictly requiressdtXto be0x0001or0x0003.- The eklendi
SERIESTEXT($100D) record inside the SERIES BEGIN/END block is a structural violation —SERIESTEXTbelongs in TEXT blocks (chart title / axis title / data label contexts), not inside the SERIES block. Embedding it there confused Excel's chart parser into rejecting the whole substream.
- v2.48.6 restores the v2.47.0 wire format AND ekler one spec-compliance fix:
SERIES.cValxis now0whensdtX = 1([MS-XLS] §2.4.252 spec MUST rule). Pre-v2.48.6 wrotecValx = count(4 in the demo) which violated the rule and may have contributed to Excel's "document has issues" Protected-View prompt.cValystill carries the actual value count (sdtY=1 has no zero-rule). - New XlsCreateChart Delphi demo under
Demo/Delphi/XlsCreateChart/creates a two-sheet çalışma kitabı: a "Data" çalışma sayfası with four (Region, Sales) rows and a "Chart1" column-chart sheet whose series bindsData!$A$2:$A$5/Data!$B$2:$B$5as Categories / Values. The demo is the permanent successor to the ad-hocchart_phase2_demo.xlsthat v2.47.0 — v2.48.5 placed in the repo root for BiffView testing; the root file has been removed, and the new demo yazar its output alongside its own .exe. - Known unresolved: with v2.48.6's wire format, Excel still renders the column chart's X-axis labels as zeroes and falls back to concatenating category hücre text for the legend (instead of using the BRAI id=2 PTG tStr literal
'Q1 Sales'). This is a real wire-format gap that needs an Excel-saved reference column chart to diff against — tracked as a follow-up. The 4-bar plot area itself renders correctly (heights 100/150/200/175 match Values).
Sürüm 2.48.5
- BIFF8 chart series records now render correctly in Excel. v2.47.0 eklendi
tArea3Dbinding for Categories / Values aralıklar, but Excel still drew the wrong X-axis labels (every category became0) and used the concatenated category text ("North South East West") as both legend label and auto-title instead of the user-supplied series name. Two düzeltir restore the intended rendering: - The
SERIESrecord'ssdtXfield is now4(text categories), not1. [MS-XLS] §2.4.252 documents only1(dates) and3(BIFF7 sequence) but real Excel-saved column / bar / line chart files yazmak4for text-axis categories (matching Apache POI'sCATEGORY_DATA_TYPE_TEXTconstant). WithsdtX=1Excel tried to coerce'North'/'South'hücreler to numbers, so the X axis showed four zeroes;sdtX=4lets the labels through verbatim. The pre-v2.48.5 wire form also violated the spec rule thatcValxmust be zero whensdtX=1. - A
SERIESTEXT($100D) record is now emitted inside the SERIES BEGIN/END block (after the BRAI cluster, beforeDataFormat) whenever a literal series Name is supplied. The Phase 2 first-half mechanism (BRAI id=2 + PTGtStr) is kept for completeness but Excel actually surfaces the legend label and the auto-title fromSERIESTEXT; with only the BRAI variant present, Excel fell back to concatenating category hücreler. After this fix the legend shows the real Name (e.g.'Q1 Sales') and an empty chart title leaves the auto-title slot blank rather than dragging category text into it. - Migration: v2.42.0 — v2.47.0 chart-sheet outputs still açma in Excel without error but rendered the symptoms above. Re-kaydetme through v2.48.5+ to get the corrected wire format; no API change is required, the same
AddChartSheetcall now produces the correct chart.
Sürüm 2.48.4
- BIFF8 CFEX ($087B) emit is retired. HotXLS no longer yazar the paired CFEX after every CF12 ($087A) record — all Data Bar / Color Scale / Icon Set configuration now travels inline in the CF12 kind tail (v2.48.1 — v2.48.3). HotXLS-saved .xls files become smaller and exactly match Excel's own output (Excel-saved samples like
poi_ConditionalFormattingSamples.xlscontain zero CFEX records). Apache POI / NPOI already ignore CFEX, so this is a pure simplification with no readability loss. - BIFF8 CF12 okumak path now consumes the kind tail directly from CF12 instead of falling back to CFEX.
ParseCfExbecomes a no-op; the lxRead dispatch entry for $087B stays so HotXLS-saved v2.34..v2.47 files don't crash, but their CFEX content is ignored (those files also have a pre-v2.48.0 CF12 header layout and would not round-trip correctly — re-kaydetme through Excel or HotXLS v2.48.x to migrate). - This completes the 5-PATCH Gap #6 wire-format rewrite (v2.48.0 header + v2.48.1 data_bar + v2.48.2 color_gradient + v2.48.3 multistate + v2.48.4 CFEX retire). HotXLS-saved Excel 2007+ conditional formatting records now match Excel's own wire format byte-for-byte (modulo formül content), making them interoperable with Apache POI / NPOI and any other spec-compliant BIFF8 reader.
Sürüm 2.48.3
- BIFF8 CF12 ($087A) Icon Set rules now emit the NPOI-compatible
multistatesub-record inline so Apache POI / NPOI can okumak the icon family identity, per-stop thresholds, and reverse / show-icon-only flags directly from CF12 without consulting the legacy CFEX record. Layout matches NPOIIconMultiStateFormatting.Serialize():reserved(2) + reserved(1) + num(1) + iconSet.id(1) + options(1)+ per-stopIconMultiStateThreshold(cfvo + equals byte + 4 reserved). - HotXLS
TXLSIconSetTypevalues0..16map 1:1 onto NPOI'sIconSetid enum (3Arrows / 3TrafficLights1 / 4RedToBlack / 5Quarters etc), so existing user code using icon-set constants continues to round-trip unchanged.ShowOnlysets options bit 0 (iconOnly),Reversesets bit 2. - Default per-stop thresholds (HotXLS
cfvPercentwith even-split values: 3-icon=0/33/67, 4-icon=0/25/50/75, 5-icon=0/20/40/60/80) emit as NPOI RangeTypePERCENT(4)+ value Double + equals byte (alwaysEQUALS_INCLUDE=1for now). This completes the kind-tail leg of the Gap #6 CF12 rewrite; CFEX emit retirement follows in v2.48.4.
Sürüm 2.48.2
- BIFF8 CF12 ($087A) 2-color and 3-color Color Scale rules now emit the NPOI-compatible
color_gradientsub-record inline so Apache POI / NPOI can okumak the per-stop threshold + color + interpolation positions directly from CF12 without consulting the legacy CFEX record. Layout matches NPOIColorGradientFormatting.Serialize():reserved(2) + reserved(1) + numI(1) + numG(1) + options(1)+ per-stopColorGradientThreshold(cfvo + position Double) + per-stopstep + ExtendedColor. - Stops use NPOI's
step = 1 / (N-1)formül so a 3-stop Color Scale gets positions 0.0 / 0.5 / 1.0 and a 2-stop Color Scale gets 0.0 / 1.0. Per-stop colors (RGB or theme viaSetThemeColor) flow through the same ExtendedColor block used by Data Bars in v2.48.1. - Default kinds for 3-stop ColorScale (cfvMinOfRange / cfvPercentile=50 / cfvMaxOfRange) map to NPOI RangeType
MIN(2) / PERCENTILE(5) / MAX(3); the middle stop's value (50.0 as Double) and per-stop position are byte-verified againstpoi_ConditionalFormattingSamples.xlsrecord 215 in the test suite.
Sürüm 2.48.1
- BIFF8 CF12 ($087A) Data Bar rules now emit the NPOI-compatible
data_barsub-record inline (28 bytes appended aftertemplate_params) so Apache POI / NPOI can decode the bar color, min/max thresholds, and percent length bounds without consulting the legacy CFEX record (which POI ignores entirely). Layout matches NPOIDataBarFormatting.Serialize():reserved1(2)+reserved2(1)+options(1)+percentMin(1)+percentMax(1)+ ExtendedColor(16) + ThresholdMin/Max. - HotXLS bar color (BGR
LongWord) is written into the ExtendedColor block withtype=RGB; theme-color Data Bars (set viaSetThemeColor) emittype=THEMED+ themeIndex + tint.MinLength/MaxLengthdefault 10% / 90% (configurable via the spec object), matching Excel's standard Data Bar appearance. - Color Scale and Icon Set kind tails (v2.48.2 — v2.48.3) and CFEX retirement (v2.48.4) are still pending; this release only completes the Data Bar leg of the Gap #6 CF12 rewrite. See the v2.48.0 entry for the header rewrite that this PATCH builds on.
Sürüm 2.48.0
- BIFF8 CF12 ($087A) record header layout corrected against NPOI
CFRule12Record.serialize()and Excel-saved reference files. The previous layout placedipriority/iTemplate/grbit/parmsimmediately aftercce2and treatedcbdxfas a 2-byte length field; Excel actually yazarext_formatting_length(4)+ an optionalSerializeFormattingBlockheader before the formül tokens, followed byformula_scale,ext_opts,priority,template_type, and a length-prefixedtemplate_paramsblock. - HotXLS-emitted CF12 records now match the byte layout of
poi_ConditionalFormattingSamples.xlsrecords 152..215 in the header section (data_bar / color_gradient / multistate kind tails arrive in v2.48.1 — v2.48.3; the paired CFEX still emits in this release and retires in v2.48.4). See the v2.47.1 entry for the CONDFMT12 sibling fix that motivated this rewrite. - The bogus 2-byte
nIDfield HotXLS appended at the end of every CF12 payload (no such field exists in the spec) is removed — rule identity is carried by the parent CONDFMT12 record. Existing v2.34.0 — v2.47.1 .xls files should be re-saved through v2.48.0 to rewrite their CF12 records.
Sürüm 2.47.1
- BIFF8 CONDFMT12 ($0879) record wire format corrected to match Excel-saved files. The previous implementation followed an early draft layout that placed the 8-byte associated aralık as "reserved" inside the FtrHeader and inserted a non-existent 4-byte Reserved field before
numCF; Excel-saved .xls files actually fill the 8 bytes inside FtrHeader with the rule's associated hücre aralık and have no Reserved field, so HotXLS-emitted files were shifted by 4 bytes plus had a zeroed aralık slot. Reference dump frompoi_ConditionalFormattingSamples.xls(Apache POI test fixture) record 152 now matches HotXLS output byte-for-byte. - Concrete fix:
StoreCondFmt12Headernow yazar FtrHeader asrt(2) + grbitFrt(2) + associatedRange(8), then the body asnumCF(2) + needRecalcAndId(2, bits packed) + enclosingRange(8) + cref(2) + sqref array. Total fixed bytes drop from 30 to 26 (Reserved 4 removed).ParseCondFmt12updated symmetrically to okumak at the corrected offsets. - Existing HotXLS-generated .xls files written by v2.34.0 — v2.47.0 should be re-saved through v2.47.1 to repair their CONDFMT12 records. Files round-tripped via Excel between version bumps were never affected because Excel rewrote the records to its own correct layout on kaydetme.
Sürüm 2.47.0
- BIFF8 chart-sheet creation now binds real data aralıklar to series. The
CategoriesandValuesA1-aralık strings supplied to the 6-argumentAddChartSheetoverload (e.g.'Data!$A$2:$A$5') are compiled intotArea3DPTG tokens written into the seriesBRAI id=0(categories) andBRAI id=1(values) records. Excel-opened .xls files now render actual data points in the plot area instead of the empty placeholder chart that v2.42.0 produced. - Sheet name resolution + EXTERNSHEET registration is automatic: the parser looks the named sheet up in the çalışma kitabı, registers an XTI entry if one is not already present, and yazar the matching 0-based
ixtiinto the PtgArea3d body. Re-saved files keep theixticonsistent with the çalışma kitabı's final EXTERNSHEET ordering because the chart record stream is re-serialized through the formül compiler at kaydetme time. - Accepted aralık shapes:
Sheet1!$A$2:$A$5(absolute),Sheet1!A2:A5(relative markers tolerated — chart series always store as absolute),'My Sheet'!$A$1:$B$5(single-quoted sheet names with spaces), and single-hücre refs likeSheet1!$A$1(degenerates to a 1×1 PtgArea3d). Series data-point counts (cValx/cValy) are now derived automatically from the area dimensions instead of staying at zero. - Unsupported reference shapes silently fall back to the v2.41.0-stil
cce=0placeholder BRAI so the chart still opens in Excel: cross-çalışma kitabı refs ([Book2.xls]Sheet1!...), named aralıklar (Sheet1!ProfitColumn), refs missing the!sheet prefix, and refs that point at the chart sheet itself. These deferred cases are tracked for follow-up phases. - This completes Roadmap #10 Phase 2 (column chart end-to-end). Series labels (Phase 2 first half, v2.42.0) plus series aralık binding (this release) means a column chart created via
AddChartSheetartık yapabilir display proper legend entries plus real plotted data without any post-processing in Excel.
Sürüm 2.46.0
- The Differential XF (DXF) decoder on the BIFF8 side now resolves xclrType=1 (indexed palette) colors from the standard Excel 2003 64-color palette. Previously indexed colors fell through to the RGB path and the icv byte was misinterpreted as part of an RGB value, producing nonsense colors (typically dark grey) on okumak; Excel-saved .xls files that used indexed colors (rather than RGB or theme) for their CF12 DXF blocks now round-trip with sensible visual colors.
- The lookup uses the built-in Excel 2003 default palette baked into HotXLS — icv 0..7 are the eight system colors (black / white / red / green / blue / yellow / magenta / cyan), icv 8..15 mirror the system colors, and icv 16..63 are the standard customizable defaults (dark variants, light tints, browns, oranges, plums, etc.). Out-of-aralık icv values fall back to black ($000000).
- BIFF8 PALETTE record (rt=$0092) çalışma kitabı customization is not consulted — a çalışma kitabı that customizes its user-changeable palette slots (8..63) will have its CF12 DXF indexed colors resolved against the default values rather than the customized ones. For most Excel files that use the default palette this is correct; for files with özel palettes the visual color may shift slightly until full PALETTE plumbing lands in a future release.
- xclrType=0 (auto) and xclrType=2 (RGB) paths are unchanged — auto still becomes RGB 0 (black), RGB still decodes the xclrValue 4-byte BGR LongWord directly. Only the previously-broken xclrType=1 path is fixed.
Sürüm 2.45.0
- Conditional formatting rules now round-trip the priority attribute on both the XLSX
<cfRule priority="N"/>and the BIFF8 CF12ipriorityfield. Previously every rule was assigned a sequential priority based on its index in the collection on kaydetme, and the priority on Excel-saved files was ignored on okumak; now user-set priorities survive a load-edit-kaydetme cycle on both backends. - New
Priorityözellik onTCondFormatRule(BIFF8 side) andTXLSXConditionalFormat(XLSX side). Default is zero, which korur the existing auto-by-index behavior on kaydetme; set to a positive value to pin the priority and override the automatic assignment. - Priority lets multi-rule layering be controlled — when several rules cover the same aralık (e.g. a Data Bar + a CellIs highlight + an Icon Set), Excel applies them in priority order (lower number first). Round-tripping the priority means HotXLS-edited çalışma kitapları keep the user's intended rendering order instead of having it recomputed from collection iteration order.
- Default behavior unchanged for callers that don't touch
Priority: the XLSX writer continues to emitpriority="1","2","3"… in collection order, and the BIFF8 CF12 writer continues to emitipriority=1. okumak paths populatePriorityfrom the wire value when present; explicit checks against zero remain backward-compatible with code that ignored the özellik.
Sürüm 2.44.0
- Icon Set conditional-format rules now destek per-stop icon overrides on the XLSX side. Each of the 3 / 4 / 5 stops in an icon set can opt out of the family default and display any icon from any of the 17 built-in Excel 2007 icon families, identified by icon set name + icon id. The OOXML element involved is
<cfIcon iconSet="OtherSet" iconId="N"/>emitted per overridden stop inside the<iconSet>body. - New yöntemler on
TXLSIconSetSpecopt a stop into override mode:SetIconOverride(stopIndex, OverrideSet, IconId)andClearIconOverride(stopIndex). okumak-only özelliklerHasIconOverride[i],IconOverrideSet[i],IconOverrideId[i]expose the per-stop override state for inspection and round-trip preservation. - The XLSX writer emits
<cfIcon>children only for stops that calledSetIconOverride; stops without an override stay on the family default (no<cfIcon>emitted). The reader parses incoming<cfIcon>elements positionally inside an iconSet body and applies them to the matching stop on the newTXLSXConditionalFormat.IconSetspec. - Known limitations: BIFF8 (.xls) CFEX wire format has no slot for per-stop icon overrides, so writing an icon-set rule with overrides to .xls renders the family default for all stops (BIFF8 readers will not see the override info). çalışma kitabı-level icon-family validation is not enforced — passing an icon id beyond the override family's icon count is preserved verbatim but Excel may fall back to a default icon at render time.
Sürüm 2.43.0
- XLSX (.xlsx) conditional-format rules now round-trip theme color references in the
<color>element of Data Bar and Color Scale rules. Previously the writer only emitted<color rgb="FFRRGGBB"/>and the reader ignoredtheme/tintattributes; now both sides korumak the theme palette index plus the optional tint, so stiller like "accent-2 lightened 50%" survive an Excel açma / HotXLS edit / Excel re-açma cycle without being flattened to a frozen RGB. - New yöntemler on
TXLSDataBarSpecandTXLSCfValue(used by ColorScale stops) opt the slot into theme mode:SetThemeColor(themeId, tint)andClearThemeColor. okumak-only özelliklerIsThemeColor,ThemeColorId,ThemeColorTintexpose the active mode. Tint is a single in the [-1.0, +1.0] aralık — negative values darken the theme color, positive values lighten it. - The XLSX writer emits
<color theme="N"/>whenTintis exactly 0.0, or<color theme="N" tint="0.5"/>when non-zero, matching Excel's own "shortest form" output. The reader parses both attribute combinations and falls back to the existingrgb=path when neitherthemenortintis present. - Default behavior is unchanged: rules created with the existing RGB-only
AddCondFormatDataBar/AddCondFormatColorScale*entry points keep emitting<color rgb="..."/>exactly as before. Theme mode is purely opt-in via the newSetThemeColorsetter on the returned spec object. - Known limitations: BIFF8 (.xls) CFEX still only carries the RGB color (single 4-byte BGR LongWord per stop / per data bar) — theme color in CFEX would need a parallel wire-format extension. çalışma kitabı theme palette resolution (theme1.xml parsing) is still out of scope; HotXLS korur the theme index verbatim but does not resolve it to a concrete RGB for rendering / preview purposes.
iconSetrules carry no<color>elements so the theme-mode addition does not affect them.
Sürüm 2.42.0
- BIFF8 chart-sheet creation API gains a fifth
AddChartSheetoverload that accepts an array ofTXLSChartSeriesInforecords (Name,Categories,Values). Each non-emptyNameis written into the chart substream as a literal series label via atStrPTG token on the series-nameBRAI(id=2). Excel uses this label in the legend and in the series selector, so a multi-series chart now ships with proper series captions instead of the default "Series1 / Series2" placeholders. TXLSChartSeriesInfois re-exported fromlxHandlealongsideTXLSChartType, so callers can build the array without importinglxChartBuilderdirectly.- This is the first half of Roadmap #10 Phase 2 (column chart end to end). The series-name path is wired up; category and value data binding (turning the
CategoriesandValuesA1-aralık strings into realtArea3Dhücre-aralık references inside the BRAI) is still a placeholder — those two fields are accepted on the API but not yet emitted into the chart substream. A follow-up release will route them through the formül compiler and the EXTERNSHEET reference tablo to land the second half of Phase 2.
Sürüm 2.41.0
- HotXLS gains programmatic BIFF8 chart-sheet creation. A new
AddChartSheetoverload set onSheetsyazar a complete chart substream into the saved .xls file, where previously chart sheets could only be preserved opaquely on a load-kaydetme round-trip. Four overloads cover the common entry points: name only / name + chart type / + title / + category-axis title + value-axis title. The returnedIXLSWorksheetappears in theSheetscollection, gets a chart-sheet boundsheet entry written on kaydetme, and Excel opens it as a chart tab. - A new
TXLSChartTypeenum selects the chart kind:xlsChartTypeColumn,xlsChartTypeBar,xlsChartTypeLine,xlsChartTypePie. The enum is re-exported fromlxHandleso user code does not need to içe aktarma the chart-builder unit directly. - The emitted chart substream covers the BIFF8 framing the spec calls for — BOF (dt=$0020), Chart / PlotGrowth / Frame / Series / SheetProperties / AxesUsed / AxisParent (POS + category axis + value axis + PlotArea + Frame + ChartFormat + chart-kind record + ChartFormatLink + Legend), EOF — so Excel recognises the result as a real chart tab of the requested kind. Existing chart-sheet round-trip via
TXLSCustomChartis unchanged. - This is the first cut of Roadmap #10 (CHART substream — the largest item in the BIFF8 audit). Phase 1 ships the framing and the API surface so that subsequent phases can layer in series data binding, axis titles, and richer per-chart-type formatting.
- Limitations: the new chart sheet renders an empty default chart of the requested kind. Series data binding (linking the chart to actual hücre aralıklar), populated title text, and per-chart-type formatting (gap width / bar overlap / pie hole size / marker stil) are deferred to subsequent phases. kaydetme-and-reopen with Excel korur the chart sheet's presence and its kind, but not yet user-supplied data.
Sürüm 2.40.0
- New XlsCondFormat12 Delphi demo under
Demo/Delphi/XlsCondFormat12/demonstrates the v2.34.0+ conditional-format extension API end to end. Three buttons let you generateCondFormat12.xls(BIFF8 backend),CondFormat12.xlsx(XLSX backend), or both side by side. Each output sheet carries the same four rule kinds — Data Bar, 3-color scale, Icon Set (3 arrows), and 2-color scale — covering ten data rows so you can açma the files in Excel and visually verify how each backend renders the extension rules. - The BIFF8 path additionally exercises the v2.35.0 DXF stil override: the Data Bar rule attaches white bold font color so the hücre text stays legible over the dark bar fill.
- New DUnitX test fixture at
Tests/Delphi/HotXLS.CondFormat12Tests.pascovers ten round-trip and API-surface scenarios for the CF12 family: BIFF8 round-trip for all four rule kinds, DXF stil round-trip for RGB colors, theme colors, and font flags (bold / italic / underline), and XLSX round-trip for Data Bar / 3-color scale / Icon Set with ShowOnly. The fixture is wired intoHotXLSDelphiTests.dprand the matching.dprojso existing CI runs pick it up automatically. - To destek the fixture,
TCondFormatexposes two new public accessors:RuleCountandRule(I), so callers can iterate rules after okumak instead of relying on the previously private rule list.
Sürüm 2.39.0
- The Differential XF (DXF) stil override on conditional formatting rules artık destekler theme color encoding in addition to the existing RGB mode. Each color slot — font color, fill background, fill foreground — can be set against a çalışma kitabı theme index plus a tint value, so stiller like "accent-2 lightened 50%" round-trip without being flattened to a frozen RGB.
- Three new yöntemler on
TXLSDxfStyleopt a slot into theme mode:SetFontColorTheme(themeId, tint),SetFillBgColorTheme(themeId, tint),SetFillFgColorTheme(themeId, tint). Tint is a single in the [-1.0, +1.0] aralık — negative values darken the theme color, positive values lighten it, 0.0 leaves the base color. The corresponding existingSetXxxColor(rgb)yöntemler stay RGB mode; the two modes are mutually exclusive per slot and whichever was called last wins. - Query the active mode via new
XxxColorIsTheme/XxxColorThemeId/XxxColorThemeTintokumak-only özellikler paired with each of the three color slots.HasXxxColorreturns True in either mode; existing callers checking onlyHasXxxColor+ readingXxxColorcontinue to work, treating theme-mode slots as having color 0 (a downgrade rather than a crash). - The BIFF8 wire format follows the standard XFProp Colour layout:
xclrType=2+ 4-byte BGR LongWord for RGB (existing v2.35.0 behavior),xclrType=3+ 2-byte signed tint × 32767 + 4-byte theme index for theme mode (new). The DXF blob decoder mirrors this dispatch — incoming Excel-saved files using theme color in their CF12 DXF blocks now expose the theme id and tint through the new özellikler. - Known limitations: theme-mode round-trip on BIFF8 (.xls) is the only path supported by this release — the XLSX (.xlsx) side still emits and okur
<color rgb="..."/>only and ignorestheme/tintattributes (planned for a follow-up release together with the çalışma kitabı theme palette plumbing).
Sürüm 2.38.0
- XLSX (.xlsx) reading now recognizes the Excel 2007+ conditional formatting extension rules in incoming files — data bar, color scale (2 and 3 stops, auto-detected from the cfvo count), and icon set — and populates the matching
TXLSXConditionalFormatobject so user code can inspect and round-trip these rules without losing them. Previously, Excel-saved .xlsx çalışma kitapları with these rule kinds had them dropped silently on load. - The reader parses the OOXML
<cfRule type="dataBar|colorScale|iconSet">envelope plus the inner<dataBar>/<colorScale>/<iconSet>body, walking child<cfvo>entries to recover each threshold's type (num / min / max / percent / percentile / formül / autoMin / autoMax) and val, and child<color>entries to recover the data bar color or per-stop scale colors. - Icon set rules round-trip the
iconSetfamily name (the 17 baseline Excel 2007 sets — 3-arrows / 3-flags / 3-traffic / 3-signs / 3-symbols / 4-arrows / 4-rating / 4-traffic / 5-arrows / 5-rating / 5-quarters and gray variants), thereverseflag, and theshowValueflag (mapped toShowOnly). - Color values parsed from the OOXML
rgb="AARRGGBB"attribute are converted to the same BGRLongWordconvention (R in the low byte, matching VCLTColorand BIFF8LongRGB) used by the existing yazmak API, so a load-edit-kaydetme round-trip korur the visual colors exactly. - Existing XLSX
<cfRule type="cellIs">handling is unchanged; the dispatch picks the new rule kinds only when thetypeattribute names them, and falls back to the hücre-value path otherwise. - Known limitations: theme color references (OOXML
<color theme="N" tint="0.5"/>) are okumak as 0 instead of being resolved against the çalışma kitabı theme palette;iconIdper-stop overrides on icon sets are not yet captured;<cfRule>priorityattribute is ignored on okumak (rules keep their parse order).
Sürüm 2.37.0
- The BIFF8 CFEX record format now carries the full per-stop cfvo array (kind + value string + color, per [MS-XLS] cfvo semantics) instead of just the bar/stop color. Data Bar rules now persist the min/max threshold kinds and values, color scales persist each stop's kind + value + color combination, and icon sets persist each threshold's kind + value alongside the reverse / showOnly flags.
- CFEX writing ekler a version flag byte (ver=1) so older HotXLS readers that expect the v2.34.0 minimal CFEX layout silently fall back to the legacy interpretation. The v2.37.0 reader also recognizes ver=0 records produced by older HotXLS builds, so round-trip with mixed-version installations works in both directions for the kind/color fields that the older format carried.
- The reader now detects mixed CONDFMT + CONDFMT12 entries on the same aralık — a common pattern in Excel-saved files where the old hücre-value backup and the new Data Bar / Color Scale / Icon Set rule cover identical sqref. The older CONDFMT entry is flagged via a new
IsShadowedözellik onTCondFormatso user-facing code that iterates the conditional-format collection can skip the duplicate. The writer continues to emit both record families on kaydetme for cross-version Excel 2003 ↔ Excel 2007+ uyumluluk. - New
TotalRangeözellik onTCondFormatexposes the merged-extent aralık that was previously private; useful for users implementing özel dedup, aralık queries, or the shadow check pattern. - Known limitations: shadow detection is bounded by an exact bounding-box match (row1/col1/row2/col2 equality). Mixed entries where CONDFMT covers a slightly different sqref subset are not deduped; ColorScale full-cfvo round-trip korur the 8 standard kind values (num/min/max/percent/percentile/formül/autoMin/autoMax) but does not round-trip Excel's theme-color tint metadata for the stop colors.
Sürüm 2.36.0
- XLSX (.xlsx) output artık destekler the three Excel 2007+ conditional formatting rule kinds — data bar, color scale (2-stop and 3-stop), and icon set — bringing the XLSX backend to parity with the v2.34.0 BIFF8 (.xls) backend. Four new public yöntemler on
TXLSXWorksheetmirror the XLS API surface:AddCondFormatDataBar,AddCondFormatColorScale2,AddCondFormatColorScale3,AddCondFormatIconSet. - The saved .xlsx file now emits the OOXML
<conditionalFormatting>element with the appropriate child structure for each rule kind:<cfRule type="dataBar"><dataBar><cfvo/><cfvo/><color/>for bars,<cfRule type="colorScale"><colorScale>with 2 or 3 cfvo + color stops, and<cfRule type="iconSet"><iconSet iconSet="...">with the appropriate cfvo set. - Built-in icon-set name mapping covers the same seventeen Excel 2007 baseline sets supported by the XLS backend (3Arrows / 3Flags / 3TrafficLights1 / 3Signs / 3Symbols / 3Symbols2 / 4Arrows / 4ArrowsGray / 4RedToBlack / 4Rating / 4TrafficLights / 5Arrows / 5ArrowsGray / 5Rating / 5Quarters), produced as the standard OOXML
iconSetattribute string. - Threshold types and color values use the same enumeration and color convention as the XLS API — same
TXLSCfValueKindfor num / min / max / percent / percentile / formül, same Delphi BGRLongWordcolor format. Existing XLSX hücre-valueAddConditionalFormatcalls continue to behave identically (no regression). - Known limitations: theme color encoding is not yet emitted (OOXML
<color>uses thergbARGB string attribute only); theshowValue="0"attribute is set whenShowOnlyis true on an icon set, buticonIdper-stop overrides are not yet supported. XLSX okumak-side recognition of incoming data bar / color scale / icon set rules from Excel-saved files remains deferred — only yazmak is wired up in this release.
Sürüm 2.35.1
- The BIFF8 reader now decodes the Differential XF (DXF) bytes attached to a CF12 rule back into the rule's
TXLSDxfStyleözellik bag, in addition to keeping the raw bytes inDxfBlob. Loading an Excel-saved çalışma kitabı with styled data bar / color scale / icon set rules now exposes the font color, fill colors, bold / italic / underline, and number format id directly through theHasXxx+ value pair on eachRule.Style. - round-trip behavior: a load-edit-kaydetme cycle now reflects any post-load mutation of
Rule.Style. If a user okur a çalışma kitabı, changesRule.Style.SetFontColor, and saves, the new color wins; if the user doesn't touch the stil, the saved file carries the same overrides as the original. - Unknown
xfPropTypevalues in the DXF blob are skipped rather than rejected, so newer Excel files using özellik types not yet recognized by this release still load (the raw bytes remain inDxfBlobfor inspection or future round-trip destek).
Sürüm 2.35.0
- Conditional formatting rules now carry a Differential XF (DXF) stil override so that a CF12 rule firing in Excel can change the hücre's font color, fill, font weight, italic, underline, or number format without altering the hücre's base XF. The override is exposed as a new
TXLSDxfStyleözellik on eachTCondFormatRule, accessible after creating a rule via the existingAddCondFormatDataBar/AddCondFormatColorScale*/AddCondFormatIconSetAPIs. - Supported stil overrides in this release: font color, fill background color, fill foreground color, fill pattern, font bold, font italic, font underline stil, and built-in number format id. Each özellik has a paired
HasXxxflag — only özellikler explicitly set viaSetXxxemit into the BIFF8 file. - The BIFF8 writer now appends a non-empty DXF block to the CF12 record whenever the rule's stil has at least one override set. The DXF block uses the public XFProp array layout (cxfp + per-özellik type / size / data tuples) so Excel can pick up the stil changes when the rule applies.
- The BIFF8 reader korur the raw DXF bytes from an Excel-saved file into the rule's
DxfBlobözellik, so a load-edit-kaydetme round-trip no longer silently loses the hücre styling carried by CF12 rules. Decoding the raw bytes back into theTXLSDxfStyleözellik bag is planned for a follow-up release. - Default behavior is unchanged for rules that don't opt into a stil —
cbdxf = 0is emitted, identical to v2.34.0, so existing data bar / color scale / icon set rules render exactly as before. - Known limitations: theme-color encoding for DXF is not supported (RGB only); border overrides and gradient stops are not in this release's özellik set; the wire-format byte ordering for the XFProp value blobs follows public [MS-XLS] notes and may require small tweaks for full Excel round-trip fidelity once validated against BiffView. XLSX-side parity for the three new rule kinds remains deferred.
Sürüm 2.34.0
- New public conditional-formatting API on the çalışma sayfası for the Excel 2007+ extension rules:
AddCondFormatDataBar,AddCondFormatColorScale2,AddCondFormatColorScale3, andAddCondFormatIconSet. Each yöntem accepts a sqref aralık like"A1:A10"plus the kind-specific parameters (bar color, gradient stop colors, or icon-set family) and returns the created rule object. - The BIFF8 (.xls) writer now emits the corresponding CONDFMT12 / CF12 / CFEX record family alongside the existing hücre-value CONDFMT / CF records, so çalışma kitapları created via the new API persist their data bar, 2-color or 3-color scale, and icon-set rules to disk.
- The BIFF8 reader recognizes incoming CONDFMT12 / CF12 / CFEX records and exposes them through the same in-memory rule model, so Excel-authored .xls files with extension rules are no longer silently dropped on load.
- Built-in icon-set catalog covers the seventeen Excel 2007 baseline sets — 3-arrow / 3-flag / 3-traffic-light / 3-sign / 3-symbol families, 4-arrow / 4-rating / 4-traffic-light, and 5-arrow / 5-rating / 5-quarter — selectable through the
TXLSIconSetTypeenumeration. - Threshold types for data bar bounds and color-scale / icon-set stops can be any of number, min/max of aralık, percent, percentile, or formül, matching the cfvo kinds used by Excel.
- Existing hücre-value conditional formatting behavior is unchanged; only new APIs and new BIFF8 record handling were eklendi.
- Known limitations in this release: XLSX output for the three new rule kinds is not yet wired up (existing XLSX hücre-value rules unaffected); the differential-XF stil block on CF12 is emitted empty so Excel may render bars and scales with default colors instead of the API-supplied colors; per-stop cfvo arrays carry only the color in CFEX, not the kind/value combination. These gaps are planned for the v2.34.x / v2.35.x follow-up releases together with the demo çalışma kitabı and Excel-rendering validation.
Sürüm 2.33.3
- New XlsTables Delphi demo under
Demo/Delphi/XlsTables/demonstrates the BIFF8 tablolar (ListObjects) yazmak side end-to-end. It generatesSalesTable.xlswith a four-column sales region (Region / Product / Quarter / Revenue) bound as a tablo at A1:D10 usingSheet.AddTable('SalesTable', 'A1:D10', headers). açma the produced .xls in Excel to verify the column dropdowns, banded-row stripes, and the SalesTable structured-reference name in the Name Box. - The demo is the shortest end-to-end recipe for adopting the v2.33.0
AddTableAPI: it setsStyleName = 'TableStyleMedium2'andShowRowStripes = True, fills nine data rows + one header row, and yazar the çalışma kitabı with a singleSaveAscall. Output goes next to the executable; an "açma Output Folder" button is provided for convenience. - Compilation infrastructure is unchanged: the existing
build-Win32-Demo.cmdpicks upXlsTables.dprautomatically via itsfor /r Demo *.dprsweep — no changes to build scripts or .cbproj/.dproj configs required.
Sürüm 2.33.2
- BIFF8 (.xls)
SaveAsnow suppresses the standalone sheet-levelAUTOFILTERINFO/AUTOFILTERrecords ($009D / $009E) when a tablo on the same sheet fully covers the autofilter aralık. Excel embeds an autofilter dropdown inside the tablo object itself, so emitting an additional sheet-level autofilter for the identical aralık triggers Office File Validation to reject the file. This matches the XLSX-side fix shipped in v2.29.4. - The coverage check is conservative: a tablo is considered to "cover" the autofilter only when its first/last row and first/last column bracket the autofilter's bounds. Partial overlap (e.g. autofilter spanning extra rows below a tablo) keeps emitting the sheet-level autofilter so legacy workflows that put a filter above or beside a tablo region continue to work.
- BIFF5 saves and sheets without any tablo are unaffected — the suppression check only runs when the file format is BIFF8 and the çalışma sayfası has at least one tablo. No public API change.
Sürüm 2.33.1
- BIFF8 (.xls) okumak side now recognizes the shared-feature tablolar records that v2.33.0 eklendi on the yazmak side. Opening an .xls saved by Excel (or by HotXLS itself) with one or more ListObjects/tablolar now populates the çalışma sayfası's
Tablescollection with aTXLSTableper parsed FEAT11 ($0872), reconstructing the tablo's aralık from the primary Ref8U, recovering the tablo id, name, and display name when present, and filling in the tablo stil name from the paired LIST12 ($0877) record. Previously these records were silently ignored, dropping all tablo state on round-trip. - The shared FEATHEADR ($0867) opcode is now dispatched by its
Isffield instead of always going to the protection parser. Isf=2 (Enhanced Protection) keeps the existing behavior; Isf=4 (SharedList) is acknowledged as the marker for tablolar on the sheet; Isf=3 (SmartTags) and other values are safely ignored. FEATHEADR11 ($0871) is also acknowledged silently as a tablolar marker. - The reader is best-effort and tolerant: malformed or Excel-variant FEAT11 payloads degrade gracefully to a tablo that has at least the correct hücre aralık, even if the higher-offset fields (per-column ids, structured-reference data) cannot be parsed. Sheet protection round-trip is unchanged — the existing options bit at Isf=2 payload offset 19 is still okumak identically.
Sürüm 2.33.0
- BIFF8 (.xls) çalışma sayfaları now destek tablolar (Excel ListObjects). Call
Worksheet.AddTable(Name, Range, Columns)on anIXLSWorksheetto attach a named tablo region to a hücre aralık — for exampleSheet.AddTable('SalesTable', 'A1:F9', HeaderList). The .xls kaydetme path emits the BIFF8 shared-feature record family that marks the sheet as containing tablolar: FEATHEADR ($0867 with Isf=4), FEATHEADR11 ($0871), and a paired FEAT11 ($0872) + LIST12 ($0877) per tablo. Previously, callingAddTableon the XLS facade was unavailable; tablolar defined on a çalışma sayfası were silently dropped onSaveAs(xlExcel97). - New public API on
IXLSWorksheet:Tables: TXLSTablesözellik (okumak-only collection) andAddTableyöntem. The shape mirrorsTXLSXTable/TXLSXTableson the XLSX side, so code that ekler tablolar to a çalışma kitabı can be format-agnostic.TXLSTableexposesId,Name,DisplayName,Range,Columns,StyleName(default'TableStyleMedium2'),ShowFirstColumn,ShowLastColumn,ShowRowStripes(default true),ShowColumnStripes, andTotalsRowShown. - The new sheet-stream records are emitted just before the çalışma sayfası EOF, after sheet protection, only when the file format is BIFF8 (
xlExcel97). çalışma kitapları without tablolar kaydetme exactly as before — no FEATHEADR is emitted, no record stream changes, no overhead. BIFF5 saves are unaffected since tablolar are a BIFF8+ concept. - tablo ids are assigned sequentially per sheet (1..N) at kaydetme time if not pre-set, so callers can leave
Idat its default afterAddTable. The default stil name'TableStyleMedium2'matches what Excel and the XLSX side already use, keeping tablo appearance consistent across both file formats. - Known limitations of this initial release (v2.33.0): totals-row formüller and structured-reference auxiliary aralıklar are not yet emitted; conflict suppression between sheet-level
AUTOFILTERINFOand a tablo aralık will be eklendi in a follow-up; the okumak side (parsing an Excel-saved .xls with tablolar back into theTablescollection) is also a follow-up. tablolar created via this v1 yazmak path are well-formed for round-trip preservation in Excel itself.
Sürüm 2.32.1
- Fixed a compilation error introduced by the v2.32.0 FILEPASS yazmak-side feature that prevented the library from building on RAD Studio 12+ with strict type-checking. The
EncryptAllBlobsyardımcı declared its scatter buffer asPBytein a context wherePByteresolved tolxHandle's local alias, while the call targetEncryptBlobDatainlxEncrypterexpectedlxBLOB.PByte. Although the two types both alias^Byte, Delphi treats them as distinct under E2010 strict type-checking. The buffer variable is now fully qualified aslxBLOB.PByte, so the v2.32.0 password-encryption path compiles cleanly across all supported RAD Studio versions (12.0–37.0).
Sürüm 2.32.0
- eklendi
EncryptionPasswordözellik onIXLSWorkbook. Setting a non-empty password beforeSaveAsnow produces an Excel-compatible password-protected .xls file: Excel, LibreOffice Calc, and other BIFF8 readers prompt for the password on açma and refuse access when it is wrong. Previously the password setter was silently ignored on the yazmak side and çalışma kitapları were always emitted in plaintext. - The yazmak path emits the BIFF8 FILEPASS record ($002F) immediately after the çalışma kitabı BOF and RC4-encrypts every subsequent record body using the existing okumak-side algorithm (vMajor=1, vMinor=1 -- Excel "Office 97/2000 Compatible" encryption). 16-byte Salt and Verifier are generated via Windows
CryptGenRandomrather than PascalRandom. Block-key re-derivation at every 1024-byte boundary is preserved so large çalışma kitapları, SST CONTINUE chains, and multi-sheet streams encrypt correctly. - Encryption applies to BIFF8 (
xlExcel97) only -- the BIFF5 kaydetme path remains plaintext. EmptyEncryptionPasswordkeeps the legacy plaintext output and is the default, so existing applications that never call the setter are unaffected. - okumak side: fixed a latent bug in
ParseFilePassthat caused the first record body after FILEPASS (typically CODEPAGE) to be treated as plaintext. HotXLS-written encrypted files now round-trip through HotXLS itself, and Excel-written encrypted files no longer hand back a garbage CODEPAGE value. - Security note: BIFF8 RC4 with vMajor=1/vMinor=1 uses a 40-bit key, considered broken by 2025 standards. Use this feature for uyumluluk with Excel's classic password-protection UI, not for confidentiality of sensitive data. For real security, prefer XLSX with AES.
Sürüm 2.31.0
- eklendi
UseSharedFormulasözellik onIXLSWorkbook. When set toTrue, BIFF8 SaveAs groups hücreler that share a template formül into native SHRFMLA records ($04BC), matching Microsoft Excel's compact wire format. Columns of formüller like=A1*B1,=A2*B2, …,=A99*B99are grouped automatically, reducing file size by 30–60 % on template-heavy sheets. - Grouping is column-down, contiguous, and template-based: only hücreler in the same column with consecutive rows and PTG-equivalent formüller are grouped. hücreler with array formüller or merged-hücre flags are excluded.
- Default is
False, keeping the existing per-hücre formül record emission unchanged. Opt in by settingWorkbook.UseSharedFormulas := Truebefore callingSaveAs. - Reading side is unaffected: HotXLS has always okumak SHRFMLA records correctly, so round-tripped files continue to work. This is a MINOR version bump (2.30.x → 2.31.0) because a new public özellik is eklendi and BIFF8 output format changes when the feature is enabled.
Sürüm 2.30.6
- Fixed a fourth class of compilation error in the C++Builder demos under RAD Studio 37.0's clang-based bcc32 compiler: indexing a border stil through a smart-pointer interface using
->Borders[idx]->Proptriggered error E5843 ("member reference type is not a pointer"). All occurrences have been changed to->Borders->Item[idx]->Prop, which accesses the indexed özellik directly on the interface. This fix appears in the ApiTour, ExportWithColoring, PurchaseOrder, and QuickStart demos and completes full clang uyumluluk for all nine C++Builder demo projects.
Sürüm 2.30.5
- All nine C++Builder demo projects now build cleanly under RAD Studio 37.0's clang-based bcc32 compiler. Fixed three classes of compilation error: the
lxFormulaözellikEOFwas renamedIsEofto eliminate a conflict with the Cstdio.hmacro of the same name; XLS API enum constants (xlHAlignCenter,xlAround,xlMedium, etc.) are now explicitly qualified with theLxhandle::namespace in C++Builder demo code; and XLSX hücre-value assignments changed fromOleVariant(...)toVariant(...)becauseTXLSXCell.ValueisSystem::Variantand the clang compiler rejects the implicit protected-base-class conversion fromOleVariant.
Sürüm 2.30.4
- The OrderCalc demo (Delphi Purchase Order sample) artık içerir an XLSX dışa aktarma option alongside the existing XLS, HTML, and RTF formats. Selecting "Excel 2007+ file (*.xlsx)" in the kaydetme dialog yazar the purchase order using the native TXLSXWorkbook API, producing a standards-compliant XLSX file with fonts, fills, borders, alignment, number formats, and Excel formüller preserved.
Sürüm 2.30.3
- SaveXLSWorkbookAsXLSX (the bridge used by TDataToXLS.SaveAs and TGridToXLS.SaveAs when the target filename ends in .xlsx) now copies hücre background fill colors, font colors, and font stil attributes (name, size, bold, italic) from the underlying XLS çalışma kitabı to the XLSX output. Column widths — including explicitly narrowed columns set before dışa aktarma — are also copied. Previously only hücre values and number formats were transferred, so the XLSX output was uniformly unstyled, all column widths were at the default, and any deliberately-narrow decorative column appeared as an oversized blank column.
Sürüm 2.30.2
- Fixed a round-trip bug in the XLS reader where the Outline.SummaryRow direction was inverted after açma. The WSBOOL record's fRwSumsBelow flag (BIFF8 spec p278 byte 0 bit 6, mask $0040) means "summary rows appear *below* detail", but the parser previously set SummaryRow = xlAbove when the bit was set (and xlBelow when clear) -- exactly the opposite of the spec. The writer side was already correct (emits $0040 for xlBelow), so opening an Excel file with "summary rows below detail" and re-saving it via HotXLS would silently flip the outline direction to "above". Now the parse direction matches the spec and the writer, so outline configurations round-trip correctly. fColSumsRight ($0080) was already handled correctly and is unchanged.
Sürüm 2.30.1
- XLS (BIFF8) writer now emits INTERFACEHDR / INTERFACEEND / WRITEACCESS records in the çalışma kitabı globals section, matching Microsoft Excel's native record layout. Native Excel always yazar this trio between CODEPAGE/DSF and WINDOW1, and stricter BIFF readers / Office File Validation paths may expect them. INTERFACEHDR carries the code page (1200, UTF-16), INTERFACEEND is an empty marker, and WRITEACCESS carries the "saved by" user name (currently hard-coded to "HotXLS"; a future release may promote this to a çalışma kitabı özellik). Output XLS files now match Excel's native byte layout more closely.
Sürüm 2.30.0
- eklendi a classic-to-XLSX dışa aktarma bridge. TDataToXLS.SaveAs and TGridToXLS.SaveAs now yazmak .xlsx file names through the XLSX engine while keeping the existing .xls, .html, and .rtf paths unchanged.
- eklendi çalışma sayfası view APIs for XLS and XLSX. IXLSWorksheet.View and TXLSXWorksheet.View destek normal view, page-break preview, and page-layout view, and the setting is preserved by the relevant file writer/reader path.
- eklendi classic çalışma kitabı uyumluluk APIs: IXLSWorkbook.SetCodePage and IXLSWorkbook.VBAProject. VBA projects artık yapabilir be inspected through TXLSVBAProject/TXLSVBAModule module names and source text when a çalışma kitabı contains a VBA storage.
- Extended TXLSXWorkbook with ParsedVBAProject, a okumak-only parsed view over a valid vbaProject.bin payload, while preserving the existing raw VbaProject byte round-trip behavior.
- eklendi the optional cxGridAddExcel unit for DevExpress cxGrid dışa aktarma workflows. It is intentionally not included in the default packages so installations without DevExpress continue to build cleanly.
- Fixed XLSX chart sheet rendering where the chart appeared blank when the çalışma kitabı was opened in Excel (a freshly opened chart sheet briefly showed the 3 chart-context icons in the top-right and then dropped them, leaving the sheet empty). Chart sheet drawings now use <xdr:absoluteAnchor> with explicit extent (~10in × 7.2in = 9525000 × 6858000 EMU) instead of <xdr:twoCellAnchor> with cx=0/cy=0; chart sheets have no hücre grid to resolve twoCellAnchor against, so Excel was falling back to the inner xfrm of zero size and rendering the chart at zero pixels. Per ECMA-376-1 14.2.3.2, chart sheet drawings must use absoluteAnchor. çalışma sayfası chart anchors are unchanged.
Sürüm 2.29.4
- Fixed an XLSX packaging bug that caused Excel's repair prompt "We found a problem with some content in <file>.xlsx" on çalışma kitapları where a sheet-level autoFilter and a tablo cover the same aralık (e.g. the MemoryDataExport demo's XlsxFeatureGallery.xlsx Details sheet, which called AddTable('SalesTable', 'A1:F9', ...) followed by SetAutoFilter('A1:F9')). OOXML forbids two filter mechanisms over the same aralık; the writer now suppresses the duplicate sheet-level <autoFilter> emission when its aralık coincides with any tablo's aralık. The tablolar' own autoFilter (rendered as the tablo header dropdowns) still works.
- Fixed a related schema violation in <dataValidation> output: an operator attribute was emitted for every validation, but ECMA-376-1 18.3.1.32 only allows it for types whole / decimal / date / time / textLength. AddListValidation produces type="list", which used to leak operator="between"; OFV is stricter than Excel about this and could reject the çalışma kitabı. The operator attribute is now omitted for list / özel / none.
- Fixed the <legacyDrawing r:id="..."/> element on çalışma sayfaları that mix internal and external hyperlinks with comments (XlsxFeatureGallery.xlsx Dashboard sheet has 1 internal + 1 external + 1 comment). The rId calculation counted all hyperlinks instead of only the externals (internals use the inline location= attribute and do not consume an rId), so legacyDrawing pointed at the comments rels target instead of the vmlDrawing target. ECMA-376-1 18.3.1.51 requires legacyDrawing to reference a vmlDrawing-typed rels. The rId is now computed from the external hyperlink count only.
- Also stopped emitting a redundant xl/çalışma sayfaları/_rels/sheetN.xml.rels file for chart sheets eklendi via AddChartSheet. The duplicate relationship file pointed at a nonexistent çalışma sayfası part and showed up as an orphan inside the .xlsx zip; chart sheets now yazmak only the correct xl/chartsheets/_rels/sheetN.xml.rels.
- Updated the MemoryDataExport demo (XlsxFeatureGallery) to drop the redundant SetAutoFilter('A1:F9') call on the Details sheet -- AddTable already attaches an autoFilter to the tablo aralık, so the extra call previously triggered the OFV rejection above. The writer's defensive suppression covers customer code that does not get the demo update.
Sürüm 2.29.3
- Fixed an XLSX round-trip regression where borders drawn on otherwise-empty rows were dropped after açma + modify + SaveAs. ApiTour's row 8 horizontal divider (produced by a aralık.SetBorders call on a row with no data) rendered correctly in the freshly generated ApiTour.xlsx but disappeared in ApiTour-XLSX-Modified.xlsx after the demo's Modify pass re-saved the file, leaving Excel showing a broken vertical grid line at C8 / D8 in the modified file only (the original ApiTour.xlsx was unaffected). The XLSX parser now also applies hücre stiller when a `<c>` element is self-closing or has no value/formül children, so styled valueless hücreler survive the round trip.
Sürüm 2.29.2
- Fixed an XLSX round-trip regression in açma + modify + SaveAs flows. When ParseWorksheetXml okumak a hücre whose
referenced a stiller.xml cellXf, it stored N directly on hücre.FormatIndex. On SaveAs the cellXfs are rebuilt from the çalışma kitabı stil pools (with optional composite entries) and the new layout's slot at the same numeric index almost never carries the same semantics; the resaved hücre ended up pointing at the wrong cellXf -- or past the end of the new cellXfs tablo -- and Excel reported "Office has detected a problem with this file. We can try to recover". ApplyStyle now reverse-maps cellStyle to FontIndex / FillIndex / BorderIndex / NumberFormatIndex / AlignmentIndex / ProtectionIndex via the CellXfXxxMap tablolar that ParseStylesXml already populates, so the round trip re-emits the hücre against the freshly-built cellXfs.
Sürüm 2.29.1
- Fixed two XLSX rendering regressions exposed by ApiTour demo: (1) hücreler inside a row could be emitted out of column order when a aralık.SetBorders call eklendi hücreler in non-monotonic order (e.g. outline pass creates A8/C8, inside pass creates B8 -- output was A8 / C8 / B8 / instead of A8 / B8 / C8 / so Excel reported "Office has detected a problem with this file" and forced Protected View). The XLSX writer now sorts each row's hücreler by column before emission, matching the OOXML CT_Row schema. (2) hücreler that set 2 or more stil indices simultaneously (Font + Fill + Border, etc.) used to be collapsed to a single-dim cellXf via priority chain (FontIndex won, Border / Fill were dropped), so e.g. a header row with FontIndex + FillIndex + BorderIndex set on a aralık[..].SetBorders rendered without the borders. The writer now collects a composite cellXf pool during SaveAs and routes multi-dim hücreler to a synthesized cellXf that korur every dimension.
Sürüm 2.29.0
- Renamed the internal yardımcı unit `lxList2` to `lxKeyList` and renamed `lxList`'s WideString-key classes from `TXLSKeyList` / `TXLSKeyEntry` / `TXLSKeyArray` to `TXLSStringKeyList` / `TXLSStringKeyEntry` / `TXLSStringKeyArray` so the unit name matches its main class `TXLSObjectKeyList` and the two key-list generations are self-describing (`TXLSStringKey*` for the legacy WideString-key pool, `TXLSObjectKey*` for the THashtableKey-based dedup pool). If your code references the old unit name or class names, update your uses clauses and type names accordingly.
Sürüm 2.28.3
- Fixed an XLSX hücre-emit regression that caused borders set on otherwise-empty rows to disappear. `aralık[''A3:C10''].SetBorders(xlsxEdgeOutline,...)` on a sheet whose row 8 carried no data used to render the C/D vertical grid line broken across that row because the writer skipped any hücre whose Value was unassigned -- even when the hücre had a BorderIndex / FontIndex / FillIndex / NumberFormatIndex / AlignmentIndex / ProtectionIndex assigned. The writer now emits `
` for valueless hücreler that carry any stil index.
Sürüm 2.28.2
- Fixed an XLSX çalışma sayfası schema violation that caused Excel to refuse loading sheets which combined merged hücreler with AutoFilter. The XLSX writer now emits the <autoFilter> element before <mergeCells>, matching the OOXML CT_çalışma sayfası sequence (autoFilter is #11, mergeCells is #15). Previously such çalışma kitapları triggered Excel's repair dialog with `Load error. Line 1, column 0` on sheet1.xml and recovery would also drop tableParts / autoFilter from sibling Details sheets.
Sürüm 2.28.1
- eklendi convenience APIs to the classic XLS facade. IXLSRange now exposes okumak-only Width and WidthInPixels yardımcılar plus SaveAsCSV(FileName); IXLSWorksheet and IXLSWorkbook now expose SaveAsCSV(FileName / Stream) overloads for the used aralık or active sheet; IXLSPageSetup now exposes Order, Draft, BlackAndWhite, PrintNotes, and okumak-only IsFitToPages. SETUP record kaydetme/açma artık korur those print flags.
Sürüm 2.28.0
- eklendi RTF dışa aktarma on TXLSXWorkbook. New SaveAsRTF overloads (FileName / Stream x default-active-sheet / explicit SheetIndex) yazmak the chosen sheet as an RTF 1.6 document containing a plain tablo. Column widths are derived from the sheet's ColWidth data (1 Excel character unit is approximated as 96 RTF twips); columns without explicit widths fall back to StandardWidth if set, otherwise to 809 twips (~8.43 chars). Per-hücre bold (\\b), italic (\\i), and font size (\\fsN in half-points) are applied from the hücre's FontIndex. Non-ASCII characters are encoded as signed-16-bit RTF \\uN? unicode escapes per RTF 1.6 §2.4.2, covering the full BMP aralık. Merged hücreler are not spanned — origin hücreler carry the content and non-origin hücreler within the aralık are emitted as empty hücreler. Default SheetIndex yazar the active sheet; out-of-aralık returns -1. Empty sheets produce a minimal valid RTF document.
Sürüm 2.27.0
- eklendi HTML dışa aktarma on TXLSXWorkbook. New SaveAsHTML overloads (FileName / Stream x default-active-sheet / explicit SheetIndex) yazmak the chosen sheet as a UTF-8 HTML document with a UTF-8 BOM. Output is a single <tablo> inside a minimal HTML page. Merged hücreler are expressed as colspan / rowspan attributes. hücre styling is emitted as inline CSS: font family, size (pt), bold (font-weight:bold), italic (font-stil:italic), strikethrough (text-decoration:line-through), and explicit font color; solid-pattern fill foreground color as background-color; horizontal alignment (left / center / right / justify) and WrapText (white-space:pre-wrap). Date variant values render as 'yyyy-mm-dd hh:nn:ss'; rich-text hücreler flatten to their concatenated run text. Theme colors are silently skipped (no theme1.xml resolution in the simple HTML dışa aktarma). Default SheetIndex yazar the active sheet; out-of-aralık returns -1.
Sürüm 2.26.0
- eklendi theme color + indexed color + tint/shade destek on TXLSXFont, TXLSXFill, and TXLSXBorderEdge. Each color slot now carries three new fields beside the existing RGB Color: ColorTheme (Integer; -1 = unset; 0..11 = OOXML theme slot), ColorIndex (Integer; -1 = unset; 0..63 = OOXML legacy palette slot — pairs with çalışma kitabı.IndexedColor[N] and XlsxDefaultIndexedPalette), and TintAndShade (Double in [-1.0, 1.0]; only emitted with theme). TXLSXFill exposes Foreground / Background variants of all three. Writer priority: theme > indexed > rgb; the older "ColorIsAuto = True" path keeps suppressing the element entirely. SaveAs and açma round-trip the full <color theme="N" tint="..."/> and <color indexed="N"/> attribute sets on font / fill / border colors. Bookkeeping: TXLSXBorders.LookupOrAdd now compares all three new fields so theme-colored borders don't collide with rgb-colored entries in the pool.
Sürüm 2.25.0
- eklendi external çalışma kitabı link round-trip on TXLSXWorkbook. New types: TXLSXExternalLink (Target URL + SheetNames list) + TXLSXExternalLinks collection. TXLSXWorkbook.ExternalLinks özellik exposes the collection; Add(Target) appends and returns a new link the caller fills out. SaveAs emits a çalışma kitabı-level <externalReferences> block in xl/çalışma kitabı.xml, an externalLink rel in xl/_rels/çalışma kitabı.xml.rels (tail of the rid aralık so existing rids stay stable), the xl/externalLinks/externalLink{N}.xml part per entry (<externalBook><sheetNames>) and its sibling .rels file pointing at the remote çalışma kitabı URL with TargetMode="External", plus matching ContentType Overrides. açma scans externalLink{N}.xml + .rels pairs starting at index 1 and stops at the first gap. The current release round-trips Target URL + SheetNames only; cached hücre values inside <sheetDataSet> are not preserved.
Sürüm 2.24.0
- eklendi composing border yardımcı TXLSXRange.SetBorders. New TXLSXBorderEdgeKind enum (xlsxEdgeAll / Outline / Inside / InsideHorizontal / InsideVertical / Top / Bottom / Left / Right / DiagonalUp / DiagonalDown) selects which edges to yazmak. SetBorders(Kind, stil, Color) / SetBorders(Kind, stil) (defaults to opaque black) iterates every hücre in the aralık, computes the edge mask per hücre position (corner hücreler get two outline edges, edge hücreler get one, interior hücreler get inside grid lines, etc.), composes stil + Color onto a clone of the hücre's current border (so successive Outline + Inside calls stack instead of overwriting), then does a çalışma kitabı-level lookup-or-add on çalışma kitabı.Borders and yazar the resulting 1-based BorderIndex back on the hücre. New TXLSXBorders.LookupOrAdd yardımcı returns 0 for empty borders so the pool never bloats with no-op entries.
Sürüm 2.23.0
- eklendi CSV dışa aktarma overloads on TXLSXWorkbook. New entry points: SaveAsCSV(FileName) / SaveAsCSV(FileName, SheetIndex, Delimiter) / SaveAsCSV(Stream) / SaveAsCSV(Stream, SheetIndex, Delimiter) yazmak the chosen sheet's populated extent as UTF-8 with leading BOM and CRLF line terminators. Default variants pick the active sheet and comma delimiter; the SheetIndex/Delimiter overload accepts any WideChar (commonly tab #9 for TSV). Field quoting follows RFC 4180 — values containing the delimiter, double quote, CR or LF are wrapped in quotes with embedded quotes doubled. Date values render as 'yyyy-mm-dd hh:nn:ss'; rich-text hücreler flatten to the concatenated run text; empty hücreler in the interior of the bounding rectangle render as bare delimiters and the row stops at the last populated column.
Sürüm 2.22.0
- eklendi çalışma kitabı-level indexed color palette overrides on TXLSXWorkbook. New entry points: IndexedColor[Index: Integer]: LongWord (okumak/yazmak, valid slots 0..63, ARGB LongWord), HasCustomIndexedColor(Index): Boolean (reports whether the caller has overridden a slot), CustomIndexedColorCount: Integer (number of overridden slots; 0 = palette emits as default), ResetIndexedColors: procedure (discard every override). The new XlsxDefaultIndexedPalette constant exposes the OOXML legacy ECMA-376 palette for slots 0..63. SaveAs emits <colors><indexedColors> with all 64 <rgbColor> children only when at least one slot has been overridden; untouched slots fall back to the default palette so files re-saved without changes stay clean. açma parses the block and silently drops slots whose value matches the default so round-trips stay minimal. Out-of-aralık slot assignments (< 0 or > 63) are dropped instead of raising.
Sürüm 2.21.0
- eklendi six sheet-view display özellikler on TXLSXWorksheet. Zoom: Integer is the zoom percent shown in Excel's status bar (10..400, default 100; out-of-aralık assignments clamp on yazmak). DisplayGridLines / DisplayZeros: Boolean (default True) hide hücre grid lines or render zero-valued hücreler as empty when set False. DisplayRightToLeft: Boolean (default False) flips the sheet to RTL layout for Arabic / Hebrew / etc. StandardWidth / StandardHeight: Double set the default column width (Excel character units) / default row height (points); 0 = unset, in which case Excel applies its built-in 8.43 / 15 defaults. SaveAs emits <sheetView showGridLines / showZeros / rightToLeft / zoomScale> and <sheetFormatPr defaultColWidth / defaultRowHeight> only when the values differ from the Excel defaults; açma parses them back. Existing freeze-pane + tab-seçili handling on <sheetView> is unchanged and now shares a single emitter.
Sürüm 2.20.7
- eklendi TStream overloads on TXLSXWorkbook for in-memory serialization. New entry points: SaveAs(Stream: TStream) / SaveAs(Stream: TStream; FileFormat: TXLSXFileFormat) yazmak the entire .xlsx package into the given stream starting at the current position; açma(Stream: TStream) okur it back. The caller owns the stream and must Free it. Useful for HTTP responses, blob storage, in-memory pipelines, and unit tests that bypass the local file system. The existing file-based SaveAs / açma overloads are unchanged and now delegate to the same internal yazmak / okumak yardımcılar.
Sürüm 2.20.6
- eklendi Hidden / Visible / Comment özellikler to TXLSXDefinedName. Hidden maps to the OOXML <definedName hidden="1"/> attribute (defaults False / Visible=True; True hides the name from Excel's Name Manager UI). Visible is a Boolean alias (inverse of Hidden) for clearer call-site code. Comment maps to <definedName comment="..."/>. SaveAs emits both attributes when they differ from defaults; açma parses them back. SheetIndex (the existing Local scope binding via localSheetId) is unchanged.
Sürüm 2.20.5
- eklendi five more font traits to TXLSXFont. New TXLSXFontVertAlign enum (xlsxVertAlignBaseline / Superscript / Subscript) drives the existing Excel "Superscript" / "Subscript" font checkboxes via a single VertAlign özellik (mutually exclusive in the UI). New Boolean OutlineFont and Shadow özellikler for the matching Excel font effects. New Integer Family (OOXML font-family number: 1=Roman / 2=Swiss / 3=Modern / 4=Script / 5=Decorative; 0=unset) and CharSet (GDI charset number: 0=ANSI / 1=Default / 134=GB2312 / 136=ChineseBig5 / etc.; -1=unset). SaveAs emits the matching <vertAlign> / <outline/> / <shadow/> / <family> / <charset> children inside <font>; açma parses them back. ColorIndex / ThemeColor / TintAndShade are deferred to the upcoming theme milestone.
Sürüm 2.20.4
- eklendi border diagonal direction toggles. TXLSXBorder now exposes DiagonalUp: Boolean and DiagonalDown: Boolean. The two flags share the existing Diagonal edge's stil and Color and pick which diagonal direction(s) Excel renders — up-only (bottom-left to top-right), down-only (top-left to bottom-right), or both. SaveAs emits diagonalUp / diagonalDown attributes on the <border> element when set; açma parses them back. Previously the engine wrote one Diagonal edge with no direction control, so Excel never drew either diagonal line.
Sürüm 2.20.3
- eklendi çalışma kitabı Date1904 toggle. TXLSXWorkbook now exposes a Date1904: Boolean özellik that selects between the Windows 1900 epoch (default; matches Excel for Windows) and the Mac 1904 epoch (Excel for Mac legacy). SaveAs emits <workbookPr date1904="1"/> in xl/çalışma kitabı.xml when set; açma okur it back. The flag is metadata only — the engine does not transform stored serials; callers must set Date1904 before assigning TDateTime hücre values so the round-trip lands on the right calendar.
Sürüm 2.20.2
- eklendi auto-filter per-column criteria destek. New types: TXLSXAutoFilterOp enum (Equal / NotEqual / GreaterThan / LessThan / GreaterOrEqual / LessOrEqual), TXLSXAutoFilterColumn class (ColId + 1 or 2 criteria + AND/OR connector), TXLSXAutoFilterColumns collection. TXLSXWorksheet exposes AutoFilterColumns özellik and AddAutoFilterColumn(ColId, Op, Criteria) / AddAutoFilterColumn(ColId, Op1, Criteria1, Op2, Criteria2, AndConnector) / ClearAutoFilterColumns convenience yöntemler. SaveAs expands the existing <autoFilter ref="..."/> into a body of <filterColumn colId=N><customFilters and=0|1><customFilter operator="..." val="..."/>...</customFilters></filterColumn> per column when criteria are set; açma parses the same structure back. Previously the engine only stored the autofilter aralık (sqref) and Excel showed empty filter dropdowns.
Sürüm 2.20.1
- eklendi manual page break destek on TXLSXWorksheet. New entries: AddRowBreak(BeforeRow) / AddColBreak(BeforeCol) to insert a horizontal or vertical page break before a given row / column (Excel UI "Before" semantics — row N starts a new page). HasRowBreak / HasColBreak check; RemoveRowBreak / RemoveColBreak drop a single entry; ClearRowBreaks / ClearColBreaks / ClearAllPageBreaks bulk-clear. RowBreakCount / ColBreakCount + indexed RowBreaks(Index) / ColBreaks(Index) expose the stored 1-based "Before" indices for iteration. SaveAs emits <rowBreaks> / <colBreaks> with <brk id="N-1" max="..." man="1"/> children between <headerFooter> and <drawing>; açma parses them back.
Sürüm 2.20.0
- eklendi sheet visibility (Hidden / VeryHidden), per-sheet selection and active-sheet tracking on TXLSXWorkbook / TXLSXSheets / TXLSXWorksheet. New types: TXLSXSheetVisibility enum (xlsxSheetVisible / xlsxSheetHidden / xlsxSheetVeryHidden). New TXLSXWorksheet özellikler: Visibility, Visible (Boolean alias), IsSelected (okumak-only). New TXLSXSheets members: ActiveIndex, Activate(Index), Move(FromIndex, ToIndex). New TXLSXWorkbook.ActiveSheet proxy. SaveAs emits <sheet state="..."/> on the çalışma kitabı's sheet entries, <bookViews><workbookView activeTab=N/></bookViews> when the active sheet is not the default 0, and tabSelected="1" on the active sheet's <sheetView>; açma parses all three back into the new özellikler. The first eklendi sheet becomes both visible and active by default so existing call sites continue to work.
Sürüm 2.19.2
- eklendi four more PageSetup attribute toggles on TXLSXWorksheet to round out the OOXML <pageSetup> coverage: BlackAndWhite (B/W rendering), Draft (suppress graphics for faster preview), PrintNotes (print hücre comments as displayed instead of hiding them), and PrintOverThenDown (left-to-right rows first instead of the default top-to-bottom columns first traversal). SaveAs emits the matching blackAndWhite / draft / cellComments / pageOrder attributes; açma parses them back. Defaults stay off so unchanged çalışma sayfaları do not gain extra attributes.
Sürüm 2.19.1
- eklendi three-part header and footer convenience özellikler to TXLSXWorksheet. New entries: LeftHeader / CenterHeader / RightHeader and LeftFooter / CenterFooter / RightFooter. Each okur or yazar the matching &L / &C / &R segment of the existing HeaderText / FooterText raw string; writing any one segment rebuilds the full raw form so the round-trip writer and reader keep working without changes.
- eklendi print-option toggles for sheet-level page output. New TXLSXWorksheet özellikler: CenterHorizontally, CenterVertically, PrintGridlines, PrintHeadings. SaveAs emits a <printOptions horizontalCentered / verticalCentered / gridLines / headings/> element when any of the four is enabled; açma parses the same attributes back. Defaults stay off so unchanged çalışma sayfaları do not gain an extra <printOptions/> element.
- eklendi per-sheet PrintArea, PrintTitleRows and PrintTitleCols round-trip. These map to the OOXML built-in çalışma kitabı-level _xlnm.Print_Area and _xlnm.Print_Titles defined names scoped via localSheetId. PrintArea takes a bare A1 reference (e.g. "$A$1:$D$10"); PrintTitleRows and PrintTitleCols take row-only or column-only references (e.g. "$1:$3" or "$A:$B") and combine into a single Print_Titles entry. The writer prepends the sheet name with proper quoting (single quotes around names that contain spaces or special chars); the reader strips the prefix and routes the entries back into the matching sheet so they do not leak into the user-facing TXLSXWorkbook.DefinedNames collection.
Sürüm 2.19.0
- eklendi row / column insert and delete operations with full sheet-wide shift on TXLSXWorksheet. New entries: InsertRows(BeforeRow, Count), DeleteRows(StartRow, Count), InsertCols(BeforeCol, Count), DeleteCols(StartCol, Count). InsertRows / InsertCols push existing rows / columns away from the cut by Count; DeleteRows / DeleteCols drop the [Start, Start+Count-1] band and pull everything past the cut back by Count.
- The shift applies across every piece of sheet geometry that depends on row / column position: hücre anchors (hücreler), merged-aralık corners (MergedCells — straddling aralıklar are clipped to the surviving edges and inside-only aralıklar are removed), the row / column metadata lists (FRowHeights / FColWidths / outline levels / hidden / collapsed), Hyperlink and Comment anchors (entries inside a deleted band are removed), FreezePane (FFreezeRow / FFreezeCol), AutoFilterRange, and the per-entry aralık string on every ConditionalFormat, DataValidation, and Excel tablo (an entry whose aralık falls entirely inside the cut is removed).
- New Delete(Index) members on the supporting collections so the shift logic can remove a single entry without a Clear: TXLSXHyperlinks, TXLSXComments, TXLSXConditionalFormats, TXLSXDataValidations, TXLSXTables.
- Out of scope in this release: Images and Charts are not shifted (their EMU pixel anchors decouple them from the hücre grid and a faithful shift would require recomputing the EMU offsets); çalışma kitabı-level DefinedNames formüller are not rewritten. Both are tracked for a follow-up release.
Sürüm 2.18.2
- eklendi AutoFit yardımcılar for column widths and row heights. TXLSXWorksheet exposes AutoFitColumn(ACol) / AutoFitColumns(ColMin, ColMax) and AutoFitRow(ARow) / AutoFitRows(RowMin, RowMax); TXLSXRange exposes AutoFitColumns and AutoFitRows that forward to the çalışma sayfası over the aralık's bounds. Width is estimated in Excel character units (Calibri 11pt baseline; ASCII counts 1, CJK characters count 2) with a 1.20 px-per-char correction and 1.0 padding, clamped to [8.43, 255.0]. Row height defaults to 15 pt and grows by 12.75 pt per embedded newline in the hücre text. Wide aralıklar (EntireRow / EntireColumn) are clamped to the last hücre-bearing row / column on the çalışma sayfası so AutoFit does not iterate to the Excel grid limits.
Sürüm 2.18.1
- eklendi per-hücre protection round-trip to the XLSX engine. TXLSXCell exposes new Locked: Boolean (default True) and FormulaHidden: Boolean (default False) convenience özellikler that mirror Excel's hücre-protection model. They surface the pool index TXLSXCell.ProtectionIndex (1-based into the new çalışma kitabı-level TXLSXProtections pool); writing the convenience özellik looks up or appends the (Locked, FormulaHidden) pair in the pool. Defaults (Locked=True, FormulaHidden=False) collapse to ProtectionIndex=0 so the pool stays empty for stock hücreler.
- eklendi TXLSXRange.SetLocked(ALocked) and TXLSXRange.SetFormulaHidden(AHidden) batch yardımcılar so unlocking or hiding a whole aralık only does one pool lookup-or-add and applies the result to every hücre in the rectangle.
- eklendi the matching writer / reader plumbing. SaveAs emits one cellXf with an inline <protection locked="N" hidden="M"/> child per çalışma kitabı Protections entry (after the alignment block); açma parses <protection> back into çalışma kitabı.Protections and threads the new CellXfProtMap through ParseStylesXml and ParseWorksheetXml so per-hücre ProtectionIndex round-trips alongside the existing font / fill / border / number-format / alignment indices.
Sürüm 2.18.0
- eklendi TXLSXRange object for multi-hücre access and batch operations on TXLSXWorksheet. New entry points: çalışma sayfası.aralık['A1:C5'], çalışma sayfası.RCRange[r1,c1,r2,c2], çalışma sayfası.UsedRange, çalışma sayfası.EntireRow(r), çalışma sayfası.EntireColumn(c). The returned aralık exposes SetValue / SetFormula / Clear / ClearAll / Merge / Unmerge / Offset / Resize plus per-hücre stil index setters (SetFontIndex / SetFillIndex / SetBorderIndex / SetNumberFormatIndex / SetAlignmentIndex) and a SetNumberFormat(Fmt) convenience that looks up or appends the format string in the çalışma kitabı pool. TXLSXRange objects are owned by the çalışma sayfası and released on çalışma sayfası destruction; callers do not free them.
- eklendi TXLSXCell.NumberFormat: WideString convenience that pairs with the existing NumberFormatIndex. Reading returns the format string from the çalışma kitabı pool; writing looks up or ekler the string and güncellemeler NumberFormatIndex transparently. Requires the hücre to be attached to a çalışma kitabı (the standard flow through TXLSXWorkbook.Sheets.Add(...).hücreler[r, c]).
- eklendi hücre -> sheet -> çalışma kitabı back-references so each TXLSXCell can resolve its owning çalışma kitabı without external bookkeeping. TXLSXSheets, TXLSXWorksheet, and TXLSXCells gained internal Owner references wired through their constructors; TXLSXCell exposes a okumak-only çalışma kitabı özellik and an internal SetWorkbook used by TXLSXCells.GetItem when auto-creating a hücre on access.
Sürüm 2.17.42
- Fixed XLSX hücre round-trip on reopen. hücreler written by SaveAs were being dropped on açma, with HasCell(row, col) returning False and all hücre-level state (value, formül, font index, fill index, border index, number format index) lost. The root cause was a spurious MoveToAttribute('r') call in the çalışma sayfası parser that flipped the reader's node type to attribute, which then made the subsequent IsEmptyElement check return True and shut off hücre parsing for every <c> element with an r="" attribute (i.e. every hücre). Removing the unnecessary cursor move restores text, numeric, formül, and date hücre round-trip together.
- Fixed XLSX stil index restore on reopen. özel font, fill, border, and number-format indices on hücreler were reading back as zero even after the matching pools (çalışma kitabı.Fonts/Fills/Borders/NumberFormats) round-tripped correctly. The cellXf parser tracked its position with a counter that only advanced on the </xf> end tag, but Excel commonly emits self-closing <xf .../> entries (no inner <alignment>), so the counter never moved past zero and every cellXf mapping clobbered the previous one. The parser now advances the counter on a self-closing <xf/> too, so per-hücre FontIndex / FillIndex / BorderIndex / NumberFormatIndex round-trip.
- Fixed XLSX date hücre round-trip. Writing a TDateTime to TXLSXCell.Value used to route through the shared-string pool with t="s" because Delphi's VarIsNumeric() returns False for varDate; SaveAs now yazar the date serial number into <v> directly and applies the date cellXf, so date hücreler reopen as a varDate Variant instead of a localized string that the caller could not coerce back to TDateTime.
Sürüm 2.17.41
- Fixed "zlib stream does not destek seeking" error raised when reopening .xlsx files that contain embedded images or a VBA project (.xlsm). The image-reload path and the VBA-payload reload path both routed the inflated entry stream through TMemoryStream.CopyFrom(Source, 0), which internally rewinds Source to derive the byte count; the rewind is not legal on a forward-only Deflate stream. Both call sites now use a chunked okumak-until-EOF yardımcı, so .xlsx files with images or macros round-trip through SaveAs/açma without raising.
Sürüm 2.17.40
- eklendi chart-sheet (full-page chart çalışma sayfası) destek to the XLSX engine. TXLSXWorksheet exposes a new IsChartSheet flag plus a çalışma kitabı-level çalışma kitabı.AddChartSheet(Name, ChartType, Title) yardımcı that creates the sheet, flips the flag, and seeds Charts[0] with a sensible default anchor. SaveAs yazar IsChartSheet sheets to xl/chartsheets/sheetN.xml with a dedicated rels file pointing at the shared drawing part, registers them as chartsheet content-types, and emits the chartsheet relationship in xl/_rels/çalışma kitabı.xml.rels. Regular çalışma sayfaları keep their existing xl/çalışma sayfaları/sheetN.xml path. açma recognizes chartsheets via the relationship type but currently loads them as plain çalışma sayfaları (their chart data still arrives via the shared chart parts).
Sürüm 2.17.39
- eklendi collapsed row / collapsed column round-trip for outline groups in the XLSX engine. TXLSXWorksheet exposes RowCollapsed[Row] and ColCollapsed[Col] Boolean özellikler along with SetRowCollapsed / SetColCollapsed / ClearRowCollapsed / ClearColCollapsed yardımcılar. SaveAs emits collapsed="1" on the matching <row> and <col> entries; açma parses the attribute back. Together with the existing outlineLevel and hidden attributes, this lets the XLSX engine round-trip a fully collapsed grouping hierarchy.
Sürüm 2.17.38
- eklendi hidden row / hidden column round-trip to the XLSX engine. TXLSXWorksheet exposes RowHidden[Row] and ColHidden[Col] Boolean özellikler along with SetRowHidden / SetColHidden / ClearRowHidden / ClearColHidden yardımcılar. SaveAs emits hidden="1" on the matching <row> and <col> entries; açma parses the attribute back into the çalışma sayfası so hidden rows / columns survive the round-trip without forcing a özel width or outline level.
Sürüm 2.17.37
- eklendi çalışma sayfası tab color round-trip to the XLSX engine. TXLSXWorksheet exposes TabColor (ARGB) and TabColorIsAuto özellikler. SaveAs emits a <sheetPr><tabColor rgb="..."/></sheetPr> block as the first child of <çalışma sayfası> when the tab color is set; açma parses <tabColor> back into the çalışma sayfası so colored sheet tabs survive the round-trip. Default çalışma kitapları stay free of the extra block (TabColorIsAuto = True).
Sürüm 2.17.36
- eklendi hücre alignment round-trip to the XLSX engine. New TXLSXHorizontalAlignment and TXLSXVerticalAlignment token enums, TXLSXAlignment class (Horizontal, Vertical, WrapText, ShrinkToFit, Indent, TextRotation), and a çalışma kitabı-level TXLSXAlignments collection (çalışma kitabı.Alignments). TXLSXCell now carries an AlignmentIndex (1-based into çalışma kitabı.Alignments). SaveAs appends one cellXf with an inline <alignment/> child per çalışma kitabı alignment entry; açma okur <alignment> attributes back into çalışma kitabı.Alignments and maps the cellXf back to TXLSXCell.AlignmentIndex. ParseWorksheetXml and ParseStylesXml grew a CellXfAlignMap parameter to carry the mapping across the two phases.
Sürüm 2.17.35
- eklendi the AES encryption (ECMA-376 Standard Encryption) API surface to the XLSX engine. TXLSXWorkbook exposes SaveAsEncrypted(FileName, Password) / OpenEncrypted(FileName, Password) / CanReadEncrypted(FileName) plus a typed EXlsxEncryptionNotImplemented exception. CanReadEncrypted recognizes the Microsoft Compound File Binary magic bytes ($D0 $CF $11 $E0 $A1 $B1 $1A $E1) so callers can detect encrypted archives before deciding how to açma them; OpenEncrypted transparently falls back to plain açma for unencrypted .xlsx files. The AES-128/256 + SHA + OLE Compound File pipeline itself is not yet wired up — both yazmak and okumak of actually-encrypted archives raise the typed exception until the follow-up release lands the algorithm. The exception type is deliberately distinct so existing callers can catch it and fall back to çalışma sayfası.Protect / çalışma kitabı.ProtectWorkbook for the visual lock.
Sürüm 2.17.34
- Performance: replaced the O(N^2) WideString concatenation that built each çalışma sayfası's hücre rows with a TXLSWideStringBuilder. Large sheets (10k+ hücreler) now stay linear in memory and CPU on SaveAs. eklendi a new WriteWorksheetXmlStreaming yardımcı and a TXLSXWorkbook.StreamingWrite opt-in flag — when enabled, SaveAs no longer holds every çalışma sayfası's XML in a sheetXmls cache at the same time; each çalışma sayfası is built, written, and dropped before moving to the next. sharedStrings.xml is emitted last so the streaming path still produces a fully-populated SST. Default behavior unchanged.
Sürüm 2.17.33
- eklendi hücre-aralık operations to the XLSX engine. TXLSXWorksheet exposes ClearRange(R1, C1, R2, C2), CopyRange(SrcR1, SrcC1, SrcR2, SrcC2, DstR, DstC) for in-sheet copy, CopyRangeTo(... TargetSheet, DstR, DstC) for cross-sheet copy, and MoveRange(SrcR1, SrcC1, SrcR2, SrcC2, DstR, DstC) for cut-and-paste. Each operation duplicates the hücre value, formül, four stil indices, and any rich-text payload; MoveRange skips overlap with the destination so partial overlaps still korumak their copied values. TXLSXCells also gains a Remove(Row, Col) yardımcı.
Sürüm 2.17.32
- eklendi internal hyperlink anchors to the XLSX engine. TXLSXHyperlink now carries a Location özellik (e.g. "Sheet2!A1") and an IsInternal yardımcı; TXLSXHyperlinks exposes AddInternal, and TXLSXWorksheet ekler three AddHyperlinkToCell overloads. SaveAs emits internal hyperlinks with the inline location="" attribute and skips the çalışma sayfası rels entry; açma recognizes location="" hyperlinks and routes them back through AddInternal. External URL hyperlinks continue to flow through the rels file unchanged.
Sürüm 2.17.31
- eklendi rich-text round-trip to the XLSX engine. New TXLSXRichTextRun class (per-run Name / Size / Bold / Italic / Strikethrough / Underline / Color) and TXLSXRichText container that exposes AddRun / AddRunText / Clear / PlainText. TXLSXCell now carries an owned RichText özellik; SaveAs yazar the hücre as a shared-string with multiple <r>/<rPr>/<t> runs and açma rebuilds the TXLSXRichText from the parsed SST entry, with the hücre's Variant Value still surfacing the concatenated plain text for callers that ignore formatting.
Sürüm 2.17.30
- eklendi chart round-trip to the XLSX engine. New TXLSXChartType enum (column / bar / line / pie), TXLSXChartSeries (Name, CategoriesRange, ValuesRange), and TXLSXChart (ChartType, Title, axis titles, From/To anchor hücreler, Series) classes plus a per-çalışma sayfası TXLSXCharts collection (çalışma sayfası.Charts). TXLSXWorksheet exposes AddChart(Type, Title, FromRow, FromCol, ToRow, ToCol). SaveAs emits xl/charts/chartN.xml (çalışma kitabı-global numbering) and binds it to a twoCellAnchor / graphicFrame inside the shared xl/drawings/drawingN.xml; açma parses both the anchor and the chart definition back into the collection. Chart titles, axis titles, series names and source aralıklar round-trip.
Sürüm 2.17.29
- Fixed an EListError "Operation not allowed on sorted list" raised by SetColWidth, SetRowHeight, SetRowOutlineLevel, and SetColOutlineLevel. Each of those four TStringList fields was created with Sorted=True but written through the Values[Name] := X setter, which RAD Studio's RTL refuses on a sorted list. The lists are now created unsorted; lookups continue to go through IndexOfName, which is fine at typical per-sheet column / row counts.
Sürüm 2.17.28
- Fixed TZipArchive.Exists, which was a stub that always returned false. The XLSX açma path uses zip.Exists(...) to gate every part okumak, so every previously-claimed round-trip (hücreler, stiller, comments, drawings, doc props, defined names, protection, VBA, etc.) silently dropped its content on okumak. Exists now delegates to the existing Fcd.Entries.Exists lookup, matching the OpenFile / CreateFile pattern.
Sürüm 2.17.27
- eklendi VBA project preservation to the XLSX engine. TXLSXWorkbook exposes a VbaProject byte payload plus LoadVbaProjectFromFile(FileName), ClearVbaProject, and HasVbaProject yardımcılar. SaveAs yazar the bytes to xl/vbaProject.bin, registers the .bin content-type, switches the çalışma kitabı content-type to the macro-enabled variant, and ekler a vbaProject relationship to the çalışma kitabı rels file; açma okur xl/vbaProject.bin back into the özellik. The bytes are not parsed or modified, so existing .xlsm projects round-trip exactly. Note: macro-enabled çalışma kitapları must be saved with a .xlsm extension for Excel to enable macros.
Sürüm 2.17.26
- eklendi çalışma kitabı and sheet protection to the XLSX engine. TXLSXWorksheet exposes Protect / Protect(Password) / UnProtect plus IsProtected and SheetProtectHash; TXLSXWorkbook ekler ProtectWorkbook (with optional password, LockStructure, LockWindows flags) and UnProtectWorkbook plus IsWorkbookProtected / WorkbookProtectHash / LockStructure / LockWindows. SaveAs emits <sheetProtection> on each protected çalışma sayfası and <workbookProtection> on protected çalışma kitapları; açma parses both blocks back into the API. Passwords are stored as the standard 4-hex legacy hash for round-trip fidelity (the original plaintext is not recoverable).
Sürüm 2.17.25
- eklendi document-özellik round-trip to the XLSX engine. TXLSXWorkbook now exposes Title, Author, Subject, Keywords, Description, Category, LastModifiedBy, Created, Modified, Company, Application, and AppVersion özellikler. SaveAs emits docProps/core.xml and docProps/app.xml (and registers them in [Content_Types].xml + _rels/.rels) when any özellik is touched; açma parses both files back so authors, modification stamps, and application metadata survive a kaydetme-and-reopen.
Sürüm 2.17.24
- eklendi Excel-stil tablo round-trip to the XLSX engine. New TXLSXTable class (Id, Name, DisplayName, aralık, Columns, StyleName, ShowFirstColumn / ShowLastColumn / ShowRowStripes / ShowColumnStripes) and a per-çalışma sayfası TXLSXTables collection. TXLSXWorksheet exposes tablolar plus AddTable(Name, aralık, ColumnNames). SaveAs emits xl/tablolar/tableN.xml (çalışma kitabı-global numbering), güncellemeler çalışma sayfası rels with tablo relationships, ekler <tableParts> to the çalışma sayfası, and registers the tablo content-type. açma parses tablo relationships and tableN.xml back into the çalışma sayfası so styled tablo bands survive a kaydetme-and-reopen.
Sürüm 2.17.23
- eklendi auto-filter round-trip to the XLSX engine. TXLSXWorksheet exposes an AutoFilterRange özellik plus SetAutoFilter(Row1, Col1, Row2, Col2) / SetAutoFilter(aralık) / ClearAutoFilter yardımcılar. SaveAs emits <autoFilter ref="..."/> after the merge-hücreler block when the aralık is non-empty; açma parses the ref back into the özellik so the filter band on a çalışma sayfası survives a kaydetme-and-reopen.
Sürüm 2.17.22
- eklendi page-setup round-trip to the XLSX engine. TXLSXWorksheet exposes Margin{Left,Right,Top,Bottom,Header,Footer}, PageLandscape, PaperSize, PageScale, FitToWidth, FitToHeight, HeaderText, and FooterText özellikler plus SetPageMargins(L, R, T, B[, H, F]) convenience overloads. SaveAs emits the corresponding <pageMargins>, <pageSetup>, and <headerFooter> blocks between hyperlinks and drawings; açma parses them back. Default-only çalışma sayfaları stay untouched (PageSetupTouched flag gates output).
Sürüm 2.17.21
- eklendi freeze-pane round-trip to the XLSX engine. TXLSXWorksheet exposes FreezePane(Col, Row) / UnfreezePane yöntemler plus okumak-only FreezeCol and FreezeRow özellikler. SaveAs yazar a <sheetViews>/<pane state="frozen"> block before <sheetData> with the matching activePane and selection; açma parses <pane state="frozen"> back into the freeze position so frozen-top/left/corner layouts survive a kaydetme-and-reopen.
Sürüm 2.17.20
- eklendi row and column outline (grouping) levels to the XLSX engine. TXLSXWorksheet exposes RowOutlineLevel[Row] and ColOutlineLevel[Col] indexed özellikler plus SetRowOutlineLevel / HasRowOutlineLevel / ClearRowOutlineLevels and the matching column yardımcılar. SaveAs emits outlineLevel attributes on <row> entries and merged <col> entries (combined with özel widths when present); açma parses both attributes back into the çalışma sayfası so grouped row/column hierarchies survive the round-trip.
Sürüm 2.17.19
- eklendi conditional formatting and data validation round-trip to the XLSX engine. New TXLSXCfOperator enum and TXLSXConditionalFormat class (aralık, Op, formül1, formül2) plus a TXLSXConditionalFormats collection on each çalışma sayfası (çalışma sayfası.ConditionalFormats). New TXLSXDataValidationType, TXLSXDvOperator, TXLSXDataValidation (aralık, ValidationType, Op, formül1, formül2, AllowBlank, ShowInputMessage, ShowErrorMessage), and a TXLSXDataValidations collection (çalışma sayfası.DataValidations) with an AddList(aralık, Items) shortcut for the common dropdown case. TXLSXWorksheet exposes AddConditionalFormat and AddDataValidation / AddListValidation yardımcılar. SaveAs yazar <conditionalFormatting> blocks (with cfRule type="cellIs") and a <dataValidations> block after sheetData; açma parses both blocks back into the collections.
Sürüm 2.17.18
- eklendi defined-name round-trip to the XLSX engine. New TXLSXDefinedName class (Name, formül, SheetIndex) and a çalışma kitabı-level TXLSXDefinedNames collection (çalışma kitabı.DefinedNames) with Add(Name, formül[, SheetIndex]) overloads and IndexOfName lookup. SaveAs emits a <definedNames> block in xl/çalışma kitabı.xml; entries with SheetIndex >= 0 carry a localSheetId attribute (sheet-scoped) and entries with SheetIndex = -1 are çalışma kitabı-scoped. açma parses <definedName> elements back into the collection so saved-and-reopened çalışma kitapları keep their named aralıklar intact.
Sürüm 2.17.17
- eklendi image round-trip to the XLSX engine. New TXLSXImageFormat enum (png, jpeg, gif, bmp), TXLSXImage class (Row/Col anchor, WidthEMU/HeightEMU, Format, Data), and a per-çalışma sayfası TXLSXImages collection. TXLSXWorksheet exposes Images plus AddImage(Row, Col, Data, Format) and AddImageFromFile(Row, Col, FileName) yardımcılar. SaveAs yazar the image bytes into xl/media/imageN.<ext>, generates xl/drawings/drawingN.xml with a oneCellAnchor per image (and a matching _rels file), registers content types and çalışma sayfası/drawing relationships, and emits a <drawing r:id="..."/> reference inside the çalışma sayfası. açma parses drawingN.xml + drawing rels + media to round-trip images back into çalışma sayfası.Images.
Sürüm 2.17.16
- eklendi özel number-format round-trip to the XLSX engine. New TXLSXNumberFormat class and a çalışma kitabı-level TXLSXNumberFormats collection (çalışma kitabı.NumberFormats) deduplicate format codes via Add(FormatCode). TXLSXCell exposes a new NumberFormatIndex özellik; SaveAs emits a <numFmts> block in xl/stiller.xml (özel ids starting at the OOXML-reserved base 164) and pairs each format with a dedicated cellXf, açma parses özel numFmts back and reverses the cellXf->numFmtId map into NumberFormatIndex on okumak. Precedence on conflict: FormatIndex > FontIndex > FillIndex > BorderIndex > NumberFormatIndex.
Sürüm 2.17.15
- eklendi hücre-border round-trip to the XLSX engine. New TXLSXBorderStyle enum, TXLSXBorderEdge class (stil + Color + ColorIsAuto for each side), TXLSXBorder class with Left/Right/Top/Bottom/Diagonal edges plus SetAll(stil[, Color]) yardımcılar, and a çalışma kitabı-level TXLSXBorders collection (çalışma kitabı.Borders) with a Borders.AddBox(stil[, Color]) shortcut. TXLSXCell exposes a new BorderIndex özellik; SaveAs emits each border into xl/stiller.xml and pairs it with a dedicated cellXf, açma parses borders back and translates the cellXf->borderId map into BorderIndex on okumak. Precedence remains FormatIndex > FontIndex > FillIndex > BorderIndex when several are set on the same hücre.
Sürüm 2.17.14
- eklendi hücre-fill round-trip to the XLSX engine. New TXLSXFillPattern enum and TXLSXFill class describe patternType, fgColor, and bgColor; the çalışma kitabı-level TXLSXFills collection is reachable via çalışma kitabı.Fills, with a Fills.AddSolid(color) convenience for the common solid-color case. TXLSXCell exposes a new FillIndex özellik; SaveAs emits each fill into xl/stiller.xml and pairs it with a dedicated cellXf, açma parses them back and reverses hücre s attributes into FillIndex on okumak. FontIndex still takes precedence when both are set.
Sürüm 2.17.13
- Completed the XLSX font round-trip. açma now parses xl/stiller.xml back into çalışma kitabı.Fonts and a cellXf->fontId tablo; each hücre's s attribute is mapped back into TXLSXCell.FontIndex so saved-and-reopened çalışma kitapları korumak özel fonts (Name, Size, Bold, Italic, Strikethrough, Underline, Color).
Sürüm 2.17.12
- eklendi a TXLSXFont class plus a çalışma kitabı.Fonts collection so XLSX hücreler can pick a özel font. TXLSXCell carries a new FontIndex özellik; SaveAs emits the fonts list in xl/stiller.xml and one cellXf per font, then references the matching cellXf from each hücre's s attribute. açma round-trip of FontIndex is planned for the next release.
Sürüm 2.17.11
- eklendi row-height round-trip to the XLSX engine. TXLSXWorksheet exposes a RowHeight[Row] özellik plus SetRowHeight, HasRowHeight, and ClearRowHeights yardımcılar. SaveAs yazar the ht and customHeight="1" attributes on each <row> with a customized height (including rows that only carry a height, with no hücre data); açma okur the ht attribute back into the row-height map.
Sürüm 2.17.10
- eklendi column-width round-trip to the XLSX engine. TXLSXWorksheet exposes a ColWidth[Col] özellik along with SetColWidth, HasColWidth, and ClearColWidths yardımcılar. SaveAs emits a <cols> block with one <col> entry per customized column; açma replays <col min/max/width> entries back into the çalışma sayfası so unmodified widths fall back to the Excel default.
Sürüm 2.17.9
- eklendi hücre-comment round-trip to the XLSX engine. TXLSXWorksheet exposes a Comments collection and AddComment(Row, Col, Text[, Author]) overloads. SaveAs emits xl/commentsN.xml (with deduplicated author list) and a companion xl/drawings/vmlDrawingN.vml so Excel can render the comment balloons; açma okur commentsN.xml back into the collection. çalışma sayfası rels, content types, and <legacyDrawing> wiring are handled automatically.
Sürüm 2.17.8
- eklendi hyperlink round-trip to the XLSX engine. TXLSXWorksheet exposes a Hyperlinks collection and AddHyperlink(Row, Col, Url[, Display[, Tooltip]]) overloads. SaveAs yazar a <hyperlinks> block in each çalışma sayfası and emits a matching xl/çalışma sayfaları/_rels/sheetN.xml.rels file with the external URL targets; açma okur the çalışma sayfası rels first to resolve <hyperlink r:id="..."/> entries into URLs in the collection.
Sürüm 2.17.7
- eklendi merged-hücre round-trip to the XLSX engine. TXLSXWorksheet exposes a MergedCells collection and a MergeCells(R1, C1, R2, C2) convenience yöntem that mirror the BIFF facade stil. SaveAs emits a <mergeCells> block after sheetData, and açma parses <mergeCell ref="A1:B2"/> entries back into the collection.
Sürüm 2.17.6
- The XLSX engine now round-trips date values and formüller. TDateTime hücre values are serialized as Excel serial numbers and tagged with a built-in date cellXf so Excel renders them as dates; on açma, hücreler whose stil references the date cellXf are decoded back to TDateTime variants. TXLSXCell exposes a new formül özellik; SaveAs yazar the formül as a <f> child element and açma parses <f> text back into the hücre.
Sürüm 2.17.5
- eklendi a stiller.xml scaffold to the XLSX engine. SaveAs now emits a minimum-valid xl/stiller.xml with default fonts, fills, borders, cellStyleXfs, and cellXfs entries, plus the corresponding content-type and çalışma kitabı-relationship registrations. hücreler carry a FormatIndex özellik and emit the s="N" hücre attribute when non-zero, and açma okur s="N" back into FormatIndex. Concrete stil descriptors (fonts, fills, borders, cellXfs as çalışma kitabı-level collections) will be eklendi in follow-up commits.
Sürüm 2.17.4
- eklendi shared strings (SST) destek to the XLSX engine. SaveAs builds a deduplicated string tablo and emits xl/sharedStrings.xml, replacing inline string emission. açma okur xl/sharedStrings.xml first and resolves t="s" hücre references through the SST. Inline string hücreler from third-party XLSX files are still accepted on açma.
Sürüm 2.17.3
- Replaced the hücre record array on TXLSXWorksheet with TXLSXCell objects and a TXLSXCells collection. The hücre-access call site now okur çalışma sayfası.hücreler.Item[Row, Col].Value, matching the IXLSCells / IXLSRange shape on the BIFF facade. çalışma sayfası.hücreler.HasCell / hücreler.Count / hücreler.CellByIndex / hücreler.Clear are also available.
Sürüm 2.17.2
- Introduced the TXLSXSheets collection class on TXLSXWorkbook, mirroring the IXLSWorkSheets collection on the BIFF facade. Code now okur çalışma kitabı.Sheets.Add / çalışma kitabı.Sheets.Count / çalışma kitabı.Sheets[i] / çalışma kitabı.Sheets.IndexByName instead of the previous çalışma kitabı.AddSheet / çalışma kitabı.SheetCount / çalışma kitabı.Sheet[i] yöntemler.
Sürüm 2.17.1
- Renamed TXLSXWorkbook.SaveToFile to SaveAs and TXLSXWorkbook.LoadFromFile to açma, matching the existing IXLSWorkBook naming stil. eklendi file-format and password overloads so the XLSX facade okur the same way as the BIFF facade. AddSheet now offers a no-argument overload that generates a default sheet name.
Sürüm 2.17.0
- TXLSXWorkbook.SaveAs produces a minimum OOXML .xlsx archive with hücre values (numbers, booleans, and inline strings). The archive contains content types, root relationships, çalışma kitabı + relationships, and a çalışma sayfası per sheet.
- TXLSXWorkbook.açma okur back the minimum OOXML .xlsx archive — sheet names from xl/çalışma kitabı.xml and hücre values from xl/çalışma sayfaları/sheetN.xml. Shared strings, stiller, dates, and formüller are not yet supported.
- eklendi OOXML namespace, content-type, and relationship constants plus reference / parsing / escape yardımcılar (XlsxColumnLabel, XlsxCellRef, XlsxColumnIndex, XlsxParseCellRef, XlsxParseRangeRef, XlsxEscapeText, XlsxEscapeAttr) for use by future XLSX features.
Sürüm 2.16.4
- The XLSX facade unit (lxHandleX) now defines its own çalışma kitabı and çalışma sayfası types (TXLSXWorkbook, TXLSXWorksheet), independent of the BIFF facade. kaydetme and load entry points are reserved; the OOXML wiring will be filled in a follow-up release.
- eklendi a developer reference topic for the new XLSX facade, describing how lxHandle and lxHandleX coexist and which yardımcı units they share.
Sürüm 2.16.3
- Introduced
lxHandleX, a dedicated XLSX facade unit that lives alongside the existinglxHandleBIFF facade. The two units share the same underlying infrastructure (stil pools, XML utilities, ZIP archive) but expose independent class hierarchies:lxHandleownsTXLSWorkBookand the classic XLS/HTML/RTF/CSV paths;lxHandleXwill ownTXLSXWorkbookand all XLSX-specific APIs. Three yöntem stubs accidentally eklendi tolxHandle(SetCodePage,GetColumnXFIndex,GetRowXFIndex) were removed to keep the BIFF facade’s public API identical to v2.15.0. Existing code thatuses lxHandlerequires no changes.
Sürüm 2.16.2
- eklendi three internal data-structure units completing the XLSX engine foundation:
lxAvlTreeprovides an O(log N) AVL tree (TAVLTree/TAVLNode) for sorted lookups;lxColsandlxRowsare column and row info containers with fine-grained deduplication and index rewriting, used by the XLSX engine’s per-sheet column-width and row-height maps. All three are dormant in this release and are activated in v2.17.0 when the XLSX okumak/yazmak engine is first enabled.
Sürüm 2.16.1
- eklendi six internal XML and ZIP utility units that complete the XLSX engine’s infrastructure layer:
lxWStream(wide-character file stream with file-existence check and AnsiString yazmak yardımcı);lxCacheStream(buffered stream wrapper that reduces underlying I/O calls);lxZlibStream(forward-only deflate/inflate stream, independent of the existingloZlibBIFF encryption binding);lxXmlReader(SAX-stil pull reader for high-speed XML parsing);lxXmlWriter(streaming XML writer with element-name reuse);lxZipArchive(central-directory ZIP reader/writer with per-entry deflate streams). Together with the seven units from v2.16.0 these form the complete internal foundation for the XLSX engine.
Sürüm 2.16.0
- eklendi seven internal stil-infrastructure units as the foundation for the upcoming XLSX engine:
lxHashTable(generic hash tablolar with integer, WideString, and object-key variants);lxKeyList(object-key list with fast lookup and index rewriting);lxStyleColor(Office theme color and palette slot manager);lxStyleFont,lxStyleFill, andlxStyleBorder(deduplicated pools for font, fill, and border stiller covering all 12 BIFF line types and XLSX stil mappings);lxStyleXf(aggregates all five stil pools with a number-format list into a single XF record). All seven units are dormant in this release and do not affect existing XLS paths.
Sürüm 2.15.1
- eklendi
lxRgbcolor utility yardımcılar:RGBtoHLS,HLStoRGB,RGBTint, andGetRGBTintconvert between the RGB and HLS color spaces (0–240 HLS aralık). These underpin theme-color tint calculations, color-scale conditional formatting, and palette interpolation in XLSX output. - eklendi
lxStrBuilderhigh-performance string builders:TXLSStringBuilder(AnsiChar) andTXLSWideStringBuilder(WideChar) use pre-allocated, doubling-growth buffers to eliminate the per-concatenation memory reallocation of standard Pascal strings. The AnsiChar variant drives the XLSX XML serialization path; the WideChar variant handles wide-string assembly in the XLSX parser.
Sürüm 2.15.0
- Reworked the HtmlHelp reference into a web-ready structure with dedicated topic, asset, script, stil, and source folders.
- eklendi a browser-friendly help home page and contents navigation page, with unified headers, topic shortcuts, and footers.