Ðа пÑедположим, Ñе ноÑна Delphi ÑÑлÑга генеÑиÑа по един XLSX Ñайл за вÑеки ÐºÐ»Ð¸ÐµÐ½Ñ - обÑо нÑколкоÑÑоÑин Ñайла, нÑкои Ð¾Ñ ÐºÐ¾Ð¸Ñо Ñ ÑиÑина 400 000 Ñеда. ÐÑоÑилиÑайÑе Ñ Ð¸ изненадаÑа ÑÑдко Ñе бÑде ÑикÑлÑÑ Ð·Ð° попÑлване на клеÑкиÑе. Ð¢Ñ Ñе кÑие в извикванеÑо на SaveAs. ÐÑи пиÑаÑÐµÐ»Ñ Ð¿Ð¾ подÑазбиÑане вÑеки ÑабоÑен лиÑÑ Ñе ÑеÑиализиÑа в един-единÑÑвен XML низ в памеÑÑа, пÑеди Ñози низ да бÑде компÑеÑиÑан в OOXML zip аÑÑ
ива, каÑо пÑи ÑиÑок лиÑÑ Ð¿ÑеÑ
одниÑÑ Ð½Ð¸Ð· може да напÑави модела на клеÑкиÑе, Ð¾Ñ ÐºÐ¾Ð¹Ñо е изгÑаден, да изглежда незнаÑиÑелен. Така задаÑа, коÑÑо комÑоÑÑно изгÑажда ÑвоиÑе данни и заема 800 MB, Ñе ÑкоÑи над лимиÑа на конÑейнеÑа Ð¾Ñ 2 GB по вÑеме на запиÑа, и OOM killer (пÑоÑеÑÑÑ Ð·Ð° ÑпÑавление на памеÑÑа пÑи недоÑÑиг) Ñе оÑÑеÑе ÑÑива в 03:00 ÑаÑа пÑез ноÑÑа, когаÑо никой не гледа. HotXLS, оÑигиналнаÑа библиоÑека за елекÑÑонни ÑаблиÑи на losLab за Delphi и C++Builder, има ÑвойÑÑво, наÑоÑено диÑекÑно кÑм Ñози пик: StreamingWrite. Ðколо него ÑÑоÑÑ Ð¾Ñе два лоÑÑа, коиÑо ÑеÑÐ°Ð²Ð°Ñ Ð´Ð°Ð»Ð¸ изпÑлниÑелÑÑ Ð½Ð° пакеÑни задаÑи Ñе Ñе вмеÑÑи в бÑджеÑа Ñи за Ð¿Ð°Ð¼ÐµÑ Ð¸ вÑеме, а именно обÑаÑниÑе Ð¸Ð·Ð²Ð¸ÐºÐ²Ð°Ð½Ð¸Ñ Ð½Ð° ниво Ñед пÑи Ð·Ð°Ð¿Ð¸Ñ Ð¸ наÑинÑÑ, по койÑо Ñе дÑÑжи пÑлÑÑ Ð¾Ñ ÑÑилове вÑÑÑе в ÑеÑен ÑикÑл.
Ðакво бÑÑеÑиÑа пÑÑÑÑ Ð·Ð° Ð·Ð°Ð¿Ð¸Ñ Ð¿Ð¾ подÑазбиÑане и какво пÑÐ¾Ð¼ÐµÐ½Ñ StreamingWrite
ÐиÑаÑелÑÑ Ð½Ð° XLSX по подÑазбиÑане залага на пÑоÑÑоÑаÑа. Той ÑендиÑа XML на ÑабоÑÐ½Ð¸Ñ Ð»Ð¸ÑÑ Ð½Ð°Ð¿Ñлно, Ñлед коеÑо пÑедава гоÑÐ¾Ð²Ð¸Ñ Ð½Ð¸Ð· на zip компÑеÑоÑа. Това е пÑавилен компÑÐ¾Ð¼Ð¸Ñ Ð·Ð° по-голÑмаÑа ÑаÑÑ Ð¾Ñ ÑабоÑниÑе книги, кÑдеÑо XML на ÑÐµÐ»Ð¸Ñ Ð»Ð¸ÑÑ Ñе побиÑа в нÑколко мегабайÑа. Това ÑпиÑа да бÑде пÑавилно, когаÑо ÑеÑиализиÑанаÑа ÑоÑма на един лиÑÑ Ð´Ð¾ÑÑигне ÑÑоÑиÑи мегабайÑи. XML на елекÑÑонниÑе ÑаблиÑи е подÑобен: вÑÑка ÑиÑлова клеÑка ÑÑÑÑва деÑеÑки Ñимволи маÑкиÑане, а низÑÑ, ÑÑдÑÑÐ¶Ð°Ñ Ð²ÑиÑко Ñова, ÑÑÑбва да бÑде непÑекÑÑнаÑ. Ðа гÑаÑикаÑа на памеÑÑа Ñози поÑеÑк е ÑÑÑден за пÑопÑÑкане. ÐÑлго плоÑко плаÑо, докаÑо ÑедовеÑе Ñе попÑлваÑ, Ñлед Ñова оÑÑÑÑ ÑÑиÑгÑлен пик по вÑеме на SaveAs и ÑÑив Ñлед изÑиÑÑване на zip аÑÑ
ива.
ÐадаванеÑо на Book.StreamingWrite := True пÑевклÑÑва SaveAs кÑм пиÑаÑел на ÑабоÑни лиÑÑове, койÑо излÑÑва XML на лиÑÑа диÑекÑно в zip поÑока, докаÑо Ñе генеÑиÑа. ÐеждинниÑÑ Ð½Ð¸Ð· никогда не Ñе заделÑ, а ÑÑиÑгÑлниÑÑ Ð¿Ð¸Ðº Ñе Ñвива до Ñонов ÑÑм.
ÐÑдеÑе ÑоÑни оÑноÑно Ñова какво вÑÑÑноÑÑ Ð²Ð¸ ноÑи Ñова, ÑÑй каÑо пÑеÑвелиÑаванеÑо Ð¼Ñ Ð²Ð¾Ð´Ð¸ до гÑеÑни планове за капаÑиÑеÑ. ФлагÑÑ Ð¿ÑÐ¾Ð¼ÐµÐ½Ñ Ñамо пÑÑÑ Ð·Ð° запиÑ. ÐзгÑажданеÑо на ÑабоÑнаÑа книга вÑе оÑе Ð·Ð°Ð´ÐµÐ»Ñ Ð¿ÑÐ»Ð½Ð¸Ñ Ð¼Ð¾Ð´ÐµÐ» на клеÑкиÑе в памеÑÑа, Ñака Ñе плаÑоÑо по вÑеме на ÑазаÑа на попÑлване е ÑоÑно Ñолкова виÑоко, колкоÑо и пÑеди. Това, коеÑо изÑезва, е пикÑÑ Ð½Ð° ÑеÑиализаÑиÑÑа, койÑо Ñе наÑÑÑпваÑе вÑÑÑ
Ñ Ñова плаÑо пÑи запиÑване, а пÑи задаÑа, попÑлваÑа 400 000 Ñеда, Ñози пик обикновено е ÑÑлаÑа Ñазлика Ð¼ÐµÐ¶Ð´Ñ Ñова да Ñе вмеÑÑиÑе в бÑджеÑа за Ð¿Ð°Ð¼ÐµÑ Ð¸Ð»Ð¸ да го пÑевиÑиÑе. СвойÑÑвоÑо е False по подÑазбиÑане, за да запази иÑÑоÑиÑеÑкоÑо поведение, Ñака Ñе вклÑÑванеÑо Ð¼Ñ Ðµ един изÑиÑен Ñед, койÑо пиÑеÑе ÑмиÑлено.
ÐаÑов екÑпоÑÑ Ñ Ð°ÐºÑивиÑан Ñлаг
Book := TXLSXWorkbook.Create;
try
BoldIdx := Book.Fonts.Add('Calibri', 11, True, False); // pool index, 0-based
Sheet := Book.Sheets.Add('Bulk');
for R := 1 to 100000 do
begin
Sheet.Cells[R, 1].Value := R;
Sheet.Cells[R, 2].Value := 'Row ' + IntToStr(R);
Sheet.Cells[R, 3].Value := R * 1.5;
if (R mod 1000) = 0 then
Sheet.Cells[R, 2].FontIndex := BoldIdx + 1; // 1-based at the cell
end;
Book.StreamingWrite := True; // stream sheet XML straight into the zip
Book.SaveAs('bulk.xlsx');
finally
Book.Free;
end;
Cells[R, C] ÑÑздава клеÑки пÑи поиÑкване, коеÑо запазва ÑÑлоÑо на ÑикÑла ÑиÑÑо. Ðве гÑаниÑи на мÑежаÑа Ñи ÑÑÑÑва да Ñе запомнÑÑ: 1 048 576 Ñеда и 16 384 колони, изложени каÑо XlsxMaxRow и XlsxMaxCol. ÐоÑок Ð¾Ñ Ð´Ð°Ð½Ð½Ð¸, койÑо надÑ
вÑÑÐ»Ñ Ð»Ð¸Ð¼Ð¸Ñа на ÑедовеÑе, ÑÑÑбва да бÑде Ñазделен Ð¼ÐµÐ¶Ð´Ñ Ð»Ð¸ÑÑове вÑв ваÑÐ¸Ñ ÑобÑÑвен код. ÐиÑо по веÑигаÑа не забелÑзва пÑевиÑаванеÑо или не го коÑигиÑа вмеÑÑо ваÑ, а ÑайлÑÑ Ð¿ÑоÑÑо Ñе оказва оÑÑÑзан на лимиÑа.
ÐопÑлване на Ñедове без допÑлниÑелно наÑоваÑване Ð¾Ñ Variant за вÑÑка клеÑка
ÐÑÑко пÑиÑвоÑване на Cells[R, C].Value заплаÑа ÑенаÑа за ÑÑÑÑене на клеÑка и Variant конвеÑÑиÑане. ÐÑи деÑÐµÑ Ñ
илÑди Ñеда никой не забелÑзва. ÐÑи милион Ñеда Ñ Ð¿Ð¾ двадеÑÐµÑ ÐºÐ¾Ð»Ð¾Ð½Ð¸ вÑеки, Ñова допÑлниÑелно наÑоваÑване пÑи вÑÑко извикване ÑÑава доминиÑаÑиÑÑ ÑазÑ
од за ÑазаÑа на попÑлване, и пÑоÑилиÑаÑиÑÑ Ð¸Ð½ÑÑÑÑÐ¼ÐµÐ½Ñ Ñе поÑоÑи диÑекÑно него. ÐакеÑниÑе инÑеÑÑейÑи ви позволÑÐ²Ð°Ñ Ð²Ð¼ÐµÑÑо Ñова да подаваÑе на пиÑаÑÐµÐ»Ñ ÑÑл Ñед наведнÑж. WriteRows задвижва обÑаÑна ÑÑнкÑиÑ, коÑÑо пÑедоÑÑÐ°Ð²Ñ Ð¿Ð¾ един Ñед на извикване:
procedure TBulkExporter.FillRow(Sender: TObject; SheetIndex, Row, FirstCol,
LastCol: Integer; var Values: Variant; var Skip: Boolean;
var Cancel: Boolean);
begin
if not FReader.Next then
begin
Cancel := True; // data source drained: stop cleanly
Exit;
end;
Values := VarArrayCreate([FirstCol, LastCol], varVariant);
Values[FirstCol] := FReader.RecordId;
Values[FirstCol + 1] := FReader.CustomerName;
Values[FirstCol + 2] := FReader.Amount;
end;
// fill rows 2..100001, columns A..C, pulling from the reader
Sheet.WriteRows(2, 1, 100001, 3, FillRow);
ФлагÑÑ Cancel е Ñова, коеÑо пÑевÑÑÑа ÑикÑиÑÐ°Ð½Ð¸Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½ Ð¾Ñ Ñедове в "до N Ñеда", коеÑо е еÑÑеÑÑвенаÑа ÑоÑма, когаÑо бÑоÑÑ Ð½Ð° ÑедовеÑе идва Ð¾Ñ Ð·Ð°Ñвка, коÑÑо не ÑÑе пÑиклÑÑили да изпÑлнÑваÑе. Skip е по-лекиÑÑ Ð²Ð°ÑианÑ: Ñой оÑÑÐ°Ð²Ñ Ð¾Ñделен Ñед пÑазен без пÑекÑÑване на изпÑлнениеÑо. ÐÑвен попÑлванеÑо на клеÑкиÑе, обÑаÑнаÑа ÑÑнкÑÐ¸Ñ Ñе оказва подÑ
одÑÑа за опеÑаÑивниÑе вÑпÑоÑи, коиÑо инаÑе Ñе добавÑÑ ÐºÑм ÑикÑла за попÑлване по неÑдобен наÑин. ÐÑоÑÑ Ð½Ð° напÑедÑка, койÑо оÑÑиÑа на вÑеки Ñ
илÑда Ñеда, Ñокен за оÑмÑна Ð¾Ñ Ð¿Ð»Ð°Ð½Ð¸ÑовÑика на задаÑи, огÑаниÑиÑел на ÑкоÑоÑÑÑа на ÑеÑене Ð¾Ñ Ð±Ð°Ð·Ð°Ñа данни-изÑоÑник: вÑиÑко Ñова живее на едно мÑÑÑо, вмеÑÑо да бÑде вплеÑено в кода за запиÑване на клеÑки. ÐÑ ÑÑÑанаÑа на ÑеÑенеÑо, ForEachRow и ForEachCell оÑÑазÑÐ²Ð°Ñ ÑÑÑÐ¸Ñ Ð¼Ð¾Ð´ÐµÐ», коеÑо е важно, когаÑо пакеÑнаÑа задаÑа какÑо конÑÑмиÑа, Ñака и пÑоизвежда големи Ñайлове.
ÐÑловеÑе Ð¾Ñ ÑÑилове вÑзнагÑÐ°Ð¶Ð´Ð°Ð²Ð°Ñ Ð¸Ð·Ð½Ð°ÑÑнеÑо нагоÑе
ÐоделÑÑ Ð·Ð° ÑÑилизиÑане на XLSX е Ð½Ð°Ð±Ð¾Ñ Ð¾Ñ Ñподелени пÑлове. Fonts.Add, Fills.AddSolid, и Borders.Add вÑÑÑÐ°Ñ 0-базиÑан Ð¸Ð½Ð´ÐµÐºÑ Ð½Ð° пÑл, а клеÑкаÑа ÑеÑеÑиÑа кÑм ÑÑиÑÑ, каÑо ÑÑÑ
ÑанÑва Ñози Ð¸Ð½Ð´ÐµÐºÑ Ð¿Ð»ÑÑ ÐµÐ´Ð½Ð¾ в FontIndex, кÑдеÑо нÑлаÑа е запазена за ÑÑиÑÑа по подÑазбиÑане. УвелиÑениеÑо Ñ +1 е показано в пÑимеÑа за маÑово генеÑиÑане по-гоÑе. ÐабÑавеÑе го и клеÑкаÑа ÑиÑ
о Ñе пÑиеме гÑеÑÐ½Ð¸Ñ ÑÑил, ÑÑй каÑо оÑмеÑÑванеÑо Ñ ÐµÐ´Ð½Ð¾ в индекÑа на пÑла Ð¾Ñ ÑÑилове вÑе оÑе е валиден Ð¸Ð½Ð´ÐµÐºÑ Ð¸ ниÑо не пÑедизвиква гÑеÑка.
ÐиÑÑиплинаÑа, коÑÑо Ñледва, е да ÑÑздадеÑе вÑеки Ð¾Ð±ÐµÐºÑ Ð·Ð° ÑÑил пÑеди ÑикÑла за Ñедове и да ÑеÑеÑиÑаÑе кÑм Ð½ÐµÐ³Ð¾Ð²Ð¸Ñ Ð¸Ð½Ð´ÐµÐºÑ Ð²ÑÑÑе в ÑикÑла. Fonts.Add дедÑплиÑиÑа иденÑиÑни деÑиниÑии, Ñака Ñе извикванеÑо Ð¼Ñ Ð²ÐµÐ´Ð½Ñж на Ñед Ñамо пилее пÑоÑеÑоÑно вÑеме. Alignments.Add е капанÑÑ, заÑоÑо вÑÑÑа нов Ð·Ð°Ð¿Ð¸Ñ Ð¿Ñи вÑÑко извикване. ÐÑÑÑе в ÑикÑл Ð¾Ñ 100 000 Ñеда Ñова заÑÑÑпва styles.xml под ÑÑо Ñ
илÑди дÑблиÑани запиÑа за подÑавнÑване, коеÑо ÑаздÑва Ñайла на диÑка и Ð·Ð°Ð±Ð°Ð²Ñ Ð²ÑÑко ÑледваÑо оÑваÑÑне в Excel, ÑÑй каÑо дÑбликаÑиÑе Ñе паÑÑÐ²Ð°Ñ Ð¾Ñново. ÐзгÑаждайÑе вÑеки ÑÑил веднÑж извÑн ÑикÑла, Ñлед коеÑо ÑеÑеÑиÑайÑе кÑм Ð½ÐµÐ³Ð¾Ð²Ð¸Ñ Ð¸Ð½Ð´ÐµÐºÑ Ñолкова пÑÑи, колкоÑо ви е необÑ
одимо.
ÐоÑоÑи, вÑеменни диÑекÑоÑии и пакеÑниÑÑ ÑикÑл около вÑиÑко Ñова
ÐиÑо Ð¾Ñ Ñова не изиÑква Ñайлова ÑиÑÑема. РдвеÑе ÑаÑади ноÑÑÑ TStream пÑеÑоваÑÐ²Ð°Ð½Ð¸Ñ Ð² ÑвоÑÑа IO повÑÑÑ
ноÑÑ, ÑÑед коиÑо Open, SaveAs, SaveAsCSV, SaveAsHTML и SaveAsODS, Ñака Ñе пакеÑниÑÑ Ð¿ÑоÑÐµÑ Ð¼Ð¾Ð¶Ðµ да ÑендиÑа диÑекÑно в TMemoryStream, пÑедназнаÑен за blob Ñ
ÑанилиÑе или HTTP оÑговоÑ, без изобÑо да докоÑва диÑка. Ðма един важен нÑанÑ, койÑо ÑÑÑбва да Ñе помни. SaveAs(Stream) пиÑе Ð¾Ñ ÑекÑÑаÑа позиÑÐ¸Ñ Ð½Ð° поÑока и не го пÑевÑÑÑа Ñлед Ñова, Ñака Ñе задайÑе Ñами Position := 0, пÑеди да пÑедадеÑе поÑока на Ñова, коеÑо го доÑÑавÑ, в пÑоÑивен ÑлÑÑай конÑÑмаÑоÑÑÑ ÑеÑе нÑла байÑа. ФаÑадаÑа XLS Ð´Ð¾Ð±Ð°Ð²Ñ Ð´Ð²Ðµ ÑобÑÑвени конÑÑоли. SetTempDir наÑоÑва вÑеменниÑе Ñайлове на BIFF пиÑаÑÐµÐ»Ñ ÐºÑм обем Ñ Ð´Ð¾ÑÑаÑÑÑно пÑоÑÑÑанÑÑво и IO капаÑиÑеÑ, коеÑо е важно на ÑÑÑвÑÑи, кÑдеÑо вÑеменниÑÑ Ð¿ÑÑ Ð¿Ð¾ подÑазбиÑане е на пÑеÑÑпкан ÑиÑÑемен диÑк. UseSharedFormulas ÑгÑва повÑаÑÑÑи Ñе ÑоÑмÑли в Ñподелени гÑÑпи - Ñеално намалÑване на ÑазмеÑа за клаÑиÑеÑкаÑа ÑоÑма на оÑÑеÑ, пÑи коÑÑо една ÑоÑмÑла Ñе копиÑа Ð½Ð°Ð´Ð¾Ð»Ñ Ð¿Ð¾ ÑÑлаÑа колона.
СамиÑÑ Ð¿Ð°ÐºÐµÑен ÑикÑл оÑÑава ÑмиÑлено пÑоÑÑ:
for FileName in SourceFiles do
begin
Book := TXLSXWorkbook.Create; // fresh instance: no state bleed
try
Book.StreamingWrite := True;
if Book.Open(FileName) <> 1 then
Continue; // one bad input must not kill the batch
Book.SaveAsCSV(ChangeFileExt(FileName, '.csv'), 0, ',');
finally
Book.Free;
end;
end;
Ðова инÑÑанÑÐ¸Ñ Ð½Ð° ÑабоÑна книга за вÑеки Ñайл ÑÑÑÑва микÑоÑекÑнди и пÑемаÑ
ва ÑÑла каÑегоÑÐ¸Ñ Ð±Ñгове Ñ Ð¼ÐµÐ¶Ð´ÑÑайлово замÑÑÑÑване: ÑÑилове, деÑиниÑани имена и ÑвойÑÑва на докÑменÑи Ð¾Ñ Ñайл 17 нÑÐ¼Ð°Ñ Ð½Ð°Ñин да изÑÐµÐºÐ°Ñ Ð²Ñв Ñайл 18. ÐÑеÑкаÑанеÑо и пÑодÑлжаванеÑо пÑи неÑÑпеÑно Open е ÑÑÑо Ñолкова полезно, ÑÑй каÑо едно пÑекÑÑнаÑо каÑване в Ð¿Ð°ÐºÐµÑ Ð¾Ñ 600 Ñайла ÑÑÑбва да ви ÑÑÑÑва Ñамо един лог Ñед, а не ÑпиÑане на ÑÐµÐ»Ð¸Ñ Ð¿ÑоÑеÑ. ÐаÑлÑжава да Ñе оÑбележи и Ñова, коеÑо CSV еÑапÑÑ ÑмиÑлено не пÑави. SaveAsCSV запиÑва ÑоÑмÑлиÑе каÑо бÑквален ÑекÑÑ Ð¸ никога не ги изÑиÑлÑва, Ñака Ñе пÑоÑеÑÑÑ Ð·Ð° пÑеобÑазÑване, ÑииÑо конÑÑмаÑоÑи оÑÐ°ÐºÐ²Ð°Ñ Ð¸Ð·ÑиÑлени ÑиÑла, ÑÑÑбва пÑÑво да изпÑлни Calculate за ÑÑоÑвеÑниÑе клеÑки или да запоÑне Ð¾Ñ ÑабоÑни книги, коиÑо веÑе ÑÑдÑÑÐ¶Ð°Ñ ÐºÐµÑиÑани ÑезÑлÑаÑи Ð¾Ñ Ð¿ÑедиÑно изÑиÑление.
Ðодел за паÑалелноÑÑ: по една ÑабоÑна книга на ниÑка
ÐбекÑиÑе на ниÑо една Ð¾Ñ ÑаÑадиÑе не Ñа ниÑково безопаÑни (thread-safe) и дизайнÑÑ Ð½Ð¸ÐºÐ¾Ð³Ð° не е ÑвÑÑдÑл обÑаÑноÑо. ТÑй каÑо нÑма Ñподелено глобално ÑÑÑÑоÑние Ð¼ÐµÐ¶Ð´Ñ Ð¸Ð½ÑÑанÑииÑе, пÑавилоÑо за маÑабиÑане е пÑоÑÑо по една ÑабоÑна книга на ÑабоÑен поÑок (worker thread), без ÑподелÑне на ÑабоÑна книга Ð¼ÐµÐ¶Ð´Ñ Ð½Ð¸Ñки. ÐÑл Ð¾Ñ N ÑабоÑника, вÑеки Ð¾Ñ ÐºÐ¾Ð¸Ñо пÑиÑежава Ñвой ÑобÑÑвен TXLSXWorkbook, Ñе маÑабиÑа поÑÑи линейно, докаÑо памеÑÑа Ñе пÑевÑÑне в Ñаван, и Ñози Ñаван е неÑо, коеÑо можеÑе да изÑиÑлиÑе ÑиÑлово: най-големиÑÑ Ð¿Ð°Ñалелен модел на клеÑки, Ñмножен по бÑÐ¾Ñ Ð½Ð° ÑабоÑниÑиÑе, плÑÑ Ð´Ð¾Ð¿ÑлниÑелниÑе ÑазÑ
оди по вÑеме на запиÑ, коиÑо StreamingWrite е изÑавнил. ÐогаÑо опаÑкаÑа ÑÑане ÑвÑÑде дÑлга, пÑиложеÑе обÑаÑен наÑиÑк (back-pressure) вÑÑÑ
Ñ Ð¾Ð¿Ð°ÑкаÑа Ð¾Ñ Ð·Ð°Ð´Ð°Ñи, вмеÑÑо вÑÑÑе в пиÑаÑелÑ. ÐиÑка без ÑеÑÑÑÑи, коÑÑо е запиÑала наполовина ÑабоÑна книга, не е пÑоизвела ниÑо полезно, докаÑо задаÑа, изÑакала нÑколко ÑекÑнди за Ñвободен ÑабоÑник, завÑÑÑва ÑÑпеÑно.
Ðа по-ÑиÑокаÑа каÑÑина на опÑимизаÑиÑÑа, вклÑÑиÑелно Ñподелени ÑоÑмÑли, пÑопÑÑкане на гÑаÑики Ð¾Ñ ÑÑÑанаÑа на ÑеÑенеÑо и ÑпеÑиÑиÑниÑе за XLS конÑÑоли, вижÑе ÑÑководÑÑвоÑо за пÑоизводиÑелноÑÑ Ð½Ð° големи ÑабоÑни книги. ÐакеÑниÑе задаÑи, ÑииÑо Ñедове Ð¸Ð´Ð²Ð°Ñ Ð´Ð¸ÑекÑно Ð¾Ñ Ð·Ð°Ñвка, Ñа Ñазгледани оÑделно в моделиÑе за екÑпоÑÑиÑане на бази данни за Delphi оÑÑеÑи.
HotXLS Ñе компилиÑа вÑв ваÑаÑа Delphi или C++Builder ÑÑлÑга каÑо оÑигинален Object Pascal код без вÑнÑни завиÑимоÑÑи; изданиÑÑа и лиÑензиÑанеÑо Ñа на ÑÑÑаниÑаÑа на пÑодÑкÑа HotXLS Component.