Joskus ainoa vastaanottorutiinin tarvitsema vastaus on rakenteellinen: onko tässä työkirjassa taulukko nimeltä "Mapping", tai kuinka monta välilehteä siinä on. Siihen vastaaminen Open-metodia kutsumalla on kallis tapa tehdä se. Täysi avaus paisuttaa jaettujen merkkijonojen taulukon, purkaa jokaisen tyylitietueen ja käy läpi jokaisen laskentataulukon solut, koska se ei voi tietää, että halusit vain sisällysluettelon. Suuressa tiedostossa tämä tarkoittaa satoja megatavuja varauksia ja useita sekunteja suoritinaikaa muutaman kilotavun kokoisen luettelon lukemiseen. HotXLS, losLabin natiivi Delphin laskentataulukkokirjasto, antaa tämän luettelon erikseen: GetSheetNames palauttaa laskentataulukoiden nimet työkirjan järjestyksessä muodostamatta yhtäkään solua
Miksi luettelo on halpa lukea
Molemmat laskentataulukkomuodot sijoittavat sisällysluettelonsa lähelle alkua, minkä ansiosta luettelointikutsu on nopea eikä vain nokkela. OOXML-paketti säilyttää taulukkoluettelon osassa xl/workbook.xml, joka pysyy pienenä riippumatta siitä, onko työkirjassa kymmenen vai kymmenen miljoonaa riviä. BIFF8 .xls tallentaa BoundSheet-tietueensa työkirjan globaalin tietovirran alkuun ennen solutietoja. Luettelointikutsun välttämä työ ei siis ole pyöristysvirhe verrattuna täyteen avaukseen. Se on suurin osa tiedostosta. Luettelon lukeminen maksaa saman kourallisen kilotavuja rivimäärästä riippumatta, kun taas täysi avaus skaalautuu datan mukana, ja monimegatavuisessa työkirjassa ero kasvaa useisiin kertaluokkiin sekä kosketetuissa tavuissa että varatussa muistissa
Tämä kiinteä kustannus on ominaisuus, jonka ympärille kannattaa suunnitella. GetSheetNames-metodille rakennettu vastaanottoportti käyttäytyy samoin 200 rivin ja 200 Mt:n tiedostolla, joten erän hitain tiedosto ei enää määrää tahtia päätettäessä, kannattaako tiedostoa edes käsitellä
Yksi kutsu .xls-, .xlsx- ja mallimuodoille
XLS-rajapinnassa TXLSWorkbook.GetSheetNames lukee muutakin kuin .xls-tiedostoja. Se hyväksyy myös zip-pohjaiset .xlsx-, .xlsm-, .xltx- ja .xltm-tiedostot ja poimii arkistosta vain workbook.xml-tiedoston. Aidolle .xls-syötteelle se lukee BoundSheet-tietueet ja pysähtyy globaalin alitietovirran ensimmäiseen EOF-tietueeseen, joten suuri binaaritiedosto maksaa edelleen vain alkuosan kilotavut. XLSX-rajapinnassa on takuu, joka merkitsee pitkäkestoiselle palvelukoodille enemmän kuin ensiksi näyttää: TXLSXWorkbook.GetSheetNames ei nollaa eikä täytä työkirjaesiintymää, joten jo avointa asiakirjaa pitävä esiintymä voi tutkia muita tiedostoja häiritsemättä käsillä olevaa. GetODSSheetNames soveltaa samaa lähestymistapaa OpenDocument-paketteihin, ja jokaisessa näistä kutsuista on tietovirtaylikuormitus, joten voit tarkistaa latauksen, joka ei koskaan päädy levylle
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;
Sama kutsu toimii hyvin työpöytäsovelluksen tuontivalintaikkunassa. Listaa taulukot, anna käyttäjän valita yksi ja maksa täydestä avauksesta vasta valinnan jälkeen. 50 taulukon työkirjassa ero näkyy: valitsin ilmestyy heti sen sijaan, että se pysähtyisi koko tiedoston latautuessa taustalla
Makroja sisältävät .xlsm-tiedostot ja mallimuodot luetteloituvat täsmälleen kuten tavallinen .xlsx, sillä luettelo on samassa workbook.xml-tiedostossa riippumatta siitä, kulkeeko paketissa mukana vbaProject.bin. Vastaanottoputki voi siksi luetella makrotyökirjan taulukot reititystä varten koskematta koskaan makrojen hyötykuormaan tai tekemättä mitään, mikä suorittaisi sen, ja jättää makrokäytännön päätöksen vaiheeseen, joka todella avaa tiedoston
Paluuarvon lukeminen harhauttamatta itseäsi
Palautuskäytännöt eivät ole HotXLS:ssä yhtenäisiä. Jotkin kutsut palauttavat onnistumisesta arvon 1, toiset määrän, joten luettelointifunktioissa ainoa kestävä tarkistus on käsitellä nolla tai sitä pienempi arvo epäonnistumisena ja tyhjentää merkkijonoluettelo. Vastusta kiusausta tulkita tyhjä luettelo "työkirjaksi ilman taulukoita". Sekä ECMA-376 että BIFF8-määrittely edellyttävät vähintään yhtä taulukkoa kelvollisessa työkirjassa, joten nolla nimeä tarkoittaa aina, että luku epäonnistui, ei koskaan sitä, että tiedosto olisi laillisesti tyhjä
Epäonnistunut luettelointi on itsessään säilyttämisen arvoinen signaali. .xlsx-tiedosto, jolle kutsu epäonnistuu, on jokin harvoista asioista: katkennut, ei todellisuudessa lainkaan OOXML-paketti (muista järjestelmistä väärin nimettyjä CSV-vientejä näkyy täällä jatkuvasti) tai salattu säilö. Niiden erottaminen toisistaan on seuraavan tarkistuksen tehtävä. Hylätyn tiedoston ensimmäisten tavujen kirjaaminen epäonnistumisen yhteyteen muuttaa tukiketjun yleensä yhdeksi viestiksi
Salattujen säilöjen tunnistaminen ennen reititystä
Salattu .xlsx ei ole zip. Se on OLE-yhdistelmätiedosto, joka käärii EncryptionInfo- ja EncryptedPackage-tietovirrat, joten GetSheetNames ei näe sen sisään ja palauttaa epäonnistumisen kuten minkä tahansa lukukelvottoman tiedoston kohdalla. CanReadEncrypted testaa tämän säilömuodon, jolloin vastaanotto voi reitittää salatun tiedoston tarkoituksellisesti sen sijaan, että se nielisi yleisen lukuvirheen jostain syvältä työntekijäprosessista:
type
TIntakeRoute = (irNormal, irNeedsPassword, irUnreadable);
function ClassifyUpload(const FileName: string; Names: TStrings): TIntakeRoute;
var
Book: TXLSXWorkbook;
begin
Book := TXLSXWorkbook.Create;
try
// Salattu OOXML on OLE-säiliö, ei zip: tarkista ensin,
// koska luettelointikutsut eivät voi katsoa sen sisään.
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;
Salaus on kohta, jossa HotXLS on tarkoituksella epäsymmetrinen, joten reitityksen on kunnioitettava sitä. Vanhaa .xls-salausta (RC4, RC4 CryptoAPI, XOR) voidaan lukea: TXLSWorkbook.Open(FileName, Password) purkaa salauksen tallennetulla salasanalla, ja nämä tiedostot voivat pysyä automatisoidulla polulla. Salatut OOXML-paketit toimivat toisin päin. HotXLS voi kirjoittaa sellaisen SaveAsEncrypted-metodilla, mutta se ei voi lukea sitä takaisin. OpenEncrypted nostaa EXlsxEncryptionNotImplemented-poikkeuksen, kun sille annetaan salattu paketti, minkä vuoksi rehellinen vastaanottosuunnittelu lähettää salatun .xlsx-tiedoston henkilölle, jolla on Excel, ja pitää salasanalla varustetun .xls-tiedoston koodissa
Erätyössä tämä luokittelija ansaitsee paikkansa suorittamalla sen koko saapuvalle hakemistolle ennen kuin yksikään työntekijä aloittaa varsinaisen käsittelyn, sillä jokainen tarkistus maksaa suunnilleen yhden tiedostoavauksen ja muutaman kilotavun lukuja. Sen tuominen alkuvaiheeseen muuttaa toimintojen kannalta merkityksellisen epäonnistumistilan. Sen sijaan, että klo 3 yöllä ajettava työ kuolisi tiedostoon 412/600, saat 412 tiedostoa jonoon ja 5 hylättyä vastaanotossa, jokaiselle syy liitettynä. Samat kirjastokutsut, paljon parempi operatiivinen tarina
Kysymykset, joihin luettelointikutsu ei voi vastata
Nimet ja järjestys ovat kaikki, mitä saat. Luettelointikutsut eivät kerro mitään näkyvyydestä, joten piilotetut ja erittäin piilotetut taulukot tulevat luetteloon kuin mitkä tahansa muutkin. Ne eivät ilmoita käytetyn alueen mittoja, solumääriä tai asiakirjan ominaisuuksia. docProps/core.xml-osa on myös pieni, mutta ominaisuuksille ei ole tänään vain-ominaisuudet-tarkistusta, joten tekijän ja otsikon metatiedot vaativat edelleen täyden Open-kutsun. Siisti tapa elää tämän kanssa on antaa halpojen faktojen reitittää jokainen tiedosto ja varata kalliit vain reitityksen läpäiseville tiedostoille. Syvälukuun eteneville tiedostoille suuren .xls-tiedoston vain luku -skannaus toimii huomattavasti nopeammin, kun käytössä on _DisableGraphics := True, joka ohittaa OfficeArt-jäsennyksen. Älä vain koskaan tallenna tästä esiintymästä: sen ohittama piirrostaso puuttuu mallista, ja tallennus pudottaisi sen tiedostosta
Triagen läpäisseet tiedostot etenevät yleensä syvempään analyysiin. työkirjan auditointi- ja muunnostyöpöytä käsittelee taulukkokohtaisia laskureita, jotka kannattaa kerätä, kun täysi avaus on perusteltu, ja suurten työkirjojen suorituskykyopas käsittelee tämän täyden avauksen pitämistä nopeana
HotXLS on Delphin ja C++Builderin natiivi Object Pascal -laskentataulukkokirjasto; täydellinen API-rajapinta, mukaan lukien tässä esitetyt tarkistuskutsut, on dokumentoitu HotXLS Delphi Component -tuotesivulla