Teknisk artikel

Rediger Excel-diagrammer uden at miste ChartML i HotXLS

HotXLS bevarer et importeret Excel-diagrams oprindelige ChartML og spiller det byte-for-byte af, når intet i den type-belagte model ændrede sig, så at åbne og gemme en projektmappe ikke stille fjerner de dele af et diagram, som objekt-modellen ikke repræsenterer. Rediger en titel, en serie eller en akse, og HotXLS fusionerer strukturelt de nye type-belagte noder ind i det oprindelige træ frem for at regenerere diagrammet fra bunden

Den distinktion — replay når urørt, flet når redigeret — er det, der gør en Delphi-applikation sikker at pege på diagrammer, en analytiker byggede i Excel. At regenerere et diagram fra en type-beligget model mister altid det, modellen ikke kender til, og Excel-diagrammer er fulde af ting, et bibliotek ikke kender til: tilpassede stile, udvidelses-lister, alternate-content-grene, navnerums-belagt formatering fra add-ins

Hvorfor flader en gemning af en projektmappe dens diagrammer ud?

Fordi den sædvanlige implementering læser, hvad den forstår, og skriver, hvad den forstår. Alt derimellem — en extLst fra en nyere Excel-build, en mc:AlternateContent-gren, en shape-effekt, modellen ikke har nogen egenskab for — eksisterer i filen, har intet hjem i objekt-modellen og forsvinder ved gemning. Brugeren ser et diagram, der mistede sin gradient, sine tilpassede data-etiketter eller sin 3D-effekt, og projektmappen kan ikke forklare hvorfor

Med PreserveUnsupportedParts aktiveret på projektmappen lagrer HotXLS de oprindelige UTF-8-diagram-byte ved import sammen med en længde og et 64-bit fingeraftryk af det modellerede indhold. Hvis den type-belagte model ikke har ændret sig ved gemning, skriver den de oprindelige byte tilbage. Ingen XML-omsortering, ingen whitespace-drift, ingen resident UTF-16-kopi af diagrammet hængende i hukommelsen for et diagram, ingen redigerede

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;

Hvad bevarer fletningen, og hvad ejer modellen?

Reglen er ejerskab. Offentlige model-noder — titel, serier, caches, plot-grupper, akser — besluttes af det nygenererede træ. Umodellerede undertræer overføres fra det oprindelige. Den asymmetri er bevidst, og det er den del, der tager et øjeblik at internalisere: at slette en serie må ikke genoplive den gamle serie fra den bevarede XML, så alt, modellen ejer, tages fra modellen, selv når modellen siger "væk"

Uejet indhold genindsættes ved siden af de matchede noder, det sad ved siden af, og extLst forbliver sidst inden for sin forælder, fordi det er der, skemaet kræver det. At rydde en kendt egenskab — fjerne et bold-flag, droppe en farve — behandles som en rydning, ikke som et hul, der skal udfyldes fra det oprindelige træ. Ukendte attributter i det samme nabolag bevarer deres plads

Markup-compatibility-indhold får specifik håndtering. Ved parse springer HotXLS mc:Choice over og læser mc:Fallback; hvis den fallback-gren indhyller en plot-gruppe, modellen kender, skriver fletningen det nye type-belagte indhold tilbage ind i fallback-undertræet. Uden det skridt ville en gemning emitte den nye plot-gruppe og efterlade den gamle inde i fallback, og diagrammet ville bære to

At melde ét diagram ud

ClearPreservedXml kassérer den oprindelige XML og fingeraftryk for ét diagram, så den næste gemning genopbygger det diagram udelukkende fra den type-belagte model. Det er en pr-diagram-beslutning; projektmappe-niveau-PreserveUnsupportedParts bestemmer stadig, om bevarings-tilstand opbygges ved import

Grib ud efter den, når du vil have et rent diagram frem for et trofast et — for eksempel når et skabelon-diagram bærer formatering fra et gammelt firma-tema, og pointen med operationen er at kassere det. Grib ikke ud efter den som en debugging-refleks: et diagram, der renderer forkert efter en redigering, er oftere et modellerings-spørgsmål end et bevarings-spørgsmål, og at rydde den bevarede XML tilintegør beviserne

Kombinationsdiagrammer og den anden akse

AddPlotGroup bygger ordnede kombinationsdiagrammer, hvor hver plot-gruppe bevarer sin egen diagram-familie og sin egen primære eller sekundære akse-tildeling. Det er, hvad det allestedsnærværende forretningsdiagram har brug for: omsætning som søjler på venstre akse, margin-procent som en linje på højre

Diagrammer udsætter primære og sekundære kategori- og værdi-akser plus en serie-akse, med type-belagte kategori-, værdi-, dato- og serie-akse-indstillinger, der dækker positioner, identifikatorer, krydsninger, dato-enheder, etiket-intervaller og synlighed. Den ældre flade API — ChartType, AddSeries, den flade Series-kollektion — adresserer stadig den primære plot-gruppe, så eksisterende kode fortsætter med at virke, mens modellen under den holder hver ordnet gruppe

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;

Før denne model eksisterede, kollapsede åbning og gemning af et kombinationsdiagram det til én diagram-familie og mistede de sekundære, dato- og serie-akser. Diagram-formel-referencer og cachede serie-værdier overlever nu også projektmappe-kopieringer og åbn/gem-cyklusser, og diagram-ankre matches til deres diagram-dele ved relations-identifikator — så en applikation, der omarrangerer relations-poster, ikke længere bytter diagram-indhold mellem regnearks-positioner

Manual-layout-fælden

Hvis du positionerer et plot-område, en titel, en akse-titel eller en forklaring manuelt, så skriv alle fire koordinater. Office kræver x, y, w og h som en komplet gruppe, når nogen af dem er til stede, og ignorerer hele manualLayout ellers. HotXLS emitterer altid det fulde rektangel af den grund, og SetPositionAndSize sætter og aktiverer det i ét kald

To flere detaljer følger Excel frem for specifikationens fulde råderum. Position skrives med xMode og yMode sat til edge, mens størrelse bruger factor til wMode og hMode, fordi det er det, Excel skriver, og det, den konverterer andre kombinationer til. Og layoutTarget emitteres kun for plot-området, aldrig for titler eller forklaringer, hvor Microsofts implementations-noter forbyder det

Placering af dette i en projektmappe-rundtur

Diagram-bevaring er én instans af en generel politik: et bibliotek, der redigerer dokumenter forfattet andetsteds, bør ændre det, det blev bedt om at ændre, og intet andet. Samme ræsonnement driver HotXLS på temaer, beregnings-kæder og regnearks-udvidelser, beskrevet i noterne om tabsfri rundtur for tema, extLst og calcChain, og om VBA-projekter og eksterne links i bevaring af VBA og eksterne links. For selve diagram-forfatter-fladen — at oprette diagrammer, placere billeder og tegninger fra Delphi — se gennemgangen af diagrammer, billeder og tegninger i HotXLS

HotXLS læser, redigerer og skriver XLSX-diagrammer fra native Delphi- og C++Builder-kode uden Excel-installation på maskinen, hvilket er det, der gør fidelitet til et biblioteksproblem frem for et automations-problem — HotXLS-regnearks-komponent-siden har diagram-funktionslisten og en trial-download