Ponekad je jedino pitanje na koje rutina za unos treba odgovoriti strukturno: ima li ova radna knjiga list pod nazivom "Mapping" ili koliko kartica sadrži. Odgovaranje na to pozivanjem Open je skup način za to. Potpuno otvaranje napuhuje tablicu dijeljenih nizova znakova (shared strings), dekodira svaki zapis stila i prolazi kroz ćelije svakog radnog lista jer nema načina da zna da ste htjeli samo sadržaj. Na velikoj datoteci to znači stotine megabajta alokacija i nekoliko sekundi procesorskog vremena potrošenog za čitanje popisa koji zauzima nekoliko kilobajta. HotXLS, nativna Delphi biblioteka za proračunske tablice tvrtke losLab, daje vam taj popis zasebno: GetSheetNames vraća nazive radnih listova, prema redoslijedu u radnoj knjizi, bez stvaranja ijedne ćelije.
Zašto je katalog jeftin za čitanje
Oba formata proračunskih tablica stavljaju svoj sadržaj blizu početka, što poziv za izlistavanje čini brzim, a ne samo pametnim. OOXML paket drži katalog listova u xl/workbook.xml, dijelu koji ostaje mali bez obzira na to sadrži li radna knjiga deset redaka ili deset milijuna. BIFF8 .xls pohranjuje svoje BoundSheet zapise na početku toka globalnih podataka radne knjige, ispred bilo kojih podataka o ćelijama. Dakle, posao koji poziv za izlistavanje izbjegava nije pogreška zaokruživanja u odnosu na potpuno otvaranje. To je većina datoteke. Čitanje kataloga košta istih nekoliko kilobajta bez obzira na broj redaka, dok se potpuno otvaranje skalira s podacima, a na radnoj knjizi od nekoliko megabajta taj raspon doseže nekoliko redova veličine i u dotaknutim bajtovima i u dodijeljenoj memoriji.
Taj fiksni trošak je svojstvo oko kojeg vrijedi dizajnirati rješenje. Ulazna vrata izgrađena na GetSheetNames ponašaju se jednako na datoteci od 200 redaka i onoj od 200 MB, tako da najsporija datoteka u paketu više ne diktira tempo za odluku o tome vrijedi li datoteku uopće obrađivati.
Jedan poziv za .xls, .xlsx i formate predložaka
Na XLS sučelju, TXLSWorkbook.GetSheetNames čita više od samog .xls-a. Također prihvaća .xlsx, .xlsm, .xltx i .xltm temeljene na zipu, izvlačeći samo workbook.xml iz arhive. Za izvorni .xls unos skenira BoundSheet zapise i zaustavlja se na prvom EOF zapisu globalnog podtoka, tako da velika binarna datoteka i dalje košta samo svoje uvodne kilobajte. XLSX sučelje nosi jamstvo koje je važnije za dugotrajni kod usluge nego što se to na prvi pogled čini: TXLSXWorkbook.GetSheetNames ostavlja instancu radne knjige niti resetiranom niti popunjenom, tako da instanca koja već drži otvoren dokument može ispitivati druge datoteke bez ometanja one u ruci. GetODSSheetNames primjenjuje isti pristup na OpenDocument pakete, a svaki od ovih poziva ima preopterećenje toka (stream), što vam omogućuje pregled prijenosa koji nikada ne slijeće na disk.
var
Book: TXLSXWorkbook;
Names: TStringList;
I: Integer;
begin
Names := TStringList.Create;
Book := TXLSXWorkbook.Create;
try
if Book.GetSheetNames('upload-7f3a.xlsx', Names) <= 0 then
raise Exception.Create('unreadable workbook package');
if Names.IndexOf('Mapping') < 0 then
raise Exception.Create('required Mapping sheet is missing');
for I := 0 to Names.Count - 1 do
Writeln(Format('sheet %d: %s', [I, Names[I]]));
finally
Book.Free;
Names.Free;
end;
end;
Isti poziv čini dobar dijaloški okvir za uvoz na stolnim računalima. Izlistajte listove, dopustite korisniku da odabere jedan i platite potpuno otvaranje tek nakon što se donese odabir. S radnom knjigom od pedeset listova razlika je vidljiva: birač koji se pojavljuje odmah u odnosu na onaj koji zapinje dok se cijela datoteka učitava iza njega.
Datoteke .xlsm omogućene za makronaredbe i formati predložaka ispisuju se točno kao obični .xlsx jer katalog sjedi u istom workbook.xml bez obzira na to putuje li vbaProject.bin u paketu ili ne. Cjevovod za unos stoga može popisati listove makro radne knjige radi usmjeravanja, nikada ne dodirujući sadržaj makronaredbe niti čineći bilo što što bi je pokrenulo, te ostaviti poziv pravila o makronaredbama za fazu koja stvarno otvara datoteku.
Čitanje povratne vrijednosti bez samozavaravanja
Konvencije o povratnim vrijednostima nisu ujednačene u cijelom HotXLS-u. Neki pozivi vraćaju 1 u slučaju uspjeha, drugi vraćaju broj, pa je za funkcije izlistavanja jedina provjera koja drži vodu tretiranje bilo koje vrijednosti od nule ili niže kao neuspjeh, uz očišćenu listu nizova. Oduprite se iskušenju da praznu listu protumačite kao "radnu knjigu bez listova". I ECMA-376 i specifikacija BIFF8 zahtijevaju najmanje jedan list u važećoj radnoj knjizi, tako da nula naziva uvijek znači da čitanje nije uspjelo, a nikada da je datoteka legitimno prazna.
Neuspjelo izlistavanje je samo po sebi signal koji vrijedi zadržati. Datoteka .xlsx koja ne uspije proći poziv je jedna od nekoliko specifičnih stvari: skraćena datoteka, uopće nije OOXML paket (krivo označeni izvozi u CSV iz drugih sustava stalno se pojavljuju ovdje) ili šifrirani spremnik. Razlikovanje tih slučajeva posao je sljedeće provjere. Bilježenje prvih bajtova odbačene datoteke uz neuspjeh obično pretvara temu podrške u jednu jedinu poruku.
Otkrivanje šifriranih spremnika prije usmjeravanja
Šifrirani .xlsx nije zip. To je OLE složena datoteka (compound file) koja obavija tokove EncryptionInfo i EncryptedPackage, tako da GetSheetNames ne može vedere unutar nje i vraća neuspjeh kao i svaka druga nečitljiva datoteka. CanReadEncrypted testira taj oblik spremnika, što omogućuje unosu da namjerno usmjeri šifriranu datoteku radije nego da proguta generičku pogrešku čitanja iz dubine radnog procesa:
type
TIntakeRoute = (irNormal, irNeedsPassword, irUnreadable);
function ClassifyUpload(const FileName: string; Names: TStrings): TIntakeRoute;
var
Book: TXLSXWorkbook;
begin
Book := TXLSXWorkbook.Create;
try
// Encrypted OOXML is an OLE container, not a zip: check first,
// because the listing calls cannot look inside it.
if Book.CanReadEncrypted(FileName) then
Exit(irNeedsPassword);
if SameText(ExtractFileExt(FileName), '.ods') then
begin
if Book.GetODSSheetNames(FileName, Names) <= 0 then
Exit(irUnreadable);
end
else if Book.GetSheetNames(FileName, Names) <= 0 then
Exit(irUnreadable);
Result := irNormal;
finally
Book.Free;
end;
end;
Šifriranje je područje u kojem je HotXLS isključivo asimetričan, pa usmjeravanje to mora poštovati. Naslijeđeno .xls šifriranje (RC4, RC4 CryptoAPI, XOR) je čitljivo: TXLSWorkbook.Open(FileName, Password) dešifrira se s pohranjenom lozinkom, i te datoteke mogu ostati na automatiziranom putu. Šifrirani OOXML paketi idu drugim putem. HotXLS može napisati jedan pomoću SaveAsEncrypted, ali ga ne može pročitati natrag. OpenEncrypted podiže EXlsxEncryptionNotImplemented kada mu se preda šifrirani paket, zbog čega pošten dizajn unosa šalje šifrirani .xlsx osobi s Excelom, a u kodu zadržava .xls koji nosi lozinku.
Pitanja na koja poziv za izlistavanje ne može odgovoriti
Nazivi i redoslijed su sve što dobivate. Pozivi za izlistavanje ne govore ništa o vidljivosti, pa skriveni i vrlo skriveni (very-hidden) listovi stižu na popis izgledajući kao i svi drugi. Ne javljaju dimenzije korištenog raspona, broj ćelija niti svojstva dokumenta. Dio docProps/core.xml je također malen, ali danas ne postoji sonda samo za svojstva, tako da metapodaci o autoru i naslovu i dalje koštaju puni Open. Čist način života s tim jest dopustiti jeftinim činjenicama da usmjere svaku datoteku, a one skupe rezervirati za datoteke koje prežive usmjeravanje. Za datoteke koje idu u duboko čitanje, skeniranje velikog .xls-a samo za čitanje radi primjetno brže s _DisableGraphics := True, što preskače analizu OfficeArt-a. Samo nikada nemojte spremati iz te instance: sloj za crtanje koji je preskočen nestao je iz modela i spremanje bi ga izbacilo iz datoteke.
Datoteke koje prođu trijažu obično idu na dublju analizu. Uzorak revizije radne knjige i konverzijske radne tablice pokriva brojače po listu koje vrijedi prikupiti nakon što se opravda potpuno otvaranje, a vodič za performanse velikih radnih knjiga pokriva kako to potpuno otvaranje održati brzim.
HotXLS je nativna Object Pascal biblioteka za proračunske tablice za Delphi i C++Builder; cjelokupna API površina, uključujući ovdje prikazane pozive za inspekciju, dokumentirana je na stranici proizvoda HotXLS komponente.