Tehnički članak

Zakrpajte jedan radni list u velikom XLSX-u iz Delphija

HotXLS može prepisati jedan radni list unutar postojećeg XLSX paketa bez raščlambe ili ponovnog komprimiranja ostatka datoteke. TXLSDirectWriter.BeginPatch otvara izvorni paket, kopira svaki unos osim ciljnog lista uz doslovno zadržavanje njegovih komprimiranih bajtova, te vam omogućuje ponovno pisanje tog jednog lista kroz uobičajene pozive AddSheet, AddRow i Write*. Grafikoni, pivot predmemorije, teme, stilovi i dijeljeni nizovi uopće se ne dekomprimiraju

Tijek rada koji ovo rješava pojavljuje se u izvještavanju i osvježavanju podataka. Radna knjiga stiže od poslovnog tima noseći pivot tablice, isječke (slicere), uvjetno oblikovanje i desetljeće nagomilanog formatiranja. Svake noći jedan list podataka mora se zamijeniti svježim brojevima. Učitavanje i ponovno spremanje cijele radne knjige košta minute po datoteci i, što je važnije, rizikuje vjernost značajki koje motor učitavanja mora rekonstruirati. Zakrpavanje zaobilazi oba problema tako da ne dira ono što ne treba dirati

Zašto je kopiranje komprimiranih bajtova zanimljiv dio?

Zip unos koji se kopira na komprimiranoj razini košta kopiju toka. Isti unos proveden kroz normalan put pisanja košta inflate pri ulazu i deflate pri izlazu, a deflate je skuplja polovica. Na radnoj knjizi s velikom pivot predmemorijom i nekoliko desetaka ugrađenih slika, ta je razlika razlika između zakrpe koja završi u vremenu potrebnom za pisanje novog lista i one koja većinu vremena provede ponovno komprimirajući bajtove koje nikada nije ni pregledala

HotXLS za to koristi CopyCompressedFrom, koji komprimirane bajtove izvornog unosa piše izravno u ciljnu arhivu. Kada se unos ne može kopirati na taj način, jer koristi drugu metodu kompresije ili slabu enkripciju, zapisivač pada natrag na dekomprimirano kopiranje toka umjesto da zakaže. Unosi oznaka direktorija preskaču se, budući da zapisivač proizvodi vlastite

Zamjena na mjestu ili pisanje u novu datoteku

Dva preopterećenja (overloada) pokrivaju dva oblika koje ovaj zadatak može poprimiti. Oblik na mjestu priprema rezultat u privremenoj datoteci pored izvornika, zatvara izvornu ručku, a zatim briše i preimenuje, tako da pad usred pisanja ostavlja izvornik netaknutim. Oblik s izričitim ciljem ostavlja izvor netaknutim i može ili zamijeniti list ili dodati novi:

var
  W: TXLSDirectWriter;
begin
  W := TXLSDirectWriter.Create;
  try
    W.BeginPatch('monthly-dashboard.xlsx', 'Data');   // na mjestu
    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;

Varijanta umetanja prima izvornu i ciljnu putanju plus InsertSheet:

  // Izvor ostaje netaknut; cilj dobiva dodatni radni list 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;

Umetanje je dio koji zahtijeva pravi kirurški zahvat u knjigovodstvu. Zapisivač raščlanjuje registar listova u xl/workbook.xml i mapu relacija koja veže svaki list uz njegov dio, zatim bira sljedeći slobodni broj dijela, identifikator lista i identifikator relacije. Tipovi relacija slijede konvencije izvornog paketa, pa zakrpavanje strogog ISO 29500 radne knjige generira stroge tipove relacija, a zakrpavanje prijelazne generira prijelazne tipove

Što zakrpa namjerno odbacuje i ograničava

Lanac izračuna odbacuje se u oba načina rada. U načinu zamjene njegovi unosi opisuju ćelije u listu koji više ne postoji u tom obliku; u načinu umetanja pomak indeksa lista posve ga poništava. Excel ponovno gradi lanac pri sljedećem ponovnom izračunu, pa je njegovo odbacivanje ispravno, a ne gubitno. Taj dio izostaje iz kopije, a njegov unos relacije i nadjačavanje tipa sadržaja uklanjaju se kirurški precizno

Dvije semantike autorstva mijenjaju se unutar zakrpe, a obje proizlaze iz istog načela: zakrpa ne smije poremetiti dijelove koje nije prepisala. Nizovi se pišu izravno u list umjesto da se dodaju u tablicu dijeljenih nizova, jer izvorna tablica prelazi dalje netaknuta. A StyleIndex upućuje na unose u cellXfs izvornog paketa, a ne na tablicu stilova koju zapisivač gradi. To znači da možete referencirati formate koje izvorna radna knjiga već definira, što je obično upravo ono što osvježavanje podataka želi, ali znači i da morate znati koji indeks nosi koji format

// Unutar zakrpe, StyleIndex indeksira cellXfs IZVORNOG paketa.
// Datum treba izričit indeks koji se ondje preslikava na format datuma:
W.WriteDateTime(3, EncodeDate(2026, 8, 22), DateStyleIndexFromTemplate);

// Preopterećenje WriteDateTime bez stila odbačeno je u načinu zakrpe,
// jer pretpostavlja vlastitu tablicu stilova zapisivača, koju zakrpa
// nikada ne stvara

Šest ulaznih točaka za autorstvo je blokirano: dodavanje tablica, grafikona, slika, komentara, definiranih naziva i stilova ćelija sve podiže iznimku u načinu zakrpe, uz drugu sigurnosnu mrežu pri zatvaranju koja zakaže ako je bilo koji od njihovih brojača različit od nule. Svaka od tih značajki zahtijevala bi uređivanje dijelova koje zakrpa kopira doslovno, a napola uređen paket gori je od odbijene operacije. Po operaciji se smije zakrpati točno jedan list

Kada zakrpati, a kada učitati

Zakrpavanje je pravi alat kada je radna knjiga velika, promjena je ograničena na jedan list, a ostatak datoteke mora preživjeti bit po bit. To je pogrešan alat kada promjena obuhvaća nekoliko listova, kada su potrebni novo oblikovanje ili novi objekti, ili kada je datoteka dovoljno mala da normalno učitavanje i spremanje ništa ne košta. Za masovno generiranje od nule, put strujanja opisan u izravnom zapisivaču strujanja ostaje bolji izbor, a dijeli isti AddRow i Write* API, pa je prelazak između dva pristupa mehanički

Manipulacija na razini lista unutar učitane radne knjige, kada doista želite potpuni objektni model, opisana je u udvostručavanju radnih listova u XLSX paketima. A ako je razlog zbog kojeg razmatrate zakrpu taj da je obrada cijele radne knjige postala spora, mjerenja i ponašanje memorije u performansama velikih radnih knjiga vrijedi pročitati prije odabira pristupa

Provjera je li zakrpa doista učinila ono što mislite

Tri provjere hvataju gotovo svaku pogrešku. Potvrdite da su dijelovi koje ste očekivali da će preživjeti i dalje u arhivi, da je xl/calcChain.xml nestao, i da ponovno otvaranje datoteke kroz TXLSXWorkbook prijavljuje broj listova koji očekujete, nepromijenjen za zamjenu, a povećan za jedan za umetanje. Čitanje zakrpanog lista natrag i usporedba nekoliko vrijednosti i formula zatvara krug

Jedan implementacijski detalj iz razvoja ove značajke vrijedi ponoviti, jer može ugristi svakoga tko piše sličan kod na razini zip arhive. Nazivi dijelova radnih listova podudaraju se prema prefiksu, a pogreška za jedan u duljini prefiksa znači da se predikat nikada ne podudara, pa novonapisani dio sudara se s postojećim nazivom, a čitači koji uzimaju posljednji unos s danim nazivom tiho biraju pogrešan list. Ako se čini da je zakrpa zamijenila sadržaj dvaju listova, pogledajte podudaranje naziva prije nego XML

Zakrpavanje na mjestu, strujno pisanje i potpuni objektni model radne knjige isporučuju se u istoj knjižnici za Delphi i C++Builder; popis značajki nalazi se na stranici HotXLS Delphi komponente proračunske tablice