Artigo Técnico

Editar Gráficos do Excel Sem Perder ChartML no HotXLS

O HotXLS mantém o ChartML original de um gráfico do Excel importado e o repassa byte a byte quando nada no modelo tipado mudou, de modo que abrir e salvar novamente uma pasta de trabalho não remove silenciosamente as partes de um gráfico que o modelo de objetos não representa. Edite um título, uma série ou um eixo e o HotXLS mescla estruturalmente os novos nós tipados na árvore original em vez de regenerar o gráfico do zero

Essa distinção — repassar quando intacto, mesclar quando editado — é o que torna segura uma aplicação Delphi apontada para gráficos que um analista construiu no Excel. Regenerar um gráfico a partir de um modelo tipado sempre perde o que o modelo não conhece, e gráficos do Excel estão cheios de coisas que uma biblioteca não conhece: estilos personalizados, listas de extensão, ramificações de conteúdo alternativo, formatação qualificada por namespace de complementos

Por que salvar novamente uma pasta de trabalho achatou seus gráficos?

Porque a implementação usual lê o que entende e escreve o que entende. Tudo no meio — um extLst de uma build mais nova do Excel, um ramo mc:AlternateContent, um efeito de shape para o qual o modelo não tem propriedade — existe no arquivo, não tem casa no modelo de objetos, e desaparece no salvamento. O usuário vê um gráfico que perdeu seu gradiente, seus rótulos de dados personalizados ou seu efeito 3D, e a pasta de trabalho não consegue explicar por quê

Com PreserveUnsupportedParts habilitado na pasta de trabalho, o HotXLS armazena os bytes UTF-8 originais do gráfico na importação junto com um comprimento e uma impressão digital de 64 bits do conteúdo modelado. Se o modelo tipado não tiver mudado até o salvamento, ele escreve os bytes originais de volta. Sem reordenação de XML, sem deriva de whitespace, sem cópia UTF-16 residente do gráfico pairando em memória para um gráfico que ninguém editou

var
  Workbook: TXLSXWorkbook;
  Chart: TXLSXChart;
begin
  Workbook := TXLSXWorkbook.Create(nil);
  try
    Workbook.PreserveUnsupportedParts := True;   // set before Open
    Workbook.Open('quarterly-review.xlsx');
    Chart := Workbook.Sheets[1].Charts[0];   // Sheets[] is 1-based
    if Chart.HasPreservedXml then
      Log('original ChartML retained; untouched charts replay exactly');
    Chart.Title := 'Revenue by region, Q3 2026';  // now the merge path runs
    Workbook.SaveAs('quarterly-review-out.xlsx');
  finally
    Workbook.Free;
  end;
end;

O que a mesclagem mantém e o que o modelo detém

A regra é propriedade. Nós públicos do modelo — título, séries, caches, grupos de plotagem, eixos — são decididos pela árvore recém-gerada. Subárvores não modeladas são carregadas a partir do original. Essa assimetria é deliberada, e é a parte que toma um momento para internalizar: excluir uma série não deve ressuscitar a série antiga do XML preservado, então tudo que o modelo detém é tomado do modelo mesmo quando o modelo diz "sumido"

Conteúdo sem dono é reinserido ao lado dos nós correspondentes junto aos quais estava, e extLst segue como último dentro de seu pai porque é onde o schema exige. Limpar uma propriedade conhecida — remover um flag de negrito, descartar uma cor — é tratado como uma limpeza, não como uma lacuna a ser preenchida pela árvore original. Atributos desconhecidos na mesma vizinhança mantêm seu lugar

Conteúdo de markup-compatibility recebe tratamento específico. Na análise, o HotXLS pula mc:Choice e lê mc:Fallback; se esse ramo de fallback envolver um grupo de plotagem que o modelo conhece, a mesclagem escreve o novo conteúdo tipado de volta na subárvore de fallback. Sem esse passo um salvamento emitiria o novo grupo de plotagem e deixaria o antigo dentro do fallback, e o gráfico carregaria dois

Retirando um gráfico do esquema

ClearPreservedXml descarta o XML original e a impressão digital de um gráfico, então o próximo salvamento reconstrói aquele gráfico puramente a partir do modelo tipado. É uma decisão por gráfico; o PreserveUnsupportedParts em nível de pasta de trabalho continua regendo se o estado de preservação é construído na importação

Alcance-o quando você quer um gráfico limpo em vez de fiel — por exemplo, quando um gráfico de template carrega formatação de um tema corporativo antigo e o ponto da operação é descartá-la. Não o alcance como reflexo de depuração: um gráfico que renderiza errado depois de uma edição é mais frequentemente uma questão de modelagem do que de preservação, e limpar o XML preservado destrói a evidência

Gráficos de combinação e o eixo secundário

AddPlotGroup constrói gráficos de combinação ordenados, em que cada grupo de plotagem mantém sua própria família de gráfico e sua própria atribuição de eixo primário ou secundário. É o que o gráfico de negócios onipresente precisa: receita como colunas no eixo esquerdo, margem em porcentagem como linha no eixo direito

Gráficos expõem eixos primário e secundário de categoria e valor mais um eixo de séries, com configurações tipadas de categoria, valor, data e eixo de séries cobrindo posições, identificadores, cruzamentos, unidades de data, intervalos de rótulo e visibilidade. A API plana mais antiga — ChartType, AddSeries, a coleção plana Series — continua endereçando o grupo de plotagem primário, de modo que código existente continua funcionando enquanto o modelo por baixo segura todos os grupos ordenados

var
  Chart: TXLSXChart;
  Line: TXLSXChartPlotGroup;
begin
  // Column chart anchored over rows 1..15, columns 5..12
  Chart := Sheet.Charts.Add(xlsxChartColumn, 'Revenue and margin',
    1, 5, 15, 12);
  Chart.AddSeries('Revenue', 'Data!$A$2:$A$13', 'Data!$B$2:$B$13');
  // Second plot group: a line, read against the secondary value axis
  Line := Chart.AddPlotGroup(xlsxChartLine, xlsxAxisSecondary);
  Line.AddSeries('Margin %', 'Data!$A$2:$A$13', 'Data!$C$2:$C$13');
end;

Antes de esse modelo existir, abrir e salvar novamente um gráfico de combinação o colapsava em uma família de gráfico única e perdia os eixos secundário, de data e de séries. Referências de fórmula de gráfico e valores de série em cache agora sobrevivem a cópias da pasta de trabalho e a ciclos de abrir/salvar também, e âncoras de gráfico são corresponderidas às suas partes de gráfico por identificador de relacionamento — de modo que uma aplicação que reordena entradas de relacionamento não troca mais conteúdos de gráfico entre posições da planilha

A armadilha do manual layout

Se você posicionar à mão uma plot area, um título, um título de eixo ou uma legenda, escreva as quatro coordenadas. O Office exige x, y, w e h como um grupo completo sempre que qualquer um deles está presente, e ignora o manualLayout inteiro de outro modo. O HotXLS sempre emite o retângulo completo por esse motivo, e SetPositionAndSize o define e habilita em uma única chamada

Dois detalhes a mais seguem o Excel em vez da latitude total da especificação. A posição é escrita com xMode e yMode definidos como edge enquanto o tamanho usa factor para wMode e hMode, porque é isso que o Excel escreve e no que ele converte outras combinações. E layoutTarget é emitido apenas para a plot area, nunca para títulos ou legendas, onde as notas de implementação da Microsoft o proíbem

Encaixando isso numa ida e volta de pasta de trabalho

A preservação de gráficos é uma instância de uma política geral: uma biblioteca que edita documentos autoralizados em outro lugar deveria mudar o que lhe foi pedido mudar e nada mais. O mesmo raciocínio conduz o HotXLS em temas, cadeias de cálculo e extensões de planilha, descrito nas notas sobre idas e voltas sem perda para tema, extLst e calcChain, e em projetos VBA e links externos em preservação de VBA e links externos. Para a superfície de autoria de gráficos em si — criar gráficos, posicionar imagens e drawings a partir de Delphi — veja o guia sobre gráficos, imagens e drawings no HotXLS

O HotXLS lê, edita e escreve gráficos XLSX a partir de código nativo em Delphi e C++Builder sem nenhuma instalação do Excel na máquina, que é o que torna fidelidade um problema de biblioteca em vez de um problema de automação — a página do componente de planilha HotXLS tem a lista de recursos de gráficos e um download de avaliação