HotXLS trzyma oryginalny ChartML importowanego wykresu Excela i odtwarza go bajt po bajcie, gdy nic w typizowanym modelu się nie zmieniło, więc otwarcie i ponowny zapis skoroszytu po cichu nie obdiera części wykresu, których model obiektów nie reprezentuje. Edytuj tytuł, serię lub oś, a HotXLS strukturalnie włącza nowe typizowane węzły do oryginalnego drzewa zamiast regenerować wykres od zera
To rozróżnienie — odtwarzanie, gdy nietknięte, scalanie, gdy edytowane — to właśnie czyni aplikację Delphi bezpieczną do wycelowania w wykresy zbudowane przez analityka w Excelu. Regeneracja wykresu z typizowanego modelu zawsze gubi to, czego model nie wie, a wykresy Excela są pełne rzeczy, których biblioteka nie wie: własne style, listy rozszerzeń, gałęzie alternate content, formatowanie kwalifikowane przestrzenią nazw z dodatków
Dlaczego ponowny zapis skoroszytu spłaszcza jego wykresy?
Ponieważ zwykła implementacja czyta to, co rozumie, i pisze to, co rozumie. Wszystko pomiędzy — extLst z nowszej kompilacji Excela, gałąź mc:AlternateContent, efekt kształtu, dla którego model nie ma właściwości — istnieje w pliku, nie ma domu w modelu obiektów i znika przy zapisie. Użytkownik widzi wykres, który stracił swój gradient, własne etykiety danych albo efekt 3D, a skoroszyt nie potrafi wyjaśnić dlaczego
Przy PreserveUnsupportedParts włączonym na skoroszycie HotXLS przechowuje oryginalne bajty UTF-8 wykresu przy imporcie wraz z długością i 64-bitowym odciskiem palca treści modelowanej. Jeśli typizowany model nie zmienił się do czasu zapisu, zapisuje oryginalne bajty z powrotem. Bez przestawiania XML, bez dryfu białych znaków, bez rezydentnej kopii UTF-16 wykresu krążącej w pamięci dla wykresu, którego nikt nie edytował
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;
Co scalanie zachowuje, a co posiada model
Regułą jest własność. Publiczne węzły modelu — tytuł, serie, pamięci podręczne, grupy wykresów, osie — są decydowane przez nowo wygenerowane drzewo. Niemodelowane poddrzewa są przenoszone z oryginału. Ta asymetria jest celowa i to jest część, której uświadomienie sobie zajmuje chwilę: usunięcie serii nie może wskrzesić starej serii z zachowanego XML, więc wszystko, co posiada model, jest brane z modelu nawet wtedy, gdy model mówi „zniknęło"
Treść bez właściciela jest reinserowana obok dopasowanych węzłów, obok których siedziała, a extLst zostaje ostatni w swoim rodzicu, bo tego wymaga schemat. Czyszczenie znanej właściwości — usunięcie flagi bold, porzucenie koloru — jest traktowane jako czyszczenie, nie jako luka do wypełnienia z oryginalnego drzewa. Nieznane atrybuty w tym samym sąsiedztwie zachowują swoje miejsce
Treść markup-compatibility dostaje specyficzną obsługę. Przy parsowaniu HotXLS pomija mc:Choice i czyta mc:Fallback; jeśli ta gałąź fallbacku opakowuje grupę wykresów, którą model zna, scalanie wpisuje nową typizowaną treść z powrotem do poddrzewa fallbacku. Bez tego kroku zapis wyemitowałby nową grupę wykresów i zostawił starą wewnątrz fallbacku, a wykres niósłby dwie
Wyłączenie jednego wykresu
ClearPreservedXml porzuca oryginalny XML i odcisk palca dla jednego wykresu, więc kolejny zapis przebudowuje ten wykres czysto z typizowanego modelu. To decyzja per wykres; skoroszytowy PreserveUnsupportedParts wciąż rządzi tym, czy stan zachowywania jest budowany przy imporcie
Sięgnij po to, gdy chcesz czysty wykres zamiast wiernego — na przykład gdy wykres z szablonu niesie formatowanie ze starego motywu korporacyjnego i celem operacji jest jego odrzucenie. Nie sięgaj po to jako odruch debuggowy: wykres, który renderuje się źle po edycji, to częściej kwestia modelowania niż zachowywania, a wyczyszczenie zachowanego XML niszczy dowód
Wykresy kombinarne i druga oś
AddPlotGroup buduje uporządkowane wykresy kombinarne, gdzie każda grupa wykresów trzyma własną rodzinę wykresu i własne przypisanie osi podstawowej lub drugorzędnej. To jest to, czego potrzebuje wszechobecny wykres biznesowy: przychód jako kolumny na lewej osi, marża procentowa jako linia na prawej
Wykresy wystawiają podstawowe i drugorzędne osie kategorii i wartości oraz oś serii, z typizowanymi ustawieniami kategorii, wartości, daty i osi serii obejmującymi pozycje, identyfikatory, przecięcia, jednostki daty, interwały etykiet i widoczność. Starsze płaskie API — ChartType, AddSeries, płaska kolekcja Series — wciąż adresuje podstawową grupę wykresów, więc istniejący kod działa dalej, podczas gdy model pod spodem trzyma każdą uporządkowaną grupę
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;
Zanim ten model istniał, otwarcie i ponowny zapis wykresu kombinarnego zwijały go do jednej rodziny wykresu i gubiły osie drugorzędne, daty i serii. Referencje formuł wykresu i buforowane wartości serii przeżywają teraz też kopie skoroszytu i cykle otwórz/zapis, a kotwice wykresów są dopasowywane do swoich części wykresu po identyfikatorze relacji — więc aplikacja, która przestawia wpisy relacji, nie zamienia już treści wykresów między pozycjami arkusza
Pułapka manualnego układu
Jeśli pozycjonujesz obszar kreślenia, tytuł, tytuł osi lub legendę ręcznie, zapisz wszystkie cztery współrzędne. Office wymaga x, y, w i h jako kompletnej grupy, gdy tylko jedna z nich jest obecna, a inaczej ignoruje cały manualLayout. HotXLS zawsze emituje pełny prostokąt z tego powodu, a SetPositionAndSize ustawia i włącza go jednym wywołaniem
Dwa kolejne szczegóły idą za Excelem zamiast za pełną swobodą specyfikacji. Pozycja jest zapisywana z xMode i yMode ustawionymi na edge, podczas gdy rozmiar używa factor dla wMode i hMode, bo to jest to, co pisze Excel i na co konwertuje inne kombinacje. A layoutTarget jest emitowany tylko dla obszaru kreślenia, nigdy dla tytułów ani legend, gdzie notatki implementacyjne Microsoftu tego zabraniają
Wpisanie tego w podróż skoroszytu w obie strony
Zachowywanie wykresów to jedna instancja ogólnej polityki: biblioteka, która edytuje dokumenty autorowane gdzie indziej, powinna zmienić to, o co poproszono, i nic więcej. To samo rozumowanie napędza HotXLS wobec motywów, łańcuchów obliczeń i rozszerzeń arkusza, opisane w notatkach o beztstratnych podróżach w obie strony dla motywu, extLst i calcChain oraz wobec projektów VBA i łączy zewnętrznych w zachowywaniu VBA i łączy zewnętrznych. Dla samej powierzchni autorskiej wykresów — tworzenia wykresów, umieszczania obrazów i rysunków z Delphi — zobacz przewodnik po wykresach, obrazach i rysunkach w HotXLS
HotXLS czyta, edytuje i zapisuje wykresy XLSX z natywnego kodu Delphi i C++Builder bez instalacji Excela na maszynie, co właśnie czyni z fidelity problem biblioteki zamiast problemu automatyzacji — strona komponentu arkuszowego HotXLS ma listę funkcji wykresów i wersję próbną