Tehnični članak

Popravek enega delovnega lista v veliki datoteki XLSX iz Delphija

HotXLS lahko na novo zapiše en delovni list znotraj obstoječega paketa XLSX, ne da bi razčlenil ali znova stisnil preostanek datoteke. TXLSDirectWriter.BeginPatch odpre izvorni paket, vsak vnos razen ciljnega lista prekopira dobesedno z njegovimi stisnjenimi bajti, nato pa vam omogoči, da ta posamezni list na novo napišete prek običajnih klicev AddSheet, AddRow in Write*. Grafikoni, pivotni predpomnilniki, teme, slogi in skupni nizi se sploh nikoli ne dekomprimirajo

Potek dela, ki ga to rešuje, se pojavlja pri poročanju in osveževanju podatkov. Delovni zvezek prispe od poslovne ekipe in nosi vrtilne tabele, rezalnike, pogojno oblikovanje in desetletje nakopičenega oblikovanja. Vsako noč je treba en podatkovni list nadomestiti s svežimi številkami. Nalaganje in ponovno shranjevanje celotnega delovnega zvezka stane minute na datoteko in, kar je pomembneje, tvega zvestobo pri funkcijah, ki jih mora mehanizem za nalaganje ponovno zgraditi. Popravljanje se izogne obema težavama tako, da se ne dotakne tega, česar se mu ni treba dotakniti

Zakaj je kopiranje stisnjenih bajtov zanimivi del?

Vnos zip, kopiran na stisnjeni ravni, stane kopiranje toka. Isti vnos, speljan skozi navadno pisalno pot, stane razširitev (inflate) na poti noter in stiskanje (deflate) na poti ven, stiskanje pa je dražja polovica. Pri delovnem zvezku z velikim pivotnim predpomnilnikom in nekaj deset vdelanimi slikami je ta razlika razlika med popravkom, ki se konča v času, kot ga vzame pisanje novega lista, in takim, ki večino časa porabi za ponovno stiskanje bajtov, ki jih nikoli ni niti pregledal

HotXLS za to uporablja CopyCompressedFrom, ki stisnjene bajte izvornega vnosa zapiše naravnost v ciljni arhiv. Kadar vnosa na ta način ni mogoče kopirati, ker uporablja drugačno metodo stiskanja ali šibko šifriranje, se pisalnik namesto neuspeha prevesi na dekomprimirano kopiranje toka. Vnosi z oznako imenika so preskočeni, saj pisalnik ustvari svoje lastne

Zamenjava na mestu ali pisanje v novo datoteko

Dve preobremenitvi pokrivata dve obliki, ki jih to opravilo lahko zavzame. Oblika na mestu rezultat pripravi v začasni datoteki poleg izvirnika, zapre izvorno ročico, nato pa izbriše in preimenuje, tako da zrušitev sredi pisanja izvirnik pusti nedotaknjen. Oblika z izrecnim ciljem izvirnik pusti nedotaknjen in lahko bodisi zamenja list bodisi doda novega:

var
  W: TXLSDirectWriter;
begin
  W := TXLSDirectWriter.Create;
  try
    W.BeginPatch('monthly-dashboard.xlsx', 'Data');   // na mestu
    W.AddSheet('Data');
    W.AddRow(1);
    W.WriteString(1, 'Region');
    W.WriteString(2, 'Revenue');
    W.AddRow(2);
    W.WriteString(1, 'North');
    W.WriteNumber(2, 184320.55);
    W.AddRow(3);
    W.WriteFormula(1, '=SUM(B2:B2)');
    W.Close;
  finally
    W.Free;
  end;
end;

Vstavitvena različica sprejme izvorno in ciljno pot plus InsertSheet:

  // Vir ostane nedotaknjen; cilj dobi dodaten delovni list z imenom Extra
  W.BeginPatch('template.xlsx', 'output.xlsx', 'Extra', True);
  W.AddSheet('Extra');
  W.AddRow(1);
  W.WriteString(1, 'appended by the nightly job');
  W.Close;

Vstavljanje je del, ki zahteva pravo kirurgijo knjigovodstva. Pisalnik razčleni register listov v xl/workbook.xml in zemljevid razmerij, ki vsak list veže na njegov del, nato pa izbere naslednjo prosto številko dela, identifikator lista in identifikator razmerja. Vrste razmerij sledijo dogovorom izvornega paketa, zato popravljanje strogega delovnega zvezka ISO 29500 izpiše stroge vrste razmerij, popravljanje prehodnega pa prehodne vrste

Kaj popravek namerno izpusti in omeji

Veriga izračunov je zavržena v obeh načinih. V načinu zamenjave njeni vnosi opisujejo celice v listu, ki v tej obliki ne obstaja več; v vstavitvenem načinu jo premik indeksa lista popolnoma izniči. Excel verigo znova zgradi ob naslednjem ponovnem izračunu, zato njena opustitev ni izguba, temveč pravilno ravnanje. Del je izpuščen iz kopiranja, njegov vnos razmerja in prepis vrste vsebine pa sta odstranjena kirurško natančno

Znotraj popravka se spremenita dve semantiki avtorstva, obe pa izhajata iz istega načela: popravek ne sme motiti delov, ki jih ni na novo zapisal. Nizi so zapisani neposredno v list namesto dodani v tabelo skupnih nizov, ker izvorna tabela prehaja nedotaknjena. StyleIndex pa se sklicuje na vnose v cellXfs izvornega paketa, ne na tabelo slogov, ki bi jo zgradil pisalnik. To pomeni, da se lahko sklicujete na oblike, ki jih izvirni delovni zvezek že definira, kar je običajno natanko to, kar osveževanje podatkov želi, hkrati pa pomeni, da morate vedeti, kateri indeks nosi katero obliko

// Znotraj popravka StyleIndex indeksira cellXfs IZVORNEGA paketa.
// Datum potrebuje izrecen indeks, ki se tam preslika na obliko datuma:
W.WriteDateTime(3, EncodeDate(2026, 8, 22), DateStyleIndexFromTemplate);

// Preobremenitev WriteDateTime brez sloga je v načinu popravka zavrnjena,
// ker predpostavlja pisalnikovo lastno tabelo slogov, ki je popravek
// nikoli ne ustvari

Šest vstopnih točk avtorstva je zaklenjenih: dodajanje tabel, grafikonov, slik, komentarjev, definiranih imen in stilov celic v načinu popravka sproži izjemo, z drugo varnostno mrežo ob zapiranju, ki spodleti, če je kateri od njihovih števcev neničeln. Vsaka od teh funkcij bi zahtevala urejanje delov, ki jih popravek kopira dobesedno, napol urejen paket pa je slabši od zavrnjene operacije. V eni operaciji je mogoče popraviti natanko en list

Kdaj popraviti in kdaj naložiti

Popravljanje je pravo orodje, kadar je delovni zvezek velik, sprememba je omejena na en list in mora preostanek datoteke preživeti bit za bitom. Je napačno orodje, kadar sprememba zajema več listov, kadar so potrebna nova oblikovanja ali novi objekti, ali kadar je datoteka dovolj majhna, da navadno nalaganje in shranjevanje ne stane ničesar. Za množično ustvarjanje iz nič ostaja boljša izbira pretočna pot, opisana v pretočnem neposrednem pisalniku, ki si deli isti API AddRow in Write*, tako da je premikanje med obema mehansko

Manipulacija na ravni lista znotraj naloženega delovnega zvezka, kadar dejansko želite celoten objektni model, je opisana v podvajanju delovnih listov v paketih XLSX. Če pa je razlog, da razmišljate o popravku, ta, da je obdelava celotnega delovnega zvezka postala počasna, je vredno pred izbiro pristopa prebrati meritve in vedenje pomnilnika v zmogljivosti velikih delovnih zvezkov

Preverjanje, ali je popravek res naredil, kar mislite

Tri preverbe ujamejo skoraj vsako napako. Potrdite, da so deli, za katere ste pričakovali, da bodo preživeli, še vedno v arhivu, da je xl/calcChain.xml izginil in da ponovno odpiranje datoteke prek TXLSXWorkbook javi pričakovano število listov — nespremenjeno pri zamenjavi in povečano za ena pri vstavitvi. Ponovno branje popravljenega lista in primerjava nekaj vrednosti in formul sklene krog

Ena podrobnost implementacije iz razvoja te funkcije je vredna ponovitve, ker lahko ugrizne vsakogar, ki piše podobno kodo na ravni zip. Imena delov delovnih listov se ujemajo po predponi, napaka za ena v dolžini predpone pa pomeni, da predikat nikoli ne uskladi, tako da na novo zapisan del trči z obstoječim imenom, bralniki, ki vzamejo zadnji vnos z danim imenom, pa tiho izberejo napačen list. Če se zdi, da je popravek zamenjal vsebino dveh listov, poglejte ujemanje imen, preden pogledate XML

Popravljanje na mestu, pretočno pisanje in celoten objektni model delovnega zvezka so na voljo v isti knjižnici za Delphi in C++Builder; seznam funkcij je na strani komponente HotXLS Excel za Delphi