Tehnični članak

Pisanje datotek XLSX po ISO 29500 Strict iz Delphija

HotXLS iz Delphija in C++Builderja piše delovne zvezke ISO/IEC 29500 Strict Open XML tako, da pred shranjevanjem nastavite eno samo lastnost, StrictOOXML. Vsak del paketa, od xl/workbook.xml do datotek razmerij in vrst vsebine, je zapisan s strogimi besednjaki purl.oclc.org namesto s prehodnimi schemas.openxmlformats.org, funkcije, ki jih Strict ne dovoljuje, pa so zavrnjene z izrecno izjemo, namesto da bi bile vseeno zapisane

Večina razvijalcev to zahtevo sreča prek nabavnega dokumenta. Javni razpisi v več državah zahtevajo ISO standardizirano obliko Open XML, ne prehodne oblike, ki jo Office privzeto zapiše, arhiv, ki predpisuje ISO 29500 Strict, pa bo zavrnil navaden .xlsx, tudi če ga Excel odpre povsem brez težav. Prehodni imenski prostori obstajajo zato, da omogočijo podedovano dvojiško vedenje; strogi imenski prostori pa so pravi standard

Kaj se dejansko razlikuje med Strict in Transitional?

Vidna razlika je besednjak. Strogi del delovnega zvezka kot svoj korenski imenski prostor deklarira http://purl.oclc.org/ooxml/spreadsheetml/main, za sklice na razmerja pa http://purl.oclc.org/ooxml/officeDocument/relationships, noben prehodni imenski prostor pa ne sme preživeti nikjer v paketu. Z njim se spremenijo tudi vrste razmerij, tako da korenski del razmerij poimenuje .../ooxml/officeDocument/relationships/officeDocument namesto znane ustreznice openxmlformats, vrsta razširjenih lastnosti pa je zapisana v camelCase kot extendedProperties

Nevidna razlika je obseg. Strict namerno izpusti dele prehodne sheme, ki so obstajali samo za brezizgubno pretvorbo podedovanih dvojiških datotek, skupaj s ponudnikovimi razširitvami, ki jih je Office dodal pozneje. Zato pretvorba ni iskanje in zamenjava nizov: nekatere funkcije preprosto nimajo strogega zapisa in jih sploh ne smemo zapisati

Vklop

Običajna koda za avtorstvo se ne spremeni. Delovni zvezek zgradite tako, kot vedno, nastavite zastavico in shranite:

var
  Wb: TXLSXWorkbook;
  Sh: TXLSXWorksheet;
begin
  Wb := TXLSXWorkbook.Create;
  try
    Sh := Wb.Sheets.Add('Data');
    Sh.Cells[1, 1].Value := 'Product';
    Sh.Cells[1, 2].Value := 'Amount';
    Sh.Cells[2, 1].Value := 'Widget';
    Sh.Cells[2, 2].Value := 17;
    Sh.Cells[3, 2].Formula := '=SUM(B2:B2)';

    Wb.StrictOOXML := True;          // izhod ISO/IEC 29500 Strict
    if Wb.SaveAs('archive-copy.xlsx') <> 1 then
      raise Exception.Create('strict save failed');
  finally
    Wb.Free;
  end;
end;

Zastavica se ponastavi na začetku vsake operacije shranjevanja in se znova dodeli iz lastnosti delovnega zvezka, tako da izjema med enim shranjevanjem ne more strogega načina prepustiti naslednjemu. Ta podrobnost je pomembna v strežniških procesih, kjer en sam objekt delovnega zvezka streže več zahtevam za izvoz

Zakaj lahko strogo shranjevanje zavrne izvedbo?

Štiri družine funkcij so razširitve Microsofta brez ustreznice v ISO 29500 Strict, HotXLS pa ob shranjevanju sproži izjemo, namesto da bi izdal paket, ki trdi, da je strogo skladen, pa ni:

// Strogi izhod ne more vdelati projekta VBA
//   -> delovne zvezke z makri shranite kot prehodni .xlsm
// Strogi izhod ne more nositi kontrolnikov obrazca
//   -> gumbov, potrditvenih polj, spustnih seznamov in njihovih ctrlProps
// Strogi izhod ne more nositi niti komentarjev
//   -> sodobnega modela persons/threads, ne klasičnih opomb
// Strogi izhod ne more nositi metapodatkov dinamičnih polj
//   -> razponov prelivanja, zapisanih prek dela metapodatkov

Glasen neuspeh je tu pravilna izbira. Tiho izpuščen projekt VBA delujoč delovni zvezek spremeni v pokvarjenega, ki se še vedno odpre, poročilo o napaki pa prispe od uporabnika šele tedne pozneje. Izjema poimenuje funkcijo in lastnost, ki jo je treba spremeniti, medtem ko klicna koda še vedno ve, kaj je izvažala. Ohranjanje makrov in zunanjih povezav na prehodni poti je opisano v ohranjanju projektov VBA in zunanjih povezav

Dve družini razširitev sta obravnavani drugače, in vredno je vedeti zakaj. Podatkovne vrstice, sparkline in podobne funkcije živijo v besednjakih x14 in xm, različice slik SVG pa v c15. To je vsebina seznama razširitev, katere imenski prostori so samoopisni, splošni razčlenjevalniki preglednic jih tolerirajo, in ne obstaja ustreznica ISO, v katero bi jih prevedli. HotXLS jih obdrži, namesto da bi uporabniško vsebino preprosto zavrgel. Če je validator v vašem cevovodu strog tudi glede razširitev in ne le glede imenskih prostorov, te funkcije pred izvozom odstranite iz izvornega delovnega zvezka

Prevod mora doseči dele, ki jih običajno nihče na novo ne piše

Zanimiv inženirski problem pri strogem izhodu ni XML delovnega lista. So deli, ki bi jih hiter pisalnik raje kopiral dobesedno. HotXLS ohranja teme, povezave, zunanje povezave, grafikone in pivotne bloke tako, da njihove izvirne stisnjene bajte neposredno prekopira, kar je natanko pravilno za zvestobo in natanko napačno za strogi izhod, ker kopirani bajti nosijo prehodne imenske prostore

Pod StrictOOXML se teh pet ohranjenih poti preklopi na ponovno gradnjo ali prevajalno ponovno predvajanje, mimo hitre poti kopiranja bajtov. Ves XML gre skozi eno samo prevajalno rutino, ki se zasidra na vrednosti atributov v dvojnih narekovajih, tako da niza, ki je videti kot URI znotraj celice, nikoli ni mogoče po pomoti prepisati. Besedilo celice, ki vsebuje isti URI, je v XML pobegnjeno kot entiteta, tako da ga zasidrana zamenjava ne more videti. Pretočni pisalnik najprej prevede svoj okostje in nato razdeli pri sheetData, saj bloki vrstic sploh ne vsebujejo URI-jev besednjaka. Sorodna mehanika za pot ohranjanja je opisana v brezizgubnih povratnih pretvorbah tem, seznamov razširitev in calcChain

Branje datotek, ki jih je Excel shranil kot stroge

Izhod je le polovica zgodbe. Excel kot možnost shranjevanja ponuja "Strict Open XML Spreadsheet", datoteke, ustvarjene na ta način, pa se morajo pravilno odpreti. HotXLS normalizira vrste razmerij na vsakem mestu razčlenjevanja razmerij v paketu — korenu, zunanjih povezavah, delovnih listih, risbah in vrtilnih tabelah — tako da se stroga vrsta razmerja ujema z isto interno konstanto kot njena prehodna ustreznica

Ustreznica na strani bralnika je normalizacija predpon imenskih prostorov, ki omogoča, da se poljubne predpone in oba besednjaka razrešita v eno kanonično tabelo imen. To delo koristi tako navadnim kot strogim datotekam, saj generatorji tretjih strani predpone vežejo poljubno, in gre za isto mehaniko, opisano v razreševanju razmerij OPC v paketih XLSX

Kratek kontrolni seznam, preden pošljete strogi izhod

Preverjajte s paketom, ne z Excelom. Excel obe obliki brez težav odpre, zato uspešno odpiranje ne dokazuje ničesar glede skladnosti. Razpakirajte rezultat in potrdite, da xl/workbook.xml deklarira imenski prostor purl, da noben del ne vsebuje schemas.openxmlformats.org/spreadsheetml in da vrste razmerij v _rels/.rels in xl/_rels/workbook.xml.rels uporabljajo stroge oblike

Nato datoteko znova odprite prek HotXLS in primerjajte vrednosti, formule, oblike in hiperpovezave z izvirnikom. Test ponovnega branja je edini poceni način, da dokažete, da prevod ni poškodoval vsebine, hkrati pa preizkusi tudi normalizacijo na strani bralnika. Če vaši delovni zvezki nosijo grafikone, preverite tudi te, saj je del grafikona eden od ohranjenih delov, ki v strogem načinu preklopi na na novo zgrajeno pot

Strogi izhod, tolerantno branje in brezizgubno ohranjanje so vsi del istega mehanizma OOXML za Delphi in C++Builder; celoten seznam funkcij je na strani komponente HotXLS Excel za Delphi