HotXLS poate rescrie o singură foaie de lucru într-un pachet XLSX existent fără să analizeze sau să recomprime restul fișierului. TXLSDirectWriter.BeginPatch deschide un pachet sursă, copiază fiecare intrare, cu excepția foii țintă, cu octeții ei comprimați neschimbați, și îți permite să recreezi acea singură foaie prin apelurile obișnuite AddSheet, AddRow și Write*. Graficele, cache-urile pivot, temele, stilurile și șirurile partajate nu sunt niciodată decomprimate
Fluxul de lucru pe care îl rezolvă apare în raportare și reîmprospătare de date. Un registru de lucru vine de la o echipă de business purtând tabele pivot, segmentatoare, formatări condiționale și un deceniu de formatare acumulată. În fiecare noapte, o foaie de date trebuie înlocuită cu numere proaspete. Încărcarea și resalvarea întregului registru de lucru costă minute per fișier și, mai important, riscă fidelitatea unor funcții pe care motorul de încărcare trebuie să le reconstruiască. Corectarea (patching) evită ambele probleme, neatingând ce nu are nevoie să atingă
De ce copierea octeților comprimați este partea interesantă?
O intrare zip copiată la nivel comprimat costă o copiere de flux. Aceeași intrare trecută printr-o cale normală de scriere costă o despachetare (inflate) la intrare și o compresie (deflate) la ieșire, iar deflate este jumătatea scumpă. Pe un registru de lucru cu un cache pivot mare și câteva zeci de imagini încorporate, acea diferență este diferența dintre o corectare care se termină în timpul necesar scrierii foii noi și una care își petrece majoritatea timpului recomprimând octeți pe care nu i-a examinat niciodată
HotXLS folosește CopyCompressedFrom pentru asta, care scrie octeții comprimați ai intrării sursă direct în arhiva țintă. Când o intrare nu poate fi copiată în acest fel, deoarece folosește o metodă de compresie diferită sau criptare slabă, scriitorul revine la o copiere de flux decomprimat, în loc să eșueze. Intrările de marcaj de director sunt sărite, deoarece scriitorul își produce propriile
Înlocuiește pe loc sau scrie într-un fișier nou
Două suprapuneri (overload) acoperă cele două forme pe care le ia această sarcină. Forma pe loc pune în scenă rezultatul într-un fișier temporar lângă original, închide handle-ul sursă, apoi șterge și redenumește, astfel încât un crash la mijlocul scrierii lasă originalul intact. Forma cu țintă explicită lasă sursa neatinsă și poate fie înlocui o foaie, fie adăuga una nouă:
var
W: TXLSDirectWriter;
begin
W := TXLSDirectWriter.Create;
try
W.BeginPatch('monthly-dashboard.xlsx', 'Data'); // pe loc
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;
Varianta de inserare primește o cale sursă și una țintă plus InsertSheet:
// Sursa rămâne neatinsă; ținta primește o foaie de lucru suplimentară numită 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;
Inserarea este partea care necesită o adevărată chirurgie de evidență. Scriitorul analizează registrul de foi din xl/workbook.xml și harta de relații care leagă fiecare foaie de partea ei, apoi alege următorul număr liber de parte, identificator de foaie și identificator de relație. Tipurile de relații urmează convențiile pachetului sursă, așa că a corecta un registru de lucru strict ISO 29500 emite tipuri de relații stricte, iar a corecta unul tranzitoriu emite tipuri tranzitorii
Ce elimină și constrânge deliberat corectarea
Lanțul de calcul este eliminat în ambele moduri. În modul de înlocuire, intrările lui descriu celule dintr-o foaie care nu mai există în acea formă; în modul de inserare, deplasarea indexului de foi îl invalidează complet. Excel reconstruiește lanțul la următoarea recalculare, așa că eliminarea lui este corectă, nu o pierdere. Partea este exclusă din copiere, iar intrarea ei de relație și suprascrierea de tip de conținut sunt eliminate chirurgical
Două semantici de creare se schimbă în interiorul unei corectări, și ambele derivă din același principiu: corectarea nu trebuie să perturbe părțile pe care nu le-a rescris. Șirurile sunt scrise inline în foaie, nu adăugate în tabelul de șiruri partajate, deoarece tabelul sursă trece dincolo neatins. Iar StyleIndex se referă la intrări din cellXfs-ul pachetului sursă, nu la un tabel de stiluri pe care îl construiește scriitorul. Asta înseamnă că poți referi formate pe care registrul de lucru original deja le definește, ceea ce e de obicei exact ce vrea o reîmprospătare de date, dar înseamnă și că trebuie să știi care index poartă care format
// În interiorul unei corectări, StyleIndex indexează cellXfs-ul PACHETULUI SURSĂ.
// O dată are nevoie de un index explicit care se mapează la un format de dată acolo:
W.WriteDateTime(3, EncodeDate(2026, 8, 22), DateStyleIndexFromTemplate);
// Suprapunerea WriteDateTime fără stil este respinsă în modul de corectare,
// deoarece presupune propriul tabel de stiluri al scriitorului, pe care o
// corectare nu îl creează niciodată
Șase puncte de intrare de creare sunt blocate: adăugarea de tabele, grafice, imagini, comentarii, nume definite și stiluri de celulă ridică toate o excepție în modul de corectare, cu o a doua plasă de siguranță la închidere care eșuează dacă vreunul dintre contoarele lor este diferit de zero. Fiecare dintre aceste funcții ar necesita editarea unor părți pe care corectarea le copiază neschimbate, iar un pachet editat pe jumătate este mai rău decât o operație refuzată. Exact o singură foaie poate fi corectată per operație
Când să corectezi și când să încarci
Corectarea este instrumentul potrivit atunci când registrul de lucru este mare, schimbarea se limitează la o singură foaie, iar restul fișierului trebuie să supraviețuiască identic la nivel de octet. Este instrumentul greșit atunci când schimbarea se întinde pe mai multe foi, când sunt necesare formatări sau obiecte noi, sau când fișierul e suficient de mic încât o încărcare și salvare normală nu costă nimic. Pentru generarea în masă de la zero, calea în flux descrisă în scriitorul direct în flux rămâne opțiunea mai bună, și împarte același API AddRow și Write*, astfel încât mutarea între cele două este mecanică
Manipularea la nivel de foaie într-un registru de lucru încărcat, când chiar ai nevoie de modelul complet de obiecte, este acoperită în duplicarea foilor de lucru în pachete XLSX. Și dacă motivul pentru care iei în considerare o corectare este că procesarea întregului registru de lucru a devenit lentă, măsurătorile și comportamentul memoriei din performanța registrelor de lucru mari merită citite înainte de a alege o abordare
Verificarea că o corectare a făcut cu adevărat ce crezi
Trei verificări prind aproape orice greșeală. Confirmă că părțile pe care te așteptai să supraviețuiască sunt încă în arhivă, că xl/calcChain.xml a dispărut, și că redeschiderea fișierului prin TXLSXWorkbook raportează numărul de foi la care te aștepți, neschimbat pentru o înlocuire și incrementat cu unu pentru o inserare. Citirea foii corectate și compararea câtorva valori și formule închide bucla
Un detaliu de implementare din dezvoltarea acestei funcții merită repetat, deoarece poate afecta pe oricine scrie cod similar la nivel de zip. Numele părților foilor de lucru sunt potrivite după prefix, iar o eroare de tip off-by-one în lungimea prefixului înseamnă că predicatul nu se mai potrivește niciodată, așa că o parte nou scrisă intră în coliziune cu un nume existent, iar cititorii care iau ultima intrare cu un anumit nume aleg tăcut foaia greșită. Dacă o corectare pare să inverseze conținutul a două foi, verifică potrivirea numelor înainte de a verifica XML-ul
Corectarea pe loc, scrierea în flux și modelul complet de obiecte al registrului de lucru se livrează în aceeași bibliotecă pentru Delphi și C++Builder; lista de funcții este pe pagina componentei de foi de calcul HotXLS pentru Delphi