HotXLS rašo ISO/IEC 29500 Strict Open XML darbaknyges iš Delphi ir C++Builder nustatydama vieną savybę – StrictOOXML – prieš išsaugant. Kiekviena paketo dalis, nuo xl/workbook.xml iki ryšių failų ir turinio tipų, rašoma naudojant griežtus purl.oclc.org žodynus vietoj pereinamųjų schemas.openxmlformats.org žodynų, o funkcijos, kurių Strict standartas neleidžia, atmetamos su aiškia išimtimi, o ne vis tiek išrašomos
Dauguma kūrėjų su šiuo reikalavimu susiduria per pirkimų dokumentą. Viešojo sektoriaus konkursai keliose jurisdikcijose reikalauja ISO standartizuotos Open XML formos, o ne pereinamosios formos, kurią pagal nutylėjimą rašo Office, ir archyvas, reikalaujantis ISO 29500 Strict, atmes įprastą .xlsx failą, net jei Excel jį puikiai atidaro. Pereinamieji vardų sritys egzistuoja tam, kad būtų suderinamos su senosios dvejetainės elgsenos ypatumais; griežtosios yra pats standartas
Kas iš tikrųjų skiriasi tarp Strict ir Transitional?
Matomas skirtumas yra žodynas. Griežta darbaknygės dalis deklaruoja http://purl.oclc.org/ooxml/spreadsheetml/main kaip savo šaknies vardų sritį ir http://purl.oclc.org/ooxml/officeDocument/relationships ryšių nuorodoms, ir jokia pereinamoji vardų sritis negali išlikti niekur pakete. Kartu keičiasi ir ryšių tipai, todėl šaknies ryšių dalis vadinasi .../ooxml/officeDocument/relationships/officeDocument, o ne įprastu openxmlformats atitikmeniu, o išplėstinių savybių tipas rašomas camelCase forma kaip extendedProperties
Nematomas skirtumas yra apimtis. Strict sąmoningai praleidžia tas pereinamosios schemos dalis, kurios egzistavo vien tam, kad būtų galima grįžtamai konvertuoti senus dvejetainius failus, taip pat vėliau Office pridėtus pardavėjo plėtinius. Būtent todėl konversija nėra paprastas eilučių paieškos ir keitimo veiksmas: kai kurios funkcijos tiesiog neturi griežtos rašybos ir apskritai neturi būti rašomos
Kaip tai įjungti
Įprastas dokumento kūrimo kodas nesikeičia. Kurkite darbaknygę taip, kaip visada, nustatykite vėliavėlę ir išsaugokite:
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; // ISO/IEC 29500 Strict išvestis
if Wb.SaveAs('archive-copy.xlsx') <> 1 then
raise Exception.Create('strict save failed');
finally
Wb.Free;
end;
end;
Vėliavėlė atkuriama kiekvieno išsaugojimo operacijos pradžioje ir iš naujo priskiriama iš darbaknygės savybės, todėl išimtis vieno išsaugojimo metu negali „nutekėti“ griežto režimo į kitą išsaugojimą. Ši detalė svarbi serverio procesuose, kur vienas darbaknygės objektas aptarnauja kelis eksporto užklausas
Kodėl griežtas išsaugojimas gali atsisakyti vykti?
Keturios funkcijų šeimos yra Microsoft plėtiniai be ISO 29500 Strict atitikmens, ir HotXLS sukelia išimtį išsaugojimo metu, o ne generuoja paketą, kuris tvirtina atitinkantis griežtąjį standartą, nors iš tikrųjų neatitinka:
// Griežta išvestis negali įterpti VBA projekto
// -> įrašykite makrokomandas turinčias darbaknyges kaip pereinamąjį .xlsm
// Griežta išvestis negali nešti formos valdiklių
// -> mygtukai, žymimieji langeliai, išskleidžiamieji sąrašai ir jų ctrlProps
// Griežta išvestis negali nešti gijinių komentarų
// -> modernus asmenų/gijų modelis, ne klasikinės pastabos
// Griežta išvestis negali nešti dinaminių masyvų metaduomenų
// -> išsiliejimo (spill) diapazonai, įrašyti per metaduomenų dalį
Garsiai sužlugti čia yra teisingas sprendimas. Tyliai numestas VBA projektas paverčia veikiančią darbaknygę sugadinta, kuri vis tiek atsidaro, o pranešimas apie gedimą iš vartotojo atkeliauja po kelių savaičių. Išimtis įvardija funkciją ir savybę, kurią reikia pakeisti, kol kviečiantis kodas dar žino, ką jis eksportavo. Makrokomandų ir išorinių nuorodų išsaugojimas pereinamajame kelyje aprašytas straipsnyje VBA projektų ir išorinių nuorodų išsaugojimas
Dvi plėtinių šeimos apdorojamos kitaip, ir verta žinoti, kodėl. Duomenų juostos, mini grafikai (sparklines) ir panašios funkcijos gyvena x14 ir xm žodynuose, o SVG paveikslų variantai gyvena c15. Tai plėtinių sąrašo turinys, kurio vardų sritys yra savaime aprašomos, bendri skaičiuoklių analizatoriai jas toleruoja, ir nėra ISO atitikmens, į kurį jas būtų galima išversti. HotXLS jas palieka, o ne numeta vartotojo turinio. Jei jūsų konvejerio validatorius griežtas ne tik vardų sričių, bet ir plėtinių atžvilgiu, pašalinkite tas funkcijas iš šaltinio darbaknygės prieš eksportuodami
Vertimas turi pasiekti dalis, kurių niekas paprastai neperrašo
Įdomi inžinerinė problema griežtoje išvestyje yra ne darbalapio XML. Tai dalys, kurias greitas rašytuvas verčiau nukopijuotų pažodžiui. HotXLS išsaugo temas, ryšius, išorines nuorodas, diagramas ir suvestinių lentelių (pivot) blokus, tiesiog nukopijuodama jų originalius suspaustus baitus, ir tai yra tiksliai teisingas sprendimas tikslumui, bet tiksliai neteisingas griežtai išvesčiai, nes nukopijuoti baitai neša pereinamąsias vardų sritis
Įjungus StrictOOXML, šie penki išsaugomi keliai persijungia į perkūrimą arba verčiantį pakartojimą, apeidami greitąjį baitų kopijavimo kelią. Visas XML pereina per vieną vertimo procedūrą, kuri fiksuojasi ties dvigubomis kabutėmis apribotomis atributų reikšmėmis, todėl į URI panaši eilutė langelio viduje niekada negali būti perrašyta atsitiktinai. Langelio tekstas, turintis tą pačią URI, XML faile išreiškiamas kaip esybė (entity), todėl fiksuotas pakeitimas jos nepamato. Srautinis rašytuvas pirmiausia išverčia savo griaučius, o tada skaido ties sheetData, nes eilučių blokai apskritai neturi jokių žodyno URI. Susijusi išsaugojimo kelio mechanika aprašyta straipsnyje temos, plėtinių sąrašo ir calcChain be nuostolių grįžtamasis konvertavimas
Failų, kuriuos Excel išsaugojo kaip griežtus, skaitymas
Išvestis yra tik pusė istorijos. Excel siūlo „Strict Open XML Spreadsheet“ kaip išsaugojimo parinktį, ir taip sukurti failai turi atsidaryti teisingai. HotXLS normalizuoja ryšių tipus kiekvienoje ryšių analizės vietoje pakete – šaknyje, išorinėse nuorodose, darbalapiuose, piešiniuose ir suvestinių lentelėse – todėl griežtas ryšio tipas atitinka tą pačią vidinę konstantą kaip ir jo pereinamasis atitikmuo
Skaitymo pusės atitikmuo yra vardų sričių priešdėlių normalizavimas, kuris leidžia savavališkus priešdėlius ir abu žodynus susieti su viena kanonine pavadinimų lentele. Ši funkcija naudinga tiek įprastiems, tiek griežtiems failams, nes trečiųjų šalių generatoriai priešdėlius sieja laisvai, ir tai ta pati mechanika, aprašyta straipsnyje OPC ryšių sprendimas XLSX paketuose
Trumpas kontrolinis sąrašas prieš išleidžiant griežtą išvestį
Tikrinkite paketą, ne Excel. Excel abi formas atidaro be problemų, todėl sėkmingas atidarymas apie atitiktį nieko neįrodo. Išarchyvuokite rezultatą ir patikrinkite, ar xl/workbook.xml deklaruoja purl vardų sritį, ar jokioje dalyje nėra schemas.openxmlformats.org/spreadsheetml, ir ar ryšių tipai _rels/.rels bei xl/_rels/workbook.xml.rels failuose naudoja griežtąsias formas
Tada iš naujo atidarykite failą per HotXLS ir palyginkite reikšmes, formules, formatus ir hipersaitus su šaltiniu. Skaitymo atgal testas yra vienintelis pigus būdas įrodyti, kad vertimas nesugadino turinio, ir jis kartu patikrina skaitymo pusės normalizavimą. Jei jūsų darbaknygėse yra diagramų, patikrinkite ir jas, nes diagramos dalis yra viena iš išsaugomų dalių, kuri griežtame režime persijungia į perkurtą kelią
Griežta išvestis, tolerantiškas skaitymas ir be nuostolių išsaugojimas yra to paties OOXML variklio dalys Delphi ir C++Builder aplinkoms; pilnas funkcijų sąrašas pateikiamas HotXLS Delphi skaičiuoklės komponento puslapyje