Patikimas budas generuoti stilizuota Excel ataskaitą is Delphi yra pradeti nuo darbaknyges, kuria dizaineris jau sukure. Finansu komandos narys sudaro saskaita faktura Excel: logo, stulpeliu antraštes, apvedima detaliu juostoje, paryskinta sumos eilute, valiutos formatus. Jusu kodas atidaro ta faila, iraso gyvus duomenis i lasteles, kurias dizaineris rezervavo jiems, ir issaugo rezultata. Isvaizdą valdo jie; skaiciai priklauso jums. HotXLS, gimtoji Delphi ir C++Builder biblioteka, skaitanti ir rasanti XLS ir XLSX darbaknygias be Excel vairavimo, suteikia jums tris operacijas, kuru siuo metodu reikia: ieškoti lasteles pagal jos teksta, kopijuoti diapazona su stiliais ir formulemis nepaliesta ir istatyti eilutes, kad viskas zemiau slinktu zyn su duomenimis.
Viena taisykle, skirianti generatoriu, kuris isgyvena sabalo redagavimus, nuo to, kuris luzsta pirmame, yra niekada nesisakyti lasteleiu absoliuciais eilutes ir stulpelio numeriais. Sabalonas yra dokumentas, kuri kiti zmones redaguoja. Finansu komanda prideda mokesciu eilute, padidina logo eilutes auksti, pertvarko adreso bloka, ir failo formatas niekaip jums nepadeda: BIFF ar OOXML issaugojimas seka nesvarbu, ar eilute 10 vis dar reiskia tai, ka reiske praejusiam ketvirciui. Generatorius, rašantis pirma detaliu eilutę i sunkoduota 10 eilute, pirmą karta, kai kas nors ideda bloka virs detaliu sekcijos, antspauduos eiluciu elementus per neteisingas lasteles ir susumuos bendra suma diapazona, kuris daugiau neapima duomenu. Niekas nemete, kiekvienas issaugojimas grazina sekme, o vienintelis signalas yra klientas, pastebintis neteisingą sąskaitą.
Inkaruokite kiekvieną koordinatę prie vietovardžio žetonų
Sprendimas yra priversti sablona nesioti savo koordinates. Dizaineris iraso zzetonus, kaip antai {{CUSTOMER}}, {{DATE}} ir {{DETAIL_START}}, i lasteles, kurias generatorius turi paliesci, o generatorius apskaiciuoja kiekvieną pozicijà vykdymo metu is to, kur randa tuos zetónus. Isdestymo redavimai daugiau nesvarbu, nes zetonas juda kartu su lastele, kurioje sedi. Antroji sutarties dalis yra nesekmes taisykle: jei truksta reikalingo zetono, uzduotis sustoja pries bet kokie kliento duomenys pasiekia faila. Sabalonas, kuris nuklydo, turetu sukelti nepasisekusio darbo bilietą, o ne pristatyta dokumentą.
Zetonu radimas: FindText ir ReplaceText
Abi HotXLS klasiu seimos atskleidzia darbalakio lygio paiešką. FindText grazina pirmosios lasteles, kurios tekstas atitinka, eilutę ir stulpeli, su perkrovimu, pridedanciu didžiuju raidziu jautrumą. ReplaceText pakeicia kiekvieną pasikartojimą ir grazina, kiek ji pakeitė. Kedu apiparescioja dvieju rusiuoti zetonu, kuriuos linkstate tureti. Viena inkarą, kaip kliento pavadinimas, randates vieną karta ir rašote šalia; zetoną, kuri turetu pasirodyti tiksliai vieną kartą, kaip ataskaitos data, pakeiste ir patikrinate skaiciu. XLSX puseje uzpildymas, kuris inkaro save siuo budu, atrodo taip:
var
Book: TXLSXWorkbook;
Sheet: TXLSXWorksheet;
R, C: Integer;
begin
Book := TXLSXWorkbook.Create;
try
if Book.Open('invoice-template.xlsx') <> 1 then
raise Exception.Create('Cannot open invoice template');
Sheet := Book.Sheets[0]; // TXLSXSheets.Items is 0-based
if not Sheet.FindText('{{CUSTOMER}}', R, C) then
raise Exception.Create('Template drift: {{CUSTOMER}} anchor missing');
Sheet.Cells[R, C].Value := 'ACME Corp';
if Sheet.ReplaceText('{{DATE}}',
FormatDateTime('yyyy-mm-dd', Date)) = 0 then
raise Exception.Create('Template drift: {{DATE}} token missing');
// detail expansion and save follow below
finally
Book.Free;
end;
end;
Dvi detalės svarbios. Pirma, FindText ir ReplaceText atitinka lasteles teksto reiksmen; zetonas, idetas formuliu eiluteje, jiems yra nematomas, todel vietovardžio zetonai priklauso paprastoms lastelems, niekada formuliu viduje. Antra, pakeitimo skaicius yra jūsų nukrypimo detektorius. Sabalonas, kuri turetu tureti tiksliai viena {{DATE}} zetoną, bet praneša nulius pakeitimų, buvo redaguotas, ir iškėlimas išimties tuo momentu yra tiksliai tai, kas tylų isdestymo nukrypimą pavercia matoma nesekme.
Detaliu eilutes klonavimas neprarandant stiliu ar formuliu
Sąskaitos faktūros detaliu sekcija auga su duomenimis. Rašant reiksmes tiesiai i tuscias eilutes zemiau imties eilutes atmetama visa, ka dizaineris parenge: rėmeliai, skaiciaus formatai, kiekvienai eilutei skirtos formulės. Modelis, kuris visa tai issaugo, yra palikti viena pilnai stilizuota imties eilute sablone ir ja klonuoti kiekvienam elementui. CopyRange dubliuoja stilius ir formules vienu kvietimu, po kurio generatorius perrašo tik reiksmes lasteles.
const
DetailRow = 10; // the formatted sample row in the template
var
I: Integer;
begin
// Open space before the totals block first, so the SUM range
// below the detail band stretches together with the data.
if Length(Items) > 1 then
Sheet.InsertRows(DetailRow + 1, Length(Items) - 1);
for I := 0 to High(Items) do
begin
if I > 0 then // clone styles + formulas from the sample row
Sheet.CopyRange(DetailRow, 1, DetailRow, 5, DetailRow + I, 1);
Sheet.Cells[DetailRow + I, 1].Value := Items[I].Name;
Sheet.Cells[DetailRow + I, 2].Value := Items[I].Qty;
Sheet.Cells[DetailRow + I, 3].Value := Items[I].UnitPrice;
Sheet.Cells[DetailRow + I, 4].Formula :=
Format('B%d*C%d', [DetailRow + I, DetailRow + I]); // no '=' prefix
end;
end;
Atidžiai stebėkite formuliu priskyrimą. XLSX savybė Formula ima israiška be pirmaujancio lygybės ženklo, o XLS fasadas tikisi '=B10*C10' priskirto per Value. Dvieju konvencijų maišymas yra dažniausia perkeliamoji klaida tarp klasiu šeimų, ir ji nepasiseka be pretenzijų: lastele tik laiko literalinę eilutę, kurią Excel rodo kaip tekstą. Jei sabalonas papuošia detaliu juostą sujungtomis pavadinimo eilutėmis, atsiminkite, kad tik virsutine-kairioji sujungto ploto lastele neša reiksmen. Isdestymo taisykles draugo straipsnyje apie sujungtas lasteles isdestymo ataskaitu sablonuose paaiškina, kodel sujungimo regionai priklauso visiškai uz duomenu juostos.
Ką InsertRows perstumia ir ką palieka
Eiluciu istatymas pries bendra sumos bloka yra tai, kas laiko SUM diapazoną driekiantis, kai detaliu sekcija auga. XLSX puseje InsertRows neša ilga priklausomu strukturu sarašą zemyn su lastelėmis: sujungti regionai, eiluciu aukšciai, hipernuorodos, komentarai, sustingdytos juostos, automatinio filtro diapazonai, salyginiai formatai, duomenu patvirtinimai, lentelės, apibrėžti pavadinimai ir vaizdu bei diagramu inkarai. Tame sarašė yra viena riba, verta išsaugoti atmintyje. Formuliu perrašymas siekia tik nuorodas tame pačiame lape. Formulė suvestiniame lape, nurodanti i perkelto regiono, laiko senas koordinates ir tykiai skaito neteisingas lasteles, todel sumos, traukiamos per lapus, saugiau isreiškiamos per darbaknyges lygio pavadinimus. Draugo straipsnis apie apibrėžtus pavadinimus ir kryžminiu lapu formules išnagrineja ta modelį.
Sensas XLS formatas brėžia ribą kietesne vieta. HotXLS laiko suvestines lenteles, uzklausų lenteles ir išorines duomenu jungtis BIFF failuose kaip neapdorotus baitu blokus. Jie išgyvena atidarymo ir issaugojimo ciklus nepakitę, taciau jie nėra modeliuojami, todel eiluciu istatymas jų niekada neliecia. Sabalonas, kuris parkuoja suvestinę lentelę žemiau besiplečiancios detaliu juostos, issaugoma be jokiu perspėjimu, kol suvestinės šaltinio staciakanpis nuslysta nuo duomenu. Išeitis yra struktūrinė, o ne gynybinė: laikykite suvestines ir užklausų turinį lapuose, i kuriuos generatorius niekada neideda eiluciu, ir pasenimas negali atsitikti.
Perskaiciuokite pries pristatymą arba žinokite, kodel praleiste
HotXLS neivykdo formuliu per SaveAs. Kai zmogus atidaro faila, Excel perskaiciuoja viska (XLS fasadas atskleidzia CalculationMode ir RecalcOnSave, jei reikia tai valdyti), todel ataskaitai, einanciaj i zmogaus gautuves, nieko daugiau nereikia. Vaizdas keiciasi akimirka, kai darbaknyge maitina kitą programą. CSV eksportas rašo formules kaip jų literalinį tekstą ir niekada jų neskaiciuoja, ir bet koks tolimesnis analizatorius, pasitikintis talpykloje esanciomis reiksmemis, skaitys pasenusius skaičius arba tuscias vietas. Toms takoms apskaiciuokite serveryje su Calculate, kuris įvertina sąlyginę israeliška pries ikrauta darbaknygę ir grazina rezultatą:
var
Total: Variant;
LastDetail: Integer;
begin
LastDetail := DetailRow + Length(Items) - 1;
Total := Book.Calculate(Format('SUM(Invoice!D%d:D%d)',
[DetailRow, LastDetail]));
if (not VarIsNumeric(Total)) or
(Abs(Total - ExpectedTotal) > 0.005) then
raise Exception.Create('Invoice total does not match the order record');
if Book.SaveAs('invoice-2026-0611.xlsx') <> 1 then
raise Exception.Create('Save failed: check output path and permissions');
end;
Tikrinant apskaiciuotą sumą su uzsakymo irasą pries issaugojimą yra pigi draudimas su geru atsilyginimu. Ji pavercia neteisinga saskaita nepasisekusia uzduotimi. Operatorius gali kartoti nepasisekusią uzduotį per kelias sekundes; neteisinga sąskaita, jau kliento gautuves, kainuoja paskyros vadovui atsiprašymą ir pataisymą.
Dvi klasiu seimos, vienas algoritmas
Ta pati logika perkeliama tarp formatu, taciau ne tas pats kodas. TXLSWorkbook sensajam .xls yra sasaja pagrindu ir nuorodomis skaiciuojamas, su 1-pagrindstu lapų indeksavimu, ir jūs jo niekada neatlaisvinate ranka. TXLSXWorkbook .xlsx yra paprastas objektas, kuri turite atlaisvinti try..finally, su 0-pagrindstu lapų indeksavimu ir formulių konvencija, parodyta aukšciaus. FindText, ReplaceText, CopyRange ir InsertRows gyvena abiejose pusėse, todel inkaro-klono-perskaiciavimo forma perkeliama švari. Praktinis patarimas yra prisiristi prie vieno formato vienam konvejeriui arba slėpti du objektu gyvenimo ciklus uz plono savo adapterio, o ne išskleisti skirtumą per generatorių.
Dydis retai svarbus to tipo ataskaitoms, kurias šis modelis generuoja. Stilizuotos eilutes klonavimas keleta tukstanciu kartu yra nieko šiuolaikinei aparatinei irangai. Issaugojimo kelias tampa butelio kakleliu tik tada, kai detaliu juosta siekia šeštą skaitmenį eiluciu, ir tame taske nustačius StreamingWrite siuncia darbalakio XML tiesiai i isvesties paketą vietoj buferiavimo; srauto rašymo serverio paketo darbams straipsnis apima, kada ta mainai verta. Diagramos elgiasi kaip likęs isdestymas: XLSX puseje tiek diagramos inkaro, tiek jo serijos nuorodos juda, kai InsertRows veikia auksciau ju, todel diagrama po bendre sumos eilutę lieka susijusi su teisingais duomenimis, o XLS puseje diagramos sedi savo diagramų lapuose ir, kaip suvestines lentelės, niekada nesislinksta. Tai yra dar vienas argumentas laikyti pristatyme lapus laisvus nuo lapo, kuri generatorius plecia.
Šis inkaro-klono-perskaiciavimo metodas leidžia dizaineriui valdyti, kaip darbaknyge atrodo, o jūsų kodas valdo, ką ji sako, kas paprastai yra tai, kas daro generuotą Excel isvestį verta prižiūrėti. Paieškos, kopijuoti ir istatymo kviecimai, parodyti cia, kartu su formuliu varikliu, naudotu pristatymo sumos patikrinimui, pristato su HotXLS Component Delphi ir C++Builder.