Примечания к выпуску HotXLS
История версий HotXLS с пользовательскими возможностями, исправлениями, улучшениями XLS/XLSX, экспортом, совместимостью и обновлениями документации.
[Unreleased]
Версия 2.88.111
- Листы Classic XLS теперь поддерживают самостоятельные рисованные TextBox. Используйте
TXLSShapes.AddTextBox, чтобы создатьTXLSTextBoxс собственным якорем строк/столбцов, текстом, text runs, форматированием линии/заливки и обычным удалением shape без создания комментария ячейки.
Версия 2.88.110
- Демонстрации ApiTour теперь показывают больше сценариев автоматизации workbook. Примеры ApiTour для Delphi и C++Builder демонстрируют запись диапазонов через callbacks с
WriteCells, обход загруженных ячеек сForEachCell, обновление шаблонов сFindTextиReplaceText, HTML-экспорт выбранного диапазона вApiTour-Range.htmlи пользовательские callbacks формул в Delphi черезOnUserFunction.
Версия 2.88.109
- Демонстрации QuickStart теперь показывают более полный первый workbook. Примеры QuickStart для Delphi и C++Builder создают оформленную таблицу умножения с формулами итогов по строкам и столбцам, закрепленными областями и согласованными действиями XLS/XLSX; дерево demo теперь также содержит аккуратные HTML readme-страницы для каждого примера.
Версия 2.88.108
- Диапазоны XLSX теперь имеют прямые вспомогательные методы экспорта HTML.
TXLSXRange.SaveAsHTML(FileName)иTXLSXRange.SaveAsHTML(Stream)экспортируют только выбранный диапазон XLSX как таблицу HTML в UTF-8, используя общее экранирование, базовый вывод стилей и обработку span объединенных ячеек renderer HTML workbook.
Версия 2.88.107
- Листы XLSX теперь включают вспомогательные методы поиска и замены текста.
TXLSXWorksheet.FindTextиTXLSXWorksheet.ReplaceTextпросматривают загруженные текстовые ячейки в порядке row-major, пропускают формулы и нетекстовые значения и поддерживают необязательное сопоставление с учетом регистра для шаблонных рабочих процессов.
Версия 2.88.106
- Флаги представления BIFF8 Window2 теперь сохраняют пользовательский цвет сетки и состояние закрепленных областей. HotXLS теперь очищает
fDefaultHdr, когдаWindow2.icvHdrхранит пользовательский цвет сетки, сохраняет записанный ExcelfFrozenNoSplitво время open/save и записываетfFrozenNoSplitдля выводаFreezePanes.
Версия 2.88.105
- Пороговые значения формул CF12 теперь проходят round-trip в правилах BIFF8 Data Bar, Color Scale и Icon Set. Пороговые значения на основе формул при сохранении компилируются в CF12 formula token bytes и восстанавливаются в
TXLSCfValue.Valueпри повторном открытии workbook.
Версия 2.88.104
- Формулы Classic XLS и пороги наборов значков теперь записывают более компактные записи BIFF8. Целочисленные константы в формулах используют компактный token
tInt, когда попадают в диапазон BIFF unsigned-integer, аTXLSIconSetSpec.ThresholdEqualsInclude[Index]теперь управляет CF12 icon-set threshold equals byte, чтобы вызывающий код мог выбрать семантику сравнения include или exclude.
Версия 2.88.103
- В листах Classic XLS появился помощник поиска текста.
IXLSWorksheet.FindText(SearchText, Row, Col[, MatchCase])находит первую подходящую загруженную текстовую ячейку, пропускает формулы и нетекстовые ячейки и очищает возвращаемые координаты, если совпадение не найдено.
Версия 2.88.102
- В листах Classic XLS появился помощник замены текста.
IXLSWorksheet.ReplaceText(SearchText, ReplacementText[, MatchCase])заменяет совпадения в загруженных текстовых ячейках, пропускает формулы и нетекстовые ячейки и возвращает количество измененных ячеек для сценариев заполнения шаблонов.
Версия 2.88.101
- Для диапазонов добавлены прямые помощники экспорта HTML.
IXLSRange.SaveAsHTML(FileName)иIXLSRange.SaveAsHTML(Stream)экспортируют выбранный диапазон через существующий HTML-рендерер, поэтому для обычных фрагментов диапазона больше не нужно создавать экземплярTXLSHTMLExportили явно передаватьxlHTML.
Версия 2.88.100
TXLSWorkbook.GetSheetNames(Stream, AList)теперь читает потоки пакетов XLSX наряду с потоками Classic XLS. Приложения могут передавать в классический фасад потоки памяти, потоки BLOB из базы данных или загруженные потоки XLSX и получать упорядоченные имена листов без предварительного сохранения в файл.
Версия 2.88.99
- API поиска листов, создания гиперссылок и выбора нескольких областей стали удобнее. Коллекции листов Classic XLS и XLSX добавляют
TryGetSheetByName, листы Classic XLS добавляют удобные перегрузкиAddHyperlink, аIXLSWorksheet.SelectAreasможет записывать активные выделения из нескольких диапазонов.
Версия 2.88.98
- Книги Classic XLS теперь предоставляют псевдоним
UserNameдля поля пользователя, сохранившего файл.IXLSWorkbook.UserNameсопоставляется с тем же значением WRITEACCESS, что иLastSavedBy, поэтому код с соглашением именованияUserNameможет напрямую читать и обновлять аудиторское имя книги.
Версия 2.88.97
- Листы XLSX теперь используют те же callback helpers для сканирования ячеек и записи диапазонов.
TXLSXWorksheet.ForEachCellперечисляет загруженные ячейки по строкам со значением и текстом формулы, аTXLSXWorksheet.WriteCellsзаполняет числовые или A1-style диапазоны из callback с пропуском ячеек и отменой.
Версия 2.88.96
- Листы Classic XLS теперь поддерживают запись диапазонов через callback.
IXLSWorksheet.WriteCellsзаполняет 1-based числовой диапазон или диапазон A1-style по строкам, позволяет callback передавать значение каждой ячейки, поддерживает пропуск отдельных ячеек и может досрочно отменить длинные циклы записи.
Версия 2.88.95
- Листы Classic XLS теперь могут перечислять загруженные ячейки через callback.
IXLSWorksheet.ForEachCellпроходит существующие ячейки листа по строкам, передает 1-based координаты листа, строки и столбца вместе со значением и текстом формулы, а callback может досрочно отменить долгий просмотр.
Версия 2.88.94
- Вычисление формул теперь может вызывать функции, определенные приложением.
TXLSWorkbook.OnUserFunctionиTXLSXWorkbook.OnUserFunctionпозволяютCalculateпередавать пользовательские или пока не поддерживаемые функции листа в код приложения, передавая вычисленные аргументы и используя возвращенный результатVariant, если вызов обработан.
Версия 2.88.93
- Защита листов Classic XLS теперь предоставляет флаги разрешений для отдельных действий.
IXLSWorksheetдобавляетAllowDeleteRows,AllowInsertRows,AllowFormatCells,AllowSort,AllowAutoFilterи остальные свойства разрешений SheetProtect; параметры BIFF8 записываются и считываются через существующие записи защиты.
Версия 2.88.92
- Для payload VBA в Classic XLS теперь есть явные helper-методы загрузки, сохранения и очистки.
IXLSWorkbook.LoadVBAProjectFromFile,SaveVBAProjectToFile,HasVBAProjectиClearVBAProjectоткрывают сохраненный payload хранилища OLE VBA, аVBAProjectостается разобранным представлением модулей только для чтения.
Версия 2.88.91
- Критерии Classic XLS AutoFilter теперь можно проверять через коллекцию полей.
IXLSWorksheet.AutoFilterColumnsпредоставляет текущий счетчик полей BIFF8 AutoFilter и 1-based элементы полей, включая active state, operator и сохраненные DOPER-значенияCriteria1/Criteria2.
Версия 2.88.90
- Classic XLS worksheets теперь могут настраивать критерии AutoFilter одним вызовом.
IXLSWorksheet.ApplyAutoFilterзадает диапазон worksheet AutoFilter и записывает критерий поля в том же вызове, поддерживая перегрузки диапазона A1-style и числового 1-based диапазона, а также необязательные операторы для двух критериев.
Версия 2.88.89
- Classic XLS shapes теперь можно удалять по диапазону ячеек.
TXLSShapes.DeleteInRangeудаляет закрепленные изображения или shapes, чьи OfficeArt client anchors пересекают 1-based диапазон листа, и возвращает количество удаленных shapes.
Версия 2.88.88
- Table layout attributes в Classic HTML export теперь настраиваются.
TXLSHTMLExport.TableBorderWidth,CellPaddingиCellSpacingуправляют создаваемыми атрибутами<table>для styled и simple HTML output, сохраняя прежние нулевые значения по умолчанию.
Версия 2.88.87
- Classic HTML export теперь поддерживает minimal table output.
TXLSHTMLExport.SimpleExportзаписывает plain HTML table без созданных CSS classes, hyperlink anchors или comment title attributes, сохраняя экранированный display text и merged-cell spans.
Версия 2.88.86
- Classic HTML export теперь может записывать document title.
TXLSHTMLExport.Titleзаписывает экранированный HTML-элемент<title>перед созданным style block, а пустое значение по умолчанию оставляет существующий вывод без изменений.
Версия 2.88.85
- Classic HTML export теперь переносит cell comments как tooltips.
TXLSHTMLExport.Optionsтеперь по умолчанию включаетxhCommentsи записывает cell comment text как экранированные атрибутыtitle, при этом вызывающий код может удалить эту option для plain cell output.
Версия 2.88.84
- Hyperlink output в Classic HTML export теперь настраивается.
TXLSHTMLExport.Optionsпо умолчанию использует[xhHyperlinks]для существующего поведения, а вызывающий код может удалитьxhHyperlinks, чтобы экспортировать linked cells как plain escaped text.
Версия 2.88.83
- Classic HTML export теперь сохраняет cell hyperlinks.
SaveAsHTMLоборачивает linked cells в HTML anchor tags, выводит hyperlink addresses как экранированные значенияhref, переносит ScreenTip text как экранированные атрибутыtitleи сохраняет отображаемый cell text экранированным внутри link.
Версия 2.88.82
- Книги Classic XLS теперь могут управлять именем пользователя saved-by.
IXLSWorkbook.LastSavedByоткрывает поле WRITEACCESS saved-by, чтобы созданные или измененные книги могли сохранять явное имя для аудита, а неизмененные исходные книги продолжали сохранять исходные metadata.
Версия 2.88.81
- Листы Classic XLS теперь могут управлять индексом цвета отображаемых линий сетки.
IXLSWorksheet.GridlineColorIndexоткрывает поле Window2icvHdr, чтобы сохраненные листы повторно открывались с выбранным цветом сетки без изменения видимости сетки или параметров печати сетки.
Версия 2.88.80
- Classic XLS workbooks теперь могут задавать active sheet по индексу.
IXLSWorkbook.ActiveSheetIndexпредоставляет 1-based свойство active-tab на основе поля active sheet в WINDOW1, позволяя сохраненным workbooks открываться на выбранном worksheet без изменения first visible tab.
Версия 2.88.79
- Classic XLS worksheet outlines теперь могут управлять автоматическими стилями структуры.
TXLSOutline.ApplyStylesпредоставляет флаг outline style из WSBool, позволяя сохраненным worksheets сохранять или явно включать применение стилей структуры Excel без изменения outline levels или размещения summary.
Версия 2.88.78
- Classic XLS page setup теперь может управлять автоматическими разрывами страниц.
IXLSPageSetup.AutoPageBreaksпредоставляет флаг automatic page-break из worksheet WSBool, позволяя сохраненным worksheets оставлять автоматические разрывы страниц включенными или явно отключать их, сохраняя ручные разрывы страниц.
Версия 2.88.77
- Classic XLS workbooks теперь могут управлять группировкой дат AutoFilter.
IXLSWorkbook.AutoFilterDateGroupingпредоставляет флаг группировки дат Window1 через положительный Boolean API, позволяя сохраненным workbooks оставлять группировку фильтров дат Excel включенной или явно отключать ее.
Версия 2.88.76
- Classic XLS workbooks теперь могут напрямую задавать положение и размер workbook window.
IXLSWorkbook.XWindow,YWindow,WindowWidthиWindowHeightоткрывают поля Window1 geometry, чтобы сохраненные workbooks могли повторно открываться с выбранным window rectangle.
Версия 2.88.75
- Classic XLS workbooks теперь могут напрямую сохранять состояние hidden для workbook window.
IXLSWorkbook.WindowHiddenсопоставляется с флагом hidden в Window1, позволяя сохраненным workbooks повторно открываться с hidden workbook window без изменения видимости worksheet.
Версия 2.88.74
- Classic XLS workbooks теперь могут напрямую сохранять состояние minimized для workbook window.
IXLSWorkbook.Minimizedсопоставляется с флагом minimized в Window1, позволяя сохраненным workbooks повторно открываться с минимизированным workbook window.
Версия 2.88.73
- Classic XLS workbooks теперь могут напрямую скрывать или показывать вертикальную полосу прокрутки.
IXLSWorkbook.ShowVerticalScrollсопоставляется с флагом Window1fDspVScroll, позволяя сохраненным workbooks открываться со скрытой или видимой вертикальной полосой прокрутки.
Версия 2.88.72
- Classic XLS workbooks теперь могут напрямую скрывать или показывать горизонтальную полосу прокрутки.
IXLSWorkbook.ShowHorizontalScrollсопоставляется с флагом Window1fDspHScroll, позволяя сохраненным workbooks открываться со скрытой или видимой горизонтальной полосой прокрутки.
Версия 2.88.71
- Classic XLS workbooks теперь могут напрямую скрывать или показывать sheet tab bar.
IXLSWorkbook.ShowSheetTabsсопоставляется с флагом Window1fDspTabs, позволяя сохраненным workbooks открываться со скрытыми или видимыми sheet tabs без изменения видимости worksheet.
Версия 2.88.70
- Classic XLS workbooks теперь могут напрямую задавать соотношение workbook tab bar.
IXLSWorkbook.TabRatioоткрывает значение Window1wTabRatio, чтобы вызывающий код мог настроить место для sheet tabs относительно горизонтальной полосы прокрутки.
Версия 2.88.69
- Classic XLS workbooks теперь могут напрямую задавать первую видимую sheet tab.
IXLSWorkbook.FirstSheetоткрывает значение Window1itabFirstкак свойство 1-based, чтобы вызывающий код мог выбрать, какая sheet tab появится у левого края при открытии workbook в Excel.
Версия 2.88.68
- Classic XLS worksheets теперь могут сохранять и задавать видимость outline symbols.
IXLSWorksheet.DisplayOutlineSymbolsсопоставляется с флагом BIFF WINDOW2fDspGuts, позволяя сохраненным sheets скрывать символы outline и grouping в оконном представлении.
Версия 2.88.67
- Classic XLS worksheets теперь могут сохранять и задавать видимость заголовков строк и столбцов.
IXLSWorksheet.DisplayHeadingsсопоставляется с флагом BIFF WINDOW2fDspRwCol, позволяя сохраненным sheets скрывать номера строк и буквы столбцов в оконном представлении.
Версия 2.88.66
- Classic XLS worksheets теперь могут сохранять и задавать режим показа формул.
IXLSWorksheet.DisplayFormulasсопоставляется с флагом BIFF WINDOW2fDspFmla, чтобы Excel мог открывать sheet с текстом формул вместо вычисленных результатов.
Версия 2.88.65
- Classic XLS worksheets теперь могут независимо задавать масштаб Normal view.
IXLSWorksheet.NormalViewZoomоткрывает кэшированный WINDOW2 Normal zoom, чтобы вызывающий код мог сохранять отдельные уровни масштаба, пока sheet находится в Page Break Preview.
Версия 2.88.64
- Classic XLS worksheets теперь могут напрямую задавать масштаб Page Break Preview.
IXLSWorksheet.PageBreakPreviewZoomоткрывает кэшированный WINDOW2 preview zoom, чтобы вызывающий код мог сохранять разные уровни масштаба для Normal и Page Break Preview.
Версия 2.88.63
- Classic XLS worksheets теперь предоставляют помощники для разделенных областей.
IXLSWorksheet.SplitPanes(Width, Height)создает перемещаемое разделение с помощью существующего BIFF pane writer, аUnsplitPanesочищает pane record перед сохранением.
Версия 2.88.62
- Classic XLS worksheets теперь имеют более простые помощники для закрепленных областей.
IXLSWorksheet.FreezePanes(Cols, Rows)закрепляет нужные левые столбцы и верхние строки, аUnfreezePanesудаляет pane record перед сохранением.
Версия 2.88.61
- Определение имен листов classic XLS теперь принимает потоки.
TXLSWorkbook.GetSheetNames(Stream, List)читает имена листов BIFF из XLS stream, переданного вызывающим кодом, без загрузки содержимого worksheet, повторяя файловый помощник для данных workbook в памяти.
Версия 2.88.60
- Коллекции worksheet теперь предоставляют прямые помощники поиска по имени.
IXLSWorkSheets.SheetByName(Name)иTXLSXSheets.SheetByName(Name)возвращают соответствующий объект worksheet илиnil, поэтому вызывающему коду больше не нужно сначала получать индекс для доступа к листу.
Версия 2.88.59
- Фасад XLSX теперь читает имена листов напрямую из потоков.
TXLSXWorkbook.GetSheetNames(Stream, List)читает упорядоченные имена изxl/workbook.xmlбез загрузки worksheet XML, как и перегрузка с именем файла для книг в памяти или в BLOB-хранилище.
Версия 2.88.58
- Фасад XLSX теперь предоставляет быстрое чтение имен листов.
TXLSXWorkbook.GetSheetNames(FileName, List)читает упорядоченные имена изxl/workbook.xmlбез загрузки worksheet XML.
Версия 2.88.57
TXLSWorkbook.GetSheetNamesтеперь поддерживает пакеты XLSX. Метод читаетxl/workbook.xmlиз файлов.xlsx,.xlsm,.xltxи.xltmи возвращает упорядоченные имена листов без загрузки worksheet XML.
Версия 2.88.56
- Классические книги XLS теперь могут читать имена листов без загрузки листов.
TXLSWorkbook.GetSheetNames(FileName, List)сканирует workbook globals stream и возвращает упорядоченные имена листов из файлов Excel 97-2003.xls.
Версия 2.88.55
- Критерии AutoFilter для диапазонов классического XLS теперь записывают фильтрующие записи BIFF8.
TXLSRange.Autofilter(Field, Criteria)при необходимости создает диапазон фильтра и выводит условияAUTOFILTERдля простых строковых, числовых, Boolean, пустых, непустых и снабженных префиксом сравнения критериев.
Версия 2.88.54
- Классические листы XLS теперь имеют помощники AutoFilter на уровне листа.
IXLSWorksheet.SetAutoFilter,ClearAutoFilterиAutoFilterRangeнапрямую управляют диапазонами раскрывающихся фильтров BIFF8, повторно используя существующую записьAUTOFILTERINFOи имени базы данных фильтра.
Версия 2.88.53
- Классические листы XLS теперь позволяют создавать проверку данных со списком.
IXLSWorksheet.AddListValidation(Range, Items)записывает записи BIFF8DVALиDV, по умолчанию оставляет раскрывающийся список видимым, поддерживает встроенные списки с разделением запятыми и сохраняет правила после цикловOpen/SaveAs.
Версия 2.88.52
- Расчет формул теперь работает согласованно для точек входа XLS и XLSX.
TXLSWorkbook.Calculateтеперь принимает формулы в стиле Excel, начинающиеся со знака равенства, например=SUM(A1:B1)+C1. Фасад XLSX добавляетTXLSXWorkbook.CalculateиTXLSXWorksheet.Calculate. Путь XLSX совместно использует парсер и вычислитель токенов формул HotXLS для ссылок на ячейки и диапазоны, ячеек, на которые ссылаются формулы, ссылок между листами и именованных диапазонов с областью действия книги или листа.
Версия 2.88.51
- Диапазоны XLSX теперь поддерживают merge across в стиле Excel.
TXLSXRange.Merge(True)записывает одну запись<mergeCell>на каждую строку, повторяя поведение классического XLSRange.Merge(True), аMergeбез аргументов иMerge(False)по-прежнему создают один объединенный прямоугольник для всего диапазона.
Версия 2.88.50
- Размещение BIFF8 HeaderFooter и HFPicture теперь соответствует текущим правилам MS-XLS. HotXLS сохраняет записанные Excel записи
HeaderFooter($089C) для колонтитулов четных / первых страниц и повторно записываетHFPicture($0866) после размеров листа и объектов рисования согласно worksheet ABNF, поэтому детали макета страницы сохраняются при циклах открытия/сохранения .xls.
Версия 2.88.49
- Для rich-text run в комментариях теперь есть типизированный API.
TXLSComment.TextRunsоткрывает записи BIFF8TXOFormatRun, чтобы код мог читать или задавать границы шрифта по символам в комментариях .xls, а HotXLS по-прежнему сохраняет исходные байты run для безопасных round-trip.
Версия 2.88.48
- Дополнительные SX-записи сводных таблиц теперь доступны через типизированный API. HotXLS теперь привязывает загруженные BIFF8 pivot records, такие как
SXIVD,SXLI,SXFormat,SXEx,SXVDEx,SXRule,SXFiltиSXAddl, кTXLSPivotTable.SupplementalRecordsдля проверки, при этом сохраняя исходные raw bytes для безопасных циклов сохранения.
Версия 2.88.47
- Кэшированные значения внешних книг теперь сохраняются при циклах открытия/сохранения .xls. HotXLS теперь сохраняет записи BIFF8
XCTиCRN, привязанные к загруженным записямSUPBOOK, поэтому cached cell values для ссылок на внешние книги больше не теряются при сохранении.
Версия 2.88.46
- Уровни структуры встроенных стилей теперь сохраняются при циклах открытия/сохранения .xls. HotXLS теперь читает и сохраняет байт
iLevelзаписи BIFF8STYLEдля встроенных стилей, поэтому метаданные Excel RowLevel_1..7 и ColLevel_1..7 больше не сбрасываются к значению по умолчанию при сохранении.
Версия 2.88.45
- Метаданные определенных имен теперь сохраняются при циклах открытия/сохранения .xls. HotXLS теперь сохраняет option bits и shortcut bytes загруженных записей BIFF8
NAME, пока определенное имя не редактируется, поэтому записанные Excel метаданные function, object, procedure, calculated-expression и binary-name больше не очищаются при сохранении.
Версия 2.88.44
- Маркеры книги ObProj теперь сохраняются при цикле открытия и сохранения .xls. HotXLS теперь сохраняет загруженные записи BIFF8
ObProj, даже когда VBA storage не представлен в объектной модели, поэтому маркеры VBA project уровня книги и сторонние метаданные больше не удаляются при сохранении.
Версия 2.88.43
- Флаги параметров листа теперь сохраняются при цикле открытия и сохранения .xls. HotXLS теперь сохраняет немоделированные биты BIFF8
WSBOOL, такие как лист диалога, автоматические разрывы страниц, применение стилей и отображение gutter структуры, при этом существующие параметры подгонки к странице и сводки структуры по-прежнему обновляются через публичный API.
Версия 2.88.42
- Дополнительные записи метаданных книги теперь сохраняются при цикле открытия и сохранения .xls. HotXLS теперь сохраняет загруженные тела записей BIFF8
COUNTRY,BOOKBOOL,BACKUP,FNGROUPCOUNT,USESELFSиRECALCIDвместо перезаписи значениями по умолчанию, сохраняя стабильными совместимость и вычислительные метаданные уровня книги.
Версия 2.88.41
- Многообластные выделения и фокус активной панели теперь сохраняются при цикле открытия и сохранения .xls. HotXLS теперь сохраняет загруженные записи BIFF8
SELECTIONи значение активной панелиPANES, если выбор листа или панели не изменялись через API, поэтому фокус разделенных/закрепленных панелей Excel и многообластные выделения больше не сворачиваются при сохранении.
Версия 2.88.40
- Имена внешних книг теперь сохраняются при цикле открытия и сохранения .xls. HotXLS теперь сохраняет загруженные записи BIFF8
EXTERNALNAME, связанные с внешними записямиSUPBOOK, включая метаданные DDE/OLE/ссылок и хвосты формул, поэтому внешние имена и определения ссылок больше не удаляются при сохранении.
Версия 2.88.39
- Защищенные паролем файлы BIFF8 .xls теперь записывают и читают записи FILEPASS RC4 CryptoAPI. HotXLS теперь записывает метаданные
FILEPASSvMajor=2 в стиле Excel 2007/2010 для зашифрованных книг .xls и читает как устаревший RC4 vMajor=1, так и RC4 CryptoAPI vMajor=2/3/4, поэтому защищенные паролем книги больше не падают на этом заголовке шифрования и не откатываются к старому заголовку.
Версия 2.88.38
- Метаданные гиперссылок .xls, записанные Excel, теперь сохраняются при циклах открытия/сохранения. HotXLS теперь сохраняет BIFF8
HLinkrecord body для загруженных гиперссылок, пока гиперссылка не редактируется, сохраняя стабильнымиstreamVersion,hlstmfoption bits, такие какfIcon, данные moniker и связанные метаданные назначения при сохранении.
Версия 2.88.37
- Состояние окна книги теперь сохраняется при циклах открытия/сохранения .xls. HotXLS теперь читает и сохраняет позицию, размер, flags видимости/iconic, первую отображаемую вкладку листа, количество выбранных вкладок и соотношение вкладок к полосе прокрутки из записи BIFF8
WINDOW1, вместо перезаписи этих значений значениями по умолчанию при каждом сохранении.
Версия 2.88.36
- Пользователи saved-by из BIFF8 WriteAccess теперь сохраняются при циклах открытия/сохранения .xls. HotXLS теперь читает и сохраняет
$005C WRITEACCESSrecord body вместо замены пользователя saved-by, записанного Excel, наHotXLS, поэтому метаданные аудита книги остаются стабильными после сохранения.
Версия 2.88.35
- Авторы комментариев Excel теперь сохраняются при .xls open/save round-trip. Поле
stAuthorзаписи BIFF8Noteтеперь разбирается и передается в drawing note model, а не заменяется пустой строкой, поэтому автор comment "Created by", записанный Excel, сохраняется при повторном сохранении workbook в HotXLS.
Версия 2.88.34
- OfficeArt FOPT options для shapes теперь доступны через низкоуровневый option bag.
TXLSShape.OfficeArtOptionsпозволяет опытным вызывающим сторонам проверять, задавать и удалять любой сохраненный FOPT PID какLongWordилиWideString, при этом существующие high-level APILine,Fill, цвета и видимости остаются без изменений.
Версия 2.88.33
- Дополнительные записи правил в OfficeArt solver-container теперь сохраняются при round-trip. Помимо типизированного
msofbtConnectorRule($F012), HotXLS теперь сохраняет solver children, которые не являются folders, напримерOfficeArtFArcRule($F014) иOfficeArtFCalloutRule($F017), как исходные записи OfficeArt внутриmsofbtSolverContainer($F005), поэтому сложные рисунки Excel больше не теряют не-connector solver relationships при сохранении.
Версия 2.88.32
- Маркеры OfficeArt ClientData больше не дублируются после сохранения неизвестных записей. MS-XLS определяет
OfficeArtClientData($F011) как маркер нулевой длины; следующийObjостается отдельной BIFF-записью. v2.88.32 распознает этот маркер вместо захвата его как неизвестного leaf в SpContainer, поэтому разобранные shape при сохранении выводят ровно один маркер $F011. Неспецификационные container-style предположения не попадают в XLS-путь.
Версия 2.88.31
- Правила соединителей OfficeArt теперь проходят round-trip. Рисунки .xls, созданные Excel, хранят привязки соединителей в
msofbtSolverContainer($F005) с дочерними записямиmsofbtConnectorRule($F012). v2.88.31 разбирает и записывает эту пару $F005/$F012 черезTMsoConnectorRules, сохраняя начальную shape, конечную shape, shape-соединитель и точки подключения при save/reload. Предыдущая audit note указывала $F121, но MS-ODRAW определяетOfficeArtFConnectorRuleкак $F012.
Версия 2.88.30
- Нераспознанные leaf-записи OfficeArt SpContainer теперь проходят round-trip. Файлы .xls, созданные Excel, часто содержат в SpContainer каждой shape leaf Fbt, такие как
msofbtClientTextbox($F00D),OfficeArtFPSPL($F11D), andOfficeArtUDefProp($F122). v2.88.30 сохраняет неизвестные shape-level leaf какTMsoFbtUnknownи повторно выводит их в порядке parse междуClientAnchorи завершающим zero-body markermsofbtClientData. - Область и продолжение. Другие drawing-level unknown leaf остаются отложенными; случай solver-container для connector rules обработан в v2.88.31. Container-form unknowns, например
msofbtClientData($F011), используемый как container вместо sibling marker, остаются для audit-round Slice 3.
Версия 2.88.29
- Неизвестные подзаписи OBJ ComboBox и ListBox теперь делают round-trip. TMSOShapeComboBox.ParseObj и TMSOShapeListBox.ParseObj уже typed-парсили FtSbs ($000C), FtSbsFmla ($000E) и FtLbsData ($0013) в выделенные поля, но любая другая подзапись из исходного файла (FtMacro $0004, ObjLinkFmla, FtNts $000D и т.д.), появляющаяся между CMO и FtLbsData, молча отбрасывалась в case fall-through. v2.88.29 добавляет ту же else-ветвь, что и v2.88.28 Picture, захватывая 4-байтный заголовок + тело неизвестной подзаписи в
FObjTailRaw. Оба метода AddObj выдают захваченные байты между телом CMO и подзаписью FtSbs, чтобы соответствовать порядку подзаписей спецификации BIFF8. - Поведение "проглотить все" FtLbsData ограничивает область. Существующий case
$0013перезаписываетRecLen := Len - offs, чтобы поглотить все байты после заголовка FtLbsData в blobFObjRec_LBSData, поэтому подзаписи, появляющиеся ПОСЛЕ FtLbsData (обычно только FtEnd), по-прежнему делают round-trip через этот механизм без изменений. Новая интеграция FObjTailRaw специально нацелена на пробел перед FtLbsData, где обычно живут FtMacro и ObjLinkFmla. Недавно созданные comb / list box через Drawing API имеют пустойFObjTailRaw→ побайтно идентичный вывод по сравнению с v2.88.28.
Версия 2.88.28
- Неизвестные подзаписи OBJ формы Picture теперь делают round-trip. TMSOShapePicture.ParseObj уже typed-парсил FtCf ($0007), FtPioGrbit ($0008) и FtPictFmla ($0009) в выделенные поля, но любая другая подзапись из исходного файла (FtMacro $0004, FtNts $000D и т.д.) молча отбрасывалась в case fall-through. v2.88.28 добавляет else-ветвь, которая добавляет полный 4-байтный заголовок + тело нераспознанных подзаписей в
FObjTailRaw; TMSOShapePicture.AddObj затем выдает эти байты дословно после своего вывода типизированных подзаписей и перед маркером FtEnd. Объекты picture из исходного файла с хуками макросов переживают пересохранение. - Шаблон сосуществования typed + raw. В отличие от PictureFrame (v2.88.27), который использовал обмен if/else между типизированной и сырой эмиссией, Picture объединяет оба: типизированные поля сохраняют поверхность API (вызывающие по-прежнему могут регулировать
ftCfValueи т.д.), а сырой хвост сохраняет только неизвестные байты. Недавно созданные изображения через Drawing API имеют пустойFObjTailRaw, поэтому вывод побайтно идентичен v2.88.27.
Версия 2.88.27
- Round-trip завершающих подзаписей OBJ расширен на формы PictureFrame. TMSOShapePictureFrame.AddObj ранее выдавал только унаследованные жестко закодированные подзаписи FtCf ($0007, тело $FFFF) и FtPioGrbit ($0008, тело $0000) между CMO и FtEnd. Для недавно созданных рамок изображения новый код по-прежнему выдает эти значения по умолчанию; для рамок изображения, проанализированных из исходного .xls, захваченные байты
FObjTailRawвыдаются дословно вместо этого, сохраняя любой FtPictFmla исходного файла / нестандартный FtCf / нестандартный FtPioGrbit содержимое через цикл сохранения. - Заметка по расследованию — Flush автоматически корректирует sz.
TMsoShapeContainer.Flushперезаписывает заголовок размера записи Obj во время коммита черезData.SetWord(Data.DataLength - 4, 2), что означает, что жестко закодированные значенияsz := $1A, которые годами жили в реализациях AddObj HotXLS, в конце концов не были багами спецификации — Flush автоматически их корректирует. v2.88.27 по-прежнему точно вычисляет sz для ясности исходного кода, но поведение во время выполнения с этой точки зрения не изменено.
Версия 2.88.26
- Round-trip завершающих подзаписей OBJ расширен на формы Chart и CheckBox. v2.88.25 ввела сохранение сырых байтов между CMO ($0015) записи Obj и её маркером FtEnd ($0000), но только TMSOShapeTextBox.AddObj выдавал захваченный хвост. В этом релизе тот же паттерн применен к TMSOShapeChart.AddObj и TMSOShapeCheckBox.AddObj — оба разделяют простую структуру эмиссии "CMO + FtEnd" TextBox, поэтому изменение представляет собой однострочную замену переменной (
sz := $1A + Word(Length(FObjTailRaw))) плюс цикл побайтной эмиссии перед маркером FtEnd. - Завершающие подзаписи Chart (например FtMacro для макросов встроенных объектов chart) и подзаписи состояния checkbox (FtCbls + FtCblsData + ObjLinkFmla, MS-XLS §2.5.140-141 / §2.5.149) теперь переживают цикл сохранение/перезагрузка HotXLS. Свеже-созданные charts и checkboxes через Drawing API продолжают выдавать стандартные 26-байтные CMO+FtEnd (побайтно идентичные v2.88.25), поэтому существующие вызывающие не видят изменений поведения. Формы Picture / ComboBox / ListBox / PictureFrame имеют собственную динамическую эмиссию типизированных подзаписей, конфликтующую с FObjTailRaw — их интеграция отложена до будущих коммитов.
Версия 2.88.25
- Завершающие подзаписи записи OBJ теперь сохраняются через цикл сохранения для примечаний. Запись BIFF8 Obj ($005D) объединяет последовательность типизированных подзаписей после обязательной CMO ($0015), завершаемую маркером FtEnd ($0000) согласно MS-XLS §2.4.181. Для форм Note (примечание) завершающий блок обычно представляет собой 26-байтный FtNts (§2.5.149), несущий GUID и флаг fSharedNote — оба необходимы, когда Excel впоследствии объединяет примечания между пользователями в общих книгах. HotXLS ранее отбрасывал каждый байт после CMO при чтении и выдавал только пустой FtEnd при записи, поэтому любой FtNts из исходного файла терялся при каждом пересохранении HotXLS.
- Захват в общей базе, эмиссия только в TextBox (R5-3 первый этап). TMsoShapeContainer.ParseObj теперь захватывает диапазон байтов между концом тела CMO и маркером FtEnd в новое внутреннее поле
FObjTailRaw: TBytes; TMSOShapeTextBox.AddObj вставляет эти байты между своей эмиссией CMO и маркером FtEnd, с соответствующим изменением размера заголовка записи Obj. Вновь созданные примечания (без исходных байтов) сохраняют побайтно идентичный вывод по сравнению с v2.88.24. Другие классы форм (Picture / CheckBox / ComboBox / ListBox / Chart) наследуют захват, но их типизированные переопределения AddObj сохраняют унаследованное поведение "синтезировать с нуля" — эмиссия сырых байтов для этих типов форм отложена до будущих коммитов.
Версия 2.88.24
- Многошрифтовые и многоцветные примечания к ячейкам теперь сохраняются через цикл сохранения. Блок прогонов форматирования записи BIFF8 TXO (
rgTxoRuns+TxOLastRunсогласно MS-XLS §2.5.272) несет переопределения шрифта и цвета по прогону, которые придают примечанию стиль форматированного текста. HotXLS ранее отбрасывал весь блок при чтении и выдавал единственный пустой прогон по умолчанию + LastRun при записи — сжимая любой выделенный красным "Важно!" или жирное слово внутри текста примечания до единообразного форматирования по умолчанию после каждого пересохранения HotXLS. - Побайтное сохранение в TMSOShapeTextBox. ParseTXO захватывает байты Continue после текста дословно в новое внутреннее поле
FFormatRunsRaw: TBytes; Store выдает их обратно как Continue прогонов форматирования и корректирует заголовокcbRunsбазовой записи для соответствия. Вновь созданные примечания (черезAddComment) сохраняют наследуемый вывод единственного прогона по умолчанию без изменений, так что побайтно идентичный вывод сохраняется для книг по умолчанию. Типизированный доступ Excel API к отдельным прогонам форматирования по-прежнему отложен — существующий API единого WideString примечания не изменен.
Версия 2.88.23
- Разрешение печати и количество копий теперь сохраняются через цикл сохранения — запись Setup полностью покрыта. Три поля Word в записи Setup (
iResпо смещению 12,iVResпо смещению 14,iCopiesпо смещению 32, согласно MS-XLS §2.4.257) несут выбор Excel "Параметры страницы → Страница → Качество печати" и "Число копий". HotXLS ранее отбрасывал все три при чтении и выдавал жестко закодированные значения (600 DPI / 600 DPI / 1 копия), поэтому любое настроенное пользователем разрешение или число копий молча возвращалось после каждого пересохранения HotXLS. - Три новых свойства TXLSPageSetup.
PrintResolution: LongWord,PrintVResolution: LongWordиCopies: LongWord— все значения по умолчанию соответствуют значениям, ранее жестко закодированным в писателе (600 / 600 / 1), так что книги, не трогающие их, дают побайтно идентичный вывод по сравнению с v2.88.22. Сеттеры ограничиваютсяHigh(Word), так что слишком большое значение от вызывающего не вызывает переполнение при выводе. - Работа round-trip записи Setup завершена. С этим исправлением каждое видимое пользователю поле записи BIFF8 Setup ($00A1) переживает round-trip от начала до конца — размер бумаги / масштаб / номер первой страницы / по ширине и высоте / ориентация / порядок печати / черно-белая / черновик / печать примечаний / ошибки ячеек / разрешение / копии. Остаются не открытыми только два бита подсказок спецификации (
fNoPls,fNoOrient) — HotXLS пишет оба как ноль, что соответствует поведению Excel по умолчанию.
Версия 2.88.22
- Пользовательский "Номер первой страницы" в Параметрах страницы теперь сохраняется через цикл сохранения. Запись BIFF8 Setup несет выбор книги Параметры страницы → Страница → "Номер первой страницы" как два связанных поля: бит 7 grbit (
fUsePage) выбирает между значением по умолчанию Excel "Авто" и явным начальным номером страницы, а знаковое Word по смещению 4 (iPageStart) содержит это пользовательское значение согласно MS-XLS §2.4.257. HotXLS ранее отбрасывал оба при чтении и выдавалiPageStart = 1с очищенным битом, поэтому введенный пользователем "Номер первой страницы: 100" молча возвращался к "Авто" после каждого пересохранения HotXLS. - Два новых свойства TXLSPageSetup.
UseFirstPageNumber: Booleanотражает бит (False = "Авто", по умолчанию);FirstPageNumber: Integerнесет значение iPageStart (по умолчанию 1, ограниченное сеттером диапазоном signed-Word спецификации -32768..32767). HotXLS выполняет round-tripiPageStartдословно, даже когдаUseFirstPageNumber= False, поэтому переключение между Авто и пользовательским в Excel сохраняет последнее введенное пользователем значение.
Версия 2.88.21
- Выбор "Печатать примечания в конце листа" теперь сохраняется через цикл сохранения. Бит 9 (
fEndNotesсогласно MS-XLS §2.4.257) поля grbit записи BIFF8 Setup несет различие в выпадающем списке Параметры страницы → Лист → Примечания между "Как на листе" (по умолчанию) и "В конце листа". HotXLS уже выполнял round-trip PrintNotes (бит 5) для управления тем, печатаются ли примечания, но бит 9 отбрасывался при чтении и выдавался как ноль при записи — поэтому выбранное пользователем "В конце листа" молча возвращалось к "Как на листе" после каждого пересохранения HotXLS. - Новое логическое свойство TXLSPageSetup.PrintNotesAtEnd. По умолчанию
Falseсоответствует значению по умолчанию интерфейса Excel. Читатель и писатель выполняют round-trip бита дословно (даже когдаPrintNotes = False), поэтому книга с временно отключенными примечаниями сохраняет предпочтение "в конце листа" на случай, когда пользователь снова включит их — отражая собственное поведение Excel.
Версия 2.88.20
- Выбор книги "Задать точность как на экране" теперь сохраняется через цикл сохранения. Запись BIFF8 CalcPrecision ($000E) несет флажок на уровне книги Файл → Параметры → Дополнительно → "Задать точность как на экране" согласно MS-XLS §2.4.35. У HotXLS ранее не было case в диспетчере для $000E, и TXLSWorkbook.StorePrecision выдавал жестко закодированную
1(= полная точность сохранена). Отмеченное пользователем "Задать точность как на экране" молча возвращалось к "полной точности" после каждого пересохранения HotXLS — скрывая намеренное намерение пользователя, чтобы любой последующий пересчет навсегда обрезал значения ячеек до их форматированных десятичных разрядов. - Новое логическое свойство TXLSWorkbook.UseFullPrecision. По умолчанию
True(соответствует значению по умолчанию BIFF8 и значению по умолчанию интерфейса Excel не отмечено). Установка вFalseравносильна выбору разрушающей опции "точность как на экране" — сам HotXLS не обрезает значения ячеек во время цикла сохранения, но флаг теперь верно записывается обратно, так что следующий пересчет Excel будет его учитывать. С этим исправлением каждая запись BIFF8 для вычислений (CalcCount / CalcMode / CalcPrecision / CalcDelta / CalcIter / CalcSaveRecalc) переживает цикл сохранения от начала до конца.
Версия 2.88.19
- Флажок "Пересчитать книгу перед сохранением" теперь сохраняется через цикл сохранения. Запись BIFF8 CalcSaveRecalc ($005F) несет логическое значение книги Файл → Параметры → Сохранение → "Пересчитать книгу перед сохранением" согласно MS-XLS §2.4.37. У HotXLS ранее не было case в диспетчере для $005F, и StoreCalculationSettings выдавал жестко закодированную
1— поэтому отключенный пользователем "пересчет при сохранении" молча включался снова при каждом пересохранении HotXLS, что особенно важно для книг в режиме ручного вычисления, где пользователь намеренно зафиксировал значения ячеек на диске. - Новое логическое свойство TXLSWorkbook.RecalcOnSave. По умолчанию
True(соответствует значению по умолчанию интерфейса Excel и наследуемому жестко закодированному значению), поэтому книги, не трогающие свойство, сохраняют побайтно идентичный вывод по сравнению с v2.88.18. Сеттер принимает любое логическое значение; читатель нормализует произвольные ненулевые исходные байты вTrue.
Версия 2.88.18
- Настройки итеративного вычисления (включить + максимум итераций + максимальное изменение) теперь сохраняются через цикл сохранения. Записи BIFF8 CalcIter ($0011), CalcCount ($000C) и CalcDelta ($0010) вместе несут трио параметров "Включить итеративные вычисления" Excel (Файл → Параметры → Формулы) согласно MS-XLS §2.4.33 / §2.4.31 / §2.4.32. Ни у одного из трех не было case в диспетчере раньше, и StoreCalculationSettings выдавал их с жестко закодированными значениями (выкл / 100 / 0.001). Настроенный пользователем цикл из 1000 итераций с дельтой сходимости 0.0001 молча сбрасывался к "итерация выкл, 100, 0.001" после каждого пересохранения HotXLS — ломая формулы с циклическими ссылками и финансовые модели, чувствительные к сходимости.
- Три новых свойства TXLSWorkbook.
EnableIteration: Booleanотражает флажок;MaxIterations: LongWord— предел итераций (сеттер ограничивает его допустимым диапазоном спецификации 1..32767);MaxIterationChange: Double— дельта сходимости (отрицательный ввод привязывается к значению по умолчанию спецификации 0.001). Значения по умолчанию соответствуют тем, что писатель раньше жестко кодировал, поэтому книги, не трогающие новые свойства, дают побайтно идентичный вывод по сравнению с v2.88.17.
Версия 2.88.17
- Режим вычислений книги (Вручную / Автоматически / Авто кроме таблиц) теперь сохраняется через цикл сохранения. Запись BIFF8 CalcMode ($000D) несет выбор уровня книги "Формулы → Параметры вычислений" согласно MS-XLS §2.4.36. У HotXLS ранее вообще не было case в диспетчере для $000D, поэтому значение исходного файла отбрасывалось при загрузке, и писатель всегда выдавал жестко закодированное
$0001(Автоматически). Выбранный пользователем режим Вручную молча возвращался к Автоматически после каждого пересохранения HotXLS — плохо для больших книг, где Вручную установлено намеренно ради производительности. Новый обработчик ParseCalcMode сохраняет значение источника в книге, и StoreCalculationSettings теперь выдает сохраненное значение вместо константы. - Новое свойство TXLSWorkbook.CalculationMode. Свойство
LongWordчтения-записи, принимающееxlCalcManual(0),xlCalcAutomatic(1, по умолчанию) илиxlCalcAutomaticExceptTables(0xFFFF) — три новых константы, экспортированные изlxTNC.inc. Сеттер ограничивает неизвестные значения значением по умолчанию из спецификации, так что поврежденный исходный файл не может оставить книгу в неопределенном состоянии. Существующий код, не трогающий это свойство, сохраняет наследуемое значение по умолчанию ("Автоматически"), прежний вывод побайтно идентичен для книг по умолчанию.
Версия 2.88.16
- Выбор "Ошибки ячеек как" в Параметрах страницы теперь сохраняется через цикл сохранения. Запись BIFF8 Setup ($00A1) упаковывает выпадающий список Параметры страницы → Лист "Ошибки ячеек как: показанные / <пусто> / <тире> / <N/A>" в биты 10-11 ее слова grbit как
iErrors, согласно MS-XLS §2.4.257. HotXLS ранее отбрасывал эти биты при чтении и выводил их как ноль при записи, поэтому книга, которую пользователь настроил так, чтобы печатать#DIV/0!как#N/A, молча возвращалась к "показанным" после каждого пересохранения HotXLS. Читатель теперь декодируетiErrorsв новое свойствоTXLSPageSetup.PrintCellErrors, а писатель воссоздает поле на его основе. - Новое свойство TXLSPageSetup.PrintCellErrors. Свойство
LongWordчтения-записи, принимающееxlPrintErrorsDisplayed(0, по умолчанию),xlPrintErrorsBlank(1),xlPrintErrorsDash(2) илиxlPrintErrorsNA(3) — четыре новых константы, экспортированные изlxTNC.inc. Существующие вызывающие PageSetup, которые не трогают свойство, сохраняют значение по умолчанию ("показанные"), прежний вывод печати остается без изменений.
Версия 2.88.15
- Выравнивание и ориентация примечаний к ячейкам теперь сохраняются при сохранении. Базовая запись BIFF8 TXO ($01B6) содержит пять типизированных флагов в своем слове
grbit(hAlignment, vAlignment, fLockText, fJustLast, fSecretEdit) и отдельное словоrotдля ориентации текста, согласно MS-XLS §2.4.329. Ранее читатель отбрасывал их все, а писатель фиксировалgrbitна жестко закодированном значении0x0012(слева + сверху) с поворотом всегда 0, поэтому каждое сохранение возвращало центрированное или повернутое примечание к слева+сверху+по горизонтали независимо от источника. Читатель теперь декодирует типизированные поля при загрузке, а писатель составляетgrbitиз них, так что расположение переживает цикл сохранить/перезагрузить. - Шесть новых свойств TMSOShapeTextBox для явной стилизации примечаний.
HAlignment,VAlignment,Rotation,LockText,JustLastLineиSecretEditпредоставляются как свойства чтения-записи на каждой фигуре примечания;AddCommentпо умолчанию инициализирует слева+сверху+по горизонтали+разблокировано, поэтому вызывающие, которые их не трогают, сохраняют прежний внешний вид. - Писатель TXO теперь располагает reserved4 / reserved5 по границам полей спецификации. Прежний код выдавал смещения 2-9 базовой записи как две записи Long (rot + reserved4, затем reserved5); писатель теперь делит их на
Wordrot,Wordreserved4,Longreserved5 — содержимое байтов не изменилось (для фигур Note по-прежнему все ноль), но структура кода теперь соответствует смещениям полей MS-XLS §2.4.329, что усложняет перепутывание выравнивания будущих исправлений TXO.
Версия 2.88.14
- Смещение cchText в TXO исправлено — исправление длины комментариев из v2.88.13 теперь действительно срабатывает. Предыдущий выпуск добавил проверку целостности базовой записи TXO, читая
cchTextпо смещению 8, но MS-XLS §2.4.329 размещаетcchTextпо смещению 10 (после grbit, rot и 6 байт reserved / controlInfo). Смещение 8 попадает внутрь long-поля reserved5, которое для объектов формы Note всегда равно нулю, поэтому каждый комментарий молча соскальзывал в защитный fallback, фактически возвращая поведение до v2.88.13. Исправление возвращает смещение на 10, длинные комментарии теперь действительно сшиваются через записи Continue, а короткие больше не подбирают завершающее заполнение. Других изменений поведения помимо того, что v2.88.13 должен был принести, нет.
Версия 2.88.13
- Длинные комментарии к ячейкам теперь считываются на полную длину. Запись TXO в BIFF8 ($01B6) делит тело текста между базовой записью и одной или несколькими записями Continue, а количество символов публикуется в базовой записи по смещению 8 как
cchText. Предыдущий читатель комментариев полностью пропускал базовую запись, рассматривал DataList[1] как весь текст и останавливался — комментарий длиннее примерно 4100 широких символов молча обрезался, а более короткий комментарий, у которого запись Continue тянула за собой завершающее заполнение, подбирал этот мусор как текст. Читатель теперь используетcchTextкак авторитетное число символов, обходит каждый сегмент Continue согласно MS-XLS §2.4.329 (разрез rgb сидит на границе символа, поэтому учёт частичных символов не нужен) и останавливается, как только бюджет исчерпан, чтобы блок runs форматирования, идущий после текста, никогда не утекал в строку. Комментарии с повреждёнными или отсутствующими базовыми записями по-прежнему используют легаси-путь "потребить все оставшиеся байты".
Версия 2.88.12
- Кэшированные строки длиннее примерно 4100 символов из формул, возвращающих строку, теперь сохраняются при round-trip через записи Continue. v2.88.11 подключил сторону чтения записи String BIFF8 ($0207), но потреблял только тело первой записи. Кэшированная строка, чьи байты UCS-2 превышали лимит BIFF в 8224 байта и переливались в одну или несколько записей Continue ($003C), молча обрезалась. Обработчик теперь обходит весь DataList уровня диспетчеризации: читает cch и fHighByte из базовой записи, копирует тело, которое туда умещается, а затем конкатенирует каждый последующий сегмент Continue как сырые байты согласно гарантии границы символа MS-XLS §2.5.293 — XLUnicodeString никогда не повторно выдаёт fHighByte в середине строки. Каждый сегмент ограничен оставшимся бюджетом символов, поэтому случайно увеличенный Continue не может сделать результат длиннее cch. Строки в одной записи (обычный случай) идут точно по тому же быстрому пути, что и раньше.
Версия 2.88.11
- Формулы, возвращающие строку, теперь сохраняют при round-trip кэшированный текст, вычисленный Excel. Предыдущий выпуск охватывал варианты число, булево, ошибка и пусто кэша BIFF8 FormulaValue (MS-XLS §2.5.133), но оставил строковый вариант в списке дел, потому что его кэшированное значение лежит в отдельной записи String ($0207), которая идёт сразу после записи Formula. ParseFormula теперь запоминает координаты ячейки, когда видит Formula строкового варианта, а новый обработчик ParseString декодирует следующую запись $0207 согласно MS-XLS §2.4.268 и направляет WideString в
FCachedFormulaValue.GetCellValueтеперь может откатываться к тексту, вычисленному Excel, когда evaluator HotXLS не может его воспроизвести. Защитный сброс в начале ParseFormula отбрасывает любой устаревший ожидающий якорь, чтобы повреждённый исходный файл с отсутствующей записью String не мог направить последующую неправильно. Записи длиннее 8224 байт, переполняющиеся в блоки Continue, продолжают откатываться к выводу evaluator как известное ограничение.
Версия 2.88.10
- Записи Formula в BIFF8 теперь сохраняют при round-trip кэшированное значение, вычисленное Excel. Раньше ParseFormula полностью пропускал 8-байтовую полезную нагрузку FormulaValue по смещению 6, поэтому кэшированный результат каждой формулы в загружаемом .xls (числа, булевы, ошибки, пусто) отбрасывался и HotXLS приходилось пересчитывать каждую ячейку собственным движком формул. Когда этот движок не мог совпасть с Excel (неподдерживаемые XLM-функции, сломанные внешние ссылки, ещё не реализованные формулы), ячейка молча становилась пустой или показывала 0. Читатель теперь декодирует четыре варианта число / булево / ошибка / пусто согласно MS-XLS §2.5.133 и сохраняет их в новом поле
TXLSCellRef.FCachedFormulaValue;GetCellValueоткатывается к этому кэшу только когда вычисление не удалось, поэтому только что созданные формулы по-прежнему проходят через вычисление. Строковый вариант продолжает зависеть от вычислителя, потому что парсер следующей записи String ($0207) ещё не подключён.
Версия 2.88.9
- Записи Formula в BIFF8 с неразрешимыми значениями теперь устанавливают fAlwaysCalc вместо бита reserved1. Когда evaluator HotXLS не мог вычислить формулу при сохранении, писатель ранее ставил
grbit = 0x0002— бит 1, который MS-XLS §2.4.127 резервирует и требует от читателей игнорировать. Excel должным образом игнорировал его, считал значение 0 в кэше авторитетным и молча показывал 0 вместо пересчёта. Писатель теперь ставитgrbit = 0x0001(fAlwaysCalc, бит 0), поэтому Excel перезапускает формулу при следующем пересчёте и ячейка показывает правильный результат.
Версия 2.88.8
- PageSetup.PrintTitleColumns и PrintTitleRows теперь выбрасывают исключение при некорректном вводе. Присвоение этим свойствам некорректной строки диапазона (любого, что
ColDiapasonToValuesилиRowDiapasonToValuesне могли разобрать) раньше молча отбрасывало присваивание — книга сохраняла прежний диапазон Print_Titles или оставалась без диапазона, и вызывающий код не мог узнать, что что-то пошло не так. Сеттеры теперь вызываютException.Createс описательным сообщением, указывающим ошибочное значение, в соответствии с существующим стилем raise на путях недопустимого индексаTXLSRange.
Версия 2.88.7
- Поле miyRw записи Row теперь остаётся в пределах диапазона спецификации MS-XLS. Версии Excel до BIFF8 кодировали "использовать высоту строки по умолчанию для книги", выполняя OR бита 15 в miyRw, и HotXLS перенёс этот идиом в BIFF8-писатель, хотя MS-XLS §2.4.221 ограничивает miyRw 8192 твипами. Современный Excel в том же случае выводит обычное 255 (12,75 пт по умолчанию) и сигнализирует ручные переопределения через бит fUnsynced в grbit, поэтому хак с битом 15 заставлял вывод HotXLS отличаться от авторитетных файлов .xls (значение 32 959 = 0x80FF для "по умолчанию" технически выходило за рамки спецификации). Писатель теперь не делает OR и записывает 255 напрямую; читатель по-прежнему снимает бит 15 при вводе для обратной совместимости с HotXLS v2.88.6 и более ранними файлами, а также с редкими сторонними генераторами, скопировавшими идиом BIFF5.
- Добавлена заметка об опечатке для раунда 2 аудита спецификации BIFF8. Повторная проверка границ полей [MS-XLS] прояснила, что две находки, помеченные как P2 в исходном отчёте (
dev-notes/XLS-BIFF8-Spec-Audit-Round2.md), не являются настоящими ошибками: установленный бит 15 во флаге истории BOF $000080C9 принадлежит полю verXLHigh (биты 14-17, значение 2 = "Excel 2002"), а не хвосту reserved1 (биты 19-31); а использование ParseFormula ведущего токена PtgExp для обнаружения общих или массивных формул соответствует тому, что подразумевает спецификация, и корректно устраняет неоднозначность через следующую запись ShrFmla или Array. Оба пункта теперь помечены как отозванные.
Версия 2.88.6
- Листы макросов и модули VBA теперь сохраняют свой порядковый слот BoundSheet8. Читатель раньше отбрасывал записи BoundSheet8 с полем
dt, равным 1 (лист макроса) или 6 (модуль VBA), поэтому коллекция Sheets в HotXLS лишалась этих записей. Любая перекрёстная ссылка XTI в ExternSheet, указывавшая в порядке файла на позицию листа за листом макроса, после SaveAs разрешалась в неправильный лист HotXLS. Читатель теперь добавляет лист-заглушку для каждой записи BoundSheet8 и сохраняет сырой байтdtв новом свойствеSheet.SheetTypeRaw; писатель снова выдаёт исходный байт. Записи BOF подпотока макроса ($0040) при разборе тоже трактуются как подпоток рабочего листа, поэтому ячейки внутри листов макросов сохраняются, а не молча поглощаются предыдущим листом.
Версия 2.88.5
- Запись Row BIFF8 теперь сохраняет fCollapsed, fExAsc, fExDes и fPhonetic при round-trip. Раньше читатель отбрасывал fCollapsed (бит 4 grbit), а писатель выводил его из переходов уровня структуры на соседних строках, неверно классифицируя строки, явно свёрнутые или помеченные как границы исходным файлом. Три верхних бита (fExAsc на 28, fExDes на 29, fPhonetic на 30) также не читались и всегда выводились как ноль, потому что писатель усекал 4-байтовый grbit до единственного 16-битного слота ixfe. Читатель теперь потребляет все четыре бита согласно MS-XLS §2.4.221 и фиксирует fCollapsed как explicit. Писатель упаковывает ExAsc, ExDes и Phonetic в биты 12-14 слова ixfe и маскирует ixfe до разрешённого спецификацией 12-битного диапазона. Подсказки толстой верхней или средней нижней границы, управляемые ExAsc и ExDes, теперь переживают HotXLS SaveAs, а видимость фонетической информации на японских листах перестаёт сбрасываться при каждом сохранении.
Версия 2.88.4
- Бит fPaged в BIFF8 Window2 теперь помечает только активный лист. В предыдущих выпусках
fPaged(MS-XLS §2.4.346 бит 10) устанавливался на каждом видимом листе, из-за чего вывод HotXLS отличался от того, что пишет сам Excel (согласно спецификации бит означает "этот лист в данный момент отображается в окне книги", поэтому его должен нести только подпоток активного листа). Excel в любом случае откатывался кWindow1.itabCur, чтобы определить настоящий активный лист, так что злоупотребление допускалось; Apache POI в строгом режиме и другие инструменты, доверяющиеfPagedкак основному сигналу, теперь видят правильно помеченный лист.
Версия 2.88.3
- Масштаб и цвет линий сетки BIFF8 Window2 теперь сохраняются при round-trip. В предыдущих выпусках при чтении отбрасывались все поля WINDOW2 после смещения 6, а при записи выдавались жёстко заданные нули, поэтому любой сохранённый в Excel масштаб листа (75 процентов, 125 процентов и т. д.) и пользовательский цвет линий сетки возвращались к значениям по умолчанию после HotXLS SaveAs. Читатель теперь потребляет
icvHdr,wScaleSLVиwScaleNormalсогласно MS-XLS §2.4.346: масштаб активного вида попадает вSheet.Zoom, а значение противоположного вида ложится в кэш-слот, так что переключение между Normal и Page Break Preview в Excel восстанавливает прежний масштаб. Писатель выдаёт активныйSheet.Zoomв соответствующий слот вида и кэшированное значение в другой, плюс сохранённый индекс цвета линий сетки.
Версия 2.88.2
- Исправлен опкод записи HFPicture в BIFF8. Сохраняемые файлы .xls теперь записывают записи фонового изображения колонтитулов с корректным
rt = 0x0866согласно MS-XLS §2.4.138. В предыдущих выпусках использовалось0x086C(опкод CellWatch), из-за чего Excel пытался разобрать встроенный OfficeArt BLIP как ссылку на отслеживаемую ячейку и молча отбрасывал изображение. Книги с изображениями колонтитулов теперь сохраняют изображение при round-trip через HotXLS.
Версия 2.88.1
- Исправлен опкод записи Theme в BIFF8. Сохраняемые файлы .xls теперь записывают запись Theme с корректным
frtHeader.rt = 0x0896согласно MS-XLS §2.4.326. В предыдущих выпусках использовалось0x0892(опкод StyleExt), из-за чего Excel интерпретировал встроенную полезную нагрузку OOXML-темы как расширение стиля ячейки и молча возвращался к встроенной теме Office. Книги с настроенными цветами темы теперь сохраняют пользовательскую палитру при round-trip через HotXLS.
Версия 2.88.0
- [MS-XLSX] cross-audit round 4 — theme part + sheet-name setter. Two follow-up fixes 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 adds a new always-emitted part.
- Saved .xlsx packages now include an
xl/theme/theme1.xmlpart. styles.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 workbook 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 range, so existingXlsxFirstExternalLinkRidoffsets for sheets / sst / styles / vba / externalLinks are unchanged. - Direct
Sheet.Name := '...'assignment now sanitises and dedupes too. Round 3 (v2.54.1) added Excel naming-rule enforcement inTXLSXSheets.Add(AName), but theTXLSXWorksheet.Nameproperty 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 property setter now routes through a newSetNamemethod that replays the sameXlsxSanitizeSheetName+' (N)'-suffix dedup logic (case-insensitive, exclude-self) against the parent workbook’s sheet collection. Detached worksheets (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.
Версия 2.87.4
- Общие формулы XLS теперь записывают корректное тело
ShrFmla. Вывод BIFF8 добавляет обязательный байтcUseперед общей формулой, поэтому приUseSharedFormulasпоток токенов больше не смещается на один байт. - Метаданные стиля и фильтра таблиц XLS теперь соответствуют текущей структуре MS-XLS.
AddTableзаписываетLIST12какList12TableStyleClientInfo, задает флаги AutoFilter вFeature11и выводит пустые блокиFeat11FdaAutoFilterдля столбцов. - Правила BIFF8 CF12 Data Bar / Color Scale / Icon Set больше не записывают запрещенный DXF payload. HotXLS оставляет блок DXF пустым, как требует MS-XLS, а настройки сохраняет в хвосте CF12 для соответствующего типа.
Версия 2.87.3
- XLS worksheet table metadata now follows the MS-XLS
Feature11table layout.AddTableoutput for .xls files now writes aFeatHdr11table header plusFeature11TableFeatureType/Feat11FieldDataItempayloads, removes the legacy$0867 FeatHdrtable marker, and stores table and column names asXLUnicodeStringvalues. - XLS table readback now understands the spec-correct field layout. HotXLS parses
TableFeatureTypetable names, ranges, totals-row state, and field captions, while keeping a fallback for older HotXLS-generated table records.
Версия 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 worksheet tables now use spec-correct
ContinueFrt11chunks. WideAddTableoutputs with largeFeature11payloads now save with$0875 ContinueFrt11continuation records and reopen with table metadata preserved, matching the [MS-XLS]Feature11/ContinueFrt11layout.
Версия 2.87.1
- XLSX worksheet grid limit now includes 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 ranges touching the last row or last column were silently clipped to the previous row/column. - XLSX encryption docs and tests now match the implemented write path. Help pages and the regression suite now state that
SaveAsEncryptedwrites ECMA-376 Standard Encryption output for non-empty passwords, whileOpenEncryptedstill raises for encrypted packages and falls back for plain .xlsx files.
Версия 2.87.0
- XLSX password-protected save now works (wave J phase 2, backlog #29).
TXLSXWorkbook.SaveAsEncrypted(FileName, Password)now writes 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 workbook into an in-memory plaintext .xlsx zip → encrypts via AES-128 CBC with a fresh random 16-byte salt and verifier → writes the CFB output viaStgCreateDocfile. Open 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.
Версия 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 write 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.
Версия 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 save/open cycle. Earlier the BIFF8 reader silently skipped
QsiSXTag($0802),QsiSXTagExt($0810), andDConn($0876), so the metadata that describes the upstream query was dropped on save and the table degraded to plain cell values. The reader now captures these records as opaque bytes and the writer emits them back into the worksheet substream (alongside the PIVOTVIEW block per [MS-XLS] §2.1.7.20.5) and the workbook 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 workbooks that already contain them no longer lose refresh metadata. BIFF8 (.xls) only; BIFF5 unaffected.
Версия 2.85.1
- Restore Win32 / Win64 library build. Two pivot-line-item helper 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.
Версия 2.85.0
- Typed pivot subtotal API (wave H5.4). The typed
TXLSPivotFieldnow exposes aSubtotals: TXLSPivotSubtotalsset property 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 read/write. Closes the wave H4.3 known limit “row field subtotal SXVD.grbitSub configuration unavailable from API” and finishes the wave H5 pivot follow-ups.
Версия 2.84.1
- Multi data-field SXLI expansion (wave H5.3). When a pivot table 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 adds minimal byte overhead. Closes the wave H4.3 known limit “multi-data-field SXLI not correctly expanded”.
Версия 2.84.0
- Pivot page-axis pre-selection API (wave H5.2). The typed
TXLSPivotFieldnow carries aPageItemIndexproperty 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 readsField.PageItemIndexinstead of hardcoding $7FFD, and the typed reader now populatesPageItemIndexfrom SXPI on Open so callers can inspect the saved page selection. Closes the wave H4.3 known limit “page filter caller-pre-selection unavailable from API”.
Версия 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.
Версия 2.83.1
- Cell fill, font, and border colors set via RGB now round-trip through .xls save/open. The BIFF8 XFExt ($087D) writer was emitting each record's ixfe field using the in-memory XF array position, but the matching cell records on disk write ixfe using the post-pruning SaveIndex order. Whenever any XF earlier in the table was pruned during save (typical when one cell 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 cell shifted to a neighbouring cell on reload. The writer now resolves SaveIndex for each rich-slot XF and emits the matching on-disk ixfe, so RGB cell colors saved by HotXLS — interior fill, font color, border colors — survive a save / reload round-trip cleanly. XFExt records for XFs that got pruned entirely are now skipped rather than emitted with a dangling ixfe.
Версия 2.83.0
- Pivot line items + page item state (wave H4.3). Programmatically-built pivot tables 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 open 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 worksheet 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-table writer. Pivot tables built via
IXLSWorksheet.AddPivotTablenow ship self-contained caches with full layout metadata.
Версия 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 range on Open — 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 read 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 workbooks (one round-tripped cache + one new cache) emit both paths cleanly.
Версия 2.81.0
- Pivot data field number formats (wave H4.1). Pivot data fields can now carry an Excel number format string so currency / percentage / date data renders with the right glyphs on Open instead of showing raw General-format values. New
IXLSWorksheet.PivotSetDataFieldFormat(DataField, FormatStr): Wordregisters the format in the workbook's NumFormats table (auto-add or reuse) and writes the resulting ifmt index toTXLSPivotDataField.NumberFormat. The typed writer already emits SXDI.ifmt, so this closes the loop. - Public NumFormats helper on TXLSWorkbook.
Workbook.RegisterNumFormat(FormatStr): Wordexposes the same auto-add behavior at workbook 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%');
Версия 2.80.1
- Icon Set conditional formats round-trip cleanly through HotXLS save/open. 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 cell-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 workbooks from either generation re-open cleanly.
Версия 2.80.0
- Programmatic pivot table creation API (wave H3, MAJOR). New
IXLSWorksheet.AddPivotTable(SourceRangeA1, DestRow, DestCol, Name): TXLSPivotTablemethod walks the supplied source range, infers each column's data type from the cell values, auto-builds aTXLSPivotCache(or reuses an existing one bound to the same range), and creates a typed pivot table on the destination sheet with one TXLSPivotField per cache field (axes initially unset). - Caller wires axes / data via convenience methods.
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 tables), 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 worksheet 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 worksheet bodies. - Round-trip safety preserved. Pivot tables and caches read 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 workbooks (one round-tripped pivot + one new pivot via AddPivotTable) emit both paths cleanly. - Wave H3 limitations. Source range types other than rectangular A1 (named ranges, external workbook refs) are out of scope. SXLI / SXPI (line items / page items) are not emitted for typed pivots — Excel computes them on Open. 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 range string each time.
Версия 2.70.0
- Pivot table typed read 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 table structure without bytecode parsing. New types —
TXLSPivotTable,TXLSPivotField,TXLSPivotItem,TXLSPivotDataField,TXLSPivotCache,TXLSPivotCacheField,TXLSPivotCacheItem,TXLSPivotCaches,TXLSPivotTables— surface via the newIXLSWorksheet.PivotTablesandTXLSWorkbook.PivotCachesproperties. - What the model captures. Per pivot table: 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 read from disk leave per-record indices unpopulated and rely on the raw-byte path for fidelity. - Round-trip safety. Pivot tables 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-exports the public types so existing imports keep working.
Версия 2.69.0
- Pivot table round-trip preservation (wave H1). HotXLS now keeps every record that makes up a pivot table when an Excel-created .xls travels through Open → Save. 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 tables on next Open. The reader now captures all of these as opaque bytes and the writer replays them verbatim, so the pivot table on the cover sheet still renders correctly in Excel after a save / reload cycle.
- Worksheet 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 Tables block and the trailing EOF), matching the [MS-XLS] §2.1.7.20.1 worksheet 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 workbook each get their own bucket. On save the writer rebuilds the full BOF / records / EOF substream for each captured cache and appends them to the Workbook 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 table structure, but the existing Excel-built pivot tables round-trip through HotXLS without loss.
Версия 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=custom.NumValuecarries the magnitude (10.0 = 10% when Ebsrc=1, raw scalar for fixed value, multiplier for stddev). For custom (Ebsrc=5) theCnumfield carries the count of custom data points; spec says MUST=0 for the other sources, so the builder forces non-custom 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" style. - Custom 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 custom value array. Custom 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.
Версия 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-range 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
AddSerieshelper 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.
Версия 2.66.0
- Chart backlog wave F sub-feature 1: 3D chart types. Programmatically built chart sheets can now 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-style 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.
Версия 2.65.0
- Formula array constants round-trip with their data.
PtgArraytokens ($20 / $40 / $60 — V / R / A class) in formula streams now carry theirPtgExtraArraypayload through both read and write paths.SUM({1,2,3}),=MMULT(...),{=COUNTIF(...)}and other array-literal formulas preserve 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/ArrayValuesproperties (with the matchingTXLSArraySerValrecord describing num / str / bool / err / empty cells 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 read 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.
Версия 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 helper 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 workbook now also keeps an in-memory side-table that remembers the original theme idx + tint per(TMsoShapeContainer, OfficeArt property id)pair. A newXlsGetDrawingThemeColorreader consults that side-table 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 property panes. After Save / Open the side-table 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 + property id). SubsequentXlsApplyThemeColorToDrawingcalls on the same slot overwrite the entry, so the table tracks the latest intent rather than accumulating history. - Stable identity through new internal properties.
TXLSColorFormatgrew read-only_Containerand_Pidaccessors so the helpers can compose the side-table 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-table bridges the in-process gap so app-internal code can pretend the format supports theme colors as long as it lives within one workbook session.
Версия 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 cell-loop pass onSetRangeXFBordersPropertyregisters up to four XFExt slots in one go. - Compound selector mapping. The new
BorderEdgeSlotSet(BorderIndex): TXLSXfRichSlotSethelper centralises the selector → slot translation:xlEdgeLeft / Right / Top / Bottom→ singleton sets (unchanged from phase 2);xlDiagonalDown / Up→[rsDiag];xlAround→[rsTop, rsBottom, rsLeft, rsRight];xlInsideVertical→[rsLeft, rsRight];xlInsideHorizontal→[rsTop, rsBottom];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 cells loop with BorderMask=15), andConsumePendingRichSlotregisters all four XFExt slots on each touched XF in the same pass. ~4x fewer cell-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 cells 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 cell genuinely has the matching border line, and the indexed wire is set by the per-cellBorderMaskExcel already understands.
Версия 2.62.0
- Chart backlog wave D phase 5: custom theme XML round-trip + drawing theme helper. Three pieces close the last theme-color gaps that phase 4 left open. Custom 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 updates the workbook'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 newXlsApplyThemeColorToDrawinghelper lets chart / shape callers address drawing colors with the same theme idx + tint vocabulary that cells 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 workbooks emit no record and stay byte-compatible with pre-Phase-5 output. - Drawing theme color helper. The new free function
XlsApplyThemeColorToDrawing(ColorFormat, Workbook, ThemeIdx, Tint)resolves a theme idx + tint through the workbook palette and writes 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: read-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 cells, which leverage XFExt $087D. - Wave D fully closed in five phases. Phase 1 (v2.58.1) added the case-table acknowledgement, Phase 2 (v2.59.0) wrote XFExt for RGB cell colors, Phase 3 (v2.60.0) closed the RGB reader loop, Phase 4 (v2.61.0) shipped the theme color path on cells, and Phase 5 (this) completes the picture with custom theme XML round-trip plus the drawing-side helper. Cells 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 helper but pay the OfficeArt format's RGB-only price on read-back.
Версия 2.61.0
- Chart backlog wave D phase 4: BIFF8 theme color support (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 cell color getters resolve the same theme idx + tint back through the workbook'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-compatibility trick Microsoft uses when "Save 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-style -1.0..+1.0 lighter/darker adjustment that gets encoded into FullColorExt.nTintShade as Q15 signed integer. - Workbook BIFF theme palette.
TXLSWorkbooknow carries anFBiffTheme: TXLSThemeColorsinitialised to the default Office theme scheme that the XLSX side has used for years throughTXLSColorManager.FTheme. Cell color getters resolve theme idx + tint through this palette viaGetThemeRGBColor(idx, tint)(which already applies HSL-based tint adjustment inlxRgb.GetRGBTInt). Internal_BiffThemeproperty exposes the palette for parser-side updates. - Theme record ($0892) acknowledged on read.
lxRead.ParseThemetakes$0892out of the default-skip path so the workbook-globals case table 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 cells render correctly through them. Workbooks with a fully customised theme will surface theme cells through the default palette here (documented known limit; XML-based theme parsing is a follow-up wave). - Why no Theme record on write. 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 cells 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.
Версия 2.60.0
- Chart backlog wave D phase 3: XFExt ($087D) read-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 workbook XF rich-color side-table. Files saved by Excel with RGB cell 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 cells. 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 workbook side-table 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. - Cell color getters consult the side-table 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 existingGetRGBTInthelper when the slot carries an RGB value. xclrType=3 (theme) falls through to the indexed path: the BIFF workbook has no theme model on this call chain, so the palette approximation remains the best available answer for theme cells. Cells whose XF was never touched by a Phase 2 setter or a parsed XFExt produce the same byte-identical read result as before. - Wave D is closed. Save preserves caller-set RGB (Phase 2). Load preserves Excel-set RGB (Phase 3). Workbooks 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-table slot rather than per-edge — both rare enough to leave for a future wave.
Версия 2.59.0
- Chart backlog wave D phase 2: XFExt ($087D) emission for BIFF8 cell 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 workbook 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 cell 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 cell 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). Cells that never took the color-setter path still emit no XFExt — workbooks with no rich colors produce the same byte stream as before. - Storage and bookkeeping. A new per-XF rich-color side-table in
TlxFormatListholds the original RGB / theme info the cell setter passed in, keyed by the workbook's hash-resolved XF index.TXLSRange.SetXFProperty/SetRangeXFBordersPropertygrew an optionalOnNewIndexcallback so the cell setter can register the rich color against every XF index the cell ends up on (multi-cell ranges that hash to multiple distinct XFs all get tagged). The side-table is consulted inStoreWorkbookright after STYLES and before PALETTE, matching the*XFExtposition in [MS-XLS] §2.1.7.20.3 Workbook 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 workbook's style objects, because doing so in the hash-keyed style 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 read back throughcell.Interior.Color. Closing that read-side gap is a separate follow-up (Phase 3) that requires reworking the style hash to admit per-XF rich color before the first hash anchor.
Версия 2.58.1
- Chart backlog wave D (read-side acknowledgement only): XFExt ($087D) no longer routed through the default-skip path. A new
ParseXFExtbranch in the BIFF8 workbook-globals case table consumes$087Drecords that Excel writes alongside RGB and theme-colored cell styles. The reader still leaves the indexed-color XF record unchanged — full RGB / theme precision recovery onto the workbook's hash-key style model is deferred to a separate wave because it would require the BIFF writer-side style 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 write + read implementation, but exploration found that the BIFF write pipeline (
TXLSWorkbook.FXFList: TlxFormatList) encodes XF style 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 style models or extendingTlxFormatListwith per-XF rich color side-tables, 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.
Версия 2.58.0
- Chart backlog wave C: SST rich-text and phonetic round-trip (BIFF8 XLUnicodeRichExtendedString). Rich-text formatting set in Excel (a cell whose individual characters carry their own font / color, the "two colors in one cell" effect from the Format Cells dialog) sits in the shared string table 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 save, so opening then resaving a workbook flattened every multi-format cell to a single font / color. The shared-string parser now preserves 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
CollectRawTailhelper 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 preserve correctly whenrtorszovershot the current record. The preserved tails are registered against the workbook SST through the newTXLSStringTable.AddWithExtras, which deliberately does not bump the cell-reference counter so subsequentLabelSSTparsing still produces correctcstTotalon save. - 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 workbook 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.
Версия 2.57.0
- Chart backlog wave G: Header / Footer pictures survive the round-trip (BIFF8 HFPicture). When Excel saves a worksheet with a header or footer background image (Insert → Header & Footer → Picture, then the company logo style), 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 workbook again therefore lost the header/footer image. The reader now preserves 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 worksheet. 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 worksheet ABNF. Each preserved body is wrapped in a fresh $086C header and routed throughAppendData— the existingAddContinuehelper 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 writes 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). Workbooks that never carried an HFPicture record produce byte-identical output as before. The internal helper
TXLSWorksheet._AddHFPictureBlobis reserved for the reader; the underscore prefix flags it the same way as_Drawing/_Autofilter.
Версия 2.56.0
- Chart backlog wave B: worksheet 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 property 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 workbook 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 workbooks. xlExcel5 output is untouched (no SheetExt record in BIFF5). - Reader restores the tab color on open. A new
ParseSheetExtbranch inParseWorkbookRecord's case table readsiTabIdand the FullColorExt block and writes the resolved RGB value back toSheets[iTabId + 1].TabColor.xclrType=2(RGB) stores the raw value;xclrType=1(indexed icv) resolves through the workbook 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 workbook that opens in Excel with a green tab; saving that same workbook back out and re-opening it returns the property 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.
Версия 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-formula multi-column writer no longer references a missing record field. The v2.50.0 SHRFMLA wire-format fix added
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-formula groups (the only kind the collector currently produces) is unchanged; the spec-correctcolLastbyte is now real instead of an alias ofcolFirst. - XLSX cell writer references
XlsxFloatToStrthrough a forward declaration. The v2.51.0 locale-safety fix introduced an XlsxFloatToStr call in the cell-value branch (line 2718) but the helper 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.
Версия 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 range had its cache slots silently cut short. The builder now (a) computes the maximum point count across all series for theDIMENSIONSrow range, 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 cells 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.
Версия 2.54.1
- [MS-XLSX] cross-audit follow-up. Two targeted fixes from the v2.52.0 audit’s "deferred" list. Both are user-observable; neither breaks existing call sites.
- Date cells keep their date format when combined with any single non-numFmt style. A
TDateTimecell withFontIndex/FillIndex/BorderIndex/AlignmentIndex/ProtectionIndexset but no explicitNumberFormatIndexused to route through a single-dim cellXf whosenumFmtIdwas 0 (General), so Excel rendered the cell as a raw serial number (e.g.46038) instead of1/15/2026. The XLSX style engine now treats the implicit date as a virtual dim: any other styled dim promotes the cell into a composite cellXf that carriesnumFmtId=14alongside the real dim. Pure-date cells 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 workbook that failed to open with the “The name you entered is not valid” dialog.TXLSXSheets.Addnow normalises the name via the newXlsxSanitizeSheetNamehelper (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.
Версия 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 Worksheet shell records, SST/Continue edges, formula PTG depth, encryption padding, chart records, drawing/comment writer, and Pivot/Table support. Public API unchanged; existing code recompiles untouched.
- Comment Note record now spec-conformant. Two distinct fixes 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
Visibleproperty 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 property 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. - Formula
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-table key, so functions emitted with the user-prompt flag (macro/UDF callers) hashed to$8000 | iftaband produced an empty function name, killing the entire formula. 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 Workbook 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 support 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 Table / QueryTable / DConn unsupported) are documented as known gaps for future feature work rather than silent omissions.
Версия 2.53.0
- OpenOffice excelfileformat.pdf cross-audit round 2. Three additional BIFF8 wire-format fixes uncovered by re-running the spec sweep after v2.50.0, targeting modules the first pass had touched only lightly: the formula token decoder, the XF alignment byte, and the ROW outline-collapse boundary check.
- Macro-command formulas with the user-prompt flag no longer corrupt the parser (§3.7.2 tFuncVar). The byte at offset+1 of a
tFuncVartoken packs the argument count in bits 6-0 ($7F) and the user-prompt flag in bit 7. Without masking, prompt-flagged tFuncVars were read as 128+N arguments, blowing the formula stack and yielding nil for the whole expression. - JustifyLastLine alignment flag round-trips correctly (§5.115 XF). The XF BIFF8 alignment byte (offset 6) packs HorAlign + WrapText + VerAlign + JustifyLastLine. Bit 7 (
$80, JustifyLastLine) was never written, so cells configured with the flag reverted to the Excel default after save / reopen. - Row 0 / row 65535 no longer mis-flagged as outline-group boundaries (§5.88 ROW). The fCollapsed (
$10) bit fired for the boundary rows when their explicit outline level differed from the absent neighbours' default level 1. Absent neighbours are now treated as matching the row's own level.
Версия 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.
- Cell 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 cell 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 worksheet 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 read it (Apache POI / NPOI / OOXML SDK) pre-size their cell buffers from the hint instead of growing dynamically. The writer now computes the bounding rectangle of populated cells during the row-grouping pass and emits the element as the second child of<worksheet>(after<sheetPr>if present, before<sheetViews>). Empty worksheets collapse to<dimension ref="A1"/>. <sst count="...">reports total cell 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.
Версия 2.51.0
- [MS-XLSX] cross-audit pass. Five wire-format and locale-safety fixes across the XLSX writer uncovered by validating against the Microsoft [MS-XLSX] — Excel (.xlsx) Extensions to the Office Open XML SpreadsheetML File Format documentation (v20260108) and the underlying XML 1.0 / OOXML schema requirements. Public API is unchanged; existing applications recompile and re-save without modification.
- Saved .xlsx files now open on every Windows region. Page margins, column widths, row heights, font sizes, color tints, theme tints, custom-font rich-text run sizes, and the
<v>-wrapped numeric value of every cell 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 cell 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 workbook in those regions. - Cells containing control characters no longer break the workbook. 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. Cell 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 open 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 reads 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.
Версия 2.50.0
- OpenOffice excelfileformat.pdf cross-audit pass. Eight follow-up wire-format and lifetime fixes uncovered by re-validating the BIFF8 writer / reader against the OpenOffice Microsoft Excel File Format documentation after the v2.49.0 [MS-XLS] pass. Public API is unchanged; existing applications recompile and re-save without modification.
- Shared formulas now span the full column range (§5.94 SHAREDFMLA). The
SHRFMLArecord body wrotecolFirstinto thecolLastbyte, collapsing every multi-column shared formula group to a single-column group in Excel. Fill-down formulas across two or more columns now expand to the correct cells when the workbook is reopened. The reader-sidecolLastwidth was also corrected. - Shared formula Boolean / Error results round-trip correctly (§5.50 FORMULA). The same
FormulaValuebyte-layout bug fixed in v2.49.0 for standalone formulas was still present in the shared-formula writer (cells that carry atExptoken pointing at aSHRFMLAmaster). CachedTRUE/FALSEand#REF!/#DIV/0!/etc. values now appear as written. - FORMULA option flags identify shared-formula members (§5.50 FORMULA). Cells inside a shared-formula group now set the
fShrFmlabit (0x0008) in the FORMULA record option flags so strict parsers recognise thetExptoken as a back-reference. - 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. - 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"). - CHOOSE() formulas read back correctly (§3.10.5 tAttrChoose). The
tAttrparser previously skipped a fixed 4 bytes for every subtype;tAttrChoose($04) is variable-length. The decoder now readsncand advances by6 + 2·ncbytes. - 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.
Версия 2.49.0
- Spec-audit pass against [MS-XLS] v20250520. Sixteen wire-format and behaviour fixes across the BIFF8 writer, formula decoder, encryption path, chart builder, conditional-format and data-validation runtime, SST/ExtSST index, VBA storage reader and OLE stream open 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 formulas read back as False and Error formulas as #NULL! in every consuming application. - Cell 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 Method-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 read FrtRefHeader anchor fields at offsets 2/4/6/8 instead of 4/6/8/10, so the anchor-range comparison never matched and per-cell tooltips were silently discarded; tooltips now associate with their hyperlinks. BIFF8 range-reference decoder also fixed aFFirstColRel/FLastColReltypo in the BIFF5/7 fallback sign-extension path that mis-decoded ranges with negative last-column relative offsets. - Conditional formatting and data validation runtime fixes.
IsContainRowin bothTCondRangeandTDVRangereturned true only when the range degenerated to a single row (the comparison was inverted); per-row clearing of CF / DV rules now works on multi-row ranges. 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 workbooks containing icon-set rules open with the rules intact. - ExtSST quick-find index spec-conformant for large workbooks. The
dsstfield is now computed asmax((cstUnique / 128) + 1, 8)per [MS-XLS] §2.4.107 instead of the static default of 8; workbooks 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 Workbook stream open path matches the spec spelling. The first OLE
OpenStreamattempt uses 'Workbook' (capital W per [MS-XLS] §2.1.7.20) instead of all-lowercase, so compound-file containers on case-sensitive OLE implementations open 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.
Версия 2.48.10
- Файлы .xls, сохранённые HotXLS, теперь включают два OLE-составных потока наборов свойств, которые Excel ожидает в каждой рабочей книге:
\005SummaryInformationи\005DocumentSummaryInformation. До v2.48.10 только TRIAL-сборки писали их (как механизм штампования баннера); release-сборки производили файлы .xls, чей поток Workbook был действительным BIFF8, но чей OLE-контейнер не имел стандартных потоков метаданных Office. Строгий парсер Excel 2003 рассматривает это как условие "File error: data may have been lost" (современный Excel сохраняет баннер Защищённого Просмотра "у этого файла есть проблемы"). Добавление потоков устраняет диалоговое окно на рабочих книгах с диаграммами без изменения какой-либо записи BIFF8. - Два потока эмитируются через путь Win32
StgCreatePropSetStg+IPropertySetStorage.Create+IPropertyStorage.WriteMultiple— тот же код, который использует Microsoft Office, поэтому Office File Validation принимает байтовую раскладку. Поток SummaryInformation создаётся сAppName="HotXLS"по умолчанию и пустым Автором; TRIAL-сборки по-прежнему перезаписывают значения Автора / AppName баннером пробной версии черезlxTrial.XlsTrialStampXlsSummaryпосле штампа по умолчанию, поэтому пробные файлы остаются идентифицируемыми в панели Файл > Сведения > Свойства Excel. Поток DocumentSummaryInformation создаётся пустым (Win32 всё ещё эмитирует заголовок набора свойств + свойство CODEPAGE — достаточно, чтобы строгий парсер Excel считал метаданные "присутствующими и хорошо сформированными"). - Это исправление универсально — каждый .xls, сохранённый HotXLS, теперь несёт стандартные метаданные OLE, не только рабочие книги с диаграммами. Выводы только-листа из предыдущих релизов избежали симптома, потому что Excel более снисходителен к рабочим книгам только-листа без метаданных, чем к рабочим книгам с листом диаграммы, но технически им также не хватало потоков. Новый модуль
Lib/lxXlsSummary.pasсодержит две вспомогательные процедуры; lxHandle.pas вызывает их безусловно внутриTXLSWorkbook.SaveWorkbookпосле того, какStoreWorkbookзаполняет поток Workbook, и передFDocStorage.Commit. - Этот релиз закрывает восьмиверсионную последовательность последующих исправлений chart Phase 2 (v2.47.0 — v2.48.10): от связывания серий
tArea3D, через перевыравнивание id BRAI, наблюдаемые Excel значения sdtX/cValx, размещение SERIESTEXT, удаление заполнения потока Workbook, оболочечные записи на уровне листа, и теперь потоки метаданных OLE. Результат — диаграммный .xls, который открывается в Excel 2003 и современном Excel без каких-либо предупреждений "у файла есть проблемы", байтово выровненный с тем, что сам Excel пишет для тех же данных.
Версия 2.48.9
- Листы диаграмм BIFF8 теперь несут полный набор оболочечных записей уровня листа, который требует Excel 2003+. chart_phase2_demo.xls v2.48.8 рендерил столбчатую диаграмму корректно, но Excel 2003 всё ещё показывал диалоговое окно "File error: data may have been lost" (новые версии Excel сохраняли баннер Защищённого Просмотра) потому что substream диаграммы пропускал те же записи уровня листа, что несёт substream рабочего листа. Реальные файлы Excel (как from-scratch, так и re-saved варианты вывода HotXLS) оборачивают записи диаграммы в эту оболочку:
- Перед записями диаграммы (между BOF и UNITS):
HEADER($0014, пустой),FOOTER($0015, пустой),HCENTER($0083, значение 0),VCENTER($0084, значение 0),SETUP($00A1, 34-байтная настройка страницы),PRINTSIZE($0033, значение 3). - После записей диаграммы (после самого внешнего CHART END, перед EOF):
DIMENSIONS($0200, 14 байт) объявляет диапазон кэшированных данных, три маркераSERIESINDEX($1065) для слотов кэша категорий / значений / размеров пузырей, по одномуNUMBER($0203, 14 байт) на кэшированную точку значения, иWINDOW2($023E, 10-байтный вариант для листа диаграммы) в конце.
dev-notes/biffview-refs/excel_column_chart_resaved.xls(референс столбчатой диаграммы, сохранённый Excel, локально). - Перед записями диаграммы (между BOF и UNITS):
- Кэш значений в настоящее время эмитирует нулевые заполнители (
0.0для каждой точки данных), соответствуя тому, что сам Excel пишет при пересохранении диаграммы, исходный кэш которой не был предварительно заполнен. Диаграмма по-прежнему рисует реальные данные, потому что ссылкиPtgArea3dBRAI разрешаются на исходные ячейки рабочего листа во время рисования — кэш позволяет Excel анализировать лист диаграммы без предупреждений, а не питает построение. Будущая версия может заполнить кэш реальными числами из диапазонаValues; wire-формат на месте. - Сквозной дымовой тест: откройте регенерированный
Demo/Delphi/XlsCreateChart/chart_phase2_demo.xlsв Excel 2003 — запрос "File error: data may have been lost" больше не появляется, и столбчатая диаграмма рендерится идентично прежней. Тот же файл чисто открывается в современном Excel без баннера Защищённого Просмотра.
Версия 2.48.8
- Писатель BIFF8 (.xls) больше не дополняет поток Workbook завершающими нулевыми байтами.
TXLSWorkbook.StoreOleFileранее вызывалStoreExtraSpace(Book)после записей последнего листа, заполняя длину потока до следующей границы 512 байт (сектор OLE). Строгий парсер Excel рассматривает эти завершающие нулевые байты как фиктивный поток записей с id0x0000и показывает запрос Защищённого Просмотра "этот файл имеет проблемы" — виден на chart_phase2_demo.xls v2.48.7 даже после исправления wire-формата BRAI / sdtX / SERIESTEXT и корректного рендеринга диаграммы. Удаление вызова убирает заполнение из содержимого потока Workbook; заполнение сектора OLE всё ещё происходит, но в слое контейнера CFB под потоком, где сам Excel его размещает (каждый сохранённый Excel .xls имеет длину потока Workbook, не выровненную по сектору). - История симптомов: любой сохранённый HotXLS .xls, общая длина в байтах действительных записей которого не совпадала случайно с границей 512 байт, нёс поток с завершающими нулями. Ошибка существовала с коммита бутстрапа репозитория, но редко проявлялась — большинство рабочих книг имеют достаточно записей, чтобы заполнение оказалось маленьким (≤ 4 нулевых байта, которые Excel терпит). Рабочие книги с листами диаграмм оказываются далеко ниже границы сектора (демо v2.47.0 — v2.48.7 заполняло 420 нулевых байт), поэтому именно там запрос Защищённого Просмотра стал постоянным.
- Сам метод
StoreExtraSpaceостаётся как приватный мёртвый код вlxHandle.pasна случай, если будущий путь кода действительно нуждается в потоках, округлённых до сектора; точка вызова вStoreOleFileудаляется. Длина потока Workbook теперь точно равна длине в байтах всех действительных записей (демо диаграммы: 3164 байт; референс Excel from-scratch: 4419 байт — оба не выровнены по сектору). Пути кода читателя не затронуты — HotXLS всегда корректно читал не-сектор-выровненные потоки Workbook из сохранённых Excel файлов.
Версия 2.48.7
- Записи серий диаграмм BIFF8 наконец корректно отображаются в Excel. Исправление заключается в выравнивании назначений id BRAI с [MS-XLS] §2.4.51 — родительский план реализации документировал их инвертированными, распространяя ошибку через каждый релиз диаграмм с v2.41.0 по v2.48.6. Правильная семантика id:
id = 0— имя серии / метка легенды (план говорил: categories)id = 1— values (правильно)id = 2— categories (план говорил: name)id = 3— bubble sizes (план говорил: errBars)
- Также выровнено с форматом wire столбчатой диаграммы, сохранённой Excel:
SERIES.sdtXтеперь0x0003(наблюдаемое значение Excel для текстовых категорий, а не0x0001, документированный [MS-XLS] §2.4.252), иcValxнесёт фактический счётчик категорий вместо0. Правило "cValx MUST = 0, когдаsdtX∈ {1, 3}" опровергнуто каждым изученным образцом, сохранённым Excel. - Носитель литерального имени
SERIESTEXT($100D) возвращается, но в правильном месте: непосредственно после BRAIid = 0, всё ещё внутри блока SERIES BEGIN/END. Это то, что делают реальные файлы Excel — точка эмиссии v2.48.5 (после всего кластера BRAI, передDataFormat) была неправильной и ломала парсинг диаграммы; правильная позиция — прямо рядом с BRAI имени серии. - Файлы диаграмм, сохранённые в v2.41.0 — v2.48.6, все несут инвертированный wire-формат BRAI. Они открываются в Excel без ошибок, но показывают вышеуказанные симптомы легенды / оси X. Пересохраните через v2.48.7+ для миграции; без изменения API — тот же вызов
AddChartSheetтеперь производит диаграмму, которая рендерится идентично тому, что сам Excel написал бы для тех же данных. - Новый инструмент инспекции на уровне байтов
dev-notes/biffview-refs/dump_chart_substream.pyвыгружает substream диаграммы любого BIFF8 .xls с декодированием по записям (SERIES / BRAI / SERIESTEXT / AXIS / CATSERRANGE / LEGEND / OBJECTLINK / POS / TEXT). Использовался во время этого релиза для byte-diff вывода HotXLS относительно образцов-эталонов, сохранённых Excel; доступен для будущих follow-up по спецификации диаграмм.
Версия 2.48.6
- BIFF8-substream листа диаграммы отзывает изменения v2.48.5. Реальные тесты Excel на регенерированном демо v2.48.5 вообще не отрендерили диаграмму — хуже базовой линии v2.47.0 (где диаграмма рисовалась, но с неверными метками оси X). Два изменения v2.48.5 были причиной:
SERIES.sdtX = 4на самом деле не принимается Excel, хотя Apache POI экспонируетCATEGORY_DATA_TYPE_TEXT = 4. [MS-XLS] §2.4.252 строго требует, чтобыsdtXбыл0x0001или0x0003.- Добавленная запись
SERIESTEXT($100D) внутри блока SERIES BEGIN/END — структурное нарушение.SERIESTEXTпринадлежит блокам TEXT (контексты заголовка диаграммы / заголовка оси / метки данных), а не внутри блока SERIES. Встраивание там запутывает парсер диаграмм Excel и отвергает весь substream.
- v2.48.6 восстанавливает wire-формат v2.47.0 И добавляет одно исправление соответствия спецификации:
SERIES.cValxтеперь0, когдаsdtX = 1(правило [MS-XLS] §2.4.252 spec MUST). До v2.48.6 писалосьcValx = count(4 в демо), нарушая правило, что, возможно, способствовало предупреждению Excel "у документа есть проблемы" в защищённом представлении.cValyвсё ещё несёт фактическое количество значений (sdtY=1 не имеет правила нуля). - Новое Delphi-демо XlsCreateChart в
Demo/Delphi/XlsCreateChart/создаёт книгу из двух листов: лист "Data" с четырьмя строками (Region, Sales) и лист "Chart1" со столбчатой диаграммой, серия которой связываетData!$A$2:$A$5/Data!$B$2:$B$5как Categories / Values. Демо — постоянный преемник ad-hocchart_phase2_demo.xls, который v2.47.0 — v2.48.5 размещали в корне репозитория для тестов BiffView; корневой файл удалён, а новое демо пишет свой вывод рядом со своим .exe. - Известно нерешённое: с wire-форматом v2.48.6 Excel по-прежнему рендерит метки оси X столбчатой диаграммы как нули и откатывается к конкатенации текста ячеек категорий для легенды (вместо использования литерала PTG tStr из BRAI id=2
'Q1 Sales'). Это реальный пробел wire-формата, который требует столбчатой диаграммы, сохранённой Excel, в качестве референса для побайтового diff — отслеживается как follow-up. Сама область построения с 4 столбцами рендерится корректно (высоты 100/150/200/175 соответствуют Values).
Версия 2.48.5
- Записи серий диаграмм BIFF8 теперь корректно отображаются в Excel. v2.47.0 подключила привязку
tArea3Dдля диапазонов Categories / Values, но Excel по-прежнему рисовал все метки оси X как0и использовал склеенный текст категорий ("North South East West") как легенду и автоматический заголовок, вместо предоставленного пользователем Name. Два исправления восстанавливают намеренное отображение: - Поле
sdtXзаписиSERIESтеперь4(текстовые категории), а не1. [MS-XLS] §2.4.252 документирует только1(даты) и3(последовательность BIFF7), но реальные файлы столбчатых / линейчатых / графических диаграмм, сохранённые Excel, пишут4для текстовых осей категорий (соответствует константеCATEGORY_DATA_TYPE_TEXTApache POI). ПриsdtX=1Excel пытался привести ячейки'North'/'South'к числам → fallback на 0; сsdtX=4текстовые метки проходят буквально. Предыдущая wire-форма также нарушала правило спецификации "cValxдолжен быть нулём приsdtX=1". - Запись
SERIESTEXT($100D) теперь эмитируется внутри блока SERIES BEGIN/END (после кластера BRAI, передDataFormat) всякий раз, когда указан литеральный Name. Механизм первой половины Phase 2 (BRAI id=2 + PTGtStr) сохранён ради полноты спецификации, но Excel фактически берёт метку легенды и автоматический заголовок изSERIESTEXT; при наличии только варианта BRAI Excel откатывался на склеивание ячеек категорий. После этого исправления легенда показывает реальный Name (например,'Q1 Sales'), а пустой заголовок диаграммы оставляет слот автоматического заголовка пустым. - Миграция: выводы листов диаграмм v2.42.0 — v2.47.0 по-прежнему открываются в Excel без ошибок, но проявляли симптомы выше. Пересохраните через v2.48.5+, чтобы получить исправленный wire-формат; изменений API не требуется, тот же вызов
AddChartSheetтеперь производит правильную диаграмму.
Версия 2.48.4
- Вывод BIFF8 CFEX ($087B) выведен на пенсию. HotXLS больше не пишет парную CFEX после каждой CF12 — вся конфигурация Data Bar / Color Scale / Icon Set теперь идёт встроенно в хвосте по типам CF12 (v2.48.1 — v2.48.3). Apache POI / NPOI всё равно игнорируют CFEX, так что это чистое упрощение.
- Путь чтения BIFF8 CF12 теперь потребляет хвост по типам прямо из CF12. Это завершает 5-PATCH переписывание wire-формата Gap #6 (v2.48.0 header + v2.48.1 data_bar + v2.48.2 color_gradient + v2.48.3 multistate + v2.48.4 пенсия CFEX).
Версия 2.48.3
- Правила Icon Set в BIFF8 CF12 ($087A) теперь выводят NPOI-совместимую подзапись
multistateвстроенно, позволяя Apache POI / NPOI читать семейство иконок, пороги по точкам и флаги reverse / icon-only прямо из CF12. Раскладка соответствует NPOIIconMultiStateFormatting.Serialize(). - Файлы .xls, сгенерированные HotXLS v2.48.2, следует пересохранить через v2.48.3, чтобы правила Icon Set получили новый встроенный хвост. Снятие вывода CFEX появится в v2.48.4.
Версия 2.48.2
- Правила Color Scale из 2 и 3 точек в BIFF8 CF12 ($087A) теперь выводят NPOI-совместимую подзапись
color_gradientвстроенно, позволяя Apache POI / NPOI читать порог, цвет и позицию интерполяции каждой точки прямо из CF12. Раскладка соответствует NPOIColorGradientFormatting.Serialize(). - Файлы .xls, сгенерированные HotXLS v2.48.1, следует пересохранить через v2.48.2, чтобы правила Color Scale получили новый встроенный хвост. Хвост Icon Set появится в v2.48.3.
Версия 2.48.1
- Правила Data Bar в BIFF8 CF12 ($087A) теперь выводят NPOI-совместимую подзапись
data_barвстроенно (28 байт послеtemplate_params), позволяя Apache POI / NPOI декодировать цвет полосы, мин/макс пороги и границы длины в процентах прямо из CF12, не обращаясь к устаревшей записи CFEX. Раскладка соответствует NPOIDataBarFormatting.Serialize(). - Файлы .xls, сгенерированные HotXLS v2.48.0, следует пересохранить через v2.48.1, чтобы правила Data Bar получили новый встроенный хвост. Хвосты Color Scale / Icon Set появятся в v2.48.2 — v2.48.3.
Версия 2.48.0
- Расположение заголовка BIFF8 CF12 ($087A) исправлено в соответствии с NPOI
CFRule12Record.serialize()и эталонными файлами, сохранёнными Excel. Excel записываетext_formatting_length(4)перед токенами формул и блокtemplate_paramsс префиксом длины; в HotXLS эти поля были в неправильном порядке. Хвосты по типам (data_bar / color_gradient / multistate) появятся в v2.48.1 — v2.48.3. - Файлы .xls, сгенерированные HotXLS v2.34.0 — v2.47.1, следует пересохранить через v2.48.0 для перезаписи их записей CF12. Внеспецификационное 2-байтовое поле
nIDв конце каждого CF12 удалено.
Версия 2.47.1
- Проводной формат записи BIFF8 CONDFMT12 ($0879) исправлен для соответствия файлам, сохранённым Excel. Предыдущая реализация следовала раннему черновику spec, который оставлял 8-байтовый связанный диапазон как "зарезервированный" внутри FtrHeader и вставлял несуществующее 4-байтовое поле Reserved перед
numCF. Файлы .xls Excel фактически заполняют эти 8 байтов связанным диапазоном ячеек. Эталон:poi_ConditionalFormattingSamples.xlsзапись 152 теперь совпадает побайтово. - Файлы .xls, сгенерированные HotXLS v2.34.0 — v2.47.0, следует пересохранить через v2.47.1 для восстановления их записей CONDFMT12.
Версия 2.47.0
- Создание листа диаграммы BIFF8 теперь привязывает реальные диапазоны данных к сериям. Строки A1
CategoriesиValues, передаваемые в 6-аргументную перегрузкуAddChartSheet(например,'Data!$A$2:$A$5'), компилируются в PTG-токеныtArea3D, записываемые в записи серииBRAI id=0(категории) иBRAI id=1(значения). Открытые в Excel файлы .xls теперь рендерят реальные точки данных в области графика вместо пустой диаграммы-заглушки из v2.42.0. - Разрешение имени листа и регистрация EXTERNSHEET выполняются автоматически: парсер находит лист по имени в книге, регистрирует запись XTI, если она ещё не существует, и записывает соответствующий 0-индексированный
ixtiв тело PtgArea3d. При повторном сохранении поток записей диаграммы сериализуется заново через компилятор формул, что сохраняетixtiв согласованности с финальным порядком EXTERNSHEET. - Принимаемые формы ссылок:
Sheet1!$A$2:$A$5(абсолютная),Sheet1!A2:A5(относительные маркеры допустимы — серии диаграммы всегда сохраняются как абсолютные),'My Sheet'!$A$1:$B$5(имена листов с пробелами в одинарных кавычках) и ссылки на одну ячейку, напримерSheet1!$A$1(вырождается в PtgArea3d размером 1×1). Количество точек данных (cValx/cValy) теперь автоматически вычисляется по размерам области. - Неподдерживаемые формы ссылок безмолвно откатываются на BRAI-заглушку
cce=0в стиле v2.41.0, чтобы диаграмма по-прежнему открывалась в Excel: межкнижные ссылки ([Book2.xls]Sheet1!...), именованные диапазоны (Sheet1!ProfitColumn), ссылки без префикса листа!и ссылки, указывающие на сам лист диаграммы. Эти случаи отложены на следующие фазы. - Завершает Roadmap #10 Phase 2 (столбчатая диаграмма end-to-end). Метки серий (первая половина Phase 2, v2.42.0) плюс привязка диапазонов серий (этот релиз) означают, что столбчатая диаграмма, созданная через
AddChartSheet, теперь отображает корректные записи легенды и реальные данные без постобработки в Excel.
Версия 2.46.0
- Декодер DXF на стороне BIFF8 теперь разрешает цвета xclrType=1 (индексированная палитра) из стандартной 64-цветной палитры Excel 2003.
- Поиск использует встроенную палитру по умолчанию Excel 2003 — icv 0..7 — это 8 системных цветов, icv 8..15 отражают системные цвета, icv 16..63 — стандартные настраиваемые значения по умолчанию. Выход за пределы диапазона icv падает на чёрный.
- Настройка записи PALETTE BIFF8 не учитывается.
- Пути xclrType=0 (auto) и xclrType=2 (RGB) не изменились.
Версия 2.45.0
- Правила условного форматирования теперь делают round-trip атрибута priority как в XLSX
<cfRule priority="N"/>, так и в поле BIFF8 CF12ipriority. - Новое свойство
PriorityнаTCondFormatRule(сторона BIFF8) иTXLSXConditionalFormat(сторона XLSX). По умолчанию ноль сохраняет существующее поведение auto-by-index при сохранении; положительное значение фиксирует приоритет. - Priority управляет слоистостью нескольких правил — когда несколько правил охватывают один и тот же диапазон, Excel применяет их в порядке приоритета. Round-trip приоритета сохраняет предполагаемый пользователем порядок рендеринга.
- Поведение по умолчанию не изменилось для вызывающих, которые не трогают
Priority.
Версия 2.44.0
- Правила условного форматирования Набор Значков теперь поддерживают переопределения значков для каждой точки остановки на стороне XLSX. Каждая из 3 / 4 / 5 точек остановки в наборе значков может отказаться от значения по умолчанию семейства и отображать любой значок из любого из 17 встроенных семейств Excel 2007, идентифицируемый именем набора + id значка. OOXML-элемент:
<cfIcon iconSet="OtherSet" iconId="N"/>. - Новые методы на
TXLSIconSetSpec:SetIconOverride(stopIndex, OverrideSet, IconId)иClearIconOverride(stopIndex). Свойства только для чтенияHasIconOverride[i],IconOverrideSet[i],IconOverrideId[i]. - Писатель XLSX выводит дочерние
<cfIcon>только для точек остановки, которые вызвалиSetIconOverride. Читатель парсит входящие элементы<cfIcon>по позиции. - Известные ограничения: BIFF8 (.xls) CFEX не имеет слота для переопределений по точке; правило с переопределениями, сохранённое в .xls, отображает значение по умолчанию семейства для всех точек.
Версия 2.43.0
- Правила условного форматирования XLSX (.xlsx) теперь делают round-trip ссылок на тематические цвета в элементе
<color>правил Гистограммы и Цветовой Шкалы. Ранее писатель выводил только<color rgb="FFRRGGBB"/>и читатель игнорировал атрибутыtheme/tint. - Новые методы на
TXLSDataBarSpecиTXLSCfValueпереключают слот в режим темы:SetThemeColor(themeId, tint)иClearThemeColor. - Писатель XLSX выводит
<color theme="N"/>, когдаTintточно равен 0.0, или<color theme="N" tint="0.5"/>, когда не равен нулю. - Поведение по умолчанию не изменилось: правила, созданные с существующими точками входа только-RGB, продолжают выводить
<color rgb="..."/>точно так же, как раньше. - Известные ограничения: BIFF8 (.xls) CFEX по-прежнему несёт только RGB-цвет; разрешение тематической палитры книги остаётся за рамками; правила
iconSetне несут элементов<color>.
Версия 2.42.0
- API создания листов-диаграмм BIFF8 получает пятую перегрузку
AddChartSheet, которая принимает массив записейTXLSChartSeriesInfo(Name,Categories,Values). Каждое непустоеNameпишется в субпоток диаграммы как литеральная метка серии через токен PTGtStrвBRAIимени серии (id=2). Excel использует эту метку в легенде и селекторе серий, поэтому многосерийная диаграмма теперь поставляется с надлежащими подписями серий вместо стандартных заполнителей "Series1 / Series2". TXLSChartSeriesInfoреэкспортируется изlxHandleвместе сTXLSChartType, чтобы вызывающие могли построить массив без прямого импортаlxChartBuilder.- Это первая половина Roadmap #10 Фаза 2 (столбчатая диаграмма от конца до конца). Путь имени серии подключён; привязка данных категории и значения (преобразование A1-range строк
CategoriesиValuesв настоящие ссылкиtArea3Dдиапазона ячеек внутри BRAI) остаётся заполнителем — эти два поля принимаются API, но пока не эмитируются в субпоток. Последующий релиз направит их через компилятор формул и таблицу EXTERNSHEET для завершения второй половины Фазы 2.
Версия 2.41.0
- HotXLS получает программное создание листов-диаграмм BIFF8. Новый набор перегрузок
AddChartSheetуSheetsпишет полный субпоток диаграммы в сохранённый файл .xls, тогда как раньше листы-диаграммы можно было сохранить только непрозрачно при load-save round-trip. Четыре перегрузки покрывают обычные точки входа: только имя / имя + тип диаграммы / + заголовок / + заголовок оси категории + заголовок оси значения. ВозвращаемыйIXLSWorksheetпоявляется в коллекцииSheets, получает запись boundsheet листа-диаграммы при сохранении, и Excel открывает его как вкладку диаграммы. - Новое перечисление
TXLSChartTypeвыбирает тип диаграммы:xlsChartTypeColumn,xlsChartTypeBar,xlsChartTypeLine,xlsChartTypePie. Перечисление реэкспортируется изlxHandle, чтобы пользовательский код не должен был импортировать модуль chart-builder напрямую. - Создаваемый субпоток диаграммы покрывает требуемое спецификацией обрамление BIFF8 — BOF (dt=$0020), Chart / PlotGrowth / Frame / Series / SheetProperties / AxesUsed / AxisParent (POS + ось категории + ось значения + PlotArea + Frame + ChartFormat + запись типа + ChartFormatLink + Legend), EOF — так что Excel распознаёт результат как настоящую вкладку диаграммы запрошенного типа. Существующий round-trip через
TXLSCustomChartне изменился. - Это первая часть Roadmap #10 (субпоток CHART — самый большой пункт аудита BIFF8). Фаза 1 предоставляет каркас и API-поверхность, чтобы последующие фазы могли добавить привязку данных серий, заголовки осей и более богатое форматирование по типам.
- Ограничения: новый лист-диаграмма отображает пустую диаграмму по умолчанию запрошенного типа. Привязка данных серий (связывание диаграммы с реальными диапазонами ячеек), заполненный текст заголовка и детальное форматирование по типу (gap width / overlap / hole size / marker style) отложены до последующих фаз. Excel сохраняет и переоткрывает с сохранением присутствия и типа диаграммы, но пока без данных, предоставленных пользователем.
Версия 2.40.0
- Новое демо Delphi XlsCondFormat12 в
Demo/Delphi/XlsCondFormat12/демонстрирует API расширения условного форматирования v2.34.0+ от начала до конца. Три кнопки позволяют генерироватьCondFormat12.xls(бэкенд BIFF8),CondFormat12.xlsx(бэкенд XLSX) или оба бок о бок. Каждый выходной лист несёт одни и те же четыре типа правил — Гистограмма, 3-цветная шкала, Набор значков (3 стрелки) и 2-цветная шкала — охватывая десять строк данных, чтобы открыть файлы в Excel и визуально проверить рендеринг каждого бэкенда. - Путь BIFF8 дополнительно осуществляет переопределение стиля DXF v2.35.0: правило Гистограммы прикрепляет белый жирный цвет шрифта, чтобы текст ячейки оставался читаемым над тёмной заливкой полосы.
- Новая фикстура тестов DUnitX в
Tests/Delphi/HotXLS.CondFormat12Tests.pasохватывает десять сценариев round-trip и поверхности API: round-trip BIFF8 для всех четырёх типов правил, round-trip DXF Style для RGB цветов, тематических цветов и флагов шрифта, и XLSX round-trip для Гистограммы / 3-цветной шкалы / Набора значков с ShowOnly. Фикстура подключена кHotXLSDelphiTests.dprи соответствующему.dproj. - Для поддержки фикстуры тестов
TCondFormatпредоставляет два новых публичных аксессора:RuleCountиRule(I). - Примечание о валидации: откройте
.xlsи.xlsxдемо в Excel, чтобы увидеть четыре правила расширения CF12 / OOXML, отрисованные бок о бок.
Версия 2.39.0
- Переопределение стиля Differential XF (DXF) на правилах условного форматирования теперь поддерживает кодирование тематического цвета в дополнение к существующему режиму RGB. Каждый слот цвета — цвет шрифта, фон заливки, передний план заливки — может быть установлен относительно индекса темы книги плюс значение оттенка.
- Три новых метода на
TXLSDxfStyleвключают слот в режим темы:SetFontColorTheme(themeId, tint),SetFillBgColorTheme(themeId, tint),SetFillFgColorTheme(themeId, tint). Tint — это single в диапазоне [-1.0, +1.0]. Соответствующие существующие методыSetXxxColor(rgb)остаются в режиме RGB; два режима взаимно исключают друг друга для каждого слота. - Запросите активный режим через новые свойства только для чтения
XxxColorIsTheme/XxxColorThemeId/XxxColorThemeTint.HasXxxColorвозвращает True в любом режиме. - Проводной формат BIFF8 следует стандартной разметке XFProp Colour: RGB —
xclrType=2+ 4-байтовое BGR LongWord, режим темы —xclrType=3+ 2-байтовый знаковый tint × 32767 + 4-байтовый индекс темы. Декодер блоба DXF зеркально отражает этот dispatch. - Известные ограничения: round-trip в режиме темы поддерживается только на стороне BIFF8 (.xls) — сторона XLSX (.xlsx) по-прежнему выводит и читает только
<color rgb="..."/>.
Версия 2.38.0
- Чтение XLSX (.xlsx) теперь распознаёт правила расширения условного форматирования Excel 2007+ во входящих файлах — гистограмму, цветовую шкалу (2 и 3 точки, автоматически определяемые из количества cfvo) и набор значков — и заполняет соответствующий объект
TXLSXConditionalFormat, чтобы пользовательский код мог проверять и round-trip-ить эти правила без потери. Ранее .xlsx-книги, сохранённые Excel с этими типами правил, молча отбрасывались при загрузке. - Читатель анализирует обёртку OOXML
<cfRule type="dataBar|colorScale|iconSet">и внутреннее тело<dataBar>/<colorScale>/<iconSet>, обходя дочерние записи<cfvo>для восстановления type и val каждого порога, и записи<color>для восстановления цвета гистограммы или цветов по точке остановки шкалы. - Правила наборов значков round-trip-ят имя семейства
iconSet(17 базовых наборов Excel 2007), флагreverseи флагshowValue(отображённый вShowOnly). - Значения цветов, проанализированные из атрибута OOXML
rgb="AARRGGBB", преобразуются в то же соглашение BGRLongWord, используемое API записи. - Существующая обработка XLSX
<cfRule type="cellIs">не изменилась; диспетчер выбирает новые типы правил только когда атрибутtypeих называет. - Известные ограничения: ссылки на цвета темы читаются как 0; переопределения
iconIdдля каждой точки остановки не захватываются; атрибутpriorityу<cfRule>игнорируется при чтении.
Версия 2.37.0
- Формат записи BIFF8 CFEX теперь несёт полный массив cfvo для каждой точки остановки (kind + строка значения + цвет, согласно семантике cfvo [MS-XLS]) вместо только цвета полосы/остановки. Правила гистограммы теперь сохраняют типы и значения порогов min/max, цветовые шкалы сохраняют комбинацию kind + value + color каждой точки остановки, а наборы значков сохраняют kind + value каждого порога вместе с флагами reverse / showOnly.
- Запись CFEX добавляет байт флага версии (ver=1), чтобы более старые читатели HotXLS, ожидающие минимальный layout CFEX v2.34.0, молча возвращались к устаревшей интерпретации. Читатель v2.37.0 также распознаёт записи ver=0, созданные более старыми сборками.
- Читатель теперь обнаруживает смешанные записи CONDFMT + CONDFMT12 в одном диапазоне — распространённый шаблон в файлах, сохранённых Excel. Более старая запись CONDFMT помечается через новое свойство
IsShadowedнаTCondFormat. Писатель продолжает выводить оба семейства записей при сохранении. - Новое свойство
TotalRangeнаTCondFormatпредоставляет ранее приватный объединённый диапазон. - Известные ограничения: обнаружение тени ограничено точным совпадением ограничивающей рамки. Полный cfvo round-trip ColorScale сохраняет 8 стандартных значений kind, но не сохраняет метаданные оттенка цвета темы Excel.
Версия 2.36.0
- Вывод XLSX (.xlsx) теперь поддерживает три типа правил расширения условного форматирования Excel 2007+ — гистограмма, цветовая шкала (2-stop и 3-stop) и набор значков — приводя бэкенд XLSX в паритет с бэкендом BIFF8 (.xls) из v2.34.0. Четыре новых публичных метода на
TXLSXWorksheetотражают API XLS:AddCondFormatDataBar,AddCondFormatColorScale2,AddCondFormatColorScale3,AddCondFormatIconSet. - Сохранённый файл .xlsx теперь выводит элемент OOXML
<conditionalFormatting>с соответствующей дочерней структурой для каждого типа правила:<cfRule type="dataBar"><dataBar>для гистограмм,<cfRule type="colorScale"><colorScale>с 2 или 3 cfvo + color stops, и<cfRule type="iconSet"><iconSet iconSet="...">с соответствующим набором cfvo. - Встроенное сопоставление имён наборов значков охватывает те же семнадцать базовых наборов Excel 2007, поддерживаемых бэкендом XLS, выводимых как стандартная строка атрибута OOXML
iconSet. - Типы порогов и значения цветов используют то же перечисление и соглашение о цвете, что и API XLS — то же
TXLSCfValueKind, тот же формат Delphi BGRLongWord. Существующие вызовы XLSXAddConditionalFormatпродолжают вести себя идентично. - Известные ограничения: тематическая кодировка цвета ещё не выводится; переопределения
iconIdдля каждой точки остановки в наборах значков не поддерживаются. Распознавание стороны чтения XLSX входящих правил гистограмм / цветовых шкал / наборов значков из файлов, сохранённых Excel, остаётся отложенным — в этом выпуске подключена только запись.
Версия 2.35.1
- Читатель BIFF8 теперь декодирует байты Differential XF (DXF), прикреплённые к правилу CF12, обратно в property bag
TXLSDxfStyleправила, в дополнение к сохранению сырых байтов вDxfBlob. Загрузка книги, сохранённой Excel, со стилизованными правилами гистограммы / шкалы цветов / набора значков теперь предоставляет цвет шрифта, цвета заливки, жирный / курсив / подчёркивание и идентификатор числового формата напрямую через паруHasXxx+значение на каждомRule.Style. - Поведение round-trip: цикл load-edit-save теперь отражает любое изменение
Rule.Styleпосле загрузки. Если пользователь читает книгу, изменяетRule.Style.SetFontColorи сохраняет, новый цвет побеждает; если пользователь не трогает Style, сохранённый файл несёт те же переопределения, что и оригинал. - Неизвестные значения
xfPropTypeв DXF blob пропускаются, а не отклоняются, поэтому более новые файлы Excel, использующие типы свойств, ещё не распознанные этим выпуском, продолжают загружаться (сырые байты остаются вDxfBlobдля проверки или будущей поддержки round-trip).
Версия 2.35.0
- Правила условного форматирования теперь могут нести переопределение стиля Differential XF (DXF), так что правило CF12, срабатывающее в Excel, может изменить цвет шрифта, заливку, насыщенность, курсив, подчёркивание или числовой формат ячейки без изменения базового XF ячейки. Переопределение представлено как новое свойство
TXLSDxfStyleна каждомTCondFormatRule, доступное после создания правила через существующие APIAddCondFormatDataBar/AddCondFormatColorScale*/AddCondFormatIconSet. - Поддерживаемые переопределения стиля в этом выпуске: цвет шрифта, цвет фона заливки, цвет переднего плана заливки, узор заливки, шрифт жирный, шрифт курсив, стиль подчёркивания шрифта, и идентификатор встроенного числового формата. У каждого свойства есть парный флаг
HasXxx— только свойства, явно установленные черезSetXxx, выводятся в файл BIFF8. - Писатель BIFF8 теперь добавляет непустой блок DXF к записи CF12, когда у Style правила установлено хотя бы одно переопределение. Блок DXF использует публичный layout массива XFProp (cxfp + кортежи на каждое свойство тип / размер / данные), позволяя Excel улавливать изменения стиля при применении правила.
- Читатель BIFF8 сохраняет сырые байты DXF из файла, сохранённого Excel, в свойство
DxfBlobправила, поэтому round-trip load-edit-save больше не теряет молча стиль ячейки, переносимый правилами CF12. Декодирование сырых байтов обратно в property bagTXLSDxfStyleзапланировано на последующий выпуск. - Поведение по умолчанию не изменилось для правил, которые не подключают стиль — выводится
cbdxf = 0, идентично v2.34.0, поэтому существующие правила гистограммы / шкалы цветов / набора значков отрисовываются точно так же, как раньше. - Известные ограничения: кодировка тематического цвета для DXF не поддерживается (только RGB); переопределения границ и точки остановки градиента отсутствуют в наборе свойств этого выпуска; порядок байтов для блобов значений XFProp следует публичным заметкам [MS-XLS] и может потребовать небольших корректировок для полной точности round-trip Excel после проверки с помощью BiffView. Паритет стороны XLSX для трёх новых типов правил остаётся отложенным.
Версия 2.34.0
- Новый публичный API условного форматирования на листе для правил расширения Excel 2007+:
AddCondFormatDataBar,AddCondFormatColorScale2,AddCondFormatColorScale3иAddCondFormatIconSet. Каждый метод принимает диапазон sqref вида"A1:A10"плюс параметры, специфичные для типа (цвет полосы, цвета остановок градиента или семейство набора значков), и возвращает созданный объект правила. - Писатель BIFF8 (.xls) теперь выдаёт соответствующие записи CONDFMT12 / CF12 / CFEX наряду с существующими записями CONDFMT / CF по значению ячейки, поэтому книги, созданные через новый API, сохраняют свои правила гистограмм, шкал из 2 или 3 цветов и наборов значков на диске.
- Читатель BIFF8 распознаёт поступающие записи CONDFMT12 / CF12 / CFEX и предоставляет их через ту же модель правил в памяти, так что .xls-файлы, созданные Excel с правилами расширения, больше не отбрасываются молча при загрузке.
- Встроенный каталог наборов значков охватывает семнадцать базовых наборов Excel 2007 (семейства 3 стрелки / 3 флага / 3 светофора / 3 знака / 3 символа, 4 стрелки / 4 оценки / 4 светофора, и 5 стрелок / 5 оценок / 5 четвертей), выбираемых через перечисление
TXLSIconSetType. - Типы порогов для границ гистограммы и точек остановки шкал цвета / наборов значков могут быть число, минимум / максимум диапазона, процент, процентиль или формула, соответствуя типам cfvo Excel.
- Существующее поведение правил по значению ячейки не изменилось; добавлены только новые API и новая обработка записей BIFF8.
- Известные ограничения этой версии: вывод XLSX для трёх новых типов правил пока не подключён (существующие правила XLSX по значению ячейки не затронуты); блок дифференциального стиля XF в CF12 выводится пустым, поэтому Excel может отображать полосы и шкалы цветами по умолчанию вместо цветов, предоставленных API; массивы cfvo для каждой точки остановки в CFEX несут только цвет, а не комбинацию тип / значение. Эти пробелы запланированы для последующих выпусков v2.34.x / v2.35.x вместе с демонстрационной книгой и проверкой рендеринга в Excel.
Версия 2.33.3
- Новый демо Delphi XlsTables в
Demo/Delphi/XlsTables/демонстрирует сторону записи Tables BIFF8 (ListObjects) от начала до конца. Он генерируетSalesTable.xlsс областью продаж из четырех столбцов (Регион / Продукт / Квартал / Выручка), связанной как Table в A1:D10 с использованиемSheet.AddTable('SalesTable', 'A1:D10', headers). Откройте созданный .xls в Excel, чтобы проверить раскрывающиеся списки столбцов, чередующиеся полосы строк и имя структурированной ссылки SalesTable в Поле имени. - Демо — это самый короткий сквозной рецепт для принятия API
AddTablev2.33.0: устанавливаетStyleName = 'TableStyleMedium2'иShowRowStripes = True, заполняет девять строк данных + одну строку заголовка и записывает рабочую книгу одним вызовомSaveAs. Вывод идёт рядом с исполняемым файлом. - Инфраструктура компиляции не изменилась: существующий
build-Win32-Demo.cmdавтоматически подхватываетXlsTables.dprчерез свой обходfor /r Demo *.dpr— никаких изменений в сценариях сборки или конфигурациях .cbproj/.dproj не требуется.
Версия 2.33.2
- BIFF8 (.xls)
SaveAsтеперь подавляет автономные записи на уровне листаAUTOFILTERINFO/AUTOFILTER($009D / $009E), когда Table на том же листе полностью покрывает диапазон автофильтра. Excel встраивает раскрывающийся список автофильтра внутрь самого объекта Table, поэтому выпуск дополнительного автофильтра на уровне листа для идентичного диапазона приводит к отклонению файла валидацией файлов Office. Это соответствует исправлению на стороне XLSX, поставленному в v2.29.4. - Проверка покрытия консервативна: Table считается "покрывающей" автофильтр только когда её первая/последняя строка и первый/последний столбец охватывают границы автофильтра. Частичное перекрытие сохраняет поведение выпуска автофильтра на уровне листа.
- Сохранения BIFF5 и рабочие листы без таблиц не затронуты — проверка подавления выполняется только когда формат файла — BIFF8 и рабочий лист содержит хотя бы одну Table. Изменений в публичном API нет.
Версия 2.33.1
- Сторона чтения BIFF8 (.xls) теперь распознает записи Tables общих функций, которые v2.33.0 добавила на стороне записи. Открытие .xls, сохраненного Excel (или самим HotXLS) с одним или несколькими ListObjects/Tables, теперь заполняет коллекцию
Tablesрабочего листа объектомTXLSTableдля каждой проанализированной записи FEAT11 ($0872), восстанавливая диапазон таблицы из первичного Ref8U, восстанавливая id, имя и имя отображения таблицы при их наличии, и заполняя имя стиля таблицы из парной записи LIST12 ($0877). Ранее эти записи молча игнорировались. - Общий opcode FEATHEADR ($0867) теперь распределяется по полю
Isfвместо того, чтобы всегда направляться в парсер защиты. Isf=2 (Расширенная защита) сохраняет существующее поведение; Isf=4 (SharedList) распознается как маркер для Tables на листе; Isf=3 (SmartTags) и другие значения безопасно игнорируются. FEATHEADR11 ($0871) также молча распознается как маркер Tables. - Читатель работает в режиме наилучшего усилия и толерантен: неправильно сформированные или варианты Excel полезные нагрузки FEAT11 элегантно деградируют до Table, которая имеет хотя бы правильный диапазон ячеек. Защита листа round-trip не изменилась.
Версия 2.33.0
- Рабочие листы BIFF8 (.xls) теперь поддерживают объекты Table (Excel ListObject). Вызовите
Worksheet.AddTable(Name, Range, Columns)наIXLSWorksheet, чтобы прикрепить именованную область таблицы к диапазону ячеек — например,Sheet.AddTable('SalesTable', 'A1:F9', HeaderList). Путь сохранения .xls теперь генерирует семейство записей общих функций BIFF8, помечающих лист как содержащий Table: FEATHEADR ($0867 с Isf=4), FEATHEADR11 ($0871) и пару FEAT11 ($0872) + LIST12 ($0877) на каждую таблицу. Ранее вызовAddTableна фасаде XLS был недоступен; таблицы, определенные на рабочем листе, молча отбрасывались приSaveAs(xlExcel97). - Новый публичный API в
IXLSWorksheet: свойствоTables: TXLSTables(коллекция только для чтения) и методAddTable. Форма зеркально отражаетTXLSXTable/TXLSXTablesна стороне XLSX.TXLSTableпредоставляетId,Name,DisplayName,Range,Columns,StyleName(по умолчанию'TableStyleMedium2'),ShowFirstColumn,ShowLastColumn,ShowRowStripes(по умолчанию true),ShowColumnStripesиTotalsRowShown. - Новые записи потока листа испускаются непосредственно перед EOF рабочего листа, после защиты листа, только когда формат файла — BIFF8 (
xlExcel97). Рабочие книги без таблиц сохраняются точно так же, как и раньше — FEATHEADR не испускается, изменений в потоке записей нет, накладных расходов нет. Сохранения BIFF5 не затрагиваются. - ID таблиц назначаются последовательно для каждого листа (1..N) во время сохранения, если не были предварительно установлены. Имя стиля по умолчанию
'TableStyleMedium2'совпадает с тем, что уже используют Excel и сторона XLSX. - Известные ограничения этого первоначального выпуска (v2.33.0): формулы строки итогов и вспомогательные диапазоны структурированных ссылок еще не испускаются; подавление конфликта между
AUTOFILTERINFOна уровне листа и диапазоном Table будет добавлено в последующем релизе; сторона чтения (разбор сохраненного Excel-ом .xls с таблицами обратно в коллекциюTables) также является последующим релизом.
Версия 2.32.1
- Исправлена ошибка компиляции, появившаяся в функции записи FILEPASS версии v2.32.0, которая препятствовала сборке библиотеки в RAD Studio 12+ со строгой проверкой типов. Помощник
EncryptAllBlobsобъявлял свой буфер рассеяния какPByteв контексте, гдеPByteразрешался в локальный псевдонимlxHandle, тогда как целевой вызовEncryptBlobDataвlxEncrypterожидалlxBLOB.PByte. Хотя оба типа являются псевдонимами для^Byte, Delphi рассматривает их как различные при строгой проверке типов E2010. Теперь переменная буфера полностью квалифицирована какlxBLOB.PByte, поэтому путь шифрования паролем v2.32.0 чисто компилируется во всех поддерживаемых версиях RAD Studio (12.0–37.0).
Версия 2.32.0
- Новое свойство
EncryptionPasswordвIXLSWorkbook. Установка непустого пароля передSaveAsтеперь создаёт совместимый с Excel защищённый паролем .xls файл: Excel, LibreOffice Calc и другие BIFF8-читатели запрашивают пароль при открытии и отказывают в доступе при неверном пароле. Ранее установщик пароля молча игнорировался на стороне записи. - Путь записи выводит запись BIFF8 FILEPASS ($002F) сразу после BOF книги и шифрует RC4 каждое последующее тело записи тем же алгоритмом, что и сторона чтения (vMajor=1, vMinor=1 -- шифрование "Office 97/2000 Compatible" от Excel). 16-байтовые Salt и Verifier генерируются через Windows
CryptGenRandom, а не через PascalRandom. Повторная деривация ключа блока на каждой границе 1024 байт сохранена. - Шифрование применяется только к BIFF8 (
xlExcel97); путь BIFF5 остаётся в открытом виде. ПустойEncryptionPasswordсохраняет прежнее поведение открытого текста (по умолчанию), существующие приложения не затронуты. - Сторона чтения: исправлена скрытая ошибка в
ParseFilePass, из-за которой первое тело записи после FILEPASS (обычно CODEPAGE) обрабатывалось как открытый текст. Зашифрованные файлы, записанные HotXLS, теперь корректно проходят туда-обратно через HotXLS. - Примечание безопасности: BIFF8 RC4 (vMajor=1/vMinor=1) использует 40-битный ключ, считающийся взломанным по стандартам 2025 года. Используйте эту функцию для совместимости с классическим интерфейсом защиты паролем Excel, а не для конфиденциальности чувствительных данных. Для реальной безопасности предпочитайте XLSX + AES.
Версия 2.31.0
- В
IXLSWorkbookдобавлено свойствоUseSharedFormulas. При значенииTrueметод SaveAs в формате BIFF8 группирует ячейки с эквивалентными формулами-шаблонами в нативные записи SHRFMLA ($04BC), соответствуя компактному формату Microsoft Excel. Столбцы формул вида=A1*B1,=A2*B2, …,=A99*B99группируются автоматически, уменьшая размер файла на 30–60 % на листах с большим количеством однотипных формул. - Группировка выполняется по столбцу вниз, последовательно, на основе шаблона: группируются только ячейки одного столбца с последовательными строками и PTG-эквивалентными формулами. Ячейки с формулами массива или флагами объединения исключаются.
- Значение по умолчанию —
False, прежняя посячейная запись FORMULA-записей остаётся без изменений. Для включения установитеWorkbook.UseSharedFormulas := Trueперед вызовомSaveAs. - Сторона чтения не затронута. Это MINOR-обновление версии (2.30.x → 2.31.0): добавлено новое публичное свойство, и при включённой функции меняется формат вывода BIFF8.
Версия 2.30.6
- Исправлен четвёртый класс ошибок компиляции в демонстрационных проектах C++Builder под компилятором bcc32 на основе clang в RAD Studio 37.0: паттерн индексации
->Borders[idx]->Propпо умному указателю интерфейса вызывал ошибку E5843 ("тип ссылки на член не является указателем"). Все вхождения изменены на->Borders->Item[idx]->Prop. Исправление затрагивает демо-проекты ApiTour, ExportWithColoring, PurchaseOrder и QuickStart и завершает полную совместимость с компилятором clang для всех девяти демо-проектов C++Builder.
Версия 2.30.5
- Все девять демонстрационных проектов C++Builder теперь успешно компилируются под компилятором bcc32 на основе clang в RAD Studio 37.0. Исправлены три класса ошибок компиляции: свойство
EOFвlxFormulaпереименовано вIsEofдля устранения конфликта с макросом Cstdio.h; константы перечисления XLS API (xlHAlignCenter,xlAround,xlMediumи др.) в демонстрационном коде C++Builder теперь явно квалифицированы пространством имёнLxhandle::; присваивание значений ячеек XLSX изменено сOleVariant(...)наVariant(...), посколькуTXLSXCell.Valueимеет типSystem::Variant, а компилятор clang отклоняет неявное преобразование из защищённой базовой классOleVariant.
Версия 2.30.4
- Демо OrderCalc (пример заказа на покупку для Delphi) теперь включает опцию экспорта в XLSX наряду с существующими форматами XLS, HTML и RTF. При выборе «Excel 2007+ (*.xlsx)» в диалоге сохранения заказ записывается через нативный API TXLSXWorkbook, создавая напрямую стандартный XLSX-файл со шрифтами, заливками, рамками, выравниванием, числовыми форматами и формулами Excel.
Версия 2.30.3
- SaveXLSWorkbookAsXLSX (мост, используемый TDataToXLS.SaveAs и TGridToXLS.SaveAs, когда имя целевого файла оканчивается на .xlsx) теперь копирует цвета заливки фона ячеек, цвета шрифта и атрибуты стиля шрифта (имя, размер, жирный, курсив) из базовой рабочей книги XLS в выходной файл XLSX. Ширины столбцов — включая намеренно узкие декоративные столбцы — также копируются. Ранее передавались только значения и числовые форматы, поэтому выходной файл XLSX был без форматирования, все ширины столбцов имели значения по умолчанию, а любой намеренно узкий декоративный столбец выглядел как увеличенный пустой столбец.
Версия 2.30.2
- Исправлена ошибка round-trip в читателе XLS, при которой направление Outline.SummaryRow инвертировалось после Open. Флаг fRwSumsBelow в записи WSBOOL (спецификация BIFF8 p278 byte 0 bit 6, маска $0040) означает «итоговые строки находятся *под* подробностями», но ранее парсер устанавливал SummaryRow = xlAbove, когда бит был установлен (и xlBelow, когда сброшен) -- ровно наоборот относительно спецификации. Сторона писателя уже была правильной (выдаёт $0040 для xlBelow), поэтому открытие Excel-файла с «итоговыми строками под подробностями» и его повторное сохранение через HotXLS молча переворачивало направление outline на «над». Теперь направление парсинга соответствует спецификации и писателю, поэтому конфигурации outline корректно проходят round-trip. fColSumsRight ($0080) уже обрабатывался правильно и не изменялся.
Версия 2.30.1
- Писатель XLS (BIFF8) теперь выдаёт записи INTERFACEHDR / INTERFACEEND / WRITEACCESS в секции globals рабочей книги, соответствуя нативному расположению записей Microsoft Excel. Нативный Excel всегда пишет эту тройку между CODEPAGE/DSF и WINDOW1, и более строгие читатели BIFF / пути Office File Validation могут их ожидать. INTERFACEHDR несёт code page (1200, UTF-16), INTERFACEEND — пустой маркер, а WRITEACCESS несёт имя пользователя «сохранил» (в настоящее время жёстко задано как "HotXLS"; в будущем выпуске оно может быть продвинуто в свойство Workbook). Выходные XLS-файлы теперь более точно соответствуют нативному байтовому расположению Excel.
Версия 2.30.0
- Добавлен мост экспорта classic-в-XLSX. TDataToXLS.SaveAs и TGridToXLS.SaveAs теперь записывают имена файлов .xlsx через движок XLSX, сохраняя без изменений существующие пути .xls, .html и .rtf.
- Добавлены API представления рабочего листа для XLS и XLSX. IXLSWorksheet.View и TXLSXWorksheet.View поддерживают обычное представление, предварительный просмотр разрывов страниц и представление макета страницы, и настройка сохраняется соответствующим путём писателя/читателя файлов.
- Добавлены классические API совместимости рабочей книги: IXLSWorkbook.SetCodePage и IXLSWorkbook.VBAProject. Проекты VBA теперь можно инспектировать через имена модулей TXLSVBAProject/TXLSVBAModule и исходный текст, когда рабочая книга содержит хранилище VBA.
- TXLSXWorkbook расширен ParsedVBAProject — представлением только для чтения, разобранным над валидной полезной нагрузкой vbaProject.bin, при этом сохраняется существующее поведение round-trip сырых байтов VbaProject.
- Добавлен опциональный unit cxGridAddExcel для рабочих процессов экспорта DevExpress cxGrid. Он намеренно не включён в пакеты по умолчанию, чтобы установки без DevExpress продолжали собираться без ошибок.
- Исправлен рендеринг листов диаграмм XLSX, при котором диаграмма выглядела пустой при открытии рабочей книги в Excel (только что открытый лист диаграммы кратко показывал 3 значка контекста диаграммы в правом верхнем углу, а затем сбрасывал их, оставляя лист пустым). Чертежи листов диаграмм теперь используют <xdr:absoluteAnchor> с явным размером (~10in × 7.2in = 9525000 × 6858000 EMU) вместо <xdr:twoCellAnchor> с cx=0/cy=0; листы диаграмм не имеют сетки ячеек, относительно которой можно было бы разрешить twoCellAnchor, поэтому Excel откатывался на внутренний xfrm нулевого размера и рендерил диаграмму с нулевым числом пикселей. Согласно ECMA-376-1 14.2.3.2, чертежи листов диаграмм должны использовать absoluteAnchor. Якоря диаграмм рабочих листов не изменены.
Версия 2.29.4
- Исправлена ошибка упаковки XLSX, которая вызывала окно восстановления Excel «Обнаружена проблема с некоторым содержимым в <file>.xlsx» в рабочих книгах, где autoFilter уровня листа и Таблица покрывали один и тот же диапазон (например, лист Details из XlsxFeatureGallery.xlsx демонстрации MemoryDataExport, который вызывал AddTable('SalesTable', 'A1:F9', ...) с последующим SetAutoFilter('A1:F9')). OOXML запрещает два механизма фильтрации на одном диапазоне; писатель теперь подавляет дублирующую эмиссию <autoFilter> на уровне листа, когда его диапазон совпадает с диапазоном любой таблицы. Собственный autoFilter Таблицы (отображаемый как раскрывающиеся списки в заголовке таблицы) продолжает работать.
- Исправлено связанное нарушение схемы в выводе <dataValidation>: атрибут operator выдавался для каждой валидации, но ECMA-376-1 18.3.1.32 разрешает его только для типов whole / decimal / date / time / textLength. AddListValidation создаёт type="list", который ранее «утекал» с operator="between"; OFV строже Excel в этом отношении и мог отклонить рабочую книгу. Атрибут operator теперь опускается для list / custom / none.
- Исправлен элемент <legacyDrawing r:id="..."/> на листах, в которых смешаны внутренние и внешние гиперссылки с комментариями (лист Dashboard XlsxFeatureGallery.xlsx содержит 1 внутреннюю + 1 внешнюю + 1 комментарий). Подсчёт rId считал все гиперссылки вместо только внешних (внутренние используют встроенный атрибут location= и не потребляют rId), поэтому legacyDrawing указывал на целевой rels комментариев вместо vmlDrawing. ECMA-376-1 18.3.1.51 требует, чтобы legacyDrawing ссылался на rels типа vmlDrawing. Теперь rId вычисляется только из числа внешних гиперссылок.
- Также прекращена эмиссия избыточного файла xl/worksheets/_rels/sheetN.xml.rels для листов с диаграммами, добавленных через AddChartSheet. Дублирующий файл отношений указывал на несуществующую часть листа и появлялся как «сирота» внутри zip .xlsx; листы с диаграммами теперь записывают только корректный xl/chartsheets/_rels/sheetN.xml.rels.
- Обновлён демо MemoryDataExport (XlsxFeatureGallery), чтобы убрать избыточный вызов SetAutoFilter('A1:F9') на листе Details -- AddTable уже прикрепляет autoFilter к диапазону таблицы, поэтому дополнительный вызов ранее вызывал указанный выше отказ OFV. Защитное подавление в писателе покрывает клиентский код, который не получил обновление демо.
Версия 2.29.3
- Исправлена регрессия round-trip XLSX, при которой границы, нарисованные на иначе пустых строках, терялись после Open + modify + SaveAs. Горизонтальный разделитель строки 8 ApiTour (создаваемый вызовом Range.SetBorders на строке без данных) корректно отображался в свежесгенерированном ApiTour.xlsx, но исчезал в ApiTour-XLSX-Modified.xlsx после того, как этап Modify демо повторно сохранял файл, оставляя Excel показывать сломанную вертикальную линию сетки в C8 / D8 только в изменённом файле (оригинальный ApiTour.xlsx не затрагивался). Парсер XLSX теперь также применяет стили ячеек, когда элемент `<c>` является самозакрывающимся или не имеет дочерних элементов value/formula, поэтому стилизованные ячейки без значения переживают round-trip.
Версия 2.29.2
- Исправлена регрессия round-trip XLSX в потоках Open + modify + SaveAs. Когда ParseWorksheetXml читал ячейку, чей <c s="N"/> ссылался на cellXf из styles.xml, он сохранял N напрямую в cell.FormatIndex. При SaveAs cellXfs перестраиваются из пулов стилей рабочей книги (с опциональными составными записями), и слот нового макета на том же числовом индексе почти никогда не несёт ту же семантику; пересохранённая ячейка указывала на неверный cellXf -- или за пределы новой таблицы cellXfs -- и Excel сообщал «Office обнаружил проблему с этим файлом. Можно попробовать восстановить его». ApplyStyle теперь обратно отображает cellStyle на FontIndex / FillIndex / BorderIndex / NumberFormatIndex / AlignmentIndex / ProtectionIndex через таблицы CellXfXxxMap, которые ParseStylesXml уже заполняет, поэтому round-trip заново выдаёт ячейку относительно свежепостроенных cellXfs.
Версия 2.29.1
- Исправлены две регрессии рендеринга XLSX, выявленные демо ApiTour: (1) ячейки внутри строки могли выдаваться вне порядка столбцов, когда вызов Range.SetBorders добавлял ячейки в немонотонном порядке (например, этап outline создаёт A8/C8, этап inside создаёт B8 -- вывод был A8 / C8 / B8 / вместо A8 / B8 / C8 / поэтому Excel сообщал «Office обнаружил проблему с этим файлом» и принудительно включал Protected View). Писатель XLSX теперь сортирует ячейки каждой строки по столбцам перед эмиссией, соответствуя схеме OOXML CT_Row. (2) Ячейки, в которых одновременно устанавливалось 2 или более индексов стиля (Font + Fill + Border и т. д.), сжимались в одномерный cellXf через цепочку приоритетов (FontIndex побеждал, Border / Fill отбрасывались), поэтому, например, строка заголовка с FontIndex + FillIndex + BorderIndex, установленными вызовом Range[..].SetBorders, отображалась без границ. Писатель теперь собирает составной пул cellXf во время SaveAs и направляет многомерные ячейки в синтезированный cellXf, который сохраняет каждое измерение.
Версия 2.29.0
- Внутренний вспомогательный unit `lxList2` переименован в `lxKeyList`, а классы `lxList` с ключом WideString переименованы из `TXLSKeyList` / `TXLSKeyEntry` / `TXLSKeyArray` в `TXLSStringKeyList` / `TXLSStringKeyEntry` / `TXLSStringKeyArray`, чтобы имя unit соответствовало его основному классу `TXLSObjectKeyList`, а два поколения key-list были самоописательными (`TXLSStringKey*` для устаревшего пула с ключом WideString, `TXLSObjectKey*` для пула дедупликации на основе THashtableKey). Если ваш код ссылается на старое имя unit или имена классов, обновите предложения uses и имена типов соответственно.
Версия 2.28.3
- Исправлена регрессия эмиссии ячеек XLSX, из-за которой границы, установленные на иначе пустых строках, исчезали. `Range[''A3:C10''].SetBorders(xlsxEdgeOutline,...)` на листе, в котором строка 8 не содержала данных, ранее отображала вертикальную линию сетки C/D разорванной в этой строке, поскольку писатель пропускал любую ячейку, в которой Value не было присвоено -- даже если ячейке был присвоен BorderIndex / FontIndex / FillIndex / NumberFormatIndex / AlignmentIndex / ProtectionIndex. Писатель теперь выдаёт `<c r='..' s='..' />` для ячеек без значения, которые несут любой индекс стиля.
Версия 2.28.2
- Исправлено нарушение схемы листа XLSX, из-за которого Excel отказывался загружать листы, в которых сочетались объединённые ячейки и AutoFilter. Писатель XLSX теперь выдаёт элемент <autoFilter> перед <mergeCells>, соответствуя последовательности OOXML CT_Worksheet (autoFilter — #11, mergeCells — #15). Ранее такие рабочие книги вызывали диалог восстановления Excel с `Load error. Line 1, column 0` на sheet1.xml, и восстановление также удаляло tableParts / autoFilter с соседних листов Details.
Версия 2.28.1
- Добавлены удобные API для классического интерфейса XLS. Теперь IXLSRange предоставляет помощники только для чтения Width и WidthInPixels, а также SaveAsCSV(FileName); IXLSWorksheet и IXLSWorkbook предоставляют перегрузки SaveAsCSV(FileName / Stream) для указанного диапазона или активного листа; IXLSPageSetup предоставляет Order, Draft, BlackAndWhite, PrintNotes и только для чтения IsFitToPages. Теперь при сохранении/открытии записи SETUP сохраняются эти флаги печати.
Версия 2.28.0
- Добавлен экспорт в формат RTF для TXLSXWorkbook. Новые перегрузки SaveAsRTF (FileName / Stream x default-active-sheet / explicit SheetIndex) записывают выбранный лист как документ RTF 1.6, содержащий простую таблицу. Ширина столбцов определяется данными ColWidth листа (1 единица Excel соответствует примерно 96 RTF twips); столбцы без явной ширины используют StandardWidth, если он задан, в противном случае - 809 twips (примерно 8.43 символа). Форматирование ячеек (полужирный, курсив и размер шрифта) применяется из FontIndex ячейки. Не-ASCII символы кодируются как RTF \\uN? unicode escapes в соответствии с RTF 1.6 §2.4.2, охватывая весь диапазон BMP. Объединенные ячейки не охватываются — содержимое отображается в исходной ячейке, а остальные ячейки в диапазоне отображаются как пустые. Значение SheetIndex по умолчанию записывает активный лист; значение вне диапазона возвращает -1. Пустые листы создают минимальный допустимый документ RTF.
Версия 2.27.0
- Добавлен экспорт в HTML для TXLSXWorkbook. Новые перегрузки SaveAsHTML (FileName / Stream x default-active-sheet / explicit SheetIndex) записывают выбранный лист как HTML-документ в кодировке UTF-8 с BOM. Результатом является одна таблица <table> внутри минимальной HTML-страницы. Объединенные ячейки отображаются как атрибуты colspan / rowspan. Форматирование ячеек отображается как встроенные CSS: шрифт, размер (pt), полужирный (font-weight:bold), курсив (font-style:italic), перечеркивание (text-decoration:line-through) и явный цвет шрифта; однотонная заливка отображается как background-color; горизонтальное выравнивание (слева / по центру / справа / по ширине) и WrapText (white-space:pre-wrap). Значения дат отображаются как 'yyyy-mm-dd hh:nn:ss'; ячейки с расширенным текстом преобразуются в объединенный текст. Цвета темы игнорируются (файл theme1.xml не используется в простом экспорте в HTML). Значение SheetIndex по умолчанию записывает активный лист; значение вне диапазона возвращает -1.
Версия 2.26.0
- Добавлена поддержка цветовых тем, индексных цветов и оттенков/нюансов для TXLSXFont, TXLSXFill и TXLSXBorderEdge. Каждый цветовой слот теперь содержит три новых поля, помимо существующего RGB-цвета: ColorTheme (целое число; -1 = не задано; 0..11 = слот цветовой темы OOXML), ColorIndex (целое число; -1 = не задано; 0..63 = слот палитры OOXML устаревшего формата — сопоставляется с Workbook.IndexedColor[N] и XlsxDefaultIndexedPalette) и TintAndShade (дробное число в диапазоне [-1.0, 1.0]; выводится только при использовании темы). TXLSXFill предоставляет варианты Foreground (передний план) и Background (задний план) для всех трех. Приоритет при сохранении: тема > индексный > RGB; старый путь "ColorIsAuto = True" по-прежнему подавляет элемент. Функции SaveAs и Open сохраняют и восстанавливают полные атрибуты <color theme="N" tint="..."/> и <color indexed="N"/> для цветов шрифта, заливки и границ. Для учета: TXLSXBorders.LookupOrAdd теперь сравнивает все три новых поля, чтобы цветные границы, использующие тему, не конфликтовали с записями, использующими RGB, в пуле.
Версия 2.25.0
- Добавлена поддержка двусторонней работы со ссылками на внешние книги. Новые типы: TXLSXExternalLink (целевой URL + список имен листов) + коллекция TXLSXExternalLinks. Свойство TXLSXWorkbook.ExternalLinks предоставляет доступ к коллекции; метод Add(Target) добавляет новую ссылку, которую вызывающий код заполняет. Функция SaveAs создает блок <externalReferences> на уровне книги в файле xl/workbook.xml, запись externalLink в файле xl/_rels/workbook.xml.rels (в конце диапазона rid, чтобы существующие rid оставались стабильными), файл xl/externalLinks/externalLink{N}.xml для каждой записи (<externalBook><sheetNames>) и связанный с ним файл .rels, указывающий на URL удаленной книги с TargetMode="External", а также соответствующие ContentType Overrides. Функция Open сканирует пары externalLink{N}.xml + .rels, начиная с индекса 1 и останавливается при первом пропуске. В текущей версии поддерживается только целевой URL и список имен листов; значения ячеек, хранящиеся в <sheetDataSet>, не сохраняются.
Версия 2.24.0
- Добавлена функция `TXLSXRange.SetBorders` для создания сложных границ. Новый перечисляемый тип `TXLSXBorderEdgeKind` (xlsxEdgeAll / Outline / Inside / InsideHorizontal / InsideVertical / Top / Bottom / Left / Right / DiagonalUp / DiagonalDown) позволяет выбирать, какие грани записывать. `SetBorders(Kind, Style, Color)` / `SetBorders(Kind, Style)` (по умолчанию - непрозрачный черный) перебирает каждую ячейку в диапазоне, вычисляет маску грани для каждой ячейки (угловые ячейки получают две внешние грани, граничные ячейки - одну, внутренние ячейки - внутренние линии сетки), комбинирует `Style` + `Color` с клоном текущей границы ячейки (поэтому последовательные вызовы `Outline + Inside` добавляются, а не перезаписывают), затем выполняет поиск или добавление на уровне книги в `Workbook.Borders` и записывает полученный индекс границы (1-based) обратно в ячейку. Новая функция `TXLSXBorders.LookupOrAdd` возвращает 0 для пустых границ, чтобы избежать ненужных записей в пуле.
Версия 2.23.0
- Добавлены перегруженные функции экспорта в CSV для `TXLSXWorkbook`. Новые точки входа: `SaveAsCSV(FileName) / SaveAsCSV(FileName, SheetIndex, Delimiter) / SaveAsCSV(Stream) / SaveAsCSV(Stream, SheetIndex, Delimiter)` записывают заполненную область выбранного листа в кодировке UTF-8 с начальным BOM и символами конца строки CRLF. Варианты по умолчанию выбирают активный лист и запятую в качестве разделителя; перегруженные варианты `SheetIndex/Delimiter` принимают любой `WideChar` (обычно табуляция #9 для TSV). Заключение полей соответствует RFC 4180 - значения, содержащие разделитель, двойную кавычку, CR или LF, заключаются в кавычки, а встроенные кавычки удваиваются. Значения даты отображаются как 'yyyy-mm-dd hh:nn:ss'; ячейки с форматированным текстом преобразуются в объединенный текст; пустые ячейки во внутренней области ограничивающей рамки отображаются как просто разделители, и строка заканчивается на последней заполненной колонке.
Версия 2.22.0
- Добавлены переопределения цветовой палитры на уровне книги для `TXLSXWorkbook`. Новые точки входа: `IndexedColor[Index: Integer]: LongWord` (чтение/запись, допустимые слоты 0..63, LongWord в формате ARGB), `HasCustomIndexedColor(Index): Boolean` (возвращает, был ли слот переопределен вызывающим), `CustomIndexedColorCount: Integer` (количество переопределенных слотов; 0 = палитра выводится как стандартная), `ResetIndexedColors: procedure` (отбрасывает все переопределения). Новая константа `XlsxDefaultIndexedPalette` предоставляет стандартную палитру ECMA-376 для слотов 0..63. `SaveAs` выводит `<colors><indexedColors>` со всеми 64 дочерними элементами `<rgbColor>` только в том случае, если хотя бы один слот был переопределен; нетронутые слоты используют палитру по умолчанию, поэтому файлы, сохраненные без изменений, остаются чистыми. `Open` анализирует этот блок и молча отбрасывает слоты, значения которых совпадают со значениями по умолчанию, чтобы обеспечить минимальную обработку. Недопустимые значения слотов (меньше 0 или больше 63) отбрасываются вместо вызова исключения.
Версия 2.21.0
- Добавлены шесть свойств отображения для TXLSXWorksheet: Zoom: Целое число, определяющее процент масштабирования, отображаемый в строке состояния Excel (от 10 до 400, по умолчанию 100; значения вне диапазона обрезаются при записи). DisplayGridLines / DisplayZeros: Булевы значения (по умолчанию True), скрывающие линии сетки ячеек или отображающие ячейки со значением 0 как пустые, если установлено значение False. DisplayRightToLeft: Булево значение (по умолчанию False), меняющее ориентацию листа на право-лево для арабского/еврейского и других языков. StandardWidth / StandardHeight: Число с плавающей точкой, устанавливающее ширину столбца (единицы символов Excel) / высоту строки (пункты); 0 означает, что значение не установлено, в этом случае Excel применяет свои значения по умолчанию 8.43 / 15. При сохранении SaveAs генерирует теги <sheetView showGridLines / showZeros / rightToLeft / zoomScale> и <sheetFormatPr defaultColWidth / defaultRowHeight> только в том случае, если значения отличаются от значений по умолчанию Excel; Open считывает их. Существующая обработка закрепленных панелей и выбранных вкладок в <sheetView> не изменена и теперь использует один и тот же механизм записи.
Версия 2.20.7
- Добавлены перегрузки TStream для TXLSXWorkbook для сериализации в памяти. Новые точки входа: SaveAs(Stream: TStream) / SaveAs(Stream: TStream; FileFormat: TXLSXFileFormat) записывают весь пакет .xlsx в указанный поток, начиная с текущей позиции; Open(Stream: TStream) считывает его. Вызывающий код владеет потоком и должен освободить его. Полезно для HTTP-ответов, хранилищ BLOB, конвейеров в памяти и модульных тестов, которые обходят локальную файловую систему. Существующие перегрузки SaveAs / Open, основанные на файлах, не изменены и теперь используют одни и те же внутренние помощники для записи / чтения.
Версия 2.20.6
- Добавлены свойства Hidden / Visible / Comment для TXLSXDefinedName. Hidden соответствует атрибуту OOXML <definedName hidden="1"> (по умолчанию False / Visible=True; True скрывает имя из интерфейса "Диспетчер имен" Excel). Visible - это псевдоним типа Boolean (обратное значение Hidden) для более понятного кода. Comment соответствует тегу <definedName comment="...">. SaveAs генерирует оба атрибута только в том случае, если они отличаются от значений по умолчанию; Open считывает их. SheetIndex (существующая привязка к локальной области через localSheetId) не изменена.
Версия 2.20.5
- Добавлено пять дополнительных атрибутов шрифта в TXLSXFont. Новый перечислитель TXLSXFontVertAlign (xlsxVertAlignBaseline / Superscript / Subscript) управляет существующими в Excel флажками "Superscript" / "Subscript" с помощью одного свойства VertAlign (взаимно исключающие в пользовательском интерфейсе). Новые свойства OutlineFont и Shadow типа Boolean для соответствующих эффектов шрифта в Excel. Новый тип Integer Family (номер семейства шрифтов OOXML: 1=Roman / 2=Swiss / 3=Modern / 4=Script / 5=Decorative; 0=не задано) и CharSet (номер кодовой страницы GDI: 0=ANSI / 1=Default / 134=GB2312 / 136=ChineseBig5 / и т.д.; -1=не задано). Метод SaveAs создает соответствующие дочерние элементы <vertAlign> / <outline/> / <shadow/> / <family> / <charset> внутри элемента <font>; метод Open считывает их. ColorIndex / ThemeColor / TintAndShade будут реализованы в будущей версии, посвященной темам.
Версия 2.20.4
- Добавлены переключатели направления диагональных линий границы. TXLSXBorder теперь предоставляет свойства DiagonalUp: Boolean и DiagonalDown: Boolean. Оба флага используют существующий стиль и цвет диагональной линии и определяют, какую диагональную линию(ии) Excel отображает: только вверх (снизу слева вверху справа), только вниз (сверху слева внизу справа) или обе. Метод SaveAs создает атрибуты diagonalUp / diagonalDown для элемента <border>, когда они установлены; метод Open считывает их. Ранее движок записывал одну диагональную линию без контроля направления, поэтому Excel никогда не рисовал ни одну из диагональных линий.
Версия 2.20.3
- Добавлена опция Date1904 для рабочей книги. TXLSXWorkbook теперь предоставляет свойство Date1904: Boolean, которое позволяет выбирать между эпохой Windows 1900 (по умолчанию; соответствует Excel для Windows) и эпохой Mac 1904 (устаревший формат Excel для Mac). Метод SaveAs создает <workbookPr date1904="1"/> в файле xl/workbook.xml, когда эта опция включена; метод Open считывает ее. Этот флаг является только метаданными — движок не преобразует сохраненные значения; вызывающий код должен установить Date1904 перед присваиванием значений ячейкам типа TDateTime, чтобы обеспечить правильное отображение даты при сохранении и открытии.
Версия 2.20.2
- Добавлена поддержка автоматической фильтрации по критериям для каждого столбца. Новые типы: TXLSXAutoFilterOp (Equal / NotEqual / GreaterThan / LessThan / GreaterOrEqual / LessOrEqual), TXLSXAutoFilterColumn (ColId + 1 или 2 критерия + соединитель AND/OR), TXLSXAutoFilterColumns. TXLSXWorksheet предоставляет свойство AutoFilterColumns и удобные методы AddAutoFilterColumn(ColId, Op, Criteria) / AddAutoFilterColumn(ColId, Op1, Criteria1, Op2, Criteria2, AndConnector) / ClearAutoFilterColumns. SaveAs расширяет существующий тег <autoFilter ref="..."/> в тело <filterColumn colId=N><customFilters and=0|1><customFilter operator="..." val="..."/>...</customFilters></filterColumn> для каждого столбца, когда заданы критерии; Open парсит ту же структуру. Ранее движок хранил только диапазон автоматической фильтрации (sqref), и Excel отображал пули выпадающих списков фильтров.
Версия 2.20.1
- Добавлена поддержка ручных переносов на страницу на TXLSXWorksheet. Новые элементы: AddRowBreak(BeforeRow) / AddColBreak(BeforeCol) для вставки горизонтального или вертикального переноса на новую страницу перед указанной строкой/столбцом (семантика интерфейса Excel "Before" — строка N начинается с новой страницы). Методы проверки: HasRowBreak / HasColBreak; методы удаления: RemoveRowBreak / RemoveColBreak (удаляет один элемент); методы массового удаления: ClearRowBreaks / ClearColBreaks / ClearAllPageBreaks. RowBreakCount / ColBreakCount + индексированные RowBreaks(Index) / ColBreaks(Index) предоставляют доступ к хранимым индексам "Before" (с отсчетом от 1) для итерации. SaveAs генерирует <rowBreaks> / <colBreaks> с дочерними элементами <brk id="N-1" max="..." man="1"/> между <headerFooter> и <drawing>; Open парсит их обратно.
Версия 2.20.0
- Добавлена поддержка видимости листа (Hidden / VeryHidden), выбор листа и отслеживание активного листа на TXLSXWorkbook / TXLSXSheets / TXLSXWorksheet. Новые типы: TXLSXSheetVisibility (xlsxSheetVisible / xlsxSheetHidden / xlsxSheetVeryHidden). Новые свойства TXLSXWorksheet: Visibility, Visible (булевский псевдоним), IsSelected (только для чтения). Новые члены TXLSXSheets: ActiveIndex, Activate(Index), Move(FromIndex, ToIndex). Добавлен прокси TXLSXWorkbook.ActiveSheet. SaveAs генерирует <sheet state="..."/> для записей листов в книге, <bookViews><workbookView activeTab=N/></bookViews>, когда активный лист не является значением по умолчанию 0, и атрибут tabSelected="1" для активного листа в <sheetView>; Open парсит все три обратно в новые свойства. Первый добавленный лист становится видимым и активным по умолчанию, чтобы существующие участки кода продолжали работать.
Версия 2.19.2
- Добавлено четыре дополнительных параметра для атрибутов PageSetup в TXLSXWorksheet, чтобы полностью охватить возможности OOXML <pageSetup>: BlackAndWhite (режим черно-белого печати), Draft (отключение графики для более быстрой предварительной печати), PrintNotes (печать комментариев к ячейкам в отображаемом виде, а не скрытие их) и PrintOverThenDown (печать строк слева направо, а не стандартное построчное построение сверху вниз). Функция SaveAs создает соответствующие атрибуты blackAndWhite / draft / cellComments / pageOrder; функция Open восстанавливает их. По умолчанию эти параметры отключены, чтобы не изменять существующие листы и не добавлять им лишние атрибуты.
Версия 2.19.1
- Добавлены удобные свойства для заголовков и нижних колонтитулов в TXLSXWorksheet. Новые свойства: LeftHeader / CenterHeader / RightHeader и LeftFooter / CenterFooter / RightFooter. Каждое из них считывает или записывает соответствующий сегмент &L / &C / &R существующей строки HeaderText / FooterText; запись любого из сегментов перестраивает всю строку, чтобы функция записи и чтения работали без изменений.
- Добавлены параметры печати для управления выводом страниц на уровне листа. Новые свойства в TXLSXWorksheet: CenterHorizontally, CenterVertically, PrintGridlines, PrintHeadings. Функция SaveAs создает элемент <printOptions horizontalCentered / verticalCentered / gridLines / headings/>, когда любой из этих параметров включен; функция Open восстанавливает эти атрибуты. По умолчанию эти параметры отключены, чтобы не добавлять лишний элемент <printOptions/> к существующим листам.
- Добавлена поддержка сохранения и загрузки области печати (PrintArea), номеров строк заголовков (PrintTitleRows) и номеров столбцов заголовков (PrintTitleCols) для каждого листа. Эти параметры соответствуют встроенным именованным диапазонам workbook-level _xlnm.Print_Area и _xlnm.Print_Titles, определенным в OOXML и имеющим область действия, определяемую localSheetId. PrintArea принимает ссылку в формате A1 (например, "$A$1:$D$10"); PrintTitleRows и PrintTitleCols принимают ссылки только на строки или только на столбцы (например, "$1:$3" или "$A:$B") и объединяются в одну запись Print_Titles. Функция записи добавляет имя листа с правильными кавычками (одинарные кавычки вокруг имен, содержащих пробелы или специальные символы); функция чтения удаляет префикс и направляет записи на соответствующий лист, чтобы они не попадали в коллекцию TXLSXWorkbook.DefinedNames, доступную пользователю.
Версия 2.19.0
- Добавлены операции вставки и удаления строк/столбцов с полным смещением по всему листу в TXLSXWorksheet. Новые функции: InsertRows(BeforeRow, Count), DeleteRows(StartRow, Count), InsertCols(BeforeCol, Count), DeleteCols(StartCol, Count). Функции InsertRows / InsertCols сдвигают существующие строки / столбцы на Count позиций в сторону от места вставки; функции DeleteRows / DeleteCols удаляют диапазон [Start, Start+Count-1] и сдвигают все строки / столбцы после удаленного диапазона на Count позиций.
- Изменение применяется ко всем элементам геометрии листа, зависящим от положения строки/столбца: ячейки (Cells), углы объединенных диапазонов (MergedCells — перекрывающиеся диапазоны обрезаются до сохранившихся краев, а диапазоны, находящиеся только внутри, удаляются), списки метаданных строк/столбцов (FRowHeights / FColWidths / уровни обводки / скрытые/свернутые), якоря гиперссылок и комментариев (записи внутри удаленного диапазона удаляются), FreezePane (FFreezeRow / FFreezeCol), AutoFilterRange, и строковое представление диапазона для каждого объекта ConditionalFormat, DataValidation и Excel Table (запись, диапазон которой полностью находится внутри удаленного диапазона, удаляется).
- Добавлены новые члены Delete(Index) в поддерживающие коллекции, чтобы логика перемещения могла удалять одну запись без очистки: TXLSXHyperlinks, TXLSXComments, TXLSXConditionalFormats, TXLSXDataValidations, TXLSXTables.
- За пределами текущего релиза: изображения и диаграммы не перемещаются (их якоря в пикселях EMU отвязывают их от сетки ячеек, и для точного перемещения потребовалось бы пересчитать смещения EMU); формулы, определенные на уровне книги, не переписываются. Оба пункта запланированы для последующего релиза.
Версия 2.18.2
- Добавлены вспомогательные функции для автоматической подгонки ширины столбцов и высоты строк. TXLSXWorksheet предоставляет AutoFitColumn(ACol) / AutoFitColumns(ColMin, ColMax) и AutoFitRow(ARow) / AutoFitRows(RowMin, RowMax); TXLSXRange предоставляет AutoFitColumns и AutoFitRows, которые передают вызов на лист в пределах границ диапазона. Ширина оценивается в единицах символов Excel (шрифт Calibri, 11pt, базовый размер; ASCII символы считаются за 1, символы CJK — за 2) с коррекцией 1.20 пикселя на символ и отступом 1.0, ограничена значениями [8.43, 255.0]. Высота строки по умолчанию равна 15pt и увеличивается на 12.75pt за каждый символ новой строки в тексте ячейки. Для широких диапазонов (EntireRow / EntireColumn) применяются ограничения до последней строки/столбца, содержащей данные на листе, чтобы AutoFit не перебирал до границ сетки Excel.
Версия 2.18.1
- Добавлена двусторонняя синхронизация защиты ячеек с движком XLSX. TXLSXCell предоставляет новые свойства Locked: Boolean (по умолчанию True) и FormulaHidden: Boolean (по умолчанию False), которые соответствуют модели защиты ячеек в Excel. Они предоставляют доступ к индексу защиты TXLSXCell.ProtectionIndex (отсчет с 1 в новом пуле защит на уровне книги); запись в свойство Locked и FormulaHidden ищет или добавляет пару (Locked, FormulaHidden) в пул. Значения по умолчанию (Locked=True, FormulaHidden=False) приводят к ProtectionIndex=0, чтобы пул оставался пустым для обычных ячеек.
- Добавлены пакетные помощники TXLSXRange.SetLocked(ALocked) и TXLSXRange.SetFormulaHidden(AHidden), чтобы разблокировка или скрытие целого диапазона выполнялись только один раз с поиском или добавлением в пул и применялись к каждой ячейке в прямоугольнике.
- Добавлены соответствующие компоненты для записи и чтения. Метод SaveAs создает один элемент cellXf с вложенным элементом <protection locked="N" hidden="M"/> для каждой записи Protections в книге (после блока выравнивания); метод Open преобразует элемент <protection> обратно в Workbook.Protections и передает новую карту CellXfProtMap через ParseStylesXml и ParseWorksheetXml, чтобы индекс защиты для каждой ячейки сохранялся вместе с существующими индексами шрифта, заливки, границы, формата числа и выравнивания.
Версия 2.18.0
- Добавлен объект TXLSXRange для доступа к нескольким ячейкам и пакетных операций в TXLSXWorksheet. Новые точки входа: Worksheet.Range['A1:C5'], Worksheet.RCRange[r1,c1,r2,c2], Worksheet.UsedRange, Worksheet.EntireRow(r), Worksheet.EntireColumn(c). Возвращенный диапазон предоставляет методы SetValue / SetFormula / Clear / ClearAll / Merge / Unmerge / Offset / Resize, а также установки индексов стилей для каждой ячейки (SetFontIndex / SetFillIndex / SetBorderIndex / SetNumberFormatIndex / SetAlignmentIndex) и удобный метод SetNumberFormat(Fmt), который ищет или добавляет строку формата в пул книги. Объекты TXLSXRange принадлежат листу и освобождаются при уничтожении листа; вызывающий код не должен освобождать их.
- Добавлен TXLSXCell.NumberFormat: WideString, который работает в паре с существующим NumberFormatIndex. Чтение возвращает строку формата из пула книги; запись ищет или добавляет строку и прозрачно обновляет NumberFormatIndex. Требуется, чтобы ячейка была связана с книгой (стандартный поток через TXLSXWorkbook.Sheets.Add(...).Cells[r, c]).
- Добавлены обратные ссылки от ячейки к листу и книге, чтобы каждая TXLSXCell могла определить свою книгу без внешнего учета. Объекты TXLSXSheets, TXLSXWorksheet и TXLSXCells получили внутренние ссылки Owner, установленные через их конструкторы; TXLSXCell предоставляет свойство Workbook только для чтения и внутренний метод SetWorkbook, используемый TXLSXCells.GetItem при автоматическом создании ячейки при обращении к ней.
Версия 2.17.42
- Исправлена проблема с сохранением и повторным открытием ячеек XLSX. Ячейки, записанные функцией SaveAs, не загружались при открытии, HasCell(row, col) возвращал False, и все атрибуты ячеек (значение, формула, индекс шрифта, индекс заливки, индекс границы, индекс формата числа) терялись. Причиной была ошибочная функция MoveToAttribute('r') в парсере листа, которая изменяла тип узла для парсера, что приводило к тому, что IsEmptyElement возвращал True, и парсинг ячеек прекращался для каждого элемента <c> с атрибутом r="" (то есть для каждой ячейки). Удаление ненужного перемещения курсора восстанавливает корректное сохранение и повторное открытие текстовых, числовых, формульных и ячеек с датами.
- Исправлена проблема с восстановлением индексов стилей XLSX при повторном открытии. Пользовательские индексы шрифтов, заливок, границ и форматов чисел в ячейках считывались как ноль, даже после того, как соответствующие наборы (Workbook.Fonts/Fills/Borders/NumberFormats) были успешно сохранены. Парсер cellXf отслеживал свою позицию с помощью счетчика, который увеличивался только при закрывающем теге </xf>, но Excel часто использует самозакрывающиеся записи <xf .../> (без внутреннего элемента <alignment>), поэтому счетчик никогда не увеличивался выше нуля, и каждое отображение cellXf перезаписывало предыдущее. Теперь парсер увеличивает счетчик и для самозакрывающихся <xf/>, что обеспечивает корректное сохранение и повторное открытие индексов FontIndex / FillIndex / BorderIndex / NumberFormatIndex для каждой ячейки.
- Исправлена проблема с сохранением и повторным открытием ячеек с датами в XLSX. Запись значения TDateTime в TXLSXCell.Value ранее проходила через общий пул строк с атрибутом t="s", потому что функция VarIsNumeric() в Delphi возвращает False для типа varDate. Теперь SaveAs записывает серийный номер даты непосредственно в <v> и применяет cellXf для даты, поэтому ячейки с датами при повторном открытии отображаются как Variant типа varDate, а не как локализованная строка, которую вызывающий код не может преобразовать обратно в TDateTime.
Версия 2.17.41
- Исправлена ошибка "zlib stream does not support seeking", возникающая при повторном открытии файлов .xlsx, содержащих встроенные изображения или проект VBA (.xlsm). Путь перезагрузки изображений и путь перезагрузки содержимого проекта VBA использовали TMemoryStream.CopyFrom(Source, 0) для обработки распакованного потока, что внутренне сбрасывало Source для определения количества байтов; такое сброс недопустим для потока Deflate, работающего только на чтение. Теперь оба места вызова используют вспомогательную функцию чтения по частям до конца файла (Read-until-EOF), поэтому файлы .xlsx с изображениями или макросами корректно сохраняются и открываются без возникновения ошибки.
Версия 2.17.40
- Добавлена поддержка диаграмм-страниц (диаграмм, занимающих всю страницу) в движок XLSX. TXLSXWorksheet предоставляет новый флаг IsChartSheet, а также вспомогательную функцию Workbook.AddChartSheet(Name, ChartType, Title) на уровне книги, которая создает страницу, устанавливает флаг, и заполняет Charts[0] разумными значениями по умолчанию. SaveAs записывает страницы диаграмм в файлы xl/chartsheets/sheetN.xml, используя отдельный файл rels, указывающий на общий элемент рисования, регистрирует их как типы содержимого для диаграмм и создает связь диаграммы в xl/_rels/workbook.xml.rels. Обычные рабочие листы сохраняют свой существующий путь xl/worksheets/sheetN.xml. Open распознает диаграммы-страницы по типу связи, но в настоящее время загружает их как обычные рабочие листы (данные диаграммы по-прежнему поступают через общие элементы диаграмм).
Версия 2.17.39
- Добавлена поддержка сохранения и открытия свернутых строк/столбцов для групп в структуре в движке XLSX. TXLSXWorksheet предоставляет свойства RowCollapsed[Row] и ColCollapsed[Col] типа Boolean, а также вспомогательные функции SetRowCollapsed / SetColCollapsed / ClearRowCollapsed / ClearColCollapsed. SaveAs добавляет атрибут collapsed="1" к соответствующим элементам <row> и <col>; Open парсит этот атрибут. Вместе с существующими атрибутами outlineLevel и hidden, это позволяет движку XLSX сохранять и открывать полностью иерархическую структуру свернутых групп.
Версия 2.17.38
- Добавлена поддержка сохранения и открытия скрытых строк/столбцов в движке XLSX. TXLSXWorksheet предоставляет свойства RowHidden[Row] и ColHidden[Col] типа Boolean, а также вспомогательные функции SetRowHidden / SetColHidden / ClearRowHidden / ClearColHidden. SaveAs добавляет атрибут hidden="1" к соответствующим элементам <row> и <col>; Open парсит этот атрибут обратно в рабочий лист, чтобы скрытые строки/столбцы сохранялись при сохранении и открытии, не требуя установки пользовательской ширины или уровня структуры.
Версия 2.17.37
- Добавлена поддержка сохранения и открытия цвета вкладки рабочего листа в движке XLSX. TXLSXWorksheet предоставляет свойства TabColor (ARGB) и TabColorIsAuto. SaveAs добавляет блок <sheetPr><tabColor rgb="..."/></sheetPr> в качестве первого дочернего элемента <worksheet>, когда цвет вкладки установлен; Open парсит <tabColor> обратно в рабочий лист, чтобы цветные вкладки сохранялись при сохранении и открытии. В стандартных книгах этот дополнительный блок отсутствует (TabColorIsAuto = True).
Версия 2.17.36
- Добавлена поддержка двусторонней передачи настроек выравнивания ячеек в движок XLSX. Новые перечисления TXLSXHorizontalAlignment и TXLSXVerticalAlignment, класс TXLSXAlignment (Horizontal, Vertical, WrapText, ShrinkToFit, Indent, TextRotation) и коллекция TXLSXAlignments на уровне книги (Workbook.Alignments). Объект TXLSXCell теперь содержит AlignmentIndex (отсчет от 1, указывающий на элемент в Workbook.Alignments). Метод SaveAs добавляет один cellXf с дочерним элементом <alignment/> для каждого элемента выравнивания на уровне книги; метод Open считывает атрибуты <alignment> обратно в Workbook.Alignments и сопоставляет cellXf с TXLSXCell.AlignmentIndex. Методы ParseWorksheetXml и ParseStylesXml получили параметр CellXfAlignMap для передачи соответствий между двумя этапами.
Версия 2.17.35
- Добавлена API для шифрования AES (стандарт шифрования ECMA-376) в движок XLSX. Объект TXLSXWorkbook предоставляет методы SaveAsEncrypted(FileName, Password) / OpenEncrypted(FileName, Password) / CanReadEncrypted(FileName), а также класс исключения EXlsxEncryptionNotImplemented. Метод CanReadEncrypted распознает магические байты Microsoft Compound File Binary ($D0 $CF $11 $E0 $A1 $B1 $1A $E1), чтобы вызывающий код мог определить, является ли архив зашифрованным, прежде чем решать, как его открыть; метод OpenEncrypted прозрачно переключается на обычный метод Open для незашифрованных файлов .xlsx. Схема AES-128/256 + SHA + OLE Compound File пока не реализована — как при записи, так и при чтении фактически зашифрованных архивов возникает исключение указанного типа, пока в следующей версии не будет реализован алгоритм. Тип исключения намеренно отличается, чтобы существующий код мог его перехватить и использовать Worksheet.Protect / Workbook.ProtectWorkbook для визуальной блокировки.
Версия 2.17.34
- Производительность: заменена операция конкатенации строк WideString, которая имела сложность O(N^2) при создании строк ячеек в каждом листе, на TXLSWideStringBuilder. Большие листы (10 000+ ячеек) теперь используют линейный объем памяти и процессорного времени при сохранении. Добавлен новый вспомогательный метод WriteWorksheetXmlStreaming и опция TXLSXWorkbook.StreamingWrite — при включении, метод SaveAs больше не хранит XML для каждого листа в кэше sheetXmls одновременно; каждый лист создается, записывается и удаляется, прежде чем перейти к следующему. Файл sharedStrings.xml генерируется последним, поэтому потоковый режим по-прежнему создает полностью заполненный SST. Поведение по умолчанию не изменено.
Версия 2.17.33
- Добавлены операции с диапазонами ячеек в движок XLSX. Класс TXLSXWorksheet предоставляет методы ClearRange(R1, C1, R2, C2), CopyRange(SrcR1, SrcC1, SrcR2, SrcC2, DstR, DstC) для копирования внутри листа, CopyRangeTo(... TargetSheet, DstR, DstC) для копирования между листами и MoveRange(SrcR1, SrcC1, SrcR2, SrcC2, DstR, DstC) для вырезания и вставки. Каждая операция дублирует значение ячейки, формулу, четыре индекса стилей и любые данные форматирования; MoveRange избегает перекрытий с целевой областью, поэтому частичные перекрытия сохраняют скопированные значения. Класс TXLSXCells также получил вспомогательный метод Remove(Row, Col).
Версия 2.17.32
- Добавлены внутренние гиперссылки в движок XLSX. Класс TXLSXHyperlink теперь имеет свойство Location (например, "Sheet2!A1") и вспомогательный метод IsInternal; TXLSXHyperlinks предоставляет методы AddInternal, а TXLSXWorksheet добавляет три перегрузки метода AddHyperlinkToCell. При сохранении внутренние гиперссылки создаются с атрибутом inline location="" и запись в раздел rels для листа пропускается; при открытии гиперссылки с location="" обрабатываются и направляются через метод AddInternal. Внешние URL-адреса гиперссылок по-прежнему сохраняются в файле rels без изменений.
Версия 2.17.31
- Добавлена поддержка двусторонней записи форматирования текста в движок XLSX. Новые классы TXLSXRichTextRun (для каждого элемента форматирования: Name / Size / Bold / Italic / Strikethrough / Underline / Color) и TXLSXRichText, предоставляющий методы AddRun / AddRunText / Clear / PlainText. Класс TXLSXCell теперь имеет свойство RichText, содержащее данные форматирования; при сохранении ячейка записывается как строка с несколькими элементами <r>/<rPr>/<t>, а при открытии TXLSXRichText восстанавливается из разобранной записи SST, при этом значение Variant ячейки по-прежнему предоставляет объединенный обычный текст для вызывающих, которые игнорируют форматирование.
Версия 2.17.30
- Добавлена поддержка двусторонней записи графиков в движок XLSX. Новые перечисления TXLSXChartType (столбчатая диаграмма / гистограмма / линейная диаграмма / круговая диаграмма), классы TXLSXChartSeries (Name, CategoriesRange, ValuesRange) и TXLSXChart (ChartType, Title, заголовки осей, ячейки From/To, Series), а также коллекция TXLSXCharts для каждого листа (Worksheet.Charts). TXLSXWorksheet предоставляет метод AddChart(Type, Title, FromRow, FromCol, ToRow, ToCol). При сохранении создаются файлы xl/charts/chartN.xml (глобальная нумерация в книге) и связываются с двумя элементами twoCellAnchor / graphicFrame внутри файла xl/drawings/drawingN.xml; при открытии как якорь, так и определение графика разбираются и восстанавливаются в коллекции. Заголовки графиков, заголовки осей, имена серий и диапазоны данных сохраняются и восстанавливаются.
Версия 2.17.29
- Исправлена ошибка EListError "Operation not allowed on sorted list", возникающая в функциях SetColWidth, SetRowHeight, SetRowOutlineLevel и SetColOutlineLevel. Четыре поля типа TStringList были созданы с параметром Sorted=True, но записывались через setter Values[Name] := X, что недопустимо для отсортированных списков в RAD Studio's RTL. Теперь списки создаются как неотсортированные; поиск продолжается через IndexOfName, что приемлемо для типичного количества столбцов/строк на листе.
Версия 2.17.28
- Исправлена функция TZipArchive.Exists, которая была заглушкой и всегда возвращала false. В пути XLSX Open используется zip.Exists(...) для проверки каждой части перед чтением, поэтому все ранее сохраненные данные (ячейки, стили, комментарии, рисунки, свойства документа, именованные диапазоны, защита, VBA и т.д.) молчаливо удалялись при чтении. Теперь Exists делегирует проверку существующему Fcd.Entries.Exists, что соответствует шаблону OpenFile / CreateFile.
Версия 2.17.27
- Добавлена поддержка сохранения проектов VBA в движке XLSX. TXLSXWorkbook предоставляет байтовый массив VbaProject, а также функции LoadVbaProjectFromFile(FileName), ClearVbaProject и HasVbaProject. SaveAs записывает байты в файл xl/vbaProject.bin, регистрирует тип содержимого .bin, изменяет тип содержимого книги на версию с поддержкой макросов и добавляет связь vbaProject к файлу rels книги; Open считывает файл xl/vbaProject.bin обратно в свойство. Байты не анализируются и не изменяются, поэтому существующие проекты .xlsm сохраняются без изменений. Обратите внимание: книги с поддержкой макросов должны быть сохранены с расширением .xlsm, чтобы Excel включил макросы.
Версия 2.17.26
- Добавлена защита листов и книг в движке XLSX. TXLSXWorksheet предоставляет функции Protect / Protect(Password) / UnProtect, а также свойства IsProtected и SheetProtectHash; TXLSXWorkbook добавляет функции ProtectWorkbook (с необязательным паролем, флагами LockStructure, LockWindows) и UnProtectWorkbook, а также свойства IsWorkbookProtected / WorkbookProtectHash / LockStructure / LockWindows. SaveAs генерирует теги <sheetProtection> для защищенных листов и <workbookProtection> для защищенных книг; Open анализирует оба блока и заполняет API. Пароли хранятся в виде стандартного 4-хексабайтового хэша для обеспечения совместимости (исходный текст пароля не может быть восстановлен).
Версия 2.17.25
- Добавлена поддержка сохранения свойств документа в движке XLSX. TXLSXWorkbook теперь предоставляет свойства Title, Author, Subject, Keywords, Description, Category, LastModifiedBy, Created, Modified, Company, Application и AppVersion. SaveAs генерирует файлы docProps/core.xml и docProps/app.xml (и регистрирует их в [Content_Types].xml + _rels/.rels), когда любое свойство изменяется; Open анализирует оба файла, чтобы авторы, метки времени изменения и метаданные приложения сохранялись при сохранении и повторном открытии.
Версия 2.17.24
- Добавлена поддержка двусторонней записи таблиц в стиле Excel для движка XLSX. Новый класс TXLSXTable (Id, Name, DisplayName, Range, Columns, StyleName, ShowFirstColumn / ShowLastColumn / ShowRowStripes / ShowColumnStripes) и коллекция TXLSXTables для каждого листа. TXLSXWorksheet предоставляет доступ к таблицам, а также методы AddTable(Name, Range, ColumnNames). Метод SaveAs создает файлы xl/tables/tableN.xml (глобальная нумерация для всего документа), обновляет связи листа с таблицами, добавляет <tableParts> к листу и регистрирует тип содержимого таблицы. Метод Open парсит связи и файл tableN.xml, чтобы стилизованные области таблицы сохранялись при сохранении и повторном открытии.
Версия 2.17.23
- Добавлена поддержка двусторонней записи фильтров в XLSX. TXLSXWorksheet предоставляет свойство AutoFilterRange, а также методы SetAutoFilter(Row1, Col1, Row2, Col2) / SetAutoFilter(Range) / ClearAutoFilter. Метод SaveAs создает тег <autoFilter ref="..."/> после блока с объединенными ячейками, если диапазон не пуст; метод Open парсит атрибут ref обратно в свойство, чтобы область фильтра на листе сохранялась при сохранении и повторном открытии.
Версия 2.17.22
- Добавлена поддержка двусторонней записи настроек страницы для движка XLSX. TXLSXWorksheet предоставляет свойства Margin{Left,Right,Top,Bottom,Header,Footer}, PageLandscape, PaperSize, PageScale, FitToWidth, FitToHeight, HeaderText и FooterText, а также удобные перегруженные методы SetPageMargins(L, R, T, B[, H, F]). Метод SaveAs создает соответствующие блоки <pageMargins>, <pageSetup> и <headerFooter> между гиперссылками и рисунками; метод Open парсит их обратно. Листы, содержащие только значения по умолчанию, остаются неизменными (флаг PageSetupTouched контролирует вывод).
Версия 2.17.21
- Добавлена поддержка двусторонней записи закрепления панели для движка XLSX. TXLSXWorksheet предоставляет методы FreezePane(Col, Row) / UnfreezePane, а также только для чтения свойства FreezeCol и FreezeRow. Метод SaveAs записывает блок <sheetViews>/<pane state="frozen"> перед <sheetData> с соответствующим активным pane и выделением; метод Open парсит <pane state="frozen"> обратно в позицию закрепления, чтобы макеты закрепления сверху/слева/в углу сохранялись при сохранении и повторном открытии.
Версия 2.17.20
- Добавлена поддержка уровней группировки строк и столбцов для движка XLSX. TXLSXWorksheet предоставляет индексированные свойства RowOutlineLevel[Row] и ColOutlineLevel[Col], а также методы SetRowOutlineLevel / HasRowOutlineLevel / ClearRowOutlineLevels и соответствующие методы для столбцов. Метод SaveAs создает атрибуты outlineLevel для элементов <row> и объединенных элементов <col> (в сочетании с пользовательскими ширинами, если они присутствуют); метод Open парсит оба атрибута обратно в лист, чтобы иерархии сгруппированных строк/столбцов сохранялись при двусторонней записи.
Версия 2.17.19
- Добавлена поддержка условного форматирования и проверки данных в движке XLSX. Новые перечисления TXLSXCfOperator и классы TXLSXConditionalFormat (Range, Op, Formula1, Formula2) и TXLSXConditionalFormats (коллекция на каждом листе, Worksheet.ConditionalFormats). Также добавлены TXLSXDataValidationType, TXLSXDvOperator, TXLSXDataValidation (Range, ValidationType, Op, Formula1, Formula2, AllowBlank, ShowInputMessage, ShowErrorMessage) и коллекция TXLSXDataValidations (Worksheet.DataValidations) с функцией AddList(Range, Items) для создания выпадающих списков. TXLSXWorksheet предоставляет вспомогательные функции AddConditionalFormat и AddDataValidation / AddListValidation. При сохранении создаются блоки <conditionalFormatting> (с атрибутом cfRule type="cellIs") и блок <dataValidations> после sheetData; при открытии эти блоки парсятся и заполняются коллекции.
Версия 2.17.18
- Добавлена поддержка именованных диапазонов в движке XLSX. Новый класс TXLSXDefinedName (Name, Formula, SheetIndex) и коллекция TXLSXDefinedNames (Workbook.DefinedNames) на уровне книги с перегрузками Add(Name, Formula[, SheetIndex]) и функцией поиска IndexOfName. При сохранении создается блок <definedNames> в файле xl/workbook.xml; записи с SheetIndex >= 0 имеют атрибут localSheetId (для диапазонов, определенных на листе), а записи с SheetIndex = -1 определены для всей книги. При открытии элементы <definedName> парсятся и заполняются коллекция, чтобы сохраненные и повторно открытые книги сохраняли свои именованные диапазоны.
Версия 2.17.17
- Добавлена поддержка изображений в движке XLSX. Новые перечисления TXLSXImageFormat (png, jpeg, gif, bmp), класс TXLSXImage (Row/Col anchor, WidthEMU/HeightEMU, Format, Data) и коллекция TXLSXImages для каждого листа. TXLSXWorksheet предоставляет доступ к коллекции Images, а также вспомогательные функции AddImage(Row, Col, Data, Format) и AddImageFromFile(Row, Col, FileName). При сохранении байты изображений записываются в файлы xl/media/imageN.<ext>, создается файл drawingN.xml в папке xl/drawings/ с одним якорным элементом для каждого изображения (и соответствующим файлом _rels), регистрируются типы содержимого и связи между листом и рисунком, и создается ссылка <drawing r:id="..."/> внутри листа. При открытии файлы drawingN.xml, drawing rels и media парсятся для восстановления изображений в коллекции Worksheet.Images.
Версия 2.17.16
- Добавлена поддержка сохранения и восстановления пользовательских форматов чисел в движке XLSX. Новые классы TXLSXNumberFormat и коллекция TXLSXNumberFormats на уровне книги (Workbook.NumberFormats) устраняют дублирование кодов форматов с помощью метода Add(FormatCode). Объект TXLSXCell теперь имеет свойство NumberFormatIndex; при сохранении генерируется блок <numFmts> в файле xl/styles.xml (пользовательские идентификаторы начинаются с зарезервированного значения 164) и каждый формат сопоставляется с отдельным cellXf. При открытии пользовательские numFmts восстанавливаются, и cellXf->numFmtId преобразуется в NumberFormatIndex при чтении. Приоритет при конфликтах: FormatIndex > FontIndex > FillIndex > BorderIndex > NumberFormatIndex.
Версия 2.17.15
- Добавлена поддержка сохранения и восстановления границ ячеек в движке XLSX. Новые перечисления TXLSXBorderStyle, классы TXLSXBorderEdge (стиль, цвет и флаг автоматического цвета для каждой стороны), TXLSXBorder с левой/правой/верхней/нижней/диагональной границами, а также вспомогательные методы SetAll(Style[, Color]) и коллекция TXLSXBorders на уровне книги (Workbook.Borders) с ярлыком Borders.AddBox(Style[, Color]). Объект TXLSXCell теперь имеет свойство BorderIndex; при сохранении каждая граница записывается в xl/styles.xml и сопоставляется с отдельным cellXf. При открытии границы восстанавливаются, и cellXf->borderId преобразуется в BorderIndex при чтении. Приоритет остается FormatIndex > FontIndex > FillIndex > BorderIndex, когда установлено несколько значений для одной ячейки.
Версия 2.17.14
- Добавлена поддержка сохранения и восстановления заливки ячеек в движке XLSX. Новые перечисления TXLSXFillPattern и класс TXLSXFill описывают patternType, fgColor и bgColor; коллекция TXLSXFills на уровне книги доступна через Workbook.Fills, а метод Fills.AddSolid(color) предназначен для распространенного случая однотонной заливки. Объект TXLSXCell теперь имеет свойство FillIndex; при сохранении каждая заливка записывается в xl/styles.xml и сопоставляется с отдельным cellXf. При открытии они восстанавливаются, и атрибуты ячейки преобразуются в FillIndex при чтении. FontIndex по-прежнему имеет приоритет, когда установлено оба значения.
Версия 2.17.13
- Завершена поддержка сохранения и восстановления шрифтов в XLSX. Теперь при открытии xl/styles.xml восстанавливается в Workbook.Fonts, создается таблица cellXf->fontId, и атрибут s каждой ячейки преобразуется в TXLSXCell.FontIndex, что позволяет сохранять и повторно открывать книги с пользовательскими шрифтами (Name, Size, Bold, Italic, Strikethrough, Underline, Color).
Версия 2.17.12
- Добавлен класс TXLSXFont и коллекция Workbook.Fonts, чтобы ячейки XLSX могли использовать пользовательские шрифты. Объект TXLSXCell теперь имеет свойство FontIndex; при сохранении список шрифтов записывается в xl/styles.xml, создается один cellXf для каждого шрифта, а затем атрибут s каждой ячейки ссылается на соответствующий cellXf. Поддержка сохранения FontIndex запланирована для следующего выпуска.
Версия 2.17.11
- Добавлена поддержка сохранения и загрузки высоты строк в движке XLSX. TXLSXWorksheet предоставляет свойство RowHeight[Row] и вспомогательные функции SetRowHeight, HasRowHeight и ClearRowHeights. При сохранении атрибуты ht и customHeight="1" записываются для каждого элемента <row> с заданной высотой (включая строки, содержащие только высоту, без данных ячеек); при открытии атрибут ht считывается обратно в карту высоты строк.
Версия 2.17.10
- Добавлена поддержка сохранения и загрузки ширины столбцов в движке XLSX. TXLSXWorksheet предоставляет свойство ColWidth[Col] и вспомогательные функции SetColWidth, HasColWidth и ClearColWidths. При сохранении создается блок <cols> с одним элементом <col> для каждого столбца с заданной шириной; при открытии элементы <col min/max/width> восстанавливаются в листе, чтобы не измененные ширины соответствовали значениям по умолчанию в Excel.
Версия 2.17.9
- Добавлена поддержка сохранения и загрузки комментариев к ячейкам в движке XLSX. TXLSXWorksheet предоставляет коллекцию Comments и перегруженные функции AddComment(Row, Col, Text[, Author]). При сохранении создаются файлы xl/commentsN.xml (со списком авторов без дубликатов) и сопутствующий файл xl/drawings/vmlDrawingN.vml, чтобы Excel мог отображать комментарии; при открытии комментарии считываются из файла commentsN.xml в коллекцию. Связи листов, типы содержимого и обработка <legacyDrawing> выполняются автоматически.
Версия 2.17.8
- Добавлена поддержка сохранения и загрузки гиперссылок в движке XLSX. TXLSXWorksheet предоставляет коллекцию Hyperlinks и перегруженные функции AddHyperlink(Row, Col, Url[, Display[, Tooltip]]). При сохранении создается блок <hyperlinks> в каждом листе и соответствующий файл xl/worksheets/_rels/sheetN.xml.rels с внешними URL-адресами; при открытии сначала считываются связи листа, чтобы преобразовать элементы <hyperlink r:id="..."/> в URL-адреса в коллекции.
Версия 2.17.7
- Добавлена поддержка сохранения и загрузки объединенных ячеек в движке XLSX. TXLSXWorksheet предоставляет коллекцию MergedCells и удобный метод MergeCells(R1, C1, R2, C2), который соответствует стилю BIFF. При сохранении создается блок <mergeCells> после sheetData, а при открытии элементы <mergeCell ref="A1:B2"/> преобразуются обратно в коллекцию.
Версия 2.17.6
- Движок XLSX теперь корректно обрабатывает значения дат и формулы. Значения ячеек типа TDateTime сериализуются как номера Excel и помечаются встроенным стилем cellXf, чтобы Excel отображал их как даты; при открытии ячейки, стиль которых ссылается на cellXf, декодируются обратно в варианты TDateTime. Класс TXLSXCell теперь имеет свойство Formula; метод SaveAs записывает формулу как дочерний элемент <f>, а метод Open преобразует текст <f> обратно в значение ячейки.
Версия 2.17.5
- Добавлена структура styles.xml в движок XLSX. Метод SaveAs теперь создает минимально допустимый файл xl/styles.xml со стандартными шрифтами, заливками, границами, cellStyleXfs и cellXfs, а также соответствующими регистрациями content-type и workbook-relationship. Ячейки имеют свойство FormatIndex и генерируют атрибут s="N", если он отличен от нуля, а метод Open считывает s="N" обратно в FormatIndex. Конкретные описатели стилей (шрифты, заливки, границы, cellXfs как коллекции на уровне книги) будут добавлены в последующих обновлениях.
Версия 2.17.4
- Добавлена поддержка общих строк (SST) в движок XLSX. Метод SaveAs создает таблицу дедуплицированных строк и генерирует файл xl/sharedStrings.xml, заменяя встроенную генерацию строк. Метод Open сначала считывает xl/sharedStrings.xml и разрешает ссылки t="s" через SST. Встроенные строковые ячейки из сторонних файлов XLSX по-прежнему принимаются при открытии.
Версия 2.17.3
- Заменена структура массива ячеек в TXLSXWorksheet на объекты TXLSXCell и коллекцию TXLSXCells. Место вызова для доступа к ячейкам теперь считывает Worksheet.Cells.Item[Row, Col].Value, что соответствует структуре IXLSCells / IXLSRange на фасаде BIFF. Также доступны Worksheet.Cells.HasCell / Cells.Count / Cells.CellByIndex / Cells.Clear.
Версия 2.17.2
- В класс TXLSXWorkbook добавлена коллекция TXLSXSheets, аналогичная коллекции IXLSWorkSheets на фасаде BIFF. Теперь код считывает Workbook.Sheets.Add / Workbook.Sheets.Count / Workbook.Sheets[i] / Workbook.Sheets.IndexByName вместо предыдущих методов Workbook.AddSheet / Workbook.SheetCount / Workbook.Sheet[i].
Версия 2.17.1
- Переименованы методы TXLSXWorkbook.SaveToFile в SaveAs и TXLSXWorkbook.LoadFromFile в Open, чтобы соответствовать существующему стилю именования IXLSWorkBook. Добавлены перегрузки для формата файла и пароля, чтобы интерфейс XLSX работал аналогично интерфейсу BIFF. Метод AddSheet теперь имеет перегрузку без аргументов, которая создает имя листа по умолчанию.
Версия 2.17.0
- Метод TXLSXWorkbook.SaveAs создает минимальный архив OOXML .xlsx, содержащий значения ячеек (числа, булевы значения и встроенные строки). Архив содержит типы содержимого, корневые связи, книгу + связи и лист для каждого листа.
- Метод TXLSXWorkbook.Open считывает минимальный архив OOXML .xlsx: имена листов из xl/workbook.xml и значения ячеек из xl/worksheets/sheetN.xml. Общие строки, стили, даты и формулы пока не поддерживаются.
- Добавлены константы для пространства имен OOXML, типа содержимого и связей, а также вспомогательные функции для ссылок / парсинга / экранирования (XlsxColumnLabel, XlsxCellRef, XlsxColumnIndex, XlsxParseCellRef, XlsxParseRangeRef, XlsxEscapeText, XlsxEscapeAttr) для использования в будущих функциях XLSX.
Версия 2.16.4
- Модуль интерфейса XLSX (lxHandleX) теперь определяет собственные типы книги и листа (TXLSXWorkbook, TXLSXWorksheet), независимо от модуля интерфейса BIFF. Точки входа для сохранения и загрузки зарезервированы; подключение к OOXML будет реализовано в последующей версии.
- Добавлена справочная тема для нового интерфейса XLSX, описывающая, как lxHandle и lxHandleX сосуществуют и какие вспомогательные компоненты они используют.
Версия 2.16.3
- Представлен
lxHandleX— специализированный модуль фасада XLSX, существующий наряду с фасадом BIFFlxHandle. Оба модуля используют одну и ту же базовую инфраструктуру (пулы стилей, утилиты XML, ZIP-архив), однако предоставляют независимые иерархии классов:lxHandleуправляетTXLSWorkBookи классическими путями XLS/HTML/RTF/CSV;lxHandleXбудет управлятьTXLSXWorkbookи всеми API, специфичными для XLSX. Три заглушки методов, случайно добавленные вlxHandle(SetCodePage,GetColumnXFIndex,GetRowXFIndex), удалены, чтобы публичный API фасада BIFF остался идентичным версии v2.15.0. Существующий код, использующийlxHandle, не требует изменений.
Версия 2.16.2
- Добавлены три внутренних модуля структур данных, завершающих формирование фундамента движка XLSX:
lxAvlTreeпредоставляет AVL-дерево O(log N) (TAVLTree/TAVLNode) для сортированного поиска;lxColsиlxRows— контейнеры информации о столбцах и строках с детальной дедупликацией и перезаписью индексов, используемые картами ширины столбцов и высоты строк для каждого листа в движке XLSX. Все три модуля в данной версии находятся в спящем режиме и будут активированы в v2.17.0 при первом включении движка чтения/записи XLSX.
Версия 2.16.1
- Добавлены шесть внутренних модулей утилит XML и ZIP, завершающих инфраструктурный слой движка XLSX:
lxWStream(файловый поток с широкими символами, проверкой существования файла и вспомогательным методом записи AnsiString);lxCacheStream(буферизированная обёртка потока, сокращающая обращения к нижележащему вводу/выводу);lxZlibStream(однонаправленный поток deflate/inflate, независимый от существующей привязки шифрования BIFFloZlib);lxXmlReader(SAX-подобный читатель с вытягиванием данных для высокоскоростного разбора XML);lxXmlWriter(потоковый XML-писатель с повторным использованием имён элементов);lxZipArchive(читатель/писатель ZIP с центральным каталогом и потоками deflate для каждой записи). Вместе с семью модулями из v2.16.0 они образуют полный внутренний фундамент движка XLSX.
Версия 2.16.0
- Добавлены семь внутренних модулей инфраструктуры стилей, составляющих основу будущего движка XLSX:
lxHashTable(универсальные хэш-таблицы с вариантами ключей Integer, WideString и объект);lxKeyList(список с объектным ключом, поддерживающий быстрый поиск и перезапись индексов);lxStyleColor(менеджер цветов темы Office и слотов палитры);lxStyleFont,lxStyleFillиlxStyleBorder(дедуплицированные пулы стилей шрифта, заливки и границ, охватывающие все 12 типов линий BIFF и сопоставления стилей XLSX);lxStyleXf(объединяет пять пулов стилей со списком числовых форматов в единую запись XF). Все семь модулей в данной версии находятся в спящем режиме и не влияют на существующие пути XLS.
Версия 2.15.1
- Добавлены вспомогательные функции работы с цветом
lxRgb:RGBtoHLS,HLStoRGB,RGBTintиGetRGBTintвыполняют преобразования между цветовыми пространствами RGB и HLS (диапазон HLS 0–240). Они лежат в основе вычислений оттенков цветов темы, условного форматирования по цветовой шкале и интерполяции палитры в выводе XLSX. - Добавлены высокопроизводительные построители строк
lxStrBuilder:TXLSStringBuilder(AnsiChar) иTXLSWideStringBuilder(WideChar) используют предварительно выделенные буферы с удвоением роста, исключая перевыделение памяти при конкатенации стандартных строк Pascal. Вариант AnsiChar обслуживает путь XML-сериализации XLSX; вариант WideChar обрабатывает сборку широких строк в парсере XLSX.
Версия 2.15.0
- Переработана справочная система HtmlHelp в структуру, оптимизированную для веб, с выделенными папками для тем, ресурсов, скриптов, стилей и исходных файлов.
- Добавлена страница домашней страницы справки, удобная для браузера, и страница навигации по содержанию, с унифицированными заголовками, ярлыками тем и нижними колонтитулами.