Technical Article

HotXLS: Zaštita lista, podešavanje stranice i štampanje u Delphi-ju

Tri grupe podešavanja radnih listova nemaju nikakve veze sa vrednostima ćelija, već isključivo sa tim kako se datoteka ponaša kada napusti vaš kod. Zaštita lista (sheet protection) odlučuje koje ćelije korisnik može da menja nakon što mu predate radnu svesku. Podešavanje stranice (page setup) određuje orijentaciju, veličinu papira i margine. Podešavanja štampanja (ponovljeni redovi naslova, skaliranje i ručni prelomi stranica) kontrolišu kako mreža proizvoljne dužine sleće na papir. Nijedno od ova tri podešavanja se ne vidi kada samo posmatrate podatke u pregledaču, a sva tri tiho zakažu na terenu kada su pogrešno podešena. HotXLS, izvorna Delphi i C++Builder biblioteka za radne tabele, izlaže kompletnu površinu za .xls i .xlsx, što znači da takođe reprodukuje svako kontraproduktivno i nelogično Excel pravilo ugrađeno u tu površinu.

Prvo od tih pravila saplete skoro svakoga kada prvi put zaštite generisani list. Pozovete Protect i odjednom niko ne može da piše ni u jednu ćeliju, uključujući kolone za unos oko kojih ste i izgradili radnu svesku. Ništa u vašem kodu nije diralo te kolone, i to je upravo razlog zašto se to dešava.

Svaka ćelija se rađa zaključana

Standard ECMA-376 definiše locked kao deo zapisa o formatiranju ćelije, a ne kao svojstvo same zaštite, i njegova podrazumevana vrednost je true. Zaštita lista je samo prekidač koji omogućava primenu te zastavice. Dakle, cela mreža nosi zastavicu zaključavanja od trenutka kada postoji, u uspavanom stanju, a poziv metode Protect ih aktivira sve odjednom. Rešenje je da redosled postavite promišljeno: izgradite raspored, eksplicitno otključajte opsege koje korisnici moraju da menjaju, i na kraju primenite zaštitu.

Book := TXLSXWorkbook.Create;
try
  Sheet := Book.Sheets.Add('Timesheet');
  // ... header row, name column, and rate formulas written here ...
  Sheet.Range['B2:B50'].SetLocked(False);         // staff type hours here
  Sheet.Range['F2:F50'].SetFormulaHidden(True);   // keep the rate math private
  Sheet.Protect('review-2026');                   // now the lock flags bite
  Book.SaveAs('timesheet.xlsx');
finally
  Book.Free;
end;

Metoda SetFormulaHidden radi nešto posebno i lako se previdi: dok je zaštita aktivna, ćelija i dalje prikazuje svoju izračunatu vrednost, ali traka za formule ne prikazuje ništa. To je važno kada formula sadrži stope naplate, marže ili težine ocenjivanja koje radije ne biste predali svakom primaocu koji klikne na ukupnu vrednost. Na XLS fasadi ista namera se izražava po opsegu preko svojstava IXLSRange.Locked i FormulaHidden. Radni list tamo takođe nosi petnaest Allow* zastavica (AllowSort, AllowAutoFilter, AllowFormatCells i ostale), tako da se zaštićeni list i dalje može sortirati i filtrirati umesto da bude zamrznut u zapečaćeni eksponat.

Šta lozinka za zaštitu zapravo štiti

Oba formata čuvaju lozinku za zaštitu lista i radne sveske kao stari hash od 4 heksadecimalne cifre. Šesnaest bitova znači da se bezbroj stringova sudara sa bilo kojom datom lozinkom, a alati za uklanjanje lozinki su na samo jednu pretragu daleko. Tretirajte zaštitu kao sigurnosni pojas protiv slučajnih izmena, a ne kao kontrolu pristupa. To je pravi alat za sprečavanje korisnika da pišu preko kolone sa formulama, a pogrešan alat za bilo šta što uključuje reč poverljivo.

Jedan nivo iznad, ProtectWorkbook na XLSX fasadi zaključava strukturu radne sveske, što sprečava dodavanje, preimenovanje, brisanje ili promenu redosleda listova. Podesite to kad god je lista listova sama po sebi ugovor sa nizvodnim parserom koji indeksira listove po nazivu ili poziciji. Preimenovani list kvari uvoz na drugoj strani jednako sigurno kao što to čini obrisana kolona. XLS fasada preslikava ovo raslojavanje pomoću TXLSWorkbook.Protect na nivou radne sveske i pojedinačnih poziva Protect na nivou lista, uz svojstvo isProtected za kod koji treba da pregleda nasleđenu datoteku pre nego što bilo šta promeni.

Kada je zahtev stvarna poverljivost, mehanizam se u potpunosti menja. SaveAsEncrypted proizvodi paket šifrovan AES algoritmom u okviru ECMA-376 Standard Encryption šeme, što je detaljno pokriveno u vodiču za AES zaštićeni XLSX izlaz, a stara XLS fasada piše i čita RC4 šifrovane .xls datoteke preko svojstva EncryptionPassword i preopterećenja metode Open sa lozinkom. Razlika nije akademska. Zaštićeni list putuje u obliku običnog teksta (cleartext), pa svaki zip alat može čitati njegove vrednosti ćelija, dok je šifrovani paket nečitljiv bez lozinke. Revizorski zahtev koji kaže "platni spisak mora biti zaštićen" skoro uvek zapravo označava šifrovanje, bez obzira na rečnik koji se koristi.

Podešavanje stranice je deo ugovora o dokumentu

Ponašanje pri štampanju je nevidljivo na ekranu, zbog čega se tako često isporučuje neispravno. Onog trenutka kada kupac odštampa radnu svesku ili je izveze u PDF za revizora, margine, skaliranje i ponovljeni naslovi se pretvaraju u funkcionalne zahteve koje niko nije testirao. Na XLSX fasadi ova podešavanja vise direktno sa radnog lista:

Sheet.PageLandscape := True;
Sheet.PaperSize := xlsxPaperA4;
Sheet.SetPageMargins(0.5, 0.5, 0.75, 0.75, 0.3, 0.3);
Sheet.CenterHeader := 'Monthly Timesheet';
Sheet.RightFooter := 'Page &P of &N';
Sheet.PrintArea := '$A$1:$F$60';     // bare reference: no sheet name here
Sheet.PrintTitleRows := '$1:$1';     // header row repeats on every page
Sheet.FitToWidth := 1;
Sheet.FitToHeight := 0;              // grow downward as the data grows
Sheet.PrintGridlines := False;

Dve od tih linija kriju zamke. Stringovi zaglavlja i podnožja koriste Excel-ove kodove za formatiranje: &P za trenutnu stranicu, &N za ukupan broj, uz &L, &C i &R za eksplicitno adresiranje tri odeljka. Druga zamka je PrintArea, koja namerno prima čistu referencu ćelije. HotXLS je čuva nekvalifikovanu i dodeva naziv lista kao prefiks kada upisuje datoteku, tako da ako sami prosledite 'Timesheet!$A$1:$F$60', proizvodite dvostruko kvalifikovanu, neispravnu referencu. Isti oprez važi i jedan nivo niže: opsezi štampe (print areas) i naslovi štampe (print titles) se čuvaju kao ugrađena definisana imena _xlnm.Print_Area i _xlnm.Print_Titles, pa nikada nemojte ručno dodavati _xlnm.* unose preko kolekcije DefinedNames, inače će se ova dva mehanizma boriti oko istog slota.

Skaliranje koje preživljava produkcione količine podataka

Kombinacija FitToWidth := 1 sa FitToHeight := 0 tumači se kao "uvek prilagodi kolone na širinu jedne stranice, a zatim pusti na dole onoliko stranica koliko podaci zahtevaju", i to je ispravna podrazumevana postavka za svaki izveštaj gde broj redova varira. Zamka je u podešavanju fiksnog procenta ili para za uklapanje na jednu stranicu prema test datoteci od trideset redova: dajte ista podešavanja za šest stotina produkcionih redova i izlaz će se ili raspasti na desetine odsečenih stranica ili smanjiti ispod granice čitljivosti. Skalirajte širinu, pustite dužinu da raste i ponovite red zaglavlja preko PrintTitleRows kako bi sedamnaesta stranica i dalje bila čitljiva sama za sebe.

Ručni prelomi prate istu disciplinu regeneracije kao i sve ostalo u generisanoj radnoj svesci. Poziv AddRowBreak(BeforeRow) započinje novu stranicu pre granice odeljka, ali kada se generator ponovo pokrene i redovi se pomere, zastareli prelom sleće na sredinu tabele. Prvo pozovite ClearAllPageBreaks, a zatim ponovo dodajte prelome izračunate iz sopstvenih brojača redova generatora umesto da krpite stare pozicije. Na XLS fasadi ekvivalentne kontrole žive na Sheet.PageSetup (orijentacija, veličina papira, margine, stringovi zaglavlja i podnožja, uklapanje na stranice), dok RepeatRows i RepeatColumns pokrivaju naslove štampe.

Provera rezultata pre nego što to uradi klijent

Bagovi vezani za zaštitu i štampanje dele jedno svojstvo: trivijalni su za ručnu proveru, a skoro nikada se ne proveravaju. Otvorite generisanu datoteku u Excel-u i posvetite joj devedeset sekundi. Kucajte u ćeliju za unos i potvrdite da prihvata unos; kucajte u zaključanu ćeliju i potvrdite da se pojavljuje poruka o zaštiti; proverite da li skrivena formula ostavlja traku za formule praznom. Zatim pokrenite Print Preview (Pregled pre štampe) na skupu podataka produkcione veličine, a ne na uzorku od trideset redova, i pročitajte broj stranica, ponovljeni red naslova i numerisanje u podnožju. Pregled je korak koji se sam otplaćuje, jer geometrija štampe zavisi od podešavanja koja se ne renderuju na ekranu, i osim fizičkog štampača, to je jedino mesto gde greška u skaliranju uopšte postaje vidljiva.

Još jedno poslednje podešavanje zaokružuje pregled. FreezePane(ACol, ARow) drži blok zaglavlja u vidokrugu dok korisnik skroluje. To je ponašanje ekrana, a ne ponašanje štampe, ali korisnik ocenjuje ceo isporučeni dokument odjednom. A radna sveska koja započinje život kao raspored koji održava dizajner dobija većinu ovoga besplatno: tok rada za generisanje izveštaja na osnovu šablona čuva podešavanje stranice u samom šablonu, gde ga je čovek podesio prema stvarnom štampaču, i prepušta kodu da popuni podatke i ponovo primeni zaštitu kada se raspored stabilizuje.

HotXLS je izvorna Object Pascal biblioteka za radne tabele za Delphi i C++Builder; kompletna referenca API-ja za zaštitu i podešavanje stranice nalazi se na stranici proizvoda HotXLS komponente.