Notas de versão do HotXLS
Histórico de versões para recursos visíveis, correções, melhorias XLS/XLSX, exportação, compatibilidade e documentação do HotXLS.
[Unreleased]
Versão 2.88.111
- Planilhas Classic XLS agora aceitam TextBox de desenho independentes. Use
TXLSShapes.AddTextBoxpara criar umTXLSTextBoxcom sua própria âncora de linha/coluna, texto, text runs, formatação de linha/preenchimento e exclusão normal de shape sem criar um comentário de célula.
Versão 2.88.110
- Os demos ApiTour agora cobrem mais padrões de automação de workbooks. Os exemplos ApiTour de Delphi e C++Builder demonstram escrita de intervalos baseada em callbacks com
WriteCells, varredura de células carregadas comForEachCell, atualizações de templates comFindTexteReplaceText, exportação HTML do intervalo selecionado paraApiTour-Range.htmle callbacks de fórmulas personalizadas em Delphi por meio deOnUserFunction.
Versão 2.88.109
- Os demos QuickStart agora mostram uma primeira pasta de trabalho mais completa. Os exemplos QuickStart de Delphi e C++Builder criam uma tabela de multiplicação formatada com fórmulas de totais por linha e coluna, painéis congelados e ações XLS/XLSX equivalentes; a árvore de demos agora também inclui páginas readme HTML polidas para cada exemplo.
Versão 2.88.108
- Intervalos XLSX agora têm helpers diretos de exportação HTML.
TXLSXRange.SaveAsHTML(FileName)eTXLSXRange.SaveAsHTML(Stream)exportam apenas o intervalo XLSX selecionado como uma tabela HTML UTF-8, compartilhando o escape, a saída de estilos básicos e o tratamento de spans de células mescladas do renderer HTML do workbook.
Versão 2.88.107
- As planilhas XLSX agora incluem helpers de pesquisa e substituição de texto.
TXLSXWorksheet.FindTexteTXLSXWorksheet.ReplaceTextpercorrem células de texto carregadas em ordem row-major, ignoram fórmulas e valores que não são texto e aceitam correspondência opcional sensível a maiúsculas/minúsculas para fluxos de modelo.
Versão 2.88.106
- Os flags de vista BIFF8 Window2 agora preservam o estado de cor de grade personalizada e painéis congelados. HotXLS agora limpa
fDefaultHdrquandoWindow2.icvHdrarmazena uma cor de grade personalizada, preservafFrozenNoSplitescrito pelo Excel durante open/save e gravafFrozenNoSplitpara a saída deFreezePanes.
Versão 2.88.105
- Os limites de fórmula CF12 agora fazem round-trip em regras BIFF8 Data Bar, Color Scale e Icon Set. Valores de limite baseados em fórmulas são compilados como CF12 formula token bytes ao salvar e restaurados em
TXLSCfValue.Valuequando um workbook é reaberto.
Versão 2.88.104
- As fórmulas Classic XLS e os limites de conjuntos de ícones agora gravam registros BIFF8 mais compactos. Constantes inteiras em fórmulas usam o token compacto
tIntquando cabem no intervalo BIFF unsigned-integer, eTXLSIconSetSpec.ThresholdEqualsInclude[Index]agora controla o CF12 icon-set threshold equals byte para que o chamador escolha a semântica de comparação include ou exclude.
Versão 2.88.103
- As planilhas Classic XLS agora incluem um helper de busca de texto.
IXLSWorksheet.FindText(SearchText, Row, Col[, MatchCase])localiza a primeira célula de texto carregada correspondente, ignora fórmulas e células que não são texto, e limpa as coordenadas retornadas quando nenhuma correspondência é encontrada.
Versão 2.88.102
- As planilhas Classic XLS agora incluem um helper de substituição de texto.
IXLSWorksheet.ReplaceText(SearchText, ReplacementText[, MatchCase])substitui correspondências em células de texto carregadas, ignora fórmulas e células que não são texto, e informa a contagem de células alteradas para fluxos de preenchimento de modelos.
Versão 2.88.101
- Os intervalos agora têm helpers diretos de exportação HTML.
IXLSRange.SaveAsHTML(FileName)eIXLSRange.SaveAsHTML(Stream)exportam o intervalo selecionado pelo renderizador HTML existente, portanto os chamadores não precisam mais criar uma instância deTXLSHTMLExportnem passarxlHTMLexplicitamente para fragmentos de intervalo comuns.
Versão 2.88.100
TXLSWorkbook.GetSheetNames(Stream, AList)agora lê streams de pacotes XLSX além de streams Classic XLS. As aplicações podem passar streams de memória, streams BLOB de banco de dados ou streams XLSX baixados para a facade clássica e receber os nomes das planilhas em ordem sem salvar primeiro em um arquivo.
Versão 2.88.99
- As APIs de busca de planilhas, criação de hiperlinks e seleção de várias áreas agora são mais fáceis de usar. As coleções de planilhas Classic XLS e XLSX adicionam
TryGetSheetByName, as planilhas Classic XLS adicionam sobrecargas de conveniênciaAddHyperlink, eIXLSWorksheet.SelectAreaspode gravar seleções ativas com vários intervalos.
Versão 2.88.98
- As pastas de trabalho Classic XLS agora expõem um alias
UserNamepara o campo de usuário que salvou o arquivo.IXLSWorkbook.UserNamemapeia para o mesmo valor WRITEACCESS queLastSavedBy, permitindo que código que usa a convençãoUserNameleia e atualize diretamente o nome de auditoria da pasta de trabalho.
Versão 2.88.97
- Planilhas XLSX agora compartilham os helpers de varredura de células e escrita de intervalo por callback.
TXLSXWorksheet.ForEachCellenumera células carregadas em ordem de linha com valor e texto da fórmula, enquantoTXLSXWorksheet.WriteCellspreenche intervalos numéricos ou A1-style a partir de um callback com pulo por célula e cancelamento.
Versão 2.88.96
- Planilhas Classic XLS agora oferecem escrita de intervalo orientada por callback.
IXLSWorksheet.WriteCellspreenche um intervalo numérico em base 1 ou um intervalo A1-style em ordem de linha, permite que o callback forneça cada valor de célula, aceita pular células individuais e pode cancelar loops longos de escrita antecipadamente.
Versão 2.88.95
- Planilhas Classic XLS agora podem enumerar células carregadas por callback.
IXLSWorksheet.ForEachCellpercorre as células existentes da planilha em ordem de linha, passa coordenadas de planilha, linha e coluna em base 1 com valor e texto da fórmula, e permite que o callback cancele varreduras longas antecipadamente.
Versão 2.88.94
- O calculo de formulas agora pode chamar funcoes definidas pela aplicacao.
TXLSWorkbook.OnUserFunctioneTXLSXWorkbook.OnUserFunctionpermitem queCalculatedelegue funcoes de planilha personalizadas ou ainda nao suportadas ao codigo da aplicacao, passando argumentos avaliados e usando o resultadoVariantretornado quando a chamada e tratada.
Versão 2.88.93
- A protecao de planilhas Classic XLS agora expõe sinalizadores de permissao por acao.
IXLSWorksheetadicionaAllowDeleteRows,AllowInsertRows,AllowFormatCells,AllowSort,AllowAutoFiltere as demais propriedades de permissao SheetProtect, com opcoes BIFF8 gravadas e relidas pelos registros de protecao existentes.
Versão 2.88.92
- Os payloads VBA do Classic XLS agora têm helpers explícitos para carregar, salvar e limpar.
IXLSWorkbook.LoadVBAProjectFromFile,SaveVBAProjectToFile,HasVBAProjecteClearVBAProjectexpõem o payload de armazenamento OLE VBA preservado, enquantoVBAProjectcontinua sendo a visualização de módulos analisada somente leitura.
Versão 2.88.91
- Os criterios Classic XLS AutoFilter agora podem ser inspecionados por uma colecao de campos.
IXLSWorksheet.AutoFilterColumnsexpoe a contagem atual de campos BIFF8 AutoFilter e itens de campo 1-based, incluindo active state, operator e valores DOPER armazenados emCriteria1/Criteria2.
Versão 2.88.90
- Classic XLS worksheets agora pode configurar criterios AutoFilter em uma unica chamada.
IXLSWorksheet.ApplyAutoFilterdefine um intervalo AutoFilter de worksheet e grava um criterio de campo na mesma chamada, com sobrecargas de intervalo A1-style e numericas 1-based mais operadores opcionais de dois criterios.
Versão 2.88.89
- Classic XLS shapes agora pode ser removido por intervalo de celulas.
TXLSShapes.DeleteInRangeremove imagens ancoradas ou shapes cujos OfficeArt client anchors intersectam um intervalo de planilha 1-based, retornando a quantidade de shapes removidas.
Versão 2.88.88
- Os table layout attributes do Classic HTML export agora sao configuraveis.
TXLSHTMLExport.TableBorderWidth,CellPaddingeCellSpacingcontrolam os atributos<table>gerados para styled e simple HTML output, mantendo como padrao os valores zero anteriores.
Versão 2.88.87
- Classic HTML export agora suporta minimal table output.
TXLSHTMLExport.SimpleExportescreve uma tabela HTML simples sem CSS classes geradas, hyperlink anchors ou comment title attributes, preservando display text escapado e merged-cell spans.
Versão 2.88.86
- Classic HTML export agora pode escrever um document title.
TXLSHTMLExport.Titleescreve um elemento HTML<title>escapado antes do style block gerado, enquanto o valor vazio padrao mantem a saida existente inalterada.
Versão 2.88.85
- Classic HTML export agora leva cell comments como tooltips.
TXLSHTMLExport.Optionsagora incluixhCommentspor padrao e escreve cell comment text como atributostitleescapados, ainda permitindo que os chamadores removam a opcao para obter cell output simples.
Versão 2.88.84
- A saida de hyperlink do Classic HTML export agora e configuravel.
TXLSHTMLExport.Optionsusa[xhHyperlinks]por padrao para manter o comportamento existente, e os chamadores podem removerxhHyperlinkspara exportar celulas com link como texto escapado simples.
Versão 2.88.83
- A exportacao Classic HTML agora preserva hyperlinks de celula.
SaveAsHTMLenvolve celulas com link em anchor tags HTML, emite enderecos de hyperlink como valoreshrefescapados, mantem o texto ScreenTip como atributostitleescapados e preserva o texto exibido da celula escapado dentro do link.
Versão 2.88.82
- As pastas de trabalho Classic XLS agora podem controlar o nome de usuario saved-by.
IXLSWorkbook.LastSavedByexpoe o campo saved-by de WRITEACCESS para que pastas geradas ou editadas possam armazenar um nome de auditoria explicito, enquanto pastas de origem nao editadas continuam preservando os metadados originais.
Versão 2.88.81
- Planilhas Classic XLS agora podem controlar o indice de cor das linhas de grade exibidas.
IXLSWorksheet.GridlineColorIndexexpoe o campo Window2icvHdr, permitindo que planilhas salvas reabram com uma cor de grade escolhida sem alterar a visibilidade das linhas de grade nem as configuracoes de impressao.
Versão 2.88.80
- Os workbooks classic XLS agora podem definir a active sheet por índice.
IXLSWorkbook.ActiveSheetIndexexpõe uma propriedade active-tab 1-based baseada no campo active sheet do WINDOW1, permitindo que workbooks salvos reabram em um worksheet escolhido sem alterar a first visible tab.
Versão 2.88.79
- Os worksheet outlines classic XLS agora podem controlar estilos de outline automáticos.
TXLSOutline.ApplyStylesexpõe o sinalizador outline style do WSBool, permitindo que worksheets salvas preservem ou ativem explicitamente a aplicação de estilos de outline do Excel sem alterar outline levels ou summary placement.
Versão 2.88.78
- A page setup classic XLS agora pode controlar quebras de página automáticas.
IXLSPageSetup.AutoPageBreaksexpõe o sinalizador automatic page-break do WSBool do worksheet, permitindo que worksheets salvas mantenham as quebras automáticas ativadas ou as desativem explicitamente enquanto preservam as quebras manuais.
Versão 2.88.77
- Os workbooks classic XLS agora podem controlar o agrupamento de datas do AutoFilter.
IXLSWorkbook.AutoFilterDateGroupingexpõe o sinalizador de agrupamento de datas do Window1 com uma API Boolean positiva, permitindo que workbooks salvos mantenham o agrupamento de filtros de data do Excel ativado ou o desativem explicitamente.
Versão 2.88.76
- Os workbooks classic XLS agora podem definir diretamente a posição e o tamanho da workbook window.
IXLSWorkbook.XWindow,YWindow,WindowWidtheWindowHeightexpõem os campos Window1 geometry para que workbooks salvos possam reabrir com um window rectangle escolhido.
Versão 2.88.75
- Os workbooks classic XLS agora podem salvar diretamente o estado hidden da workbook window.
IXLSWorkbook.WindowHiddenmapeia para o sinalizador hidden de Window1, permitindo que workbooks salvos reabram com a workbook window hidden sem alterar a visibilidade de worksheet.
Versão 2.88.74
- Os workbooks classic XLS agora podem salvar diretamente o estado minimized da workbook window.
IXLSWorkbook.Minimizedmapeia para o sinalizador minimized de Window1, permitindo que workbooks salvos reabram com a workbook window minimizada.
Versão 2.88.73
- Os workbooks classic XLS agora podem ocultar ou mostrar diretamente a barra de rolagem vertical.
IXLSWorkbook.ShowVerticalScrollmapeia para o sinalizador Window1fDspVScroll, permitindo que workbooks salvos abram com a barra de rolagem vertical oculta ou visível.
Versão 2.88.72
- Os workbooks classic XLS agora podem ocultar ou mostrar diretamente a barra de rolagem horizontal.
IXLSWorkbook.ShowHorizontalScrollmapeia para o sinalizador Window1fDspHScroll, permitindo que workbooks salvos abram com a barra de rolagem horizontal oculta ou visível.
Versão 2.88.71
- Os workbooks classic XLS agora podem ocultar ou mostrar diretamente a sheet tab bar.
IXLSWorkbook.ShowSheetTabsmapeia para o sinalizador Window1fDspTabs, permitindo que workbooks salvos abram com sheet tabs ocultas ou visíveis sem alterar a visibilidade de worksheet.
Versão 2.88.70
- Os workbooks classic XLS agora podem definir diretamente a proporção da workbook tab bar.
IXLSWorkbook.TabRatioexpõe o valor Window1wTabRatiopara que os chamadores possam ajustar o espaço reservado para sheet tabs em relação à barra de rolagem horizontal.
Versão 2.88.69
- Os workbooks classic XLS agora podem definir diretamente a primeira sheet tab visível.
IXLSWorkbook.FirstSheetexpõe o valor Window1itabFirstcomo uma propriedade 1-based, para que os chamadores possam escolher qual sheet tab aparece na borda esquerda quando o Excel abre o workbook.
Versão 2.88.68
- As worksheets classic XLS agora podem preservar e definir a visibilidade de outline symbols.
IXLSWorksheet.DisplayOutlineSymbolsmapeia para o sinalizador BIFF WINDOW2fDspGuts, permitindo que sheets salvas ocultem símbolos de outline e grouping na visualização da janela.
Versão 2.88.67
- As worksheets classic XLS agora podem preservar e definir a visibilidade de cabeçalhos de linhas e colunas.
IXLSWorksheet.DisplayHeadingsmapeia para o sinalizador BIFF WINDOW2fDspRwCol, permitindo que sheets salvas ocultem números de linha e letras de coluna na visualização da janela.
Versão 2.88.66
- As worksheets classic XLS agora podem preservar e definir a visualização de fórmulas.
IXLSWorksheet.DisplayFormulasmapeia para o sinalizador BIFF WINDOW2fDspFmla, para que o Excel possa abrir uma sheet mostrando texto de fórmula em vez de resultados calculados.
Versão 2.88.65
- As worksheets classic XLS agora podem definir o zoom de Normal view de forma independente.
IXLSWorksheet.NormalViewZoomexpõe o WINDOW2 Normal zoom em cache para que os chamadores possam salvar níveis de zoom distintos enquanto uma sheet está em Page Break Preview.
Versão 2.88.64
- As worksheets classic XLS agora podem definir diretamente o zoom de Page Break Preview.
IXLSWorksheet.PageBreakPreviewZoomexpõe o WINDOW2 preview zoom em cache para que os chamadores possam salvar níveis de zoom diferentes para Normal e Page Break Preview.
Versão 2.88.63
- As worksheets classic XLS agora expõem auxiliares de painéis divididos.
IXLSWorksheet.SplitPanes(Width, Height)cria uma divisão móvel usando o BIFF pane writer existente, eUnsplitPaneslimpa o pane record antes de salvar.
Versão 2.88.62
- As worksheets classic XLS agora têm auxiliares mais simples para painéis congelados.
IXLSWorksheet.FreezePanes(Cols, Rows)congela as colunas à esquerda e as linhas superiores solicitadas, enquantoUnfreezePanesremove o pane record antes de salvar.
Versão 2.88.61
- A descoberta de nomes de planilhas classic XLS agora aceita streams.
TXLSWorkbook.GetSheetNames(Stream, List)lê nomes de planilhas BIFF de um XLS stream fornecido pelo chamador sem carregar conteúdo de worksheet, acompanhando o auxiliar por nome de arquivo para dados de workbook em memória.
Versão 2.88.60
- As coleções de worksheet agora expõem auxiliares diretos de busca por nome.
IXLSWorkSheets.SheetByName(Name)eTXLSXSheets.SheetByName(Name)retornam o objeto worksheet correspondente ounil, então o chamador não precisa mais resolver um índice antes de acessar uma planilha.
Versão 2.88.59
- A facade XLSX agora lê nomes de planilhas diretamente de streams.
TXLSXWorkbook.GetSheetNames(Stream, List)lê nomes ordenados dexl/workbook.xmlsem carregar worksheet XML, acompanhando a sobrecarga por nome de arquivo para pastas de trabalho em memória ou armazenadas como BLOB.
Versão 2.88.58
- A facade XLSX agora expõe leitura rápida de nomes de planilhas.
TXLSXWorkbook.GetSheetNames(FileName, List)lê nomes ordenados dexl/workbook.xmlsem carregar worksheet XML.
Versão 2.88.57
TXLSWorkbook.GetSheetNamesagora oferece suporte a pacotes XLSX. O método lêxl/workbook.xmlde arquivos.xlsx,.xlsm,.xltxe.xltme retorna nomes de planilhas ordenados sem carregar worksheet XML.
Versão 2.88.56
- Pastas de trabalho XLS clássicas agora podem ler nomes de planilhas sem carregar as planilhas.
TXLSWorkbook.GetSheetNames(FileName, List)examina o workbook globals stream e retorna nomes de planilhas ordenados de arquivos Excel 97-2003.xls.
Versão 2.88.55
- Os critérios AutoFilter de ranges XLS clássicos agora gravam registros de filtro BIFF8.
TXLSRange.Autofilter(Field, Criteria)cria o range de filtro quando necessário e emite condiçõesAUTOFILTERpara critérios simples de string, numéricos, Boolean, em branco, não em branco e com prefixos de comparação.
Versão 2.88.54
- As planilhas XLS clássicas agora têm auxiliares AutoFilter no nível da planilha.
IXLSWorksheet.SetAutoFilter,ClearAutoFiltereAutoFilterRangegerenciam diretamente os intervalos suspensos de filtro BIFF8, reutilizando o escritor existente deAUTOFILTERINFOe do nome de banco de dados de filtro.
Versão 2.88.53
- As planilhas XLS clássicas agora expõem a criação de validação de dados de lista.
IXLSWorksheet.AddListValidation(Range, Items)grava registros BIFF8DVALeDV, mantém a lista suspensa visível por padrão, oferece suporte a listas embutidas separadas por vírgulas e preserva as regras em ciclosOpen/SaveAs.
Versão 2.88.52
- O cálculo de fórmulas agora funciona de forma consistente nos pontos de entrada XLS e XLSX.
TXLSWorkbook.Calculateagora aceita fórmulas no estilo do Excel que começam com o sinal de igual, como=SUM(A1:B1)+C1. A fachada XLSX adicionaTXLSXWorkbook.CalculateeTXLSXWorksheet.Calculate. O caminho XLSX compartilha o analisador e o avaliador de tokens de fórmula do HotXLS para referências de células e intervalos, células referenciadas em fórmulas, referências entre planilhas e intervalos nomeados definidos no escopo da pasta de trabalho ou da planilha.
Versão 2.88.51
- Os intervalos XLSX agora suportam merge across ao estilo do Excel.
TXLSXRange.Merge(True)escreve uma entrada<mergeCell>por linha, alinhando-se ao comportamento clássico de XLSRange.Merge(True), enquantoMergesem argumentos eMerge(False)continuam a criar um único retângulo mesclado para todo o intervalo.
Versão 2.88.50
- BIFF8 HeaderFooter e HFPicture agora seguem as regras MS-XLS atuais. HotXLS preserva os registos
HeaderFooter($089C) escritos pelo Excel para cabeçalhos e rodapés de páginas pares / primeira página, e reemite os registosHFPicture($0866) após as dimensões da folha e os objetos de desenho conforme o worksheet ABNF, para que os detalhes de layout de página sobrevivam aos ciclos abrir/guardar .xls.
Versão 2.88.49
- Os runs de rich text de comentários agora têm uma API tipada.
TXLSComment.TextRunsexpõe entradas BIFF8TXOFormatRun, permitindo inspecionar ou definir limites de fonte por caractere em comentários .xls, enquanto o HotXLS preserva os bytes de run subjacentes para round-trips seguros.
Versão 2.88.48
- Os registros SX suplementares de tabelas dinâmicas agora são expostos pela API tipada. O HotXLS agora anexa registros pivot BIFF8 carregados, como
SXIVD,SXLI,SXFormat,SXEx,SXVDEx,SXRule,SXFilteSXAddl, aTXLSPivotTable.SupplementalRecordspara inspeção, enquanto ainda preserva os raw bytes originais para round-trips de salvamento.
Versão 2.88.47
- Os valores em cache de pastas de trabalho externas agora sobrevivem a ciclos de abrir/salvar .xls. O HotXLS agora preserva os registros BIFF8
XCTeCRNanexados a entradasSUPBOOKcarregadas, portanto os cached cell values de links para pastas de trabalho externas não são mais descartados ao salvar.
Versão 2.88.46
- Os níveis de contorno de estilos internos agora sobrevivem a ciclos de abrir/salvar .xls. O HotXLS agora lê e preserva o byte
iLeveldeSTYLEBIFF8 para estilos internos, portanto os metadados RowLevel_1..7 e ColLevel_1..7 do Excel não são mais redefinidos para o padrão ao salvar.
Versão 2.88.45
- Os metadados de nomes definidos agora sobrevivem a ciclos de abrir/salvar .xls. O HotXLS agora preserva os bits de opção e os bytes de atalho dos registros BIFF8
NAMEcarregados enquanto o nome definido não for editado, portanto os metadados de function, object, procedure, calculated-expression e binary-name gravados pelo Excel não são mais apagados ao salvar.
Versão 2.88.44
- Marcadores ObProj da pasta de trabalho agora sobrevivem a ciclos de abrir/salvar .xls. O HotXLS agora preserva registros BIFF8
ObProjcarregados mesmo quando nenhum storage VBA é exposto pelo modelo de objetos, para que marcadores de projeto VBA no nível da pasta de trabalho e metadados de terceiros não sejam mais descartados ao salvar.
Versão 2.88.43
- Flags de opções da planilha agora sobrevivem a ciclos de abrir/salvar .xls. O HotXLS agora preserva bits BIFF8
WSBOOLnão modelados, como planilha de diálogo, quebras de página automáticas, aplicação de estilos e exibição de gutters de estrutura, enquanto ainda atualiza pelas APIs públicas as configurações existentes de ajustar à página e resumo de estrutura.
Versão 2.88.42
- Registros adicionais de metadados da pasta de trabalho agora sobrevivem a ciclos de abrir/salvar .xls. O HotXLS agora preserva os corpos carregados dos registros BIFF8
COUNTRY,BOOKBOOL,BACKUP,FNGROUPCOUNT,USESELFSeRECALCIDem vez de regravá-los com padrões, mantendo estáveis a compatibilidade e os metadados de cálculo no nível da pasta de trabalho.
Versão 2.88.41
- Seleções de várias áreas e o foco do painel ativo agora sobrevivem a ciclos de abrir/salvar .xls. O HotXLS agora preserva registros BIFF8
SELECTIONcarregados e o valor de painel ativo dePANES, a menos que a seleção da planilha ou os painéis sejam alterados pela API, para que o foco de painéis divididos/congelados do Excel e seleções de vários intervalos não sejam mais colapsados ao salvar.
Versão 2.88.40
- Nomes de pastas de trabalho externas agora sobrevivem a ciclos de abrir/salvar .xls. O HotXLS agora preserva registros BIFF8
EXTERNALNAMEcarregados e associados a entradas externasSUPBOOK, incluindo metadados DDE/OLE/de link e caudas de fórmula, para que nomes externos e definições de links não sejam mais descartados ao salvar.
Versão 2.88.39
- Arquivos BIFF8 .xls protegidos por senha agora gravam e leem registros FILEPASS RC4 CryptoAPI. O HotXLS agora grava metadados
FILEPASSvMajor=2 no estilo do Excel 2007/2010 para pastas de trabalho .xls criptografadas e le tanto RC4 legado vMajor=1 quanto RC4 CryptoAPI vMajor=2/3/4, para que pastas protegidas por senha nao falhem mais nesse cabecalho de criptografia nem rebaixem para o cabecalho antigo.
Versão 2.88.38
- Os metadados de hiperlinks .xls gravados pelo Excel agora sobrevivem aos ciclos de abrir/salvar. O HotXLS agora preserva o
HLinkrecord body BIFF8 para hiperlinks carregados enquanto o hiperlink não for editado, mantendo estáveisstreamVersion, oshlstmfoption bits comofIcon, dados moniker e metadados de destino relacionados ao salvar.
Versão 2.88.37
- O estado da janela da pasta de trabalho agora sobrevive aos ciclos de abrir/salvar .xls. O HotXLS agora lê e preserva posição, tamanho, flags de visibilidade/iconic, primeira guia de planilha exibida, contagem de guias selecionadas e proporção entre guias e barra de rolagem do registro BIFF8
WINDOW1, em vez de regravá-los com padrões a cada salvamento.
Versão 2.88.36
- Os usuários saved-by do BIFF8 WriteAccess agora sobrevivem aos ciclos de abrir/salvar .xls. O HotXLS agora lê e preserva o
$005C WRITEACCESSrecord body em vez de substituir o usuário saved-by gravado pelo Excel porHotXLS, mantendo estáveis os metadados de auditoria da pasta de trabalho após salvar.
Versão 2.88.35
- Autores de comentários do Excel agora sobrevivem a round-trips de abrir/salvar .xls. O campo
stAuthordo registro BIFF8Noteagora é analisado e passado ao drawing note model em vez de ser substituído por uma string vazia, então o autor "Created by" do comentário escrito pelo Excel é preservado quando o HotXLS salva o workbook novamente.
Versão 2.88.34
- As opções OfficeArt FOPT de formas agora são expostas por um option bag de baixo nível.
TXLSShape.OfficeArtOptionspermite que chamadores avançados inspecionem, definam e excluam qualquer PID FOPT armazenado comoLongWordouWideString, enquanto as APIs de alto nível existentes deLine,Fill, cor e visibilidade permanecem inalteradas.
Versão 2.88.33
- Mais registros de regra do solver-container OfficeArt agora fazem round-trip. Além do
msofbtConnectorRule($F012) tipado, o HotXLS agora preserva solver children que não são folders, comoOfficeArtFArcRule($F014) eOfficeArtFCalloutRule($F017), como registros OfficeArt brutos dentro demsofbtSolverContainer($F005), para que desenhos avançados do Excel não percam relações solver que não sejam de conectores ao salvar.
Versão 2.88.32
- Marcadores OfficeArt ClientData não são mais duplicados após a preservação de registros desconhecidos. O MS-XLS define
OfficeArtClientData($F011) como um marcador de comprimento zero; o registroObjseguinte continua sendo um registro BIFF separado. A v2.88.32 reconhece esse marcador em vez de capturá-lo como um leaf SpContainer desconhecido, então formas analisadas emitem exatamente um marcador $F011 ao salvar. Suposições container-style fora da especificação permanecem fora do caminho XLS.
Versão 2.88.31
- As regras de conectores OfficeArt agora fazem round-trip. Desenhos .xls criados pelo Excel armazenam vínculos de conectores em
msofbtSolverContainer($F005) com registros filhosmsofbtConnectorRule($F012). A v2.88.31 analisa e emite esse par $F005/$F012 por meio deTMsoConnectorRules, preservando a forma inicial, a forma final, a forma conectora e os pontos de conexão entre salvar e recarregar. A nota de auditoria anterior indicava $F121, mas o MS-ODRAW defineOfficeArtFConnectorRulecomo $F012.
Versão 2.88.30
- Registros leaf OfficeArt SpContainer não reconhecidos agora fazem round-trip. Arquivos .xls criados pelo Excel costumam incluir no SpContainer de cada forma Fbts leaf como
msofbtClientTextbox($F00D),OfficeArtFPSPL($F11D), andOfficeArtUDefProp($F122). A v2.88.30 captura leaf desconhecidos de nível de forma comoTMsoFbtUnknowne os reemite na ordem de parse entreClientAnchore o marcador finalmsofbtClientDatade corpo zero. - Escopo e continuidade. Outros leaf desconhecidos de nível de desenho seguem adiados; o caso SolverContainer das regras de conector é tratado pela v2.88.31. Unknowns em forma de contêiner, como
msofbtClientData($F011) usado como contêiner em vez de sibling marker, ficam para o Slice 3 da auditoria.
Versão 2.88.29
- Subregistros OBJ desconhecidos de ComboBox e ListBox agora fazem round-trip. TMSOShapeComboBox.ParseObj e TMSOShapeListBox.ParseObj ja faziam typed-parse de FtSbs ($000C), FtSbsFmla ($000E) e FtLbsData ($0013) em campos dedicados, mas qualquer outro subregistro do arquivo origem (FtMacro $0004, ObjLinkFmla, FtNts $000D, etc.) aparecendo entre CMO e FtLbsData era descartado silenciosamente no case fall-through. v2.88.29 adiciona o mesmo ramo else que v2.88.28 Picture, capturando o cabecalho de 4 bytes + corpo do subregistro desconhecido em
FObjTailRaw. Ambos os metodos AddObj emitem os bytes capturados entre o corpo CMO e o subregistro FtSbs para corresponder a ordem de subregistros da spec BIFF8. - O comportamento "engolir tudo" do FtLbsData limita o escopo. O case existente
$0013sobrescreveRecLen := Len - offspara absorver todos os bytes apos o cabecalho FtLbsData no blob deFObjRec_LBSData, entao subregistros que aparecem APOS FtLbsData (tipicamente apenas FtEnd) ainda fazem round-trip atraves desse mecanismo inalterados. A nova integracao FObjTailRaw mira especificamente a lacuna antes de FtLbsData onde FtMacro e ObjLinkFmla tipicamente vivem. Combo / list boxes recem-criados via Drawing API temFObjTailRawvazio → saida byte-identica a v2.88.28.
Versão 2.88.28
- Subregistros OBJ desconhecidos da forma Picture agora fazem round-trip. TMSOShapePicture.ParseObj ja fazia typed-parse de FtCf ($0007), FtPioGrbit ($0008) e FtPictFmla ($0009) em campos dedicados, mas qualquer outro subregistro do arquivo origem (FtMacro $0004, FtNts $000D, etc.) era descartado silenciosamente no case fall-through. v2.88.28 adiciona um ramo else que anexa o cabecalho completo de 4 bytes + corpo de subregistros nao reconhecidos a
FObjTailRaw; TMSOShapePicture.AddObj entao emite esses bytes verbatim apos sua saida de subregistros tipados e antes do marcador FtEnd. Objetos picture do arquivo origem com hooks de macro sobrevivem ao salvamento. - Padrao de coexistencia typed + raw. Ao contrario do PictureFrame (v2.88.27) que usava uma troca if/else entre emissao tipada e bruta, o Picture combina ambos: os campos tipados preservam a superficie da API (os chamadores ainda podem ajustar
ftCfValueetc.), enquanto a cauda bruta preserva apenas os bytes desconhecidos. Imagens recem-criadas via Drawing API temFObjTailRawvazio, entao a saida e byte-identica a v2.88.27.
Versão 2.88.27
- Round-trip de subregistros finais OBJ estendido para formas PictureFrame. TMSOShapePictureFrame.AddObj antes emitia apenas os subregistros legados codificados FtCf ($0007, corpo $FFFF) e FtPioGrbit ($0008, corpo $0000) entre CMO e FtEnd. Para molduras de imagem recem-criadas, o novo codigo ainda emite esses valores padrao; para molduras de imagem analisadas de um .xls origem, os bytes
FObjTailRawcapturados sao emitidos verbatim em vez disso, preservando qualquer FtPictFmla do arquivo origem / FtCf nao-padrao / FtPioGrbit nao-padrao atraves do ciclo de salvar. - Nota de investigacao — Flush corrige sz automaticamente.
TMsoShapeContainer.Flushreescreve o cabecalho de tamanho do registro Obj no momento do commit viaData.SetWord(Data.DataLength - 4, 2), o que significa que os valores codificadossz := $1Aque viveram nas implementacoes AddObj do HotXLS por anos nao eram bugs de spec afinal — Flush os corrige automaticamente. v2.88.27 ainda calcula sz com precisao para clareza do codigo fonte, mas o comportamento em tempo de execucao e inalterado dessa perspectiva.
Versão 2.88.26
- Round-trip de subregistros finais OBJ estendido para formas Chart e CheckBox. v2.88.25 introduziu a preservacao de bytes brutos entre o CMO ($0015) de um registro Obj e seu marcador FtEnd ($0000), mas apenas TMSOShapeTextBox.AddObj emitia a cauda capturada. Esta versao aplica o mesmo padrao a TMSOShapeChart.AddObj e TMSOShapeCheckBox.AddObj — ambos compartilham a estrutura simples de emissao "CMO + FtEnd" do TextBox, entao a mudanca e uma substituicao de variavel de uma linha (
sz := $1A + Word(Length(FObjTailRaw))) mais um loop de emissao verbatim de bytes antes do marcador FtEnd. - Subregistros finais de Chart (por exemplo FtMacro para macros de objetos chart embutidos) e subregistros de estado de checkbox (FtCbls + FtCblsData + ObjLinkFmla, MS-XLS §2.5.140-141 / §2.5.149) agora sobrevivem ao ciclo salvar/recarregar do HotXLS. Charts e checkboxes recem-criados via Drawing API continuam emitindo um CMO+FtEnd padrao de 26 bytes (identico byte a byte a v2.88.25), entao chamadores existentes nao veem mudanca de comportamento. Formas Picture / ComboBox / ListBox / PictureFrame possuem sua propria emissao dinamica de subregistros tipados que conflita com FObjTailRaw — sua integracao e adiada para commits futuros.
Versão 2.88.25
- Subregistros finais do registro OBJ agora preservados ao longo do ciclo de salvar para comentarios. O registro BIFF8 Obj ($005D) encadeia uma sequencia de subregistros tipados apos o CMO obrigatorio ($0015), terminada por um marcador FtEnd ($0000), conforme MS-XLS §2.4.181. Para formas Note (comentario), o bloco final e tipicamente um FtNts (§2.5.149) de 26 bytes carregando um GUID e o flag fSharedNote — ambos essenciais quando o Excel posteriormente mescla comentarios entre usuarios em pastas de trabalho compartilhadas. O HotXLS antes descartava cada byte apos CMO na leitura e emitia apenas um FtEnd vazio na escrita, entao qualquer FtNts do arquivo origem era perdido em cada gravacao do HotXLS.
- Captura na base generica, emissao apenas TextBox (R5-3 primeira fase). TMsoShapeContainer.ParseObj agora captura o intervalo de bytes entre o final do corpo CMO e o marcador FtEnd em um novo campo interno
FObjTailRaw: TBytes; TMSOShapeTextBox.AddObj insere esses bytes entre sua emissao CMO e o marcador FtEnd, com o tamanho do cabecalho do registro Obj ajustado de acordo. Comentarios recem-criados (sem bytes fonte) mantem saida byte-identica a v2.88.24. Outras classes de forma (Picture / CheckBox / ComboBox / ListBox / Chart) herdam a captura mas suas sobreposicoes AddObj tipadas mantem o comportamento legado de "sintetizar do zero" — emissao de bytes brutos para esses tipos de forma e adiada para commits futuros.
Versão 2.88.24
- Comentarios de celula com varias fontes e cores agora sobrevivem ao ciclo de salvar. O bloco de execucoes de formatacao do registro BIFF8 TXO (
rgTxoRuns+TxOLastRunconforme MS-XLS §2.5.272) carrega as substituicoes de fonte e cor por execucao que dao ao comentario seu estilo de texto enriquecido. O HotXLS antes descartava o bloco inteiro na leitura e emitia uma unica execucao vazia padrao + LastRun na escrita — achatando qualquer "Importante!" destacado em vermelho ou palavra em negrito dentro do texto do comentario para formatacao padrao uniforme a cada gravacao do HotXLS. - Preservacao byte-a-byte em TMSOShapeTextBox. ParseTXO captura os bytes Continue apos o texto verbatim em um novo campo interno
FFormatRunsRaw: TBytes; Store os emite de volta como Continue de execucoes de formatacao e ajusta o cabecalhocbRunsdo registro base para coincidir. Comentarios recem-criados (viaAddComment) mantem a saida legada de unica execucao padrao inalterada, entao saida byte-identica e preservada para pastas de trabalho padrao. O acesso da API Excel tipado a execucoes de formatacao individuais ainda esta adiado — a API existente de comentario WideString unica nao foi alterada.
Versão 2.88.23
- Resolucao de impressao e numero de copias agora sobrevivem ao ciclo de salvar — registro Setup totalmente coberto. Tres campos Word do registro Setup (
iResno offset 12,iVResno offset 14,iCopiesno offset 32, conforme MS-XLS §2.4.257) carregam as escolhas "Configurar pagina → Pagina → Qualidade de impressao" e "Numero de copias" do Excel. O HotXLS antes descartava todos os tres na leitura e emitia valores codificados (600 DPI / 600 DPI / 1 copia), entao qualquer resolucao ou contagem de copias ajustada pelo usuario revertia silenciosamente apos cada gravacao do HotXLS. - Tres novas propriedades TXLSPageSetup.
PrintResolution: LongWord,PrintVResolution: LongWordeCopies: LongWord— todos os padroes correspondem aos valores que o gravador codificava antes (600 / 600 / 1), entao pastas de trabalho que nunca os tocam produzem saida byte-identica a v2.88.22. Os setters limitam aHigh(Word)para que um valor de chamador demasiado grande nao transborde no emit. - Trabalho de round-trip do registro Setup completo. Com esta correcao, cada campo visivel ao usuario do registro BIFF8 Setup ($00A1) sobrevive ao round-trip de ponta a ponta — tamanho do papel / escala / numero da primeira pagina / ajustar a largura e altura / orientacao / ordem de impressao / preto e branco / rascunho / imprimir comentarios / erros de celula / resolucao / copias. Restam sem exposicao apenas os dois bits de hint da spec (
fNoPls,fNoOrient) — HotXLS escreve ambos como zero, correspondendo ao comportamento padrao do Excel.
Versão 2.88.22
- "Numero da primeira pagina" personalizado de Configurar pagina agora sobrevive ao ciclo de salvar. O registro BIFF8 Setup carrega a escolha da pasta de trabalho Configurar pagina → Pagina → "Numero da primeira pagina" como dois campos relacionados: o bit 7 do grbit (
fUsePage) seleciona entre o padrao "Auto" do Excel e um numero de pagina inicial explicito, e o Word com sinal no offset 4 (iPageStart) detem esse valor personalizado, conforme MS-XLS §2.4.257. O HotXLS antes descartava ambos na leitura e emitiaiPageStart = 1com o bit limpo, entao um "Numero da primeira pagina: 100" digitado pelo usuario revertia silenciosamente para "Auto" apos cada gravacao do HotXLS. - Duas novas propriedades TXLSPageSetup.
UseFirstPageNumber: Booleanreflete o bit (False = "Auto", padrao);FirstPageNumber: Integercarrega o valor iPageStart (padrao 1, limitado pelo setter ao intervalo signed-Word da spec -32768..32767). HotXLS faz round-trip deiPageStartverbatim mesmo quandoUseFirstPageNumbere False, entao alternar entre Auto e personalizado no Excel preserva o ultimo valor digitado pelo usuario.
Versão 2.88.21
- A escolha "Imprimir comentarios no final da planilha" agora sobrevive ao ciclo de salvar. O bit 9 (
fEndNotesconforme MS-XLS §2.4.257) do campo grbit do registro BIFF8 Setup carrega a distincao do menu suspenso Configurar pagina → Planilha → Comentarios entre "Como exibido na planilha" (padrao) e "No final da planilha". O HotXLS ja fazia round-trip de PrintNotes (bit 5) para controlar se os comentarios sao impressos, mas o bit 9 era descartado na leitura e emitido como zero na escrita — entao um "No final da planilha" escolhido pelo usuario revertia silenciosamente para "Como exibido na planilha" apos cada gravacao do HotXLS. - Nova propriedade booleana TXLSPageSetup.PrintNotesAtEnd. Padrao
Falsecorresponde ao padrao da UI do Excel. O leitor e o gravador fazem round-trip do bit verbatim (mesmo quandoPrintNotes = False), entao uma pasta de trabalho com comentarios temporariamente desabilitados mantem a preferencia "no final da planilha" para quando o usuario os reabilita — espelhando o proprio comportamento do Excel.
Versão 2.88.20
- A escolha da pasta de trabalho "Definir precisao conforme exibida" agora sobrevive ao ciclo de salvar. O registro BIFF8 CalcPrecision ($000E) carrega a caixa de selecao em nivel de pasta de trabalho Arquivo → Opcoes → Avancado → "Definir precisao conforme exibida", conforme MS-XLS §2.4.35. O HotXLS antes nao tinha caso no dispatcher para $000E e TXLSWorkbook.StorePrecision emitia um
1codificado (= precisao total retida). Uma "Definir precisao conforme exibida" marcada pelo usuario revertia silenciosamente para "precisao total" apos cada gravacao do HotXLS — escondendo a intencao deliberada do usuario de que qualquer recalculo posterior truncasse permanentemente os valores de celula para suas casas decimais formatadas. - Nova propriedade booleana TXLSWorkbook.UseFullPrecision. Padrao
True(corresponde ao padrao BIFF8 e ao padrao da UI do Excel desmarcado). Defini-la comoFalseequivale a marcar a opcao destrutiva "precisao conforme exibida" — o HotXLS em si nao trunca nenhum valor de celula durante o round-trip, mas o flag agora e fielmente reescrito para que o proximo recalculo do Excel o respeite. Com esta correcao, cada registro BIFF8 de calculo (CalcCount / CalcMode / CalcPrecision / CalcDelta / CalcIter / CalcSaveRecalc) sobrevive ao round-trip de ponta a ponta.
Versão 2.88.19
- A caixa "Recalcular pasta de trabalho antes de salvar" agora sobrevive ao ciclo de salvar. O registro BIFF8 CalcSaveRecalc ($005F) carrega o booleano da pasta de trabalho Arquivo → Opcoes → Salvar → "Recalcular pasta de trabalho antes de salvar", conforme MS-XLS §2.4.37. O HotXLS antes nao tinha caso no dispatcher para $005F e StoreCalculationSettings emitia um
1codificado — entao "recalcular ao salvar" desabilitado pelo usuario se reabilitava silenciosamente a cada gravacao do HotXLS, o que era especialmente relevante para pastas de trabalho em modo de calculo manual onde o usuario havia deliberadamente congelado os valores de celula em disco. - Nova propriedade booleana TXLSWorkbook.RecalcOnSave. Padrao
True(corresponde ao padrao da UI do Excel e ao valor codificado legado), entao pastas de trabalho que nunca tocam a propriedade mantem saida byte-identica a v2.88.18. O setter aceita qualquer booleano; o leitor normaliza bytes de origem arbitrarios diferentes de zero paraTrue.
Versão 2.88.18
- As configuracoes de calculo iterativo (habilitar + maximo de iteracoes + mudanca maxima) agora sobrevivem ao ciclo de salvar. Os registros BIFF8 CalcIter ($0011), CalcCount ($000C) e CalcDelta ($0010) carregam juntos o trio de opcoes "Habilitar calculo iterativo" do Excel (Arquivo → Opcoes → Formulas), conforme MS-XLS §2.4.33 / §2.4.31 / §2.4.32. Nenhum dos tres tinha caso no dispatcher antes, e StoreCalculationSettings os emitia com valores codificados (desligado / 100 / 0.001). Um loop de 1000 iteracoes configurado pelo usuario com delta de convergencia de 0.0001 era redefinido silenciosamente para "iteracao desligada, 100, 0.001" apos cada gravacao do HotXLS — quebrando formulas com referencia circular e modelos financeiros sensiveis a convergencia.
- Tres novas propriedades TXLSWorkbook.
EnableIteration: Booleanreflete a caixa de selecao;MaxIterations: LongWorde o limite de iteracao (o setter o limita ao intervalo legal da spec 1..32767);MaxIterationChange: Doublee o delta de convergencia (entrada negativa salta para o padrao da spec 0.001). Os valores padrao correspondem aos que o gravador codificava antes, entao pastas de trabalho que nunca tocam as novas propriedades produzem saida byte-identica a v2.88.17.
Versão 2.88.17
- O modo de calculo da pasta de trabalho (Manual / Automatico / Automatico exceto tabelas) agora sobrevive ao ciclo de salvar. O registro BIFF8 CalcMode ($000D) carrega a escolha de "Formulas → Opcoes de calculo" no nivel da pasta de trabalho conforme MS-XLS §2.4.36. O HotXLS antes nao tinha nenhum caso no dispatcher para $000D, entao o valor do arquivo de origem era descartado ao carregar, e o gravador sempre emitia um
$0001codificado (Automatico). Um modo Manual escolhido pelo usuario revertia silenciosamente para Automatico apos cada gravacao do HotXLS — ruim para pastas de trabalho grandes onde Manual e definido propositadamente por desempenho. O novo manipulador ParseCalcMode armazena o valor de origem na pasta de trabalho e StoreCalculationSettings agora emite o valor armazenado em vez da constante. - Nova propriedade TXLSWorkbook.CalculationMode. Propriedade
LongWordde leitura/escrita que aceitaxlCalcManual(0),xlCalcAutomatic(1, padrao) ouxlCalcAutomaticExceptTables(0xFFFF) — tres novas constantes exportadas delxTNC.inc. O setter limita valores desconhecidos ao padrao da spec, de modo que um arquivo de origem corrompido nao pode deixar a pasta de trabalho em um estado indefinido. O codigo existente que nunca toca a propriedade mantem o valor padrao legado ("Automatico"), a saida anterior e identica byte a byte para pastas de trabalho padrao.
Versão 2.88.16
- A escolha "Erros de celula como" da Configurar pagina agora sobrevive ao ciclo de salvar. O registro BIFF8 Setup ($00A1) empacota o menu suspenso Configurar pagina → Planilha "Erros de celula como: exibido / <branco> / <traco> / <N/A>" nos bits 10-11 de sua palavra grbit como
iErrors, conforme MS-XLS §2.4.257. O HotXLS antes descartava esses bits na leitura e os emitia como zero na escrita, entao uma pasta de trabalho que o usuario havia configurado para imprimir#DIV/0!como#N/Arevertia silenciosamente para "exibido" apos cada gravacao do HotXLS. O leitor agora decodificaiErrorsem uma nova propriedadeTXLSPageSetup.PrintCellErrorse o gravador reconstroi o campo a partir dela. - Nova propriedade TXLSPageSetup.PrintCellErrors. Propriedade
LongWordde leitura/escrita que aceitaxlPrintErrorsDisplayed(0, padrao),xlPrintErrorsBlank(1),xlPrintErrorsDash(2) ouxlPrintErrorsNA(3) — quatro novas constantes exportadas delxTNC.inc. Chamadores existentes de PageSetup que nunca tocam a propriedade mantem o valor padrao ("exibido"), a saida de impressao anterior permanece inalterada.
Versão 2.88.15
- O alinhamento e a orientacao dos comentarios de celula agora se preservam no ciclo de salvar. O registro base TXO do BIFF8 ($01B6) carrega cinco flags tipados em sua palavra
grbit(hAlignment, vAlignment, fLockText, fJustLast, fSecretEdit) mais uma palavrarotseparada para a orientacao do texto, conforme MS-XLS §2.4.329. O leitor antes descartava todos eles e o gravador fixavagrbitno valor codificado0x0012(esquerda + topo) com rotacao sempre 0, de modo que cada gravacao revertia um comentario centralizado ou girado para esquerda+topo+horizontal independentemente da origem. O leitor agora decodifica os campos tipados ao carregar e o gravador compoegrbita partir deles, entao o layout sobrevive ao ciclo gravar/recarregar. - Seis novas propriedades de TMSOShapeTextBox para estilizar comentarios explicitamente.
HAlignment,VAlignment,Rotation,LockText,JustLastLineeSecretEditsao expostas como propriedades de leitura/escrita em cada forma de comentario;AddCommentinicializa por padrao com esquerda+topo+horizontal+desbloqueado, entao chamadores que nao as alteram mantem a aparencia anterior. - O gravador TXO agora dispoe reserved4 / reserved5 ao longo dos limites de campo da spec. O codigo anterior emitia os offsets 2-9 do registro base como duas escritas Long (rot + reserved4 e depois reserved5); o gravador agora divide-os em
Wordrot,Wordreserved4,Longreserved5 — o conteudo em bytes nao mudou (continua tudo zero para formas Note), mas a estrutura do codigo agora corresponde aos offsets de campo de MS-XLS §2.4.329, tornando mais dificil desalinhar futuras correcoes de TXO.
Versão 2.88.14
- Offset cchText do TXO corrigido — a correcao de comprimento de comentarios de v2.88.13 agora realmente dispara. A versao anterior introduziu uma verificacao de sanidade do registo base TXO lendo
cchTextno offset 8, mas o MS-XLS §2.4.329 colocacchTextno offset 10 (depois de grbit, rot e os 6 bytes reserved / controlInfo). O offset 8 cai dentro do long reserved5, que e sempre zero em objetos com forma Note, pelo que cada comentario deslizava silenciosamente para o fallback defensivo, restaurando na pratica o comportamento anterior a v2.88.13. A correcao repoe o offset em 10, os comentarios longos sao agora realmente costurados atraves de registos Continue e os curtos deixam de apanhar padding final. Sem outras mudancas de comportamento alem do que o v2.88.13 devia entregar.
Versão 2.88.13
- Os comentarios de celula longos sao agora relidos no seu comprimento total. O registo TXO BIFF8 ($01B6) divide o corpo de texto entre o registo base e um ou mais registos Continue, com a contagem de caracteres publicada no registo base no offset 8 como
cchText. O leitor de comentarios anterior saltava o registo base por completo, tratava o DataList[1] como o texto inteiro e parava ai — um comentario com mais de cerca de 4100 caracteres wide ficava silenciosamente truncado, e um comentario mais curto cujo registo Continue arrastasse padding final apanhava esse lixo no fim da cadeia. O leitor consome agoracchTextcomo contagem de caracteres autoritativa, percorre cada segmento Continue conforme MS-XLS §2.4.329 (o corte rgb fica numa fronteira de caractere, pelo que nao e precisa contabilidade de caracteres parciais) e para assim que o orcamento e cumprido, para que o bloco de runs de formatacao que segue o texto nunca escorra para a cadeia. Os comentarios com registos base corrompidos ou em falta continuam a seguir o caminho legacy "consumir todos os bytes restantes".
Versão 2.88.12
- As cadeias em cache com mais de cerca de 4100 caracteres provenientes de formulas que devolvem cadeia preservam-se agora em ida e volta atraves de registos Continue. O v2.88.11 ligou o lado de leitura do registo String BIFF8 ($0207) mas apenas consumia o corpo do primeiro registo. Uma cadeia em cache cujos bytes UCS-2 ultrapassavam o limite BIFF de 8224 bytes e transbordavam para um ou mais registos Continue ($003C) ficava silenciosamente truncada. O manipulador percorre agora toda a DataList do nivel de despacho: le cch e fHighByte do registo base, copia o corpo que la cabe e depois concatena cada segmento Continue subsequente como bytes em bruto conforme a garantia de fronteira de caractere de MS-XLS §2.5.293 — o XLUnicodeString nunca reemite fHighByte a meio de uma cadeia. Cada segmento esta limitado pelo orcamento de caracteres restantes, pelo que um Continue extraviadamente sobredimensionado nao pode tornar o resultado mais longo que cch. As cadeias de registo unico (o caso comum) seguem exatamente o mesmo caminho rapido que antes.
Versão 2.88.11
- As formulas que devolvem cadeia agora preservam em ida e volta o texto em cache calculado pelo Excel. A versao anterior cobria as variantes numero, booleano, erro e vazio da cache BIFF8 FormulaValue (MS-XLS §2.5.133), mas deixava a variante cadeia na lista por fazer porque o seu valor em cache reside num registo String separado ($0207) que segue imediatamente o registo Formula. O ParseFormula recorda agora as coordenadas da celula quando ve uma Formula de variante cadeia, e o novo manipulador ParseString descodifica o registo $0207 seguinte conforme MS-XLS §2.4.268 e encaminha a WideString para
FCachedFormulaValue.GetCellValuepode agora recorrer ao texto calculado pelo Excel quando o avaliador do HotXLS nao consegue reproduzi-lo. Um reset defensivo no topo do ParseFormula descarta qualquer ancora pendente obsoleta para que um ficheiro origem mal formado a que falte um registo String nao possa encaminhar erradamente um posterior. Os registos com mais de 8224 bytes que transbordam para blocos Continue continuam a recorrer a saida do avaliador como limitacao conhecida.
Versão 2.88.10
- Os registos Formula do BIFF8 agora preservam em ida e volta o valor em cache calculado pelo Excel. O ParseFormula antes saltava completamente o payload FormulaValue de 8 bytes no offset 6, pelo que o resultado em cache de cada formula num .xls carregado (numeros, booleanos, erros, vazio) era descartado e o HotXLS tinha de reavaliar cada celula com o seu proprio motor de formulas. Quando esse motor nao conseguia corresponder ao Excel (funcoes XLM nao suportadas, ligacoes externas partidas, formulas ainda nao implementadas), a celula ficava silenciosamente vazia ou mostrava 0. O leitor descodifica agora as quatro variantes numero / booleano / erro / vazio conforme MS-XLS §2.5.133 e guarda-as num novo campo
TXLSCellRef.FCachedFormulaValue; oGetCellValuerecorre a essa cache apenas quando a avaliacao falha, pelo que as formulas recem-criadas continuam a passar pela avaliacao. A variante string continua a depender do avaliador porque o parser do registo String ($0207) seguinte ainda nao esta ligado.
Versão 2.88.9
- Os registos Formula BIFF8 com valores irresoluveis agora ativam fAlwaysCalc em vez do bit reserved1. Quando o avaliador HotXLS nao conseguia calcular uma formula ao guardar, o escritor punha
grbit = 0x0002— bit 1, que MS-XLS §2.4.127 reserva e pede aos leitores para ignorar. O Excel ignorava-o conforme a especificacao, tratava o valor 0 em cache como autoritativo e mostrava silenciosamente 0 em vez de recalcular. O escritor agora poegrbit = 0x0001(fAlwaysCalc, bit 0), pelo que o Excel reexecuta a formula no proximo recalculo e a celula mostra o resultado correto.
Versão 2.88.8
- PageSetup.PrintTitleColumns e PrintTitleRows agora levantam excecao em entrada invalida. Atribuir a estas propriedades uma cadeia de intervalo mal formada (qualquer coisa que
ColDiapasonToValuesouRowDiapasonToValuesnao conseguissem analisar) descartava antes a atribuicao em silencio — o livro mantinha o intervalo Print_Titles existente ou ficava sem intervalo, e o chamador nao tinha forma de saber que algo havia falhado. Os setters levantam agoraException.Createcom uma mensagem descritiva que nomeia o valor incorreto, de acordo com o estilo raise existente nos caminhos de indice invalido deTXLSRange.
Versão 2.88.7
- O campo miyRw de Row mantem-se agora dentro do intervalo da especificacao MS-XLS. As versoes pre-BIFF8 do Excel codificavam "usar a altura de linha predefinida do livro" fazendo OR do bit 15 em miyRw, e o HotXLS arrastou esse idioma para o escritor BIFF8 apesar de MS-XLS §2.4.221 limitar miyRw a 8192 twips. O Excel moderno emite um simples 255 (12,75 pt predefinido) no mesmo caso e sinaliza as substituicoes manuais atraves do bit fUnsynced do grbit, pelo que o hack do bit 15 fazia divergir a saida do HotXLS dos ficheiros .xls de referencia (um valor de 32 959 = 0x80FF para "predefinido" estava tecnicamente fora da especificacao). O escritor omite agora o OR e escreve 255 diretamente; o leitor continua a remover o bit 15 a entrada para manter a compatibilidade com HotXLS v2.88.6 e ficheiros anteriores assim como com os poucos geradores de terceiros que copiaram o idioma BIFF5.
- Nota de errata da ronda 2 da auditoria da especificacao BIFF8 adicionada. Uma nova verificacao dos limites de campo de [MS-XLS] esclareceu que duas conclusoes assinaladas como P2 no relatorio original (
dev-notes/XLS-BIFF8-Spec-Audit-Round2.md) nao sao bugs reais: o bit 15 definido no sinalizador de historico BOF $000080C9 pertence ao campo verXLHigh (bits 14-17, valor 2 = "Excel 2002"), nao a cauda reserved1 (bits 19-31); e o uso pelo ParseFormula de um token PtgExp inicial para detetar formulas partilhadas ou matriciais corresponde ao que a especificacao implica e desambigua corretamente atraves do ShrFmla ou Array seguinte. Ambos os pontos ficam anotados como retirados.
Versão 2.88.6
- As folhas de macro e os modulos VBA mantem agora a sua ranhura ordinal BoundSheet8. O leitor descartava antes os registos BoundSheet8 cujo campo
dtera 1 (folha de macro) ou 6 (modulo VBA), pelo que a colecao Sheets do HotXLS ficava curta nessas entradas. Qualquer referencia cruzada XTI em ExternSheet que apontasse em ordem de ficheiro para uma posicao de folha alem de uma folha de macro resolvia na folha HotXLS errada apos um SaveAs. O leitor adiciona agora uma folha marcador por cada registo BoundSheet8 e armazena o byte brutodtnuma nova propriedadeSheet.SheetTypeRaw; o escritor reemite o byte original. Os registos BOF de substream macro ($0040) sao tambem tratados como substream de folha de calculo durante a analise, pelo que as celulas dentro das folhas de macro sao preservadas em vez de absorvidas silenciosamente pela folha anterior.
Versão 2.88.5
- O registo Row do BIFF8 conserva agora fCollapsed, fExAsc, fExDes e fPhonetic. O leitor descartava antes fCollapsed (grbit bit 4) e o escritor inferia-o a partir das transicoes de nivel de estrutura nas linhas vizinhas, classificando mal as linhas que o ficheiro origem comprimiu ou marcou como limite. Os tres bits superiores (fExAsc em 28, fExDes em 29, fPhonetic em 30) tambem nao eram lidos e eram emitidos sempre a zero porque o escritor truncava o grbit de 4 bytes a um ixfe de 16 bits. O leitor consome agora os quatro bits conforme MS-XLS §2.4.221 e fixa fCollapsed como explicito. O escritor empacota ExAsc, ExDes e Phonetic nos bits 12-14 da palavra ixfe, mascarando ixfe ao intervalo 12 bits permitido. As dicas de bordo superior grosso ou inferior medio impulsionadas por ExAsc e ExDes sobrevivem agora a HotXLS SaveAs, e a visibilidade fonetica em folhas japonesas deixa de reiniciar.
Versão 2.88.4
- O bit fPaged do BIFF8 Window2 agora assinala apenas a folha ativa. Versões anteriores definiam
fPaged(MS-XLS §2.4.346 bit 10) em todas as folhas visíveis, fazendo divergir a saída do HotXLS daquilo que o próprio Excel escreve (segundo a especificação o bit significa "esta folha está atualmente apresentada na janela do livro", pelo que apenas o subfluxo da folha ativa o deveria portar). Os leitores do Excel recorriam de qualquer modo aWindow1.itabCurpara identificar a verdadeira folha ativa, pelo que o abuso era tolerado; o Apache POI em modo estrito e outras ferramentas que confiam emfPagedcomo sinal primário veem agora a folha correta assinalada.
Versão 2.88.3
- O zoom Window2 BIFF8 e a cor das linhas de grelha agora preservam-se em ida e volta. Versões anteriores descartavam na leitura todos os campos WINDOW2 além do offset 6 e emitiam zeros codificados na escrita, por isso qualquer zoom de folha guardado no Excel (75 por cento, 125 por cento, etc.) e a personalização da cor da grelha voltavam aos valores predefinidos após um HotXLS SaveAs. O leitor consome agora
icvHdr,wScaleSLVewScaleNormalconforme MS-XLS §2.4.346: o zoom da vista ativa alimentaSheet.Zoome o valor da vista oposta fica num slot em cache para que alternar entre Normal e Pré-visualização de quebra de página no Excel restaure o zoom anterior. O escritor emite oSheet.Zoomativo no slot de vista correspondente e o valor em cache no outro, mais o índice de cor da grelha preservado.
Versão 2.88.2
- Corrigido o opcode do registo HFPicture do BIFF8. Os ficheiros .xls guardados agora emitem os registos de imagem de fundo de cabeçalho e rodapé com o
rt = 0x0866correto, conforme MS-XLS §2.4.138. Versões anteriores usavam0x086C(o opcode de CellWatch), pelo que o Excel tentava analisar o BLIP de OfficeArt incorporado como referência de célula monitorizada e descartava a imagem silenciosamente. Os livros com imagens de cabeçalho ou rodapé mantêm agora a imagem ao fazer round-trip através do HotXLS.
Versão 2.88.1
- Corrigido o opcode do registo Theme do BIFF8. Os ficheiros .xls guardados agora emitem o registo Theme com o
frtHeader.rt = 0x0896correto, conforme MS-XLS §2.4.326. Versões anteriores usavam0x0892(o opcode de StyleExt), pelo que o Excel interpretava o payload do tema OOXML incorporado como uma extensão de estilo de célula e regressava silenciosamente ao tema Office integrado. Os livros com cores de tema personalizadas mantêm agora a paleta ao fazer round-trip através do HotXLS.
Versão 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.
Versão 2.87.4
- As fórmulas compartilhadas XLS agora gravam um corpo
ShrFmlaválido. A saída BIFF8 inclui o byte obrigatóriocUseantes da fórmula compartilhada, evitando o deslocamento de um byte comUseSharedFormulas. - Os metadados de estilo e filtro das tabelas XLS agora seguem o layout MS-XLS atual.
AddTablegravaLIST12comoList12TableStyleClientInfo, define os sinalizadores AutoFilter emFeature11e emite blocos vaziosFeat11FdaAutoFilterpor coluna. - As regras BIFF8 CF12 Data Bar / Color Scale / Icon Set não gravam mais payloads DXF proibidos. HotXLS mantém o bloco DXF vazio conforme MS-XLS e preserva as configurações na cauda específica do tipo CF12.
Versão 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.
Versão 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.
Versão 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.
Versão 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.
Versão 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.
Versão 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.
Versão 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.
Versão 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.
Versão 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”.
Versão 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”.
Versão 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.
Versão 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.
Versão 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.
Versão 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.
Versão 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%');
Versão 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.
Versão 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.
Versão 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.
Versão 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.
Versão 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.
Versão 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.
Versão 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.
Versão 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.
Versão 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.
Versão 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.
Versão 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.
Versão 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.
Versão 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.
Versão 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.
Versão 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.
Versão 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.
Versão 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.
Versão 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.
Versão 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.
Versão 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.
Versão 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.
Versão 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.
Versão 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.
Versão 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.
Versão 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.
Versão 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.
Versão 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.
Versão 2.48.10
- Os arquivos .xls salvos pelo HotXLS agora incluem os dois fluxos de conjunto de propriedades de arquivo composto OLE que o Excel espera em cada pasta de trabalho:
\005SummaryInformatione\005DocumentSummaryInformation. Antes de v2.48.10, apenas os builds TRIAL os escreviam (como mecanismo de carimbo de banner); os builds de release produziam arquivos .xls cujo fluxo Workbook era BIFF8 válido, mas cujo contêiner OLE faltava dos fluxos de metadados Office padrão. O parser estrito do Excel 2003 trata isso como a condição "File error: data may have been lost" (o Excel moderno mantém o banner Vista Protegida "este arquivo tem problemas"). Adicionar os fluxos resolve a caixa de diálogo em pastas de trabalho de gráfico sem alterar nenhum registro BIFF8. - Os dois fluxos são emitidos via o caminho Win32
StgCreatePropSetStg+IPropertySetStorage.Create+IPropertyStorage.WriteMultiple— o mesmo código que o Microsoft Office usa, então o Office File Validation aceita o layout de bytes. O fluxo SummaryInformation é criado comAppName="HotXLS"padrão e Autor vazio; os builds TRIAL ainda sobrescrevem os valores Autor / AppName com o banner de teste vialxTrial.XlsTrialStampXlsSummaryapós o carimbo padrão, portanto os arquivos de teste permanecem identificáveis no painel Arquivo > Informações > Propriedades do Excel. O fluxo DocumentSummaryInformation é criado vazio (o Win32 ainda emite o cabeçalho do conjunto de propriedades + propriedade CODEPAGE — suficiente para o parser estrito do Excel considerar os metadados "presentes e bem formados"). - Esta correção é universal — cada .xls salvo pelo HotXLS agora carrega os metadados OLE padrão, não apenas pastas de trabalho de gráfico. As saídas apenas-planilha de releases anteriores escapavam do sintoma porque o Excel é mais indulgente com pastas de trabalho sem metadados apenas-planilha do que com pastas de trabalho com folha de gráfico, mas tecnicamente também faltavam os fluxos. A nova unidade
Lib/lxXlsSummary.pascontém os dois procedimentos auxiliares; lxHandle.pas os chama incondicionalmente dentro deTXLSWorkbook.SaveWorkbookdepois queStoreWorkbookpopula o fluxo Workbook e antes deFDocStorage.Commit. - Esta release fecha a sequência de follow-up do chart Phase 2 de oito versões (v2.47.0 — v2.48.10): desde o binding de séries
tArea3D, passando pelo realinhamento do id BRAI, valores observados do Excel para sdtX/cValx, posicionamento de SERIESTEXT, remoção de preenchimento do fluxo Workbook, registros shell em nível de folha, e agora fluxos de metadados OLE. O resultado é um .xls de gráfico que abre no Excel 2003 e Excel moderno sem nenhum aviso "o arquivo tem problemas", alinhado em nível de byte com o que o próprio Excel escreve para os mesmos dados.
Versão 2.48.9
- As folhas de gráfico BIFF8 agora carregam o conjunto completo de registros shell em nível de folha que o Excel 2003+ requer. O chart_phase2_demo.xls de v2.48.8 renderizava o gráfico de colunas corretamente, mas o Excel 2003 ainda exibia uma caixa de diálogo "File error: data may have been lost" (versões mais novas do Excel mantinham o banner de Vista Protegida) porque o substream do gráfico estava faltando os mesmos registros em nível de folha que um substream de planilha carrega. Arquivos Excel reais (tanto variantes from-scratch quanto re-saved da saída do HotXLS) envolvem os registros do gráfico nesta shell:
- Antes dos registros do gráfico (entre BOF e UNITS):
HEADER($0014, vazio),FOOTER($0015, vazio),HCENTER($0083, valor 0),VCENTER($0084, valor 0),SETUP($00A1, configuração de página de 34 bytes),PRINTSIZE($0033, valor 3). - Depois dos registros do gráfico (após o CHART END mais externo, antes de EOF):
DIMENSIONS($0200, 14 bytes) declarando o intervalo de dados em cache, três marcadoresSERIESINDEX($1065) para os slots de cache de categorias / valores / tamanhos de bolha, umNUMBER($0203, 14 bytes) por ponto de valor em cache, eWINDOW2($023E, variante de 10 bytes para folha de gráfico) no final.
dev-notes/biffview-refs/excel_column_chart_resaved.xls(a referência de gráfico de colunas salva pelo Excel, local). - Antes dos registros do gráfico (entre BOF e UNITS):
- O cache de valores atualmente emite placeholders zero (
0.0para cada ponto de dados), correspondendo ao que o próprio Excel escreve ao re-salvar um gráfico cujo cache de origem não estava pré-populado. O gráfico ainda plota os dados reais porque as referênciasPtgArea3ddo BRAI se resolvem para as células da planilha de origem no momento do desenho — o cache é o que permite ao Excel analisar a folha de gráfico sem avisos, não o que alimenta a plotagem. Uma versão futura pode popular o cache com os números reais do intervaloValues; o formato wire está no lugar. - Teste fumaça de ponta a ponta: abra o
Demo/Delphi/XlsCreateChart/chart_phase2_demo.xlsregenerado no Excel 2003 — o prompt "File error: data may have been lost" não aparece mais, e o gráfico de colunas renderiza idêntico ao anterior. O mesmo arquivo abre limpo no Excel moderno sem o banner de Vista Protegida.
Versão 2.48.8
- O escritor BIFF8 (.xls) não preenche mais o stream Workbook com bytes zero finais.
TXLSWorkbook.StoreOleFilechamava anteriormenteStoreExtraSpace(Book)após os registros da última planilha, preenchendo o comprimento do stream até o próximo limite de 512 bytes (setor OLE). O parser estrito do Excel trata esses bytes zero finais como um stream fictício de registros com id0x0000e exibe o prompt de Vista Protegida "este arquivo tem problemas" — visível no chart_phase2_demo.xls de v2.48.7 mesmo após o formato wire BRAI / sdtX / SERIESTEXT ter sido corrigido e o gráfico renderizado corretamente. Remover a chamada elimina o preenchimento do conteúdo do stream Workbook; o preenchimento de setor OLE ainda acontece, mas na camada do contêiner CFB abaixo do stream onde o próprio Excel o coloca (cada .xls salvo pelo Excel tem um comprimento de stream Workbook não alinhado ao setor). - Histórico de sintomas: qualquer .xls salvo pelo HotXLS cujo comprimento total em bytes de registros válidos não caía por acaso em um limite de 512 bytes carregava o stream de zeros finais. O bug existia desde o commit de bootstrap do repositório mas raramente se manifestava — a maioria dos livros de trabalho tem registros suficientes para o preenchimento acabar pequeno (≤ 4 bytes zero tolerados pelo Excel). Livros com folhas de gráfico ficam muito abaixo do limite de setor (o demo v2.47.0 — v2.48.7 preenchia 420 bytes zero), então é aí que o prompt Vista Protegida tornou-se consistente.
- O método
StoreExtraSpacesobrevive como código morto privado emlxHandle.pascaso um caminho de código futuro realmente precise de streams arredondados ao setor; o ponto de chamada emStoreOleFileé removido. O comprimento do stream Workbook agora é exatamente igual ao comprimento em bytes de todos os registros válidos (demo de gráfico: 3164 bytes; referência Excel from-scratch: 4419 bytes — ambos não alinhados ao setor). Os caminhos de código do leitor não são afetados — o HotXLS sempre leu corretamente streams Workbook não alinhados ao setor de arquivos salvos pelo Excel.
Versão 2.48.7
- Os registros de série de gráfico BIFF8 finalmente renderizam corretamente no Excel. A correção é realinhar as atribuições de id BRAI com [MS-XLS] §2.4.51 — o plano de implementação pai as documentava invertidas, propagando o bug através de cada release de gráfico de v2.41.0 a v2.48.6. As semânticas de id corretas são:
id = 0— nome da série / rótulo de legenda (o plano dizia: categories)id = 1— values (correto)id = 2— categories (o plano dizia: name)id = 3— bubble sizes (o plano dizia: errBars)
- Também realinhado ao formato wire do gráfico de colunas salvo pelo Excel:
SERIES.sdtXagora é0x0003(o valor observado do Excel para categorias de texto, não0x0001documentado por [MS-XLS] §2.4.252), ecValxcarrega a contagem real de categorias em vez de0. A regra "cValx MUST = 0quandosdtX∈ {1, 3}" é contradita por cada amostra salva pelo Excel examinada. - O portador literal de nome
SERIESTEXT($100D) retorna, mas no lugar certo: imediatamente após o BRAIid = 0, ainda dentro do bloco SERIES BEGIN/END. Isso é o que arquivos Excel reais fazem — o ponto de emissão de v2.48.5 (após todo o cluster BRAI, antes deDataFormat) estava errado e quebrava o parsing do gráfico; a posição correta é logo ao lado do BRAI do nome de série. - Os arquivos de gráfico salvos por v2.41.0 — v2.48.6 todos carregam o formato wire BRAI invertido. Abrem no Excel sem erro mas mostram os sintomas de legenda / eixo X acima. Re-salve via v2.48.7+ para migrar; nenhuma mudança de API — a mesma chamada
AddChartSheetagora produz um gráfico que renderiza identicamente ao que o Excel mesmo escreveria para os mesmos dados. - Nova ferramenta de inspeção em nível de byte
dev-notes/biffview-refs/dump_chart_substream.pydespeja o substream de gráfico de qualquer .xls BIFF8 com decodificação por registro (SERIES / BRAI / SERIESTEXT / AXIS / CATSERRANGE / LEGEND / OBJECTLINK / POS / TEXT). Usada durante este lançamento para byte-diff a saída do HotXLS contra as amostras de referência salvas pelo Excel; disponível para follow-ups futuros de spec de gráfico.
Versão 2.48.6
- O substream de folha de gráfico BIFF8 retira as alterações de v2.48.5. Testes reais com Excel no demo regenerado v2.48.5 não renderizaram o gráfico de forma alguma — pior que a linha de base v2.47.0 (onde o gráfico era desenhado mas com rótulos errados do eixo X). As duas alterações de v2.48.5 foram a causa:
SERIES.sdtX = 4não é realmente aceito pelo Excel mesmo que o Apache POI exponhaCATEGORY_DATA_TYPE_TEXT = 4. [MS-XLS] §2.4.252 exige estritamente quesdtXseja0x0001ou0x0003.- O registro
SERIESTEXT($100D) adicionado dentro do bloco SERIES BEGIN/END é uma violação estrutural —SERIESTEXTpertence aos blocos TEXT (contextos de título de gráfico / título de eixo / rótulo de dados), não dentro do bloco SERIES. Incorporá-lo ali confundiu o parser de gráficos do Excel a ponto de rejeitar todo o substream.
- v2.48.6 restaura o formato wire v2.47.0 E adiciona uma correção de conformidade com a spec:
SERIES.cValxagora é0quandosdtX = 1(regra [MS-XLS] §2.4.252 spec MUST). Antes de v2.48.6 escrevia-secValx = count(4 no demo) violando a regra, possivelmente contribuindo para o prompt Vista Protegida "o documento tem problemas" do Excel.cValycontinua carregando a contagem real de valores (sdtY=1 não tem regra de zero). - Novo demo Delphi XlsCreateChart em
Demo/Delphi/XlsCreateChart/cria uma pasta de trabalho de duas folhas: uma folha "Data" com quatro linhas (Region, Sales) e uma folha "Chart1" de gráfico de colunas cuja série vinculaData!$A$2:$A$5/Data!$B$2:$B$5como Categories / Values. O demo é o sucessor permanente dochart_phase2_demo.xlsad hoc que v2.47.0 — v2.48.5 colocava na raiz do repositório para testes BiffView; o arquivo raiz foi removido, e o novo demo escreve sua saída ao lado do próprio .exe. - Não resolvido conhecido: com o formato wire de v2.48.6, o Excel ainda renderiza os rótulos do eixo X do gráfico de colunas como zeros e cai na concatenação do texto das células de categoria para a legenda (em vez de usar o literal PTG tStr de BRAI id=2
'Q1 Sales'). É uma lacuna real do formato wire que precisa de um gráfico de colunas salvo pelo Excel como referência para diff — rastreado como follow-up. A área de plotagem de 4 barras em si renderiza corretamente (alturas 100/150/200/175 correspondem aos Values).
Versão 2.48.5
- Os registros de série de gráfico BIFF8 agora renderizam corretamente no Excel. v2.47.0 conectou o binding
tArea3Dpara os intervalos Categories / Values, mas o Excel continuava desenhando todos os rótulos do eixo X como0e usava o texto de categorias concatenado ("North South East West") tanto como legenda quanto como título automático, em vez do Name fornecido pelo usuário. Duas correções restauram o comportamento pretendido: - O campo
sdtXdo registroSERIESagora é4(categorias de texto), não1. [MS-XLS] §2.4.252 documenta apenas1(datas) e3(sequência BIFF7), mas os arquivos reais de gráfico de colunas / barras / linhas salvos pelo Excel escrevem4para eixos de categoria de texto (corresponde à constanteCATEGORY_DATA_TYPE_TEXTdo Apache POI). ComsdtX=1, o Excel tentava forçar as células'North'/'South'a números → fallback para 0;sdtX=4permite que os rótulos de texto passem verbatim. A forma wire anterior também violava a regra da spec "cValxdeve ser zero quandosdtX=1". - Um registro
SERIESTEXT($100D) agora é emitido dentro do bloco SERIES BEGIN/END (após o cluster BRAI, antes deDataFormat) sempre que um Name literal é fornecido. O mecanismo da primeira metade da Phase 2 (BRAI id=2 + PTGtStr) é mantido para completude da spec, mas o Excel realmente obtém o rótulo da legenda e o título automático deSERIESTEXT; com apenas a variante BRAI presente, o Excel fazia fallback para concatenar células de categoria. Após esta correção, a legenda mostra o Name real (ex.'Q1 Sales') e um título vazio deixa o slot de título automático em branco. - Migração: saídas de folha de gráfico v2.42.0 — v2.47.0 ainda abrem no Excel sem erro, mas apresentavam os sintomas acima. Re-salve com v2.48.5+ para obter o formato wire corrigido; nenhuma mudança de API necessária, a mesma chamada
AddChartSheetagora produz o gráfico correto.
Versão 2.48.4
- A emissão BIFF8 CFEX ($087B) está aposentada. O HotXLS não escreve mais o CFEX emparelhado após cada CF12 — toda a configuração de Data Bar / Color Scale / Icon Set agora viaja inline na cauda por tipo de CF12 (v2.48.1 — v2.48.3). O Apache POI / NPOI já ignoram CFEX, então é simplificação pura.
- O caminho de leitura BIFF8 CF12 agora consome a cauda por tipo diretamente do CF12. Isto completa a reescrita do formato wire do Gap #6 em 5 PATCHes (v2.48.0 header + v2.48.1 data_bar + v2.48.2 color_gradient + v2.48.3 multistate + v2.48.4 aposentadoria de CFEX).
Versão 2.48.3
- As regras Icon Set do BIFF8 CF12 ($087A) agora emitem o subregistro
multistatecompatível com NPOI inline, permitindo que o Apache POI / NPOI leiam a família de ícones, os limiares por parada e os flags reverse / icon-only diretamente do CF12. O layout corresponde a NPOIIconMultiStateFormatting.Serialize(). - Os arquivos .xls HotXLS-gerados v2.48.2 devem ser re-salvos via v2.48.3 para que as regras Icon Set recebam a nova cauda inline. A aposentadoria do emit de CFEX chega em v2.48.4.
Versão 2.48.2
- As regras Color Scale de 2 e 3 paradas do BIFF8 CF12 ($087A) agora emitem o subregistro
color_gradientcompatível com NPOI inline, permitindo que o Apache POI / NPOI leiam o limiar, cor e posição de interpolação de cada parada diretamente do CF12. O layout corresponde a NPOIColorGradientFormatting.Serialize(). - Os arquivos .xls HotXLS-gerados v2.48.1 devem ser re-salvos via v2.48.2 para que as regras Color Scale recebam a nova cauda inline. A cauda Icon Set chega em v2.48.3.
Versão 2.48.1
- As regras Data Bar do BIFF8 CF12 ($087A) agora emitem o subregistro
data_barcompatível com NPOI inline (28 bytes anexados apóstemplate_params), permitindo que o Apache POI / NPOI decodifiquem a cor da barra, limiares mín/máx e limites de comprimento percentual diretamente do CF12, sem consultar o registro CFEX legado. O layout corresponde a NPOIDataBarFormatting.Serialize(). - Os arquivos .xls HotXLS-gerados v2.48.0 devem ser re-salvos via v2.48.1 para que as regras Data Bar recebam a nova cauda inline. As caudas Color Scale / Icon Set chegam em v2.48.2 — v2.48.3.
Versão 2.48.0
- Layout do cabeçalho BIFF8 CF12 ($087A) corrigido conforme NPOI
CFRule12Record.serialize()e arquivos de referência salvos pelo Excel. O Excel escreveext_formatting_length(4)antes dos tokens de fórmula e um blocotemplate_paramscom prefixo de comprimento; o HotXLS tinha esses campos em ordem errada. Caudas por tipo (data_bar / color_gradient / multistate) chegam em v2.48.1 — v2.48.3. - Os arquivos .xls HotXLS-gerados v2.34.0 — v2.47.1 devem ser re-salvos via v2.48.0 para reescrever seus registros CF12. O campo
nIDde 2 bytes fora de especificação no final de cada CF12 foi removido.
Versão 2.47.1
- Formato wire do registro BIFF8 CONDFMT12 ($0879) corrigido para corresponder aos arquivos salvos pelo Excel. A implementação anterior seguia um rascunho spec inicial que deixava o intervalo associado de 8 bytes como "reservado" dentro do FtrHeader e inseria um campo Reservado de 4 bytes inexistente antes de
numCF. Os arquivos .xls do Excel realmente preenchem esses 8 bytes com o intervalo de células associado. Referência:poi_ConditionalFormattingSamples.xlsregistro 152 agora corresponde byte por byte. - Os arquivos .xls HotXLS-gerados v2.34.0 — v2.47.0 devem ser re-salvos via v2.47.1 para reparar seus registros CONDFMT12.
Versão 2.47.0
- A criação de folhas de gráfico BIFF8 agora vincula intervalos de dados reais às séries. As cadeias A1
CategorieseValuespassadas para a sobrecarga de 6 argumentos deAddChartSheet(por exemplo'Data!$A$2:$A$5') são compiladas em tokens PTGtArea3Descritos nos registrosBRAI id=0(categorias) eBRAI id=1(valores) da série. O Excel agora renderiza pontos de dados reais na área de plotagem em vez do gráfico vazio produzido pelo v2.42.0. - Resolução do nome da planilha e registro EXTERNSHEET são automáticos: o parser localiza a planilha nomeada na pasta de trabalho, registra uma entrada XTI caso ainda não exista e escreve o
ixtide base zero correspondente no corpo do PtgArea3d. Ao salvar novamente, o fluxo de registros do gráfico é reserializado pelo compilador de fórmulas, mantendoixticoerente com a ordem final do EXTERNSHEET. - Formas de referência aceitas:
Sheet1!$A$2:$A$5(absoluta),Sheet1!A2:A5(marcadores relativos tolerados — séries de gráfico sempre armazenam como absolutas),'My Sheet'!$A$1:$B$5(nomes de planilha com espaços entre aspas simples) e referências de célula única comoSheet1!$A$1(degenera para PtgArea3d 1×1). As contagens de pontos de dados (cValx/cValy) são derivadas automaticamente das dimensões da área. - Formas de referência não suportadas fazem fallback silencioso para o placeholder BRAI
cce=0no estilo v2.41.0 para que o gráfico ainda abra no Excel: referências entre pastas de trabalho ([Book2.xls]Sheet1!...), intervalos nomeados (Sheet1!ProfitColumn), referências sem o prefixo!da planilha e referências apontando para a própria folha de gráfico. Esses casos ficam diferidos para fases futuras. - Conclui a Roadmap #10 Phase 2 (gráfico de colunas ponta a ponta). Rótulos de série (primeira metade da Phase 2, v2.42.0) mais binding de intervalos de série (este release) significam que um gráfico de colunas criado via
AddChartSheetagora exibe entradas de legenda corretas e dados reais sem pós-processamento no Excel.
Versão 2.46.0
- O decodificador DXF do lado BIFF8 agora resolve cores xclrType=1 (paleta indexada) a partir da paleta padrão Excel 2003 de 64 cores.
- A pesquisa usa a paleta padrão Excel 2003 incorporada — icv 0..7 são as 8 cores do sistema, icv 8..15 espelham as cores do sistema, icv 16..63 são os valores padrão personalizáveis padrão. icv fora do intervalo retorna ao preto.
- A personalização do registro PALETTE BIFF8 não é consultada.
- Os caminhos xclrType=0 (auto) e xclrType=2 (RGB) não mudam.
Versão 2.45.0
- As regras de formatação condicional agora fazem round-trip do atributo priority tanto em XLSX
<cfRule priority="N"/>quanto no campo BIFF8 CF12ipriority. - Nova propriedade
PriorityemTCondFormatRule(lado BIFF8) eTXLSXConditionalFormat(lado XLSX). Padrão zero, mantém o comportamento auto-por-índice; valor positivo fixa a prioridade. - Priority controla a camada de várias regras — quando várias regras cobrem o mesmo intervalo, o Excel as aplica em ordem de prioridade. O round-trip da priority mantém a ordem de renderização pretendida pelo usuário.
- Comportamento padrão inalterado para chamadores que não tocam
Priority.
Versão 2.44.0
- As regras de formatação condicional Conjunto de Ícones agora suportam substituições de ícone por stop no lado XLSX. Cada um dos 3 / 4 / 5 stops pode optar por sair do padrão da família e exibir qualquer ícone de qualquer uma das 17 famílias integradas Excel 2007, identificado por nome do conjunto + id do ícone. Elemento OOXML:
<cfIcon iconSet="OtherSet" iconId="N"/>. - Novos métodos em
TXLSIconSetSpec:SetIconOverride(stopIndex, OverrideSet, IconId)eClearIconOverride(stopIndex). Propriedades somente leituraHasIconOverride[i],IconOverrideSet[i],IconOverrideId[i]. - O escritor XLSX emite filhos
<cfIcon>apenas para stops que chamaramSetIconOverride. O leitor analisa elementos<cfIcon>recebidos por posição. - Limitações conhecidas: BIFF8 (.xls) CFEX não tem slot para substituições por stop; uma regra com substituições salva em .xls renderiza o padrão da família para todos os stops.
Versão 2.43.0
- As regras de formatação condicional XLSX (.xlsx) agora fazem round-trip de referências de cor de tema no elemento
<color>de regras de Barra de Dados e Escala de Cor. Anteriormente o escritor emitia apenas<color rgb="FFRRGGBB"/>e o leitor ignorava os atributostheme/tint. - Novos métodos em
TXLSDataBarSpeceTXLSCfValuealternam o slot para modo tema:SetThemeColor(themeId, tint)eClearThemeColor. - O escritor XLSX emite
<color theme="N"/>quandoTinté exatamente 0.0, ou<color theme="N" tint="0.5"/>quando não-zero. - O comportamento padrão permanece inalterado: regras criadas com os pontos de entrada apenas-RGB existentes continuam a emitir
<color rgb="..."/>exatamente como antes. - Limitações conhecidas: BIFF8 (.xls) CFEX ainda carrega apenas a cor RGB; a resolução da paleta de tema da planilha permanece fora do escopo; as regras
iconSetnão carregam elementos<color>.
Versão 2.42.0
- A API de criação de folhas-gráfico BIFF8 ganha uma quinta sobrecarga
AddChartSheetque aceita um array de registrosTXLSChartSeriesInfo(Name,Categories,Values). CadaNamenão vazio é escrito no substream do gráfico como rótulo de série literal via token PTGtStrnoBRAIde nome-de-série (id=2). O Excel usa esse rótulo na legenda e no seletor de séries, então um gráfico multi-série agora exibe legendas apropriadas em vez dos placeholders padrão "Series1 / Series2". TXLSChartSeriesInfoé re-exportado delxHandlejunto comTXLSChartType, para que os chamadores possam construir o array sem importarlxChartBuilderdiretamente.- Esta é a primeira metade da Roadmap #10 Fase 2 (gráfico de colunas ponta a ponta). O caminho do nome-de-série está cabeado; o vínculo de dados de categoria e valor (transformar as strings A1-range
CategorieseValuesem referênciastArea3Dreais de intervalo de células dentro do BRAI) permanece como placeholder — esses dois campos são aceitos pela API mas ainda não são emitidos no substream. Um release subsequente os direcionará via o compilador de fórmulas e a tabela EXTERNSHEET para concluir a segunda metade da Fase 2.
Versão 2.41.0
- HotXLS ganha criação programática de folhas-gráfico BIFF8. Um novo conjunto de sobrecargas
AddChartSheetemSheetsescreve um substream de gráfico completo no arquivo .xls salvo, enquanto antes as folhas-gráfico só podiam ser preservadas opacamente em um round-trip load-save. Quatro sobrecargas cobrem os pontos de entrada comuns: somente nome / nome + tipo de gráfico / + título / + título de eixo categoria + título de eixo valor. OIXLSWorksheetretornado aparece na coleçãoSheets, recebe uma entrada boundsheet de folha-gráfico ao salvar, e Excel o abre como aba de gráfico. - Uma nova enumeração
TXLSChartTypeseleciona o tipo de gráfico:xlsChartTypeColumn,xlsChartTypeBar,xlsChartTypeLine,xlsChartTypePie. A enumeração é re-exportada delxHandlepara que o código de usuário não precise importar a unidade chart-builder diretamente. - O substream de gráfico emitido cobre o framing BIFF8 exigido pela especificação — BOF (dt=$0020), Chart / PlotGrowth / Frame / Series / SheetProperties / AxesUsed / AxisParent (POS + eixo categoria + eixo valor + PlotArea + Frame + ChartFormat + registro de tipo + ChartFormatLink + Legend), EOF — para que o Excel reconheça o resultado como uma aba de gráfico real do tipo solicitado. O round-trip existente via
TXLSCustomChartpermanece inalterado. - Esta é a primeira entrega da Roadmap #10 (substream CHART — o maior item do audit BIFF8). A fase 1 entrega o framework e a superfície de API para que as fases seguintes adicionem o vínculo de dados de séries, títulos de eixos e formatação detalhada por tipo.
- Limitações: a nova folha-gráfico renderiza um gráfico vazio padrão do tipo solicitado. O vínculo de dados de séries, o texto de título preenchido e a formatação detalhada por tipo (gap width / overlap / hole size / marker style) são adiados para fases posteriores. O Excel preserva a presença e o tipo do gráfico ao salvar e reabrir, mas ainda não os dados fornecidos pelo usuário.
Versão 2.40.0
- Novo demo Delphi XlsCondFormat12 em
Demo/Delphi/XlsCondFormat12/que demonstra a API de extensão de formatação condicional v2.34.0+ de ponta a ponta. Três botões permitem gerarCondFormat12.xls(backend BIFF8),CondFormat12.xlsx(backend XLSX) ou ambos lado a lado. Cada planilha de saída carrega os mesmos quatro tipos de regra — Barra de Dados, escala de 3 cores, Conjunto de Ícones (3 setas) e escala de 2 cores — cobrindo dez linhas de dados para abrir os arquivos no Excel e verificar visualmente. - O caminho BIFF8 exercita adicionalmente a sobrescrita de estilo DXF v2.35.0: a regra Barra de Dados anexa cor de fonte branca em negrito para que o texto da célula permaneça legível.
- Nova fixture de teste DUnitX em
Tests/Delphi/HotXLS.CondFormat12Tests.pascobre dez cenários de round-trip e superfície de API: round-trip BIFF8 para todos os quatro tipos de regra, round-trip de estilo DXF para cores RGB, cores tema e flags de fonte, e round-trip XLSX para Barra de Dados / escala de 3 cores / Conjunto de Ícones com ShowOnly. A fixture está conectada aHotXLSDelphiTests.dpre ao.dprojcorrespondente. - Para suportar a fixture de teste,
TCondFormatexpõe dois novos acessores públicos:RuleCounteRule(I). - Nota de validação: abra o
.xlse.xlsxdo demo no Excel para ver as quatro regras de extensão CF12 / OOXML renderizadas lado a lado.
Versão 2.39.0
- A substituição de estilo XF diferencial (DXF) em regras de formatação condicional agora suporta codificação de cor de tema além do modo RGB existente. Cada slot de cor — cor da fonte, fundo do preenchimento, primeiro plano do preenchimento — pode ser definido contra um índice de tema da planilha mais um valor de matiz.
- Três novos métodos em
TXLSDxfStyleativam um slot no modo tema:SetFontColorTheme(themeId, tint),SetFillBgColorTheme(themeId, tint),SetFillFgColorTheme(themeId, tint). Tint é um single no intervalo [-1.0, +1.0]. Os métodos existentesSetXxxColor(rgb)permanecem no modo RGB; os dois modos são mutuamente exclusivos por slot. - Consulte o modo ativo através das novas propriedades somente leitura
XxxColorIsTheme/XxxColorThemeId/XxxColorThemeTint.HasXxxColorretorna True em qualquer modo. - O formato de fio BIFF8 segue o layout padrão XFProp Colour:
xclrType=2+ LongWord BGR de 4 bytes para RGB,xclrType=3+ tint assinado de 2 bytes × 32767 + índice de tema de 4 bytes para o modo tema. O decodificador do blob DXF espelha este dispatch. - Limitações conhecidas: o round-trip no modo tema é suportado apenas no lado BIFF8 (.xls) — o lado XLSX (.xlsx) continua emitindo e lendo apenas
<color rgb="..."/>.
Versão 2.38.0
- A leitura XLSX (.xlsx) agora reconhece as regras de formatação condicional de extensão Excel 2007+ em arquivos recebidos — barra de dados, escala de cor (2 e 3 stops, detectados automaticamente da contagem cfvo), e conjunto de ícones — e popula o objeto
TXLSXConditionalFormatcorrespondente para que o código de usuário possa inspecionar e fazer round-trip dessas regras sem perdê-las. - O leitor analisa o envelope OOXML
<cfRule type="dataBar|colorScale|iconSet">e o corpo interno<dataBar>/<colorScale>/<iconSet>, percorrendo as entradas filho<cfvo>para recuperar o type e val de cada limiar, e as entradas<color>para recuperar a cor da barra ou as cores por stop da escala. - As regras de conjunto de ícones fazem round-trip do nome de família
iconSet(os 17 conjuntos base Excel 2007), da flagreverse, e da flagshowValue(mapeada paraShowOnly). - Os valores de cor analisados do atributo OOXML
rgb="AARRGGBB"são convertidos para a mesma convenção BGRLongWordusada pela API de escrita. - O manuseio XLSX
<cfRule type="cellIs">existente está inalterado; o dispatch escolhe os novos tipos de regra apenas quando o atributotypeos nomeia. - Limitações conhecidas: referências de cor de tema são lidas como 0; substituições
iconIdpor stop não são capturadas; o atributopriorityde<cfRule>é ignorado na leitura.
Versão 2.37.0
- O formato de registro BIFF8 CFEX agora carrega o array cfvo completo por stop (kind + string de valor + cor, conforme semântica cfvo de [MS-XLS]) em vez de apenas a cor da barra/stop. As regras de barra de dados agora persistem os tipos e valores de limite min/max, as escalas de cor persistem a combinação kind + value + color de cada stop, e os conjuntos de ícones persistem kind + value de cada limite junto com as flags reverse / showOnly.
- A escrita CFEX adiciona um byte de flag de versão (ver=1) para que leitores HotXLS mais antigos que esperam o layout minimal CFEX v2.34.0 recorram silenciosamente à interpretação legada. O leitor v2.37.0 também reconhece registros ver=0 produzidos por builds mais antigas.
- O leitor agora detecta entradas mistas CONDFMT + CONDFMT12 no mesmo intervalo — um padrão comum em arquivos salvos pelo Excel. A entrada CONDFMT mais antiga é marcada via uma nova propriedade
IsShadowedemTCondFormat. O escritor continua emitindo ambas as famílias de registros ao salvar. - Nova propriedade
TotalRangeemTCondFormatexpõe o intervalo de extensão mesclado anteriormente privado. - Limitações conhecidas: a detecção shadow é limitada a uma correspondência exata de caixa delimitadora. O round-trip cfvo completo do ColorScale preserva os 8 valores kind padrão mas não preserva os metadados de matiz de cor tema do Excel.
Versão 2.36.0
- A saída XLSX (.xlsx) agora suporta os três tipos de regra de formatação condicional de extensão Excel 2007+ — barra de dados, escala de cor (2-stop e 3-stop), e conjunto de ícones — trazendo o backend XLSX para paridade com o backend BIFF8 (.xls) de v2.34.0. Quatro novos métodos públicos em
TXLSXWorksheetespelham a API XLS:AddCondFormatDataBar,AddCondFormatColorScale2,AddCondFormatColorScale3,AddCondFormatIconSet. - O arquivo .xlsx salvo agora emite o elemento OOXML
<conditionalFormatting>com a estrutura filha apropriada para cada tipo de regra:<cfRule type="dataBar"><dataBar>para barras,<cfRule type="colorScale"><colorScale>com 2 ou 3 cfvo + color stops, e<cfRule type="iconSet"><iconSet iconSet="...">com o conjunto cfvo apropriado. - O mapeamento de nomes de conjuntos de ícones integrados cobre os mesmos dezessete conjuntos base Excel 2007 suportados pelo backend XLS, produzidos como string de atributo OOXML
iconSetpadrão. - Os tipos de limiar e valores de cor usam a mesma enumeração e convenção de cor da API XLS — mesmo
TXLSCfValueKind, mesmo formatoLongWordBGR Delphi. As chamadas existentesAddConditionalFormatXLSX continuam se comportando de forma idêntica. - Limitações conhecidas: a codificação de cor de tema ainda não é emitida; as substituições
iconIdpor stop em conjuntos de ícones não são suportadas. O reconhecimento do lado de leitura XLSX de regras barra de dados / escala de cor / conjunto de ícones provenientes de arquivos salvos pelo Excel permanece adiado — apenas escrita está conectada nesta versão.
Versão 2.35.1
- O leitor BIFF8 agora decodifica os bytes Differential XF (DXF) anexados a uma regra CF12 de volta para o property bag
TXLSDxfStyleda regra, além de manter os bytes brutos emDxfBlob. Carregar uma planilha salva pelo Excel com regras de barra de dados / escala de cor / conjunto de ícones estilizadas agora expõe a cor da fonte, cores de preenchimento, negrito / itálico / sublinhado e id de formato de número diretamente através do parHasXxx+valor em cadaRule.Style. - Comportamento round-trip: um ciclo load-edit-save agora reflete qualquer mutação pós-carregamento de
Rule.Style. Se um usuário lê uma planilha, alteraRule.Style.SetFontColore salva, a nova cor vence; se o usuário não tocar no Style, o arquivo salvo carrega as mesmas substituições do original. - Valores
xfPropTypedesconhecidos no blob DXF são ignorados em vez de rejeitados, então arquivos Excel mais novos usando tipos de propriedade ainda não reconhecidos por esta versão continuam carregando (os bytes brutos permanecem emDxfBlobpara inspeção ou suporte futuro de round-trip).
Versão 2.35.0
- As regras de formatação condicional agora podem carregar uma substituição de estilo XF diferencial (DXF), de modo que uma regra CF12 disparada no Excel pode alterar a cor da fonte, o preenchimento, o peso, o itálico, o sublinhado ou o formato de número da célula sem alterar o XF base da célula. A substituição é exposta como uma nova propriedade
TXLSDxfStyleem cadaTCondFormatRule, acessível após criar uma regra via as APIs existentesAddCondFormatDataBar/AddCondFormatColorScale*/AddCondFormatIconSet. - Substituições de estilo suportadas nesta versão: cor da fonte, cor de fundo do preenchimento, cor de primeiro plano do preenchimento, padrão de preenchimento, fonte em negrito, fonte em itálico, estilo de sublinhado da fonte e id de formato de número integrado. Cada propriedade tem uma flag
HasXxxpareada — apenas propriedades explicitamente definidas viaSetXxxsão emitidas no arquivo BIFF8. - O escritor BIFF8 agora anexa um bloco DXF não vazio ao registro CF12 sempre que o Style da regra tem pelo menos uma substituição definida. O bloco DXF usa o layout público de array XFProp (cxfp + tuplas por propriedade de tipo / tamanho / dados), permitindo ao Excel captar as mudanças de estilo quando a regra se aplica.
- O leitor BIFF8 preserva os bytes DXF brutos de um arquivo salvo pelo Excel na propriedade
DxfBlobda regra, então um round-trip load-edit-save não perde mais silenciosamente o estilo da célula carregado pelas regras CF12. A decodificação dos bytes brutos de volta para o property bagTXLSDxfStyleestá planejada para uma release de seguimento. - O comportamento padrão permanece inalterado para regras que não aderem a um estilo —
cbdxf = 0é emitido, idêntico a v2.34.0, então as regras existentes de barra de dados / escala de cor / conjunto de ícones são renderizadas exatamente como antes. - Limitações conhecidas: a codificação de cor de tema para DXF não é suportada (somente RGB); substituições de borda e paradas de gradiente não estão no conjunto de propriedades desta versão; a ordem de bytes para os blobs de valor XFProp segue as notas públicas [MS-XLS] e pode requerer pequenos ajustes para a fidelidade completa de round-trip do Excel uma vez validado com BiffView. A paridade do lado XLSX para os três novos tipos de regra permanece adiada.
Versão 2.34.0
- Nova API pública de formatação condicional na planilha para as regras de extensão do Excel 2007+:
AddCondFormatDataBar,AddCondFormatColorScale2,AddCondFormatColorScale3eAddCondFormatIconSet. Cada método aceita um intervalo sqref como"A1:A10"mais os parâmetros específicos do tipo (cor da barra, cores das paradas do gradiente ou família do conjunto de ícones) e retorna o objeto de regra criado. - O escritor BIFF8 (.xls) agora emite os registros CONDFMT12 / CF12 / CFEX juntamente com os registros CONDFMT / CF existentes, de modo que as planilhas criadas pela nova API persistam em disco as suas regras de barra de dados, escala de 2 ou 3 cores e conjunto de ícones.
- O leitor BIFF8 reconhece os registros CONDFMT12 / CF12 / CFEX recebidos e os expõe através do mesmo modelo de regras em memória; arquivos .xls criados pelo Excel com regras de extensão não são mais silenciosamente descartados ao carregar.
- Catálogo integrado dos dezessete conjuntos de ícones base do Excel 2007 (famílias 3-setas / 3-bandeiras / 3-semáforos / 3-sinais / 3-símbolos, 4-setas / 4-avaliações / 4-semáforos, e 5-setas / 5-avaliações / 5-trimestres), selecionáveis através do enum
TXLSIconSetType. - Os tipos de limiar para os limites da barra de dados e as paradas de escalas / conjuntos de ícones podem ser número, mínimo / máximo do intervalo, percentual, percentil ou fórmula, alinhados com os tipos cfvo do Excel.
- O comportamento das regras de valor de célula existentes não foi alterado; apenas novas APIs e novo tratamento de registros BIFF8 foram adicionados.
- Limitações conhecidas nesta versão: a saída XLSX para os três novos tipos de regra ainda não está conectada (regras XLSX de valor de célula existentes não são afetadas); o bloco de estilo XF diferencial no CF12 é emitido vazio, portanto o Excel pode renderizar barras e escalas com cores padrão em vez das cores fornecidas pela API; os arrays cfvo por parada no CFEX carregam apenas a cor, não a combinação tipo / valor. Estas lacunas estão planejadas para as releases de acompanhamento v2.34.x / v2.35.x junto com a planilha de demonstração e a validação de renderização no Excel.
Versão 2.33.3
- Novo demo Delphi XlsTables em
Demo/Delphi/XlsTables/demonstra o lado de gravação de Tables BIFF8 (ListObjects) de ponta a ponta. GeraSalesTable.xlscom uma região de vendas de quatro colunas (Região / Produto / Trimestre / Receita) vinculada como uma Table em A1:D10 usandoSheet.AddTable('SalesTable', 'A1:D10', headers). Abra o .xls produzido no Excel para verificar os menus suspensos de coluna, as faixas de linhas alternadas e o nome de referência estruturada SalesTable na Caixa de Nome. - O demo é a receita de ponta a ponta mais curta para adotar a API
AddTableda v2.33.0: defineStyleName = 'TableStyleMedium2'eShowRowStripes = True, preenche nove linhas de dados + uma linha de cabeçalho, e escreve a pasta de trabalho com uma única chamadaSaveAs. A saída vai ao lado do executável. - A infraestrutura de compilação não foi alterada: o
build-Win32-Demo.cmdexistente pegaXlsTables.dprautomaticamente através de sua varredurafor /r Demo *.dpr— não são necessárias alterações nos scripts de build ou nas configurações .cbproj/.dproj.
Versão 2.33.2
- O
SaveAsBIFF8 (.xls) agora suprime os registros independentes em nível de planilhaAUTOFILTERINFO/AUTOFILTER($009D / $009E) quando uma Table na mesma planilha cobre completamente o intervalo do filtro automático. O Excel incorpora um menu suspenso de filtro automático dentro do próprio objeto Table, então emitir um filtro automático adicional em nível de planilha para o intervalo idêntico aciona a Validação de Arquivo do Office a rejeitar o arquivo. Isto corresponde à correção do lado XLSX enviada na v2.29.4. - A verificação de cobertura é conservadora: uma Table é considerada como "cobrindo" o filtro automático apenas quando sua primeira/última linha e primeira/última coluna abrangem os limites do filtro automático. A sobreposição parcial mantém o comportamento de emissão do filtro automático em nível de planilha.
- Salvamentos BIFF5 e planilhas sem nenhuma Table não são afetados — a verificação de supressão é executada apenas quando o formato do arquivo é BIFF8 e a planilha tem pelo menos uma Table. Sem mudança de API pública.
Versão 2.33.1
- O lado de leitura BIFF8 (.xls) agora reconhece os registros de Tables de recursos compartilhados que a v2.33.0 adicionou no lado de gravação. Abrir um .xls salvo pelo Excel (ou pelo próprio HotXLS) com um ou mais ListObjects/Tables agora popula a coleção
Tablesda planilha com umTXLSTablepor FEAT11 ($0872) analisado, reconstruindo o intervalo da tabela a partir do Ref8U primário, recuperando o id, nome e nome de exibição da tabela quando presentes, e preenchendo o nome do estilo da tabela a partir do registro LIST12 ($0877) emparelhado. Anteriormente, esses registros eram silenciosamente ignorados. - O opcode FEATHEADR ($0867) compartilhado agora é despachado por seu campo
Isfem vez de ir sempre para o analisador de proteção. Isf=2 (Proteção Aprimorada) mantém o comportamento existente; Isf=4 (SharedList) é reconhecido como marcador para Tables na planilha; Isf=3 (SmartTags) e outros valores são ignorados com segurança. FEATHEADR11 ($0871) também é reconhecido silenciosamente como marcador de Tables. - O leitor é de melhor esforço e tolerante: cargas úteis FEAT11 malformadas ou variantes do Excel degradam graciosamente para uma Table que tem pelo menos o intervalo de células correto. A proteção de planilha no round-trip está inalterada.
Versão 2.33.0
- As planilhas BIFF8 (.xls) agora suportam objetos Table (ListObjects do Excel). Chame
Worksheet.AddTable(Name, Range, Columns)em umaIXLSWorksheetpara anexar uma região de tabela nomeada a um intervalo de células — por exemploSheet.AddTable('SalesTable', 'A1:F9', HeaderList). O caminho de salvamento .xls agora emite a família de registros de recursos compartilhados BIFF8 que marca a planilha como contendo Tables: FEATHEADR ($0867 com Isf=4), FEATHEADR11 ($0871), e um par FEAT11 ($0872) + LIST12 ($0877) por tabela. Anteriormente, chamarAddTablena fachada XLS não estava disponível; tabelas definidas em uma planilha eram descartadas silenciosamente emSaveAs(xlExcel97). - Nova API pública em
IXLSWorksheet: propriedadeTables: TXLSTables(coleção somente leitura) e métodoAddTable. A forma refleteTXLSXTable/TXLSXTablesno lado XLSX.TXLSTableexpõeId,Name,DisplayName,Range,Columns,StyleName(padrão'TableStyleMedium2'),ShowFirstColumn,ShowLastColumn,ShowRowStripes(padrão true),ShowColumnStripeseTotalsRowShown. - Os novos registros do fluxo da planilha são emitidos imediatamente antes do EOF da planilha, após a proteção da planilha, apenas quando o formato do arquivo é BIFF8 (
xlExcel97). Pastas de trabalho sem tabelas são salvas exatamente como antes — nenhum FEATHEADR é emitido, sem alterações no fluxo de registros, sem sobrecarga. Os salvamentos BIFF5 não são afetados. - IDs de tabela são atribuídos sequencialmente por planilha (1..N) no momento do salvamento se não forem predefinidos. O nome de estilo padrão
'TableStyleMedium2'corresponde ao que o Excel e o lado XLSX já usam. - Limitações conhecidas desta versão inicial (v2.33.0): fórmulas de linha de totais e intervalos auxiliares de referências estruturadas ainda não são emitidos; a supressão de conflito entre
AUTOFILTERINFOem nível de planilha e um intervalo de Table será adicionada em um follow-up; o lado de leitura (análise de um .xls salvo pelo Excel com tabelas de volta para a coleçãoTables) também é um follow-up.
Versão 2.32.1
- Corrigido um erro de compilação introduzido pelo recurso de gravação FILEPASS da v2.32.0 que impedia a construção da biblioteca no RAD Studio 12+ com verificação rigorosa de tipos. O auxiliar
EncryptAllBlobsdeclarava seu buffer de dispersão comoPByteem um contexto ondePByteresolvia para o alias local delxHandle, enquanto o alvo da chamadaEncryptBlobDataemlxEncrypteresperavalxBLOB.PByte. Embora ambos os tipos sejam aliases de^Byte, Delphi os trata como distintos sob a verificação rigorosa E2010. A variável de buffer agora está totalmente qualificada comolxBLOB.PByte, então o caminho de criptografia por senha da v2.32.0 compila limpamente em todas as versões RAD Studio suportadas (12.0–37.0).
Versão 2.32.0
- Nova propriedade
EncryptionPasswordemIXLSWorkbook. Definir uma senha não vazia antes deSaveAsagora produz um arquivo .xls protegido por senha compatível com Excel: Excel, LibreOffice Calc e outros leitores BIFF8 solicitam a senha ao abrir e recusam acesso se incorreta. Anteriormente, o setter de senha era silenciosamente ignorado no lado de escrita. - O caminho de escrita emite o registro BIFF8 FILEPASS ($002F) imediatamente após o BOF da pasta de trabalho e criptografa RC4 cada corpo de registro subsequente com o mesmo algoritmo do lado de leitura (vMajor=1, vMinor=1 -- criptografia "Office 97/2000 Compatible" do Excel). Salt e Verifier de 16 bytes são gerados via
CryptGenRandomdo Windows em vez deRandomdo Pascal. A re-derivação da chave de bloco a cada limite de 1024 bytes é preservada. - A criptografia aplica-se apenas a BIFF8 (
xlExcel97); o caminho BIFF5 permanece em texto plano.EncryptionPasswordvazio mantém o comportamento de texto plano (padrão), aplicações existentes não são afetadas. - Lado de leitura: corrigido um bug latente em
ParseFilePassque fazia o primeiro corpo de registro após FILEPASS (tipicamente CODEPAGE) ser tratado como texto plano. Arquivos criptografados escritos pelo HotXLS agora fazem ida e volta corretamente através do HotXLS. - Nota de segurança: BIFF8 RC4 (vMajor=1/vMinor=1) usa uma chave de 40 bits, considerada quebrada pelos padrões de 2025. Use este recurso para compatibilidade com a UI clássica de proteção por senha do Excel, não para confidencialidade de dados sensíveis. Para segurança real, prefira XLSX com AES.
Versão 2.31.0
- Adicionada a propriedade
UseSharedFormulasemIXLSWorkbook. Quando definida comoTrue, o SaveAs em formato BIFF8 agrupa as células que compartilham uma fórmula modelo em registros SHRFMLA nativos ($04BC), correspondendo ao formato compacto do Microsoft Excel. Colunas de fórmulas como=A1*B1,=A2*B2, …,=A99*B99são agrupadas automaticamente, reduzindo o tamanho do arquivo em 30–60 % em planilhas com muitas fórmulas modelo. - O agrupamento é descendente por coluna, contíguo e baseado em modelo: apenas células da mesma coluna com linhas consecutivas e fórmulas PTG equivalentes são agrupadas. Células com fórmulas de matriz ou sinalizadores de mesclagem são excluídas.
- O valor padrão é
False, mantendo inalterada a emissão de registros FORMULA por célula. Ative definindoWorkbook.UseSharedFormulas := Trueantes de chamarSaveAs. - O lado de leitura não é afetado. Esta é uma versão MINOR (2.30.x → 2.31.0) porque uma nova propriedade pública é adicionada e o formato de saída BIFF8 muda quando o recurso está habilitado.
Versão 2.30.6
- Corrigida uma quarta classe de erros de compilação nas demos C++Builder sob o compilador bcc32 baseado em clang do RAD Studio 37.0: o padrão de indexação
->Borders[idx]->Propem um ponteiro inteligente de interface gerava o erro E5843 ("o tipo de referência de membro não é um ponteiro"). Todas as ocorrências foram alteradas para->Borders->Item[idx]->Prop. Esta correção afeta as demos ApiTour, ExportWithColoring, PurchaseOrder e QuickStart e completa a compatibilidade total com clang para todos os nove projetos de demo C++Builder.
Versão 2.30.5
- Todos os nove projetos de demonstração C++Builder agora compilam corretamente com o compilador bcc32 baseado em clang do RAD Studio 37.0. Três classes de erros de compilação foram corrigidas: a propriedade
EOFdelxFormulafoi renomeada paraIsEofpara eliminar um conflito com a macro Cstdio.h; as constantes de enumeração da API XLS (xlHAlignCenter,xlAround,xlMedium, etc.) agora são explicitamente qualificadas com o namespaceLxhandle::; e as atribuições de valores de células XLSX foram alteradas deOleVariant(...)paraVariant(...)porqueTXLSXCell.Valueé do tipoSystem::Variante o compilador clang rejeita a conversão implícita da classe base protegidaOleVariant.
Versão 2.30.4
- A demo OrderCalc (exemplo de ordem de compra para Delphi) agora inclui uma opção de exportação XLSX além dos formatos XLS, HTML e RTF existentes. Ao selecionar «Excel 2007+ (*.xlsx)» na caixa de diálogo de salvar, a ordem de compra é gravada com a API nativa TXLSXWorkbook, gerando diretamente um arquivo XLSX padrão com fontes, preenchimentos, bordas, alinhamento, formatos de número e fórmulas Excel.
Versão 2.30.3
- SaveXLSWorkbookAsXLSX (a ponte usada por TDataToXLS.SaveAs e TGridToXLS.SaveAs quando o nome do arquivo de destino termina em .xlsx) agora copia as cores de preenchimento de fundo das células, cores de fonte e atributos de estilo de fonte (nome, tamanho, negrito, itálico) da pasta de trabalho XLS subjacente para a saída XLSX. As larguras das colunas — incluindo colunas decorativas intencionalmente estreitas — também são copiadas. Anteriormente, apenas valores e formatos numéricos eram transferidos, tornando a saída XLSX sem formatação, com todas as larguras de coluna no valor padrão e qualquer coluna decorativa estreita aparecendo como uma coluna vazia sobredimensionada.
Versão 2.30.2
- Corrigido um bug de round-trip no leitor XLS em que a direção Outline.SummaryRow era invertida após Open. A flag fRwSumsBelow do registro WSBOOL (especificação BIFF8 p278 byte 0 bit 6, máscara $0040) significa "linhas de resumo aparecem *abaixo* do detalhe", mas o parser anteriormente definia SummaryRow = xlAbove quando o bit estava definido (e xlBelow quando estava limpo) -- exatamente o oposto da especificação. O lado do escritor já estava correto (emite $0040 para xlBelow), então abrir um arquivo Excel com "linhas de resumo abaixo do detalhe" e salvá-lo novamente via HotXLS invertia silenciosamente a direção do outline para "acima". Agora a direção de parsing corresponde à especificação e ao escritor, portanto as configurações de outline fazem round-trip corretamente. fColSumsRight ($0080) já era tratado corretamente e permanece inalterado.
Versão 2.30.1
- O escritor XLS (BIFF8) agora emite os registros INTERFACEHDR / INTERFACEEND / WRITEACCESS na seção globals da pasta de trabalho, correspondendo ao layout de registros nativo do Microsoft Excel. O Excel nativo sempre escreve esse trio entre CODEPAGE/DSF e WINDOW1, e leitores BIFF mais rigorosos / caminhos de Office File Validation podem esperá-los. INTERFACEHDR carrega a code page (1200, UTF-16), INTERFACEEND é um marcador vazio, e WRITEACCESS carrega o nome de usuário "salvo por" (atualmente codificado como "HotXLS"; uma versão futura pode promovê-lo a uma propriedade da Workbook). Os arquivos XLS de saída agora correspondem mais fielmente ao layout de bytes nativo do Excel.
Versão 2.30.0
- Adicionada uma ponte de exportação clássica para XLSX. TDataToXLS.SaveAs e TGridToXLS.SaveAs agora escrevem nomes de arquivo .xlsx através do motor XLSX, mantendo inalterados os caminhos existentes .xls, .html e .rtf.
- Adicionadas APIs de visualização de planilha para XLS e XLSX. IXLSWorksheet.View e TXLSXWorksheet.View suportam visualização normal, visualização de quebra de página e visualização de layout de página, e a configuração é preservada pelo caminho correspondente de escritor/leitor de arquivos.
- Adicionadas APIs de compatibilidade clássicas de pasta de trabalho: IXLSWorkbook.SetCodePage e IXLSWorkbook.VBAProject. Os projetos VBA agora podem ser inspecionados através dos nomes de módulo TXLSVBAProject/TXLSVBAModule e texto-fonte quando uma pasta de trabalho contém um armazenamento VBA.
- TXLSXWorkbook estendido com ParsedVBAProject, uma visualização analisada somente leitura sobre um payload válido de vbaProject.bin, preservando o comportamento existente de round-trip de bytes brutos de VbaProject.
- Adicionada a unidade opcional cxGridAddExcel para fluxos de exportação cxGrid DevExpress. Ela intencionalmente não está incluída nos pacotes padrão para que instalações sem DevExpress continuem compilando de forma limpa.
- Corrigida a renderização de planilhas de gráfico XLSX onde o gráfico aparecia em branco quando a pasta de trabalho era aberta no Excel (uma planilha de gráfico recém-aberta mostrava brevemente os 3 ícones de contexto de gráfico no canto superior direito e depois os descartava, deixando a planilha vazia). Os desenhos de planilhas de gráfico agora usam <xdr:absoluteAnchor> com extensão explícita (~10in × 7.2in = 9525000 × 6858000 EMU) em vez de <xdr:twoCellAnchor> com cx=0/cy=0; as planilhas de gráfico não têm grade de células contra a qual resolver twoCellAnchor, portanto o Excel recorria ao xfrm interno de tamanho zero e renderizava o gráfico com zero pixels. De acordo com ECMA-376-1 14.2.3.2, os desenhos de planilhas de gráfico devem usar absoluteAnchor. Os âncoras de gráfico em planilhas estão inalterados.
Versão 2.29.4
- Corrigido um bug de empacotamento XLSX que causava o prompt de reparo do Excel "Encontramos um problema com algum conteúdo em <file>.xlsx" em pastas de trabalho onde um autoFilter no nível da planilha e uma Tabela cobriam o mesmo intervalo (por exemplo, a planilha Details de XlsxFeatureGallery.xlsx no demo MemoryDataExport, que chamava AddTable('SalesTable', 'A1:F9', ...) seguido de SetAutoFilter('A1:F9')). OOXML proíbe dois mecanismos de filtro sobre o mesmo intervalo; o escritor agora suprime a emissão duplicada de <autoFilter> no nível da planilha quando seu intervalo coincide com o intervalo de qualquer tabela. O autoFilter das próprias Tabelas (renderizado como os dropdowns do cabeçalho da tabela) continua funcionando.
- Corrigida uma violação de esquema relacionada na saída <dataValidation>: um atributo operator era emitido para cada validação, mas ECMA-376-1 18.3.1.32 só permite isso para os tipos whole / decimal / date / time / textLength. AddListValidation produz type="list", que costumava vazar operator="between"; OFV é mais rigoroso que o Excel quanto a isso e podia rejeitar a pasta de trabalho. O atributo operator agora é omitido para list / custom / none.
- Corrigido o elemento <legacyDrawing r:id="..."/> em planilhas que mesclam hyperlinks internos e externos com comentários (a planilha Dashboard de XlsxFeatureGallery.xlsx tem 1 interno + 1 externo + 1 comentário). O cálculo de rId contava todos os hyperlinks em vez de apenas os externos (os internos usam o atributo inline location= e não consomem rId), de modo que legacyDrawing apontava para o alvo rels dos comentários em vez do alvo vmlDrawing. ECMA-376-1 18.3.1.51 exige que legacyDrawing referencie um rels do tipo vmlDrawing. O rId agora é calculado apenas a partir da contagem de hyperlinks externos.
- Também parou de emitir um arquivo redundante xl/worksheets/_rels/sheetN.xml.rels para planilhas de gráfico adicionadas via AddChartSheet. O arquivo de relacionamento duplicado apontava para uma parte de planilha inexistente e aparecia como órfão dentro do zip .xlsx; planilhas de gráfico agora escrevem apenas o xl/chartsheets/_rels/sheetN.xml.rels correto.
- Atualizado o demo MemoryDataExport (XlsxFeatureGallery) para remover a chamada redundante SetAutoFilter('A1:F9') na planilha Details -- AddTable já anexa um autoFilter ao intervalo da tabela, portanto a chamada extra anteriormente acionava a rejeição OFV acima. A supressão defensiva do escritor cobre o código do cliente que não recebe a atualização do demo.
Versão 2.29.3
- Corrigida uma regressão de round-trip XLSX em que bordas desenhadas em linhas de outra forma vazias eram descartadas após Open + modify + SaveAs. O divisor horizontal da linha 8 do ApiTour (produzido por uma chamada Range.SetBorders em uma linha sem dados) era renderizado corretamente no ApiTour.xlsx recém-gerado, mas desaparecia em ApiTour-XLSX-Modified.xlsx depois que a etapa Modify do demo salvava o arquivo novamente, deixando o Excel mostrando uma linha de grade vertical quebrada em C8 / D8 apenas no arquivo modificado (o ApiTour.xlsx original não era afetado). O parser XLSX agora também aplica estilos de célula quando um elemento `<c>` é auto-fechado ou não tem filhos value/formula, de modo que células sem valor mas com estilo sobrevivem ao round-trip.
Versão 2.29.2
- Corrigida uma regressão de round-trip XLSX nos fluxos Open + modify + SaveAs. Quando ParseWorksheetXml lia uma célula cuja <c s="N"/> referenciava um cellXf de styles.xml, armazenava N diretamente em cell.FormatIndex. Em SaveAs, os cellXfs são reconstruídos a partir dos pools de estilo da pasta de trabalho (com entradas compostas opcionais) e o slot do novo layout no mesmo índice numérico quase nunca carrega a mesma semântica; a célula re-salva acabava apontando para o cellXf errado -- ou além do final da nova tabela cellXfs -- e o Excel reportava "O Office detectou um problema com este arquivo. Podemos tentar recuperá-lo". ApplyStyle agora remapeia cellStyle para FontIndex / FillIndex / BorderIndex / NumberFormatIndex / AlignmentIndex / ProtectionIndex via as tabelas CellXfXxxMap que ParseStylesXml já popula, de modo que o round-trip re-emite a célula contra os cellXfs recém-construídos.
Versão 2.29.1
- Corrigidas duas regressões de renderização XLSX expostas pelo demo ApiTour: (1) células dentro de uma linha podiam ser emitidas fora de ordem de coluna quando uma chamada Range.SetBorders adicionava células em ordem não monotônica (por exemplo, a etapa outline cria A8/C8, a etapa inside cria B8 -- a saída era A8 / C8 / B8 / em vez de A8 / B8 / C8 / então o Excel reportava "O Office detectou um problema com este arquivo" e forçava a Visualização Protegida). O escritor XLSX agora ordena as células de cada linha por coluna antes da emissão, correspondendo ao esquema OOXML CT_Row. (2) Células que definiam 2 ou mais índices de estilo simultaneamente (Font + Fill + Border, etc.) costumavam ser colapsadas em um cellXf unidimensional via cadeia de prioridade (FontIndex vencia, Border / Fill eram descartados), portanto, por exemplo, uma linha de cabeçalho com FontIndex + FillIndex + BorderIndex definidos em um Range[..].SetBorders era renderizada sem as bordas. O escritor agora coleta um pool composto de cellXf durante SaveAs e roteia células multidimensionais para um cellXf sintetizado que preserva todas as dimensões.
Versão 2.29.0
- Renomeada a unidade auxiliar interna `lxList2` para `lxKeyList` e renomeadas as classes de chave WideString de `lxList` de `TXLSKeyList` / `TXLSKeyEntry` / `TXLSKeyArray` para `TXLSStringKeyList` / `TXLSStringKeyEntry` / `TXLSStringKeyArray`, de modo que o nome da unidade corresponda à sua classe principal `TXLSObjectKeyList` e as duas gerações de key-list sejam autodescritivas (`TXLSStringKey*` para o pool legado de chave WideString, `TXLSObjectKey*` para o pool de deduplicação baseado em THashtableKey). Se seu código referencia o antigo nome da unidade ou nomes de classes, atualize as cláusulas uses e os nomes de tipo de acordo.
Versão 2.28.3
- Corrigida uma regressão de emissão de células XLSX que fazia com que as bordas definidas em linhas de outra forma vazias desaparecessem. `Range[''A3:C10''].SetBorders(xlsxEdgeOutline,...)` em uma planilha cuja linha 8 não carregava dados costumava renderizar a linha vertical da grade C/D quebrada nessa linha porque o escritor pulava qualquer célula cujo Value fosse não atribuído -- mesmo quando a célula tinha um BorderIndex / FontIndex / FillIndex / NumberFormatIndex / AlignmentIndex / ProtectionIndex atribuído. O escritor agora emite `<c r='..' s='..' />` para células sem valor que carregam qualquer índice de estilo.
Versão 2.28.2
- Corrigida uma violação de esquema de planilhas XLSX que fazia o Excel recusar carregar planilhas que combinavam células mescladas com AutoFilter. O escritor XLSX agora emite o elemento <autoFilter> antes de <mergeCells>, correspondendo à sequência OOXML CT_Worksheet (autoFilter é #11, mergeCells é #15). Anteriormente, tais pastas de trabalho acionavam a caixa de diálogo de reparo do Excel com `Load error. Line 1, column 0` em sheet1.xml e a recuperação também descartava tableParts / autoFilter de planilhas Details irmãs.
Versão 2.28.1
- Adicionadas APIs de conveniência à interface clássica XLS. IXLSRange agora expõe os helpers somente para leitura Width e WidthInPixels, além de SaveAsCSV(FileName); IXLSWorksheet e IXLSWorkbook agora expõem as sobrecargas SaveAsCSV(FileName / Stream) para o intervalo usado ou a planilha ativa; IXLSPageSetup agora expõe Order, Draft, BlackAndWhite, PrintNotes e IsFitToPages (somente para leitura). O salvamento/abertura do registro SETUP agora preserva essas flags de impressão.
Versão 2.28.0
- Adicionada a exportação para RTF em TXLSXWorkbook. Novas sobrecargas SaveAsRTF (FileName / Stream x planilha ativa padrão / índice de planilha explícito) escrevem a planilha escolhida como um documento RTF 1.6 contendo uma tabela simples. As larguras das colunas são derivadas dos dados ColWidth da planilha (1 unidade de caractere do Excel é aproximada como 96 twips do RTF); as colunas sem larguras explícitas usam StandardWidth, se definido, caso contrário, usam 809 twips (aproximadamente 8,43 caracteres). O negrito por célula (\\b), itálico (\\i) e tamanho da fonte (\\fsN em meio-pontos) são aplicados a partir do FontIndex da célula. Caracteres não ASCII são codificados como escapes Unicode RTF de 16 bits com sinal (\\uN?) de acordo com RTF 1.6 §2.4.2, cobrindo toda a faixa BMP. Células mescladas não são expandidas — a célula de origem carrega o conteúdo e as células não de origem dentro do intervalo são emitidas como células vazias. O SheetIndex padrão escreve a planilha ativa; fora do intervalo retorna -1. Planilhas vazias produzem um documento RTF válido mínimo.
Versão 2.27.0
- Adicionada a exportação para HTML em TXLSXWorkbook. Novas sobrecargas SaveAsHTML (FileName / Stream x planilha ativa padrão / índice de planilha explícito) escrevem a planilha escolhida como um documento HTML UTF-8 com um BOM UTF-8. A saída é uma única tabela <table> dentro de uma página HTML mínima. Células mescladas são expressas como atributos colspan / rowspan. O estilo da célula é emitido como CSS inline: família de fontes, tamanho (pt), negrito (font-weight:bold), itálico (font-style:italic), tachado (text-decoration:line-through) e cor da fonte explícita; preenchimento sólido como background-color; alinhamento horizontal (esquerda / centro / direita / justificado) e WrapText (white-space:pre-wrap). Os valores de data são renderizados como 'yyyy-mm-dd hh:nn:ss'; células de texto rico são achatadas para seu texto concatenado. As cores do tema são ignoradas silenciosamente (nenhuma resolução de theme1.xml na exportação HTML simples). O SheetIndex padrão escreve a planilha ativa; fora do intervalo retorna -1.
Versão 2.26.0
- Adicionado suporte a cores de tema, cores indexadas e tons/matizes em TXLSXFont, TXLSXFill e TXLSXBorderEdge. Cada slot de cor agora possui três novos campos, além dos campos RGB existentes: ColorTheme (Inteiro; -1 = não definido; 0..11 = slot de tema OOXML), ColorIndex (Inteiro; -1 = não definido; 0..63 = slot de paleta legado OOXML — emparelhado com Workbook.IndexedColor[N] e XlsxDefaultIndexedPalette) e TintAndShade (Double no intervalo [-1.0, 1.0]; emitido apenas com tema). TXLSXFill expõe as variantes Foreground/Background de todos os três. Prioridade do escritor: tema > indexado > rgb; o caminho "ColorIsAuto = True" mais antigo continua a suprimir completamente o elemento. SaveAs e Open preservam todos os atributos <color theme="N" tint="..."/> e <color indexed="N"/> nos conjuntos de atributos de cores de fonte/preenchimento/borda. Contabilidade: TXLSXBorders.LookupOrAdd agora compara todos os três novos campos para que as bordas coloridas por tema não entrem em conflito com as entradas coloridas por rgb no pool.
Versão 2.25.0
- Adicionado suporte para links externos a planilhas, com preservação durante a operação de SaveAs e Open, em TXLSXWorkbook. Novos tipos: TXLSXExternalLink (URL de destino + lista de nomes de planilhas) + coleção TXLSXExternalLinks. A propriedade TXLSXWorkbook.ExternalLinks expõe a coleção; Add(Target) adiciona e retorna um novo link que o chamador preenche. SaveAs emite um bloco <externalReferences> no nível da planilha em xl/workbook.xml, um rel de externalLink em xl/_rels/workbook.xml.rels (no final do intervalo de rid para manter os rids existentes estáveis), o arquivo xl/externalLinks/externalLink{N}.xml para cada entrada (<externalBook><sheetNames>) e seu arquivo .rels correspondente apontando para a URL da planilha remota com TargetMode="External", além das ContentType Overrides correspondentes. Open examina os pares externalLink{N}.xml + .rels começando no índice 1 e para no primeiro intervalo. A versão atual preserva apenas a URL de destino e os nomes das planilhas; os valores de célula armazenados em cache dentro de <sheetDataSet> não são preservados.
Versão 2.24.0
- Adicionada a função auxiliar TXLSXRange.SetBorders para definir bordas. Novo enum TXLSXBorderEdgeKind (xlsxEdgeAll / Outline / Inside / InsideHorizontal / InsideVertical / Top / Bottom / Left / Right / DiagonalUp / DiagonalDown) que seleciona quais bordas serão escritas. SetBorders(Kind, Style, Color) / SetBorders(Kind, Style) (por padrão, preto opaco) itera por cada célula no intervalo, calcula a máscara da borda para a posição de cada célula (células de canto recebem duas bordas de contorno, células de borda recebem uma, células internas recebem linhas de grade internas, etc.), combina Style + Color em uma cópia da borda atual da célula (portanto, chamadas sucessivas de Outline + Inside se acumulam em vez de sobrescrever), e então realiza uma pesquisa ou adição no nível do Workbook em Workbook.Borders e escreve o BorderIndex resultante (base 1) de volta na célula. A nova função auxiliar TXLSXBorders.LookupOrAdd retorna 0 para bordas vazias, evitando que o pool fique cheio de entradas inúteis.
Versão 2.23.0
- Adicionadas sobrecargas para exportação CSV em TXLSXWorkbook. Novos pontos de entrada: SaveAsCSV(FileName) / SaveAsCSV(FileName, SheetIndex, Delimiter) / SaveAsCSV(Stream) / SaveAsCSV(Stream, SheetIndex, Delimiter) escrevem a área preenchida da planilha selecionada como UTF-8, com BOM inicial e terminadores de linha CRLF. As variantes padrão selecionam a planilha ativa e a vírgula como delimitador; a sobrecarga SheetIndex/Delimiter aceita qualquer WideChar (comumente tab #9 para TSV). A formatação de campos segue o RFC 4180 — valores que contêm o delimitador, aspas duplas, CR ou LF são envolvidos em aspas, com aspas internas duplicadas. Valores de data são renderizados como 'yyyy-mm-dd hh:nn:ss'; células de texto rico são achatadas para o texto concatenado da execução; células vazias no interior do retângulo delimitador são renderizadas como delimitadores simples e a linha termina na última coluna preenchida.
Versão 2.22.0
- Adicionadas substituições de paleta de cores indexadas no nível do workbook em TXLSXWorkbook. Novos pontos de entrada: IndexedColor[Index: Integer]: LongWord (leitura/escrita, slots válidos de 0 a 63, LongWord ARGB), HasCustomIndexedColor(Index): Boolean (indica se o chamador substituiu um slot), CustomIndexedColorCount: Integer (número de slots substituídos; 0 = a paleta é emitida como padrão), ResetIndexedColors: procedure (descarta todas as substituições). A constante XlsxDefaultIndexedPalette expõe a paleta ECMA-376 legada do OOXML para os slots de 0 a 63. SaveAs emite <colors><indexedColors> com todos os 64 filhos <rgbColor> apenas quando pelo menos um slot foi substituído; slots não modificados recorrem à paleta padrão, mantendo os arquivos salvos sem alterações. Open analisa o bloco e descarta silenciosamente slots cujo valor corresponde ao padrão, minimizando as operações de ida e volta. Atribuições de slots fora da faixa (< 0 ou > 63) são descartadas em vez de gerar um erro.
Versão 2.21.0
- Adicionadas seis propriedades de exibição de planilha em TXLSXWorksheet: Zoom: Um inteiro que representa a porcentagem de zoom exibida na barra de status do Excel (10..400, padrão 100; valores fora da faixa são ajustados para os limites). DisplayGridLines / DisplayZeros: Boolean (padrão True) para ocultar as linhas da grade da célula ou renderizar células com valor zero como vazias quando definido como False. DisplayRightToLeft: Boolean (padrão False) para inverter a planilha para o layout da direita para a esquerda para idiomas como árabe/hebraico. StandardWidth / StandardHeight: Double para definir a largura padrão da coluna (unidades de caractere do Excel) / altura padrão da linha (pontos); 0 = não definido, caso em que o Excel aplica seus valores padrão internos de 8,43 / 15. SaveAs emite <sheetView showGridLines / showZeros / rightToLeft / zoomScale> e <sheetFormatPr defaultColWidth / defaultRowHeight> apenas quando os valores diferem dos padrões do Excel; Open os analisa de volta. O tratamento existente de painéis de congelamento e seleção de guia em <sheetView> permanece inalterado e agora compartilha um único emissor.
Versão 2.20.7
- Adicionadas sobrecargas de TStream em TXLSXWorkbook para serialização na memória. Novos pontos de entrada: SaveAs(Stream: TStream) / SaveAs(Stream: TStream; FileFormat: TXLSXFileFormat) escrevem todo o pacote .xlsx no fluxo fornecido, começando na posição atual; Open(Stream: TStream) lê os dados de volta. O chamador é proprietário do fluxo e deve liberá-lo. Útil para respostas HTTP, armazenamento de blobs, pipelines na memória e testes unitários que contornam o sistema de arquivos local. As sobrecargas existentes baseadas em arquivo SaveAs / Open permanecem inalteradas e agora delegam aos mesmos auxiliares internos de escrita/leitura.
Versão 2.20.6
- Adicionadas as propriedades Hidden / Visible / Comment em TXLSXDefinedName. Hidden corresponde ao atributo OOXML <definedName hidden="1"/> (padrão False / Visible=True; True oculta o nome do gerenciador de nomes do Excel). Visible é um alias booleano (inverso de Hidden) para um código de chamada mais claro. Comment corresponde a <definedName comment="..."/> . SaveAs emite ambos os atributos quando diferem dos padrões; Open os analisa de volta. SheetIndex (a ligação de escopo Local existente via localSheetId) permanece inalterado.
Versão 2.20.5
- Adicionadas cinco novas características de fonte a TXLSXFont. Novo enum TXLSXFontVertAlign (xlsxVertAlignBaseline / Superscript / Subscript) que controla as caixas de seleção existentes de "Superscript" / "Subscript" na interface do Excel, através de uma única propriedade VertAlign (mutuamente exclusivas na interface do usuário). Novas propriedades Boolean OutlineFont e Shadow para os efeitos de fonte correspondentes do Excel. Novo Integer Family (número de família de fontes OOXML: 1=Roman / 2=Swiss / 3=Modern / 4=Script / 5=Decorative; 0=não definido) e CharSet (número de charset GDI: 0=ANSI / 1=Default / 134=GB2312 / 136=ChineseBig5 / etc.; -1=não definido). SaveAs emite os elementos filhos correspondentes <vertAlign> / <outline/> / <shadow/> / <family> / <charset> dentro de <font>; Open os analisa de volta. ColorIndex / ThemeColor / TintAndShade serão implementados em um futuro milestone de temas.
Versão 2.20.4
- Adicionadas opções para controlar a direção das bordas diagonais. TXLSXBorder agora expõe DiagonalUp: Boolean e DiagonalDown: Boolean. As duas flags compartilham o Style e a Cor da borda Diagonal existente e determinam qual(is) direção(ões) diagonal(is) o Excel renderiza — apenas para cima (de baixo-esquerda para cima-direita), apenas para baixo (de cima-esquerda para baixo-direita) ou ambos. SaveAs emite os atributos diagonalUp / diagonalDown no elemento <border> quando definidos; Open os analisa de volta. Anteriormente, o engine escrevia uma única borda Diagonal sem controle de direção, então o Excel nunca desenhava nenhuma das linhas diagonais.
Versão 2.20.3
- Adicionado o toggle workbook Date1904. TXLSXWorkbook agora expõe uma propriedade Date1904: Boolean que seleciona entre a época Windows 1900 (padrão; corresponde ao Excel para Windows) e a época Mac 1904 (legado do Excel para Mac). SaveAs emite <workbookPr date1904="1"/> em xl/workbook.xml quando definido; Open o lê de volta. A flag é apenas metadado — o engine não transforma os números armazenados; os chamadores devem definir Date1904 antes de atribuir valores de célula TDateTime para que a conversão de ida e volta corresponda ao calendário correto.
Versão 2.20.2
- Adicionada o suporte para critérios de filtro automático por coluna. Novos tipos: enum TXLSXAutoFilterOp (Igual / NãoIgual / MaiorQue / MenorQue / MaiorOuIgual / MenorOuIgual), classe TXLSXAutoFilterColumn (ColId + 1 ou 2 critérios + conector AND/OR), coleção TXLSXAutoFilterColumns. TXLSXWorksheet expõe a propriedade AutoFilterColumns e os métodos de conveniência AddAutoFilterColumn(ColId, Op, Criteria) / AddAutoFilterColumn(ColId, Op1, Criteria1, Op2, Criteria2, AndConnector) / ClearAutoFilterColumns. SaveAs expande o existente <autoFilter ref="..."/> em um corpo de <filterColumn colId=N><customFilters and=0|1><customFilter operator="..." val="..."/>...</customFilters></filterColumn> por coluna quando os critérios são definidos; Open analisa a mesma estrutura de volta. Anteriormente, o mecanismo armazenava apenas o intervalo de filtro automático (sqref) e o Excel exibia menus de filtro vazios.
Versão 2.20.1
- Adicionado suporte para quebras de página manuais em TXLSXWorksheet. Novos elementos: AddRowBreak(BeforeRow) / AddColBreak(BeforeCol) para inserir uma quebra de página horizontal ou vertical antes de uma determinada linha / coluna (semântica "Antes" da interface do Excel — a linha N inicia uma nova página). Métodos HasRowBreak / HasColBreak para verificar; RemoveRowBreak / RemoveColBreak para remover uma única entrada; ClearRowBreaks / ClearColBreaks / ClearAllPageBreaks para limpar em lote. RowBreakCount / ColBreakCount + RowBreaks(Index) / ColBreaks(Index) indexados expõem os índices "Antes" de 1 para iteração. SaveAs emite <rowBreaks> / <colBreaks> com filhos <brk id="N-1" max="..." man="1"/> entre <headerFooter> e <drawing>; Open os analisa de volta.
Versão 2.20.0
- Adicionada a visibilidade da planilha (Oculta / MuitoOculta), seleção por planilha e rastreamento da planilha ativa em TXLSXWorkbook / TXLSXSheets / TXLSXWorksheet. Novos tipos: enum TXLSXSheetVisibility (xlsxSheetVisible / xlsxSheetHidden / xlsxSheetVeryHidden). Novas propriedades TXLSXWorksheet: Visibility, Visible (alias booleano), IsSelected (somente leitura). Novos membros TXLSXSheets: ActiveIndex, Activate(Index), Move(FromIndex, ToIndex). Novo proxy TXLSXWorkbook.ActiveSheet. SaveAs emite <sheet state="..."/> nas entradas da planilha no livro, <bookViews><workbookView activeTab=N/></bookViews> quando a planilha ativa não é o padrão 0, e tabSelected="1" na <sheetView> da planilha ativa; Open analisa os três de volta para as novas propriedades. A primeira planilha adicionada se torna visível e ativa por padrão, para que os sites de chamada existentes continuem a funcionar.
Versão 2.19.2
- Adicionados quatro novos controles de atributo em TXLSXWorksheet para completar a cobertura do OOXML <pageSetup>: BlackAndWhite (renderização em preto e branco), Draft (suprime gráficos para visualização mais rápida), PrintNotes (imprime comentários de células como exibidos, em vez de ocultá-los) e PrintOverThenDown (ordem de leitura da esquerda para a direita, em vez da ordem padrão de cima para baixo). O método SaveAs emite os atributos correspondentes blackAndWhite / draft / cellComments / pageOrder; o método Open os interpreta. Os valores padrão permanecem desativados para que as planilhas não modificadas não adquiram atributos extras.
Versão 2.19.1
- Adicionadas propriedades de conveniência para cabeçalho e rodapé em TXLSXWorksheet. Novas entradas: LeftHeader / CenterHeader / RightHeader e LeftFooter / CenterFooter / RightFooter. Cada uma lê ou grava o segmento &L / &C / &R da string bruta existente HeaderText / FooterText; ao gravar qualquer um dos segmentos, a forma bruta completa é reconstruída, permitindo que o escritor e o leitor funcionem sem alterações.
- Adicionadas opções de impressão para a saída de página em nível de planilha. Novas propriedades em TXLSXWorksheet: CenterHorizontally, CenterVertically, PrintGridlines, PrintHeadings. O método SaveAs emite um elemento <printOptions horizontalCentered / verticalCentered / gridLines / headings/> quando qualquer um dos quatro está habilitado; o método Open interpreta os mesmos atributos. Os valores padrão permanecem desativados para que as planilhas não modificadas não adquiram um elemento <printOptions/> adicional.
- Adicionada a funcionalidade de leitura e escrita para PrintArea, PrintTitleRows e PrintTitleCols em nível de planilha. Estes mapeiam para os nomes definidos no nível do livro de trabalho OOXML _xlnm.Print_Area e _xlnm.Print_Titles, com escopo definido por localSheetId. PrintArea recebe uma referência A1 simples (por exemplo, "$A$1:$D$10"); PrintTitleRows e PrintTitleCols recebem referências apenas de linha ou coluna (por exemplo, "$1:$3" ou "$A:$B") e são combinados em uma única entrada Print_Titles. O escritor adiciona o nome da planilha com aspas adequadas (aspas simples em nomes que contêm espaços ou caracteres especiais); o leitor remove o prefixo e direciona as entradas para a planilha correspondente, evitando que sejam incluídas na coleção TXLSXWorkbook.DefinedNames visível ao usuário.
Versão 2.19.0
- Adicionadas operações de inserção e exclusão de linhas/colunas com deslocamento completo em nível de planilha em TXLSXWorksheet. Novas entradas: InsertRows(BeforeRow, Count), DeleteRows(StartRow, Count), InsertCols(BeforeCol, Count), DeleteCols(StartCol, Count). InsertRows / InsertCols deslocam as linhas/colunas existentes para longe da inserção em Count; DeleteRows / DeleteCols removem a faixa [Start, Start+Count-1] e puxam tudo após a exclusão para trás em Count.
- A alteração se aplica a todos os elementos da geometria da planilha que dependem da posição da linha/coluna: âncoras de células (Cells), cantos de células mescladas (MergedCells — intervalos que abrangem várias células são cortados nas bordas restantes e intervalos internos são removidos), listas de metadados de linha/coluna (FRowHeights / FColWidths / níveis de contorno / oculto / colapsado), âncoras de hiperlinks e comentários (entradas dentro de uma banda excluída são removidas), FreezePane (FFreezeRow / FFreezeCol), AutoFilterRange e a string de intervalo para cada ConditionalFormat, DataValidation e Excel Table (uma entrada cujo intervalo está completamente dentro do corte é removida).
- Novos membros Delete(Index) nas coleções de suporte para que a lógica de deslocamento possa remover uma única entrada sem a necessidade de Clear: TXLSXHyperlinks, TXLSXComments, TXLSXConditionalFormats, TXLSXDataValidations, TXLSXTables.
- Fora do escopo desta versão: Imagens e gráficos não são deslocados (suas âncoras de pixels EMU as separam da grade de células e um deslocamento preciso exigiria recalcular os deslocamentos EMU); fórmulas de DefinedNames no nível do livro de trabalho não são reescritas. Ambos estão sendo monitorados para uma versão futura.
Versão 2.18.2
- Adicionados utilitários AutoFit para larguras de colunas e alturas de linhas. TXLSXWorksheet expõe AutoFitColumn(ACol) / AutoFitColumns(ColMin, ColMax) e AutoFitRow(ARow) / AutoFitRows(RowMin, RowMax); TXLSXRange expõe AutoFitColumns e AutoFitRows que encaminham para a planilha dentro dos limites do intervalo. A largura é estimada em unidades de caractere do Excel (Calibri 11pt, caracteres ASCII contam como 1, caracteres CJK contam como 2) com uma correção de 1,20 px por caractere e 1,0 de preenchimento, limitada a [8,43, 255,0]. A altura da linha padrão é de 15 pt e aumenta em 12,75 pt por quebra de linha incorporada no texto da célula. Intervalos amplos (EntireRow / EntireColumn) são limitados à última linha/coluna com células na planilha para que o AutoFit não itere até os limites da grade do Excel.
Versão 2.18.1
- Adicionado suporte para proteção de células, com conversão de ida e volta para o mecanismo XLSX. TXLSXCell expõe novas propriedades convenientes Locked: Boolean (padrão True) e FormulaHidden: Boolean (padrão False) que espelham o modelo de proteção de células do Excel. Elas expõem o índice do pool TXLSXCell.ProtectionIndex (de 1 em diante para o novo pool de nível de livro TXLSXProtections); ao gravar na propriedade conveniente, o par (Locked, FormulaHidden) é pesquisado ou adicionado ao pool. Os padrões (Locked=True, FormulaHidden=False) resultam em ProtectionIndex=0 para que o pool permaneça vazio para células padrão.
- Adicionados os helpers em lote TXLSXRange.SetLocked(ALocked) e TXLSXRange.SetFormulaHidden(AHidden) para desbloquear ou ocultar uma faixa inteira, realizando apenas uma busca ou adição e aplicando o resultado a cada célula do retângulo.
- Adicionada a infraestrutura correspondente para escrita/leitura. SaveAs emite um cellXf com um filho inline <protection locked="N" hidden="M"/> para cada entrada de Proteções no livro; Open analisa <protection> de volta para Workbook.Protections e passa o novo CellXfProtMap através de ParseStylesXml e ParseWorksheetXml, de modo que o ProtectionIndex de cada célula é preservado junto com os índices existentes de fonte, preenchimento, borda, formato de número e alinhamento.
Versão 2.18.0
- Adicionado o objeto TXLSXRange para acesso a múltiplas células e operações em lote em TXLSXWorksheet. Novos pontos de entrada: Worksheet.Range['A1:C5'], Worksheet.RCRange[r1,c1,r2,c2], Worksheet.UsedRange, Worksheet.EntireRow(r), Worksheet.EntireColumn(c). A faixa retornada expõe SetValue / SetFormula / Clear / ClearAll / Merge / Unmerge / Offset / Resize, além de setters de índice de estilo por célula (SetFontIndex / SetFillIndex / SetBorderIndex / SetNumberFormatIndex / SetAlignmentIndex) e uma função de conveniência SetNumberFormat(Fmt) que busca ou adiciona a string de formato no pool do livro. Os objetos TXLSXRange são de propriedade da planilha e liberados na destruição da planilha; os chamadores não os liberam.
- Adicionado TXLSXCell.NumberFormat: WideString, que funciona em conjunto com o existente NumberFormatIndex. A leitura retorna a string de formato do pool do livro; a escrita busca ou adiciona a string e atualiza o NumberFormatIndex de forma transparente. Requer que a célula esteja anexada a um livro (o fluxo padrão através de TXLSXWorkbook.Sheets.Add(...).Cells[r, c]).
- Adicionadas referências de volta de célula para planilha para livro, para que cada TXLSXCell possa resolver seu livro proprietário sem contabilidade externa. TXLSXSheets, TXLSXWorksheet e TXLSXCells ganharam referências internas de Owner, conectadas através de seus construtores; TXLSXCell expõe uma propriedade Workbook somente para leitura e uma referência interna SetWorkbook usada por TXLSXCells.GetItem quando uma célula é criada automaticamente durante o acesso.
Versão 2.17.42
- Corrigido o problema de arredondamento de células ao reabrir arquivos XLSX. Células escritas pelo SaveAs estavam sendo descartadas ao abrir, com HasCell(row, col) retornando False e todo o estado da célula (valor, fórmula, índice da fonte, índice do preenchimento, índice da borda, índice do formato de número) sendo perdido. A causa raiz era uma chamada desnecessária de MoveToAttribute('r') no analisador da planilha, que alterava o tipo de nó do leitor para atributo, o que fazia com que a verificação subsequente IsEmptyElement retornasse True e desativasse a análise de células para cada elemento <c> com um atributo r="", ou seja, para cada célula. A remoção desse movimento desnecessário do cursor restaura o arredondamento de texto, números, fórmulas e células de data.
- Corrigido o problema de restauração do índice de estilo ao reabrir arquivos XLSX. Os índices de fonte, preenchimento, borda e formato de número personalizados nas células estavam sendo lidos como zero, mesmo após os pools correspondentes (Workbook.Fonts/Fills/Borders/NumberFormats) terem sido restaurados corretamente. O analisador cellXf rastreava sua posição com um contador que só avançava na tag de fechamento </xf>, mas o Excel frequentemente emite entradas auto-fechadas <xf .../> (sem <alignment> interno), então o contador nunca avançava além de zero e cada mapeamento cellXf sobrescrevia o anterior. O analisador agora avança o contador em uma tag auto-fechada <xf/> também, para que o índice da fonte, preenchimento, borda e formato de número de cada célula sejam restaurados corretamente.
- Corrigido o problema de arredondamento de células de data em arquivos XLSX. A escrita de um TDateTime em TXLSXCell.Value anteriormente passava pelo pool de strings compartilhadas com t="s" porque a função VarIsNumeric() do Delphi retorna False para varDate. Agora, o SaveAs escreve o número serial da data diretamente em <v> e aplica o cellXf da data, para que as células de data sejam reabertas como uma Variant varDate em vez de uma string localizada que o chamador não consegue converter de volta para TDateTime.
Versão 2.17.41
- Corrigido o erro "zlib stream does not support seeking" que ocorria ao reabrir arquivos .xlsx que continham imagens incorporadas ou um projeto VBA (.xlsm). Tanto o caminho de recarregamento de imagens quanto o caminho de recarregamento da carga VBA roteavam o fluxo de entrada inflado através de TMemoryStream.CopyFrom(Source, 0), que internamente rebobina Source para derivar a contagem de bytes; esse rebobinamento não é permitido em um fluxo Deflate de apenas leitura. Ambos os locais de chamada agora usam um auxiliar de leitura em blocos até o EOF, para que os arquivos .xlsx com imagens ou macros sejam restaurados através do SaveAs/Open sem gerar erros.
Versão 2.17.40
- Adicionada o suporte para planilhas de gráficos (planilha de gráfico de página inteira) ao motor XLSX. A classe TXLSXWorksheet expõe um novo atributo IsChartSheet, além de um método auxiliar Workbook.AddChartSheet(Name, ChartType, Title) que cria a planilha, define o atributo, e preenche Charts[0] com um valor padrão. O método SaveAs grava planilhas IsChartSheet em xl/chartsheets/sheetN.xml com um arquivo rels dedicado apontando para a parte de desenho compartilhada, registra-as como tipos de conteúdo de planilha de gráfico e emite o relacionamento da planilha de gráfico em xl/_rels/workbook.xml.rels. As planilhas regulares mantêm seu caminho existente em xl/worksheets/sheetN.xml. O método Open reconhece planilhas de gráficos através do tipo de relacionamento, mas atualmente as carrega como planilhas simples (seus dados de gráfico ainda chegam através das partes de gráfico compartilhadas).
Versão 2.17.39
- Adicionado suporte para linhas/colunas recolhidas para grupos de contorno no motor XLSX. A classe TXLSXWorksheet expõe as propriedades Boolean RowCollapsed[Row] e ColCollapsed[Col], juntamente com os métodos auxiliares SetRowCollapsed / SetColCollapsed / ClearRowCollapsed / ClearColCollapsed. O método SaveAs emite "collapsed=\"1\"" nas entradas <row> e <col> correspondentes; o método Open analisa o atributo de volta. Juntamente com os atributos existentes outlineLevel e hidden, isso permite que o motor XLSX realize a conversão completa de uma hierarquia de agrupamento recolhida.
Versão 2.17.38
- Adicionado suporte para linhas/colunas ocultas para o motor XLSX. A classe TXLSXWorksheet expõe as propriedades Boolean RowHidden[Row] e ColHidden[Col], juntamente com os métodos auxiliares SetRowHidden / SetColHidden / ClearRowHidden / ClearColHidden. O método SaveAs emite "hidden=\"1\"" nas entradas <row> e <col> correspondentes; o método Open analisa o atributo de volta para a planilha, para que as linhas/colunas ocultas sobrevivam à conversão sem forçar uma largura personalizada ou nível de contorno.
Versão 2.17.37
- Adicionado suporte para a cor da aba da planilha para o motor XLSX. A classe TXLSXWorksheet expõe as propriedades TabColor (ARGB) e TabColorIsAuto. O método SaveAs emite um bloco <sheetPr><tabColor rgb="..."/></sheetPr> como o primeiro filho de <worksheet> quando a cor da aba é definida; o método Open analisa o elemento <tabColor> de volta para a planilha, para que as abas de planilha coloridas sobrevivam à conversão. Os livros padrão não contêm o bloco extra (TabColorIsAuto = True).
Versão 2.17.36
- Adicionada a funcionalidade de arredondamento de alinhamento de células ao motor XLSX. Novos enums TXLSXHorizontalAlignment e TXLSXVerticalAlignment, classe TXLSXAlignment (Horizontal, Vertical, WrapText, ShrinkToFit, Indent, TextRotation) e uma coleção TXLSXAlignments no nível do livro de trabalho (Workbook.Alignments). TXLSXCell agora possui um AlignmentIndex (base 1 dentro de Workbook.Alignments). SaveAs adiciona um cellXf com um filho inline <alignment/> para cada entrada de alinhamento no livro de trabalho; Open lê os atributos <alignment> de volta para Workbook.Alignments e mapeia o cellXf para TXLSXCell.AlignmentIndex. ParseWorksheetXml e ParseStylesXml receberam um parâmetro CellXfAlignMap para carregar o mapeamento entre as duas fases.
Versão 2.17.35
- Adicionada a API de criptografia AES (Padrão de Criptografia ECMA-376) ao motor XLSX. TXLSXWorkbook expõe SaveAsEncrypted(FileName, Password) / OpenEncrypted(FileName, Password) / CanReadEncrypted(FileName) e uma exceção EXlsxEncryptionNotImplemented. CanReadEncrypted reconhece os bytes mágicos do arquivo binário composto da Microsoft ($D0 $CF $11 $E0 $A1 $B1 $1A $E1) para que os chamadores possam detectar arquivos criptografados antes de decidir como abri-los; OpenEncrypted volta automaticamente para o Open padrão para arquivos .xlsx não criptografados. O pipeline AES-128/256 + SHA + OLE Compound File em si ainda não está implementado — tanto a escrita quanto a leitura de arquivos realmente criptografados geram a exceção tipada até que a próxima versão implemente o algoritmo. O tipo de exceção é intencionalmente distinto para que os chamadores existentes possam capturá-lo e usar Worksheet.Protect / Workbook.ProtectWorkbook para o bloqueio visual.
Versão 2.17.34
- Desempenho: substituída a concatenação WideString O(N^2) que construía as linhas de células de cada planilha por um TXLSWideStringBuilder. Planilhas grandes (10.000+ células) agora permanecem lineares em memória e CPU durante o SaveAs. Adicionado um novo helper WriteWorksheetXmlStreaming e uma flag TXLSXWorkbook.StreamingWrite opcional — quando habilitada, SaveAs não mantém mais o XML de cada planilha em um cache sheetXmls simultaneamente; cada planilha é construída, escrita e descartada antes de passar para a próxima. O arquivo sharedStrings.xml é emitido por último, portanto, o caminho de streaming ainda produz um SST totalmente preenchido. O comportamento padrão permanece inalterado.
Versão 2.17.33
- Adicionadas operações de intervalo de células ao motor XLSX. A classe TXLSXWorksheet expõe ClearRange(R1, C1, R2, C2), CopyRange(SrcR1, SrcC1, SrcR2, SrcC2, DstR, DstC) para cópia dentro da planilha, CopyRangeTo(... TargetSheet, DstR, DstC) para cópia entre planilhas e MoveRange(SrcR1, SrcC1, SrcR2, SrcC2, DstR, DstC) para recortar e colar. Cada operação duplica o valor da célula, a fórmula, os quatro índices de estilo e qualquer payload de texto formatado; MoveRange ignora as sobreposições com o destino, preservando os valores copiados em sobreposições parciais. A classe TXLSXCells também ganha um helper Remove(Row, Col).
Versão 2.17.32
- Adicionadas âncoras de hiperlinks internos ao motor XLSX. A classe TXLSXHyperlink agora possui uma propriedade Location (por exemplo, "Sheet2!A1") e um helper IsInternal; TXLSXHyperlinks expõe AddInternal e TXLSXWorksheet adiciona três sobrecargas de AddHyperlinkToCell. SaveAs emite hiperlinks internos com o atributo inline location="" e ignora a entrada de rels da planilha; Open reconhece hiperlinks com location="" e os direciona de volta através de AddInternal. Os hiperlinks de URL externos continuam a fluir pelo arquivo rels sem alterações.
Versão 2.17.31
- Adicionado suporte para texto formatado (rich-text) de ida e volta ao motor XLSX. Nova classe TXLSXRichTextRun (por execução: Nome / Tamanho / Negrito / Itálico / Tachado / Sublinhado / Cor) e contêiner TXLSXRichText que expõe AddRun / AddRunText / Clear / PlainText. A classe TXLSXCell agora possui uma propriedade RichText própria; SaveAs grava a célula como uma string compartilhada com várias execuções <r>/<rPr>/<t> e Open reconstrói o TXLSXRichText a partir da entrada SST analisada, com o valor Variant da célula ainda exibindo o texto simples concatenado para chamadores que ignoram a formatação.
Versão 2.17.30
- Adicionado suporte para gráficos de ida e volta ao motor XLSX. Novos tipos de enumeração TXLSXChartType (coluna / barra / linha / pizza), TXLSXChartSeries (Nome, Intervalo de Categorias, Intervalo de Valores) e classes TXLSXChart (Tipo de Gráfico, Título, títulos de eixos, células de ancoragem de Início/Fim, Séries) e uma coleção TXLSXCharts por planilha (Worksheet.Charts). TXLSXWorksheet expõe AddChart(Type, Title, FromRow, FromCol, ToRow, ToCol). SaveAs emite xl/charts/chartN.xml (numeração global do livro) e o vincula a um twoCellAnchor / graphicFrame dentro do xl/drawings/drawingN.xml compartilhado; Open analisa tanto a âncora quanto a definição do gráfico de volta para a coleção. Títulos de gráficos, títulos de eixos, nomes de séries e intervalos de origem são preservados na ida e volta.
Versão 2.17.29
- Corrigido um erro EListError "Operação não permitida em lista ordenada" que ocorria em SetColWidth, SetRowHeight, SetRowOutlineLevel e SetColOutlineLevel. Cada um desses quatro campos TStringList foi criado com Sorted=True, mas era modificado através do setter Values[Name] := X, o que o RTL do RAD Studio não permite em uma lista ordenada. As listas agora são criadas sem ordenação; as buscas continuam através de IndexOfName, o que é adequado para o número típico de colunas/linhas por planilha.
Versão 2.17.28
- Corrigido TZipArchive.Exists, que era um espaço reservado que sempre retornava falso. O caminho de abertura XLSX usa zip.Exists(...) para verificar cada parte antes de ler, então todas as operações anteriores (células, estilos, comentários, desenhos, propriedades do documento, nomes definidos, proteção, VBA, etc.) silenciosamente descartavam seu conteúdo durante a leitura. Agora, Exists delega a pesquisa existente Fcd.Entries.Exists, seguindo o padrão de OpenFile / CreateFile.
Versão 2.17.27
- Adicionado suporte para preservação de projetos VBA no motor XLSX. TXLSXWorkbook expõe um payload de bytes do projeto VbaProject, além de LoadVbaProjectFromFile(FileName), ClearVbaProject e HasVbaProject. SaveAs grava os bytes em xl/vbaProject.bin, registra o tipo de conteúdo .bin, alterna o tipo de conteúdo do livro para a variante habilitada para macros e adiciona um relacionamento vbaProject ao arquivo rels do livro; Open lê xl/vbaProject.bin de volta para a propriedade. Os bytes não são analisados nem modificados, portanto, os projetos .xlsm existentes são preservados exatamente. Observação: os livros habilitados para macros devem ser salvos com a extensão .xlsm para que o Excel habilite as macros.
Versão 2.17.26
- Adicionado suporte para proteção de planilhas e livros no motor XLSX. TXLSXWorksheet expõe Protect / Protect(Password) / UnProtect, além de IsProtected e SheetProtectHash; TXLSXWorkbook adiciona ProtectWorkbook (com flags opcionais de senha, LockStructure, LockWindows) e UnProtectWorkbook, além de IsWorkbookProtected / WorkbookProtectHash / LockStructure / LockWindows. SaveAs emite <sheetProtection> em cada planilha protegida e <workbookProtection> em livros protegidos; Open analisa ambos os blocos de volta para a API. As senhas são armazenadas como o hash hexadecimal padrão para garantir a fidelidade na preservação (o texto original não pode ser recuperado).
Versão 2.17.25
- Adicionado suporte para preservação de propriedades do documento no motor XLSX. TXLSXWorkbook agora expõe as propriedades Title, Author, Subject, Keywords, Description, Category, LastModifiedBy, Created, Modified, Company, Application e AppVersion. SaveAs emite docProps/core.xml e docProps/app.xml (e os registra em [Content_Types].xml + _rels/.rels) sempre que alguma propriedade é modificada; Open analisa ambos os arquivos para que autores, carimbos de data/hora de modificação e metadados da aplicação sejam preservados ao salvar e reabrir.
Versão 2.17.24
- Adicionada a funcionalidade de leitura e escrita de tabelas no estilo Excel para o motor XLSX. Nova classe TXLSXTable (Id, Name, DisplayName, Range, Columns, StyleName, ShowFirstColumn / ShowLastColumn / ShowRowStripes / ShowColumnStripes) e uma coleção TXLSXTables por planilha. TXLSXWorksheet expõe as tabelas e o método AddTable(Name, Range, ColumnNames). Ao salvar, gera xl/tables/tableN.xml (numeração global do livro), atualiza os relacionamentos da planilha com os relacionamentos da tabela, adiciona <tableParts> à planilha e registra o tipo de conteúdo da tabela. Ao abrir, analisa os relacionamentos da tabela e o arquivo tableN.xml de volta para a planilha, garantindo que as bandas de tabela formatadas sobrevivam ao salvamento e reabertura.
Versão 2.17.23
- Adicionada a funcionalidade de leitura e escrita de filtros automáticos para o motor XLSX. TXLSXWorksheet expõe a propriedade AutoFilterRange e os métodos SetAutoFilter(Row1, Col1, Row2, Col2) / SetAutoFilter(Range) / ClearAutoFilter. Ao salvar, gera o bloco <autoFilter ref="..."/> após o bloco de mesclagem de células quando o intervalo não está vazio; ao abrir, analisa o atributo ref de volta para a propriedade, garantindo que a faixa de filtro em uma planilha sobreviva ao salvamento e reabertura.
Versão 2.17.22
- Adicionada a funcionalidade de leitura e escrita de configurações de página para o motor XLSX. TXLSXWorksheet expõe as propriedades Margin{Left,Right,Top,Bottom,Header,Footer}, PageLandscape, PaperSize, PageScale, FitToWidth, FitToHeight, HeaderText e FooterText, além das funções de conveniência SetPageMargins(L, R, T, B[, H, F]). Ao salvar, gera os blocos correspondentes <pageMargins>, <pageSetup> e <headerFooter> entre hiperlinks e desenhos; ao abrir, os analisa de volta. Planilhas com configurações padrão permanecem inalteradas (a flag PageSetupTouched controla a saída).
Versão 2.17.21
- Adicionada a funcionalidade de leitura e escrita de painéis fixos para o motor XLSX. TXLSXWorksheet expõe os métodos FreezePane(Col, Row) / UnfreezePane e as propriedades somente leitura FreezeCol e FreezeRow. Ao salvar, escreve um bloco <sheetViews>/<pane state="frozen"> antes de <sheetData> com o activePane e a seleção correspondentes; ao abrir, analisa o bloco <pane state="frozen"> de volta para a posição de congelamento, garantindo que os layouts de congelamento superior/esquerdo/canto sobrevivam ao salvamento e reabertura.
Versão 2.17.20
- Adicionados níveis de agrupamento de linhas e colunas para o motor XLSX. TXLSXWorksheet expõe as propriedades RowOutlineLevel[Row] e ColOutlineLevel[Col] indexadas, além dos métodos SetRowOutlineLevel / HasRowOutlineLevel / ClearRowOutlineLevels e os métodos correspondentes para colunas. Ao salvar, gera os atributos outlineLevel nas entradas <row> e nas entradas <col> mescladas (combinados com larguras personalizadas, quando presentes); ao abrir, analisa ambos os atributos de volta para a planilha, garantindo que as hierarquias de linhas/colunas agrupadas sobrevivam ao processo de leitura e escrita.
Versão 2.17.19
- Adicionada formatação condicional e validação de dados com suporte bidirecional no motor XLSX. Novos tipos de enumeração TXLSXCfOperator e classe TXLSXConditionalFormat (Range, Op, Formula1, Formula2) e uma coleção TXLSXConditionalFormats em cada planilha (Worksheet.ConditionalFormats). Novos TXLSXDataValidationType, TXLSXDvOperator, TXLSXDataValidation (Range, ValidationType, Op, Formula1, Formula2, AllowBlank, ShowInputMessage, ShowErrorMessage) e uma coleção TXLSXDataValidations (Worksheet.DataValidations) com um atalho AddList(Range, Items) para o caso comum de listas suspensas. TXLSXWorksheet expõe AddConditionalFormat e AddDataValidation / AddListValidation como auxiliares. SaveAs escreve blocos <conditionalFormatting> (com cfRule type="cellIs") e um bloco <dataValidations> após sheetData; Open analisa ambos os blocos de volta para as coleções.
Versão 2.17.18
- Adicionada funcionalidade de nomes definidos com suporte bidirecional no motor XLSX. Nova classe TXLSXDefinedName (Name, Formula, SheetIndex) e uma coleção de nível de livro TXLSXDefinedNames (Workbook.DefinedNames) com sobrecargas Add(Name, Formula[, SheetIndex]) e pesquisa IndexOfName. SaveAs emite um bloco <definedNames> em xl/workbook.xml; as entradas com SheetIndex >= 0 possuem um atributo localSheetId (com escopo de planilha) e as entradas com SheetIndex = -1 são com escopo de livro. Open analisa os elementos <definedName> de volta para a coleção para que os livros salvos e reabertos mantenham seus intervalos nomeados intactos.
Versão 2.17.17
- Adicionada funcionalidade de imagens com suporte bidirecional no motor XLSX. Novos tipos de enumeração TXLSXImageFormat (png, jpeg, gif, bmp), classe TXLSXImage (Row/Col anchor, WidthEMU/HeightEMU, Format, Data) e uma coleção TXLSXImages por planilha. TXLSXWorksheet expõe Images, além de AddImage(Row, Col, Data, Format) e AddImageFromFile(Row, Col, FileName) como auxiliares. SaveAs escreve os bytes da imagem em xl/media/imageN.<ext>, gera xl/drawings/drawingN.xml com uma oneCellAnchor por imagem (e um arquivo _rels correspondente), registra tipos de conteúdo e relacionamentos de planilha/desenho e emite uma referência <drawing r:id="..."/> dentro da planilha. Open analisa drawingN.xml + drawing rels + media para trazer as imagens de volta para Worksheet.Images.
Versão 2.17.16
- Adicionada a funcionalidade de formatação de número personalizada para leitura e escrita no motor XLSX. Nova classe TXLSXNumberFormat e uma coleção de nível de planilha TXLSXNumberFormats (Workbook.NumberFormats) que remove formatações duplicadas através de Add(FormatCode). TXLSXCell expõe uma nova propriedade NumberFormatIndex; SaveAs emite um bloco <numFmts> em xl/styles.xml (IDs personalizados começando no valor reservado 164) e associa cada formatação a um cellXf dedicado. Open analisa os numFmts personalizados e inverte o mapeamento cellXf->numFmtId para NumberFormatIndex durante a leitura. A precedência em caso de conflito é: FormatIndex > FontIndex > FillIndex > BorderIndex > NumberFormatIndex.
Versão 2.17.15
- Adicionada a funcionalidade de bordas de célula para leitura e escrita no motor XLSX. Novo enum TXLSXBorderStyle, classe TXLSXBorderEdge (Estilo + Cor + ColorIsAuto para cada lado), classe TXLSXBorder com bordas Esquerda/Direita/Superior/Inferior/Diagonal, além de helpers SetAll(Estilo[, Cor]), e uma coleção de nível de planilha TXLSXBorders (Workbook.Borders) com um atalho Borders.AddBox(Estilo[, Cor]). TXLSXCell expõe uma nova propriedade BorderIndex; SaveAs emite cada borda em xl/styles.xml e a associa a um cellXf dedicado. Open analisa as bordas e converte o mapeamento cellXf->borderId para BorderIndex durante a leitura. A precedência permanece FormatIndex > FontIndex > FillIndex > BorderIndex quando vários atributos são definidos na mesma célula.
Versão 2.17.14
- Adicionada a funcionalidade de preenchimento de célula para leitura e escrita no motor XLSX. Novos enum TXLSXFillPattern e classe TXLSXFill que descrevem patternType, fgColor e bgColor; a coleção de nível de planilha TXLSXFills está acessível via Workbook.Fills, com um helper Fills.AddSolid(cor) para o caso comum de preenchimento sólido. TXLSXCell expõe uma nova propriedade FillIndex; SaveAs emite cada preenchimento em xl/styles.xml e o associa a um cellXf dedicado. Open os analisa e inverte os atributos da célula para FillIndex durante a leitura. FontIndex ainda tem precedência quando ambos são definidos.
Versão 2.17.13
- Concluída a funcionalidade de fonte para leitura e escrita no motor XLSX. Open agora analisa xl/styles.xml e o converte em Workbook.Fonts e uma tabela cellXf->fontId; cada atributo s de uma célula é mapeado para TXLSXCell.FontIndex, para que planilhas salvas e reabertas preservem fontes personalizadas (Nome, Tamanho, Negrito, Itálico, Tachado, Sublinhado, Cor).
Versão 2.17.12
- Adicionada a classe TXLSXFont e a coleção Workbook.Fonts para que as células XLSX possam usar fontes personalizadas. TXLSXCell possui uma nova propriedade FontIndex; SaveAs emite a lista de fontes em xl/styles.xml e um cellXf por fonte, referenciando o cellXf correspondente do atributo s de cada célula. A leitura e escrita de FontIndex está planejada para a próxima versão.
Versão 2.17.11
- Adicionada a funcionalidade de leitura e escrita da altura das linhas no motor XLSX. A classe TXLSXWorksheet expõe a propriedade RowHeight[Row] e os métodos auxiliares SetRowHeight, HasRowHeight e ClearRowHeights. Ao salvar, os atributos "ht" e "customHeight="1"" são escritos em cada tag <row> com uma altura personalizada (incluindo linhas que só possuem altura, sem dados de célula); ao abrir, o atributo "ht" é lido e armazenado no mapa de altura das linhas.
Versão 2.17.10
- Adicionada a funcionalidade de leitura e escrita da largura das colunas no motor XLSX. A classe TXLSXWorksheet expõe a propriedade ColWidth[Col] e os métodos auxiliares SetColWidth, HasColWidth e ClearColWidths. Ao salvar, é emitido um bloco <cols> com uma entrada <col> para cada coluna personalizada; ao abrir, as entradas <col min/max/width> são lidas e aplicadas à planilha, permitindo que as larguras não modificadas voltem ao padrão do Excel.
Versão 2.17.9
- Adicionada a funcionalidade de leitura e escrita de comentários de células no motor XLSX. A classe TXLSXWorksheet expõe uma coleção de Comments e as sobrecargas AddComment(Row, Col, Text[, Author]). Ao salvar, são gerados os arquivos xl/commentsN.xml (com lista de autores sem duplicatas) e um arquivo xl/drawings/vmlDrawingN.vml correspondente para que o Excel possa renderizar os balões de comentários; ao abrir, os comentários são lidos do arquivo commentsN.xml para a coleção. As relações da planilha, os tipos de conteúdo e a estrutura <legacyDrawing> são tratados automaticamente.
Versão 2.17.8
- Adicionada a funcionalidade de leitura e escrita de hiperlinks no motor XLSX. A classe TXLSXWorksheet expõe uma coleção de Hyperlinks e as sobrecargas AddHyperlink(Row, Col, Url[, Display[, Tooltip]]). Ao salvar, é escrito um bloco <hyperlinks> em cada planilha e é gerado um arquivo xl/worksheets/_rels/sheetN.xml.rels correspondente com os URLs de destino externos; ao abrir, o arquivo worksheet rels é lido primeiro para resolver as entradas <hyperlink r:id="..."/> em URLs na coleção.
Versão 2.17.7
- Adicionada a funcionalidade de leitura e escrita de células mescladas no motor XLSX. A classe TXLSXWorksheet expõe uma coleção de MergedCells e um método auxiliar MergeCells(R1, C1, R2, C2) que espelha o estilo da fachada BIFF. Ao salvar, é emitido um bloco <mergeCells> após sheetData, e ao abrir, as entradas <mergeCell ref="A1:B2"/> são lidas e aplicadas à coleção.
Versão 2.17.6
- O mecanismo XLSX agora preserva valores de data e fórmulas durante a leitura e escrita. Os valores de célula TDateTime são serializados como números de série do Excel e marcados com um cellXf de data interno, para que o Excel os renderize como datas; ao abrir, as células cujo estilo referencia o cellXf de data são decodificadas de volta para variantes TDateTime. A classe TXLSXCell expõe uma nova propriedade Formula; SaveAs escreve a fórmula como um elemento filho <f> e Open analisa o texto <f> de volta para a célula.
Versão 2.17.5
- Adicionada uma estrutura básica de styles.xml ao mecanismo XLSX. SaveAs agora gera um arquivo xl/styles.xml mínimo e válido, com fontes, preenchimentos, bordas, cellStyleXfs e cellXfs padrão, além dos registros de content-type e workbook-relationship correspondentes. As células possuem uma propriedade FormatIndex e emitem o atributo de célula s="N" quando não é zero, e Open lê s="N" de volta para FormatIndex. Descritores de estilo concretos (fontes, preenchimentos, bordas, cellXfs como coleções de nível de livro) serão adicionados em commits futuros.
Versão 2.17.4
- Adicionado suporte para strings compartilhadas (SST) ao mecanismo XLSX. SaveAs cria uma tabela de strings desduplicada e emite xl/sharedStrings.xml, substituindo a emissão de strings inline. Open lê xl/sharedStrings.xml primeiro e resolve as referências de célula t="s" através do SST. Células de string inline de arquivos XLSX de terceiros ainda são aceitas ao abrir.
Versão 2.17.3
- Substituída a matriz de registros de célula em TXLSXWorksheet por objetos TXLSXCell e uma coleção TXLSXCells. O local de chamada de acesso à célula agora lê Worksheet.Cells.Item[Row, Col].Value, correspondendo à forma IXLSCells / IXLSRange na fachada BIFF. Worksheet.Cells.HasCell / Cells.Count / Cells.CellByIndex / Cells.Clear também estão disponíveis.
Versão 2.17.2
- Introduzida a classe de coleção TXLSXSheets em TXLSXWorkbook, espelhando a coleção IXLSWorkSheets na fachada BIFF. O código agora lê Workbook.Sheets.Add / Workbook.Sheets.Count / Workbook.Sheets[i] / Workbook.Sheets.IndexByName em vez dos métodos Workbook.AddSheet / Workbook.SheetCount / Workbook.Sheet[i] anteriores.
Versão 2.17.1
- Renomeado TXLSXWorkbook.SaveToFile para SaveAs e TXLSXWorkbook.LoadFromFile para Open, para corresponder ao estilo de nomenclatura existente do IXLSWorkBook. Adicionadas sobrecargas para formato de arquivo e senha, para que a fachada XLSX leia da mesma forma que a fachada BIFF. AddSheet agora oferece uma sobrecarga sem argumentos que gera um nome de planilha padrão.
Versão 2.17.0
- TXLSXWorkbook.SaveAs produz um arquivo .xlsx OOXML mínimo com valores de células (números, booleanos e strings inline). O arquivo contém tipos de conteúdo, relações raiz, livro de trabalho + relações e uma planilha por cada folha.
- TXLSXWorkbook.Open lê o arquivo .xlsx OOXML mínimo — nomes de planilha de xl/workbook.xml e valores de células de xl/worksheets/sheetN.xml. Strings compartilhadas, estilos, datas e fórmulas ainda não são suportados.
- Adicionados namespaces, tipos de conteúdo e constantes de relação OOXML, além de funções auxiliares de referência/análise/escape (XlsxColumnLabel, XlsxCellRef, XlsxColumnIndex, XlsxParseCellRef, XlsxParseRangeRef, XlsxEscapeText, XlsxEscapeAttr) para uso em recursos futuros do XLSX.
Versão 2.16.4
- A unidade da fachada XLSX (lxHandleX) agora define seus próprios tipos de livro de trabalho e planilha (TXLSXWorkbook, TXLSXWorksheet), independentemente da fachada BIFF. Os pontos de entrada de salvar e carregar estão reservados; a implementação OOXML será preenchida em uma versão futura.
- Adicionada uma seção de referência para desenvolvedores para a nova interface XLSX, descrevendo como lxHandle e lxHandleX coexistem e quais unidades auxiliares compartilham.
Versão 2.16.3
- Introduzida
lxHandleX, uma unidade de fachada XLSX dedicada que coexiste com a fachada BIFF existentelxHandle. As duas unidades compartilham a mesma infraestrutura subjacente (pools de estilos, utilitários XML, arquivo ZIP), mas expõem hierarquias de classes independentes:lxHandlegerenciaTXLSWorkBooke os caminhos clássicos XLS/HTML/RTF/CSV;lxHandleXgerenciaráTXLSXWorkbooke todas as APIs específicas de XLSX. Três stubs de métodos adicionados acidentalmente aolxHandle(SetCodePage,GetColumnXFIndex,GetRowXFIndex) foram removidos para manter a API pública da fachada BIFF idêntica à da v2.15.0. O código existente que usalxHandlenão requer alterações.
Versão 2.16.2
- Adicionadas três unidades internas de estruturas de dados que completam a fundação do motor XLSX:
lxAvlTreefornece uma árvore AVL O(log N) (TAVLTree/TAVLNode) para buscas ordenadas;lxColselxRowssão contêineres de informações de colunas e linhas com deduplicação refinada e reescrita de índices, usados pelos mapas de largura de coluna e altura de linha por planilha do motor XLSX. As três unidades estão inativas nesta versão e são ativadas na v2.17.0 quando o motor de leitura/escrita XLSX é habilitado pela primeira vez.
Versão 2.16.1
- Adicionadas seis unidades internas de utilitários XML e ZIP que completam a camada de infraestrutura do motor XLSX:
lxWStream(stream de arquivo de caracteres largos com verificação de existência do arquivo e auxiliar de escrita AnsiString);lxCacheStream(wrapper de stream com buffer que reduz as chamadas de E/S subjacentes);lxZlibStream(stream deflate/inflate somente para frente, independente da vinculação de criptografia BIFFloZlibexistente);lxXmlReader(leitor pull estilo SAX para análise XML de alta velocidade);lxXmlWriter(escritor XML em streaming com reutilização de nomes de elementos);lxZipArchive(leitor/escritor ZIP de diretório central com streams deflate por entrada). Junto com as sete unidades da v2.16.0, formam a fundação interna completa para o motor XLSX.
Versão 2.16.0
- Adicionadas sete unidades internas de infraestrutura de estilos como base para o futuro motor XLSX:
lxHashTable(tabelas hash genéricas com variantes de chave inteira, WideString e objeto);lxKeyList(lista com chave de objeto com busca rápida e reescrita de índices);lxStyleColor(gerenciador de cores de tema Office e slots de paleta);lxStyleFont,lxStyleFillelxStyleBorder(pools deduplicados para estilos de fonte, preenchimento e borda cobrindo todos os 12 tipos de linha BIFF e os mapeamentos de estilo XLSX);lxStyleXf(agrega os cinco pools de estilos com uma lista de formatos numéricos em um único registro XF). As sete unidades estão inativas nesta versão e não afetam os caminhos XLS existentes.
Versão 2.15.1
- Adicionadas as funções auxiliares de cor
lxRgb:RGBtoHLS,HLStoRGB,RGBTinteGetRGBTintconvertem entre os espaços de cores RGB e HLS (intervalo HLS 0–240). Estas sustentam os cálculos de matiz de cor de tema, a formatação condicional por escala de cores e a interpolação de paleta na saída XLSX. - Adicionados os construtores de strings de alto desempenho
lxStrBuilder:TXLSStringBuilder(AnsiChar) eTXLSWideStringBuilder(WideChar) usam buffers pré-alocados de crescimento duplo para eliminar a realocação de memória por concatenação das strings Pascal padrão. A variante AnsiChar alimenta o caminho de serialização XML XLSX; a variante WideChar gerencia a montagem de strings largas no analisador XLSX.
Versão 2.15.0
- Refatorada a referência HtmlHelp para uma estrutura compatível com a web, com pastas dedicadas para tópicos, ativos, scripts, estilos e fontes.
- Adicionada uma página inicial de ajuda amigável para navegadores e uma página de navegação de conteúdo, com cabeçalhos unificados, atalhos para tópicos e rodapés.