ÐÑеобÑазÑванеÑо на ÑезÑлÑÐ°Ñ Ð¾Ñ Ð·Ð°Ñвка в Excel оÑÑÐµÑ Ñе ÑÑÑÑои Ð¾Ñ ÑÑи оÑновни ÑÑÑпки: ÑÑпоÑÑавÑне на полеÑаÑа Ð¾Ñ Delphi кÑм пÑавилниÑе Ñипове в Excel, оÑоÑмÑне на Ð·Ð°Ð³Ð»Ð°Ð²Ð½Ð¸Ñ Ñед каÑо оÑÑÐµÑ (а не каÑо ÑÑ ÐµÐ¼Ð° на база данни) и пÑавилно ÑоÑмаÑиÑане на ÑиÑла, даÑи и валÑÑи. Ðко пÑопÑÑнеÑе нÑкое Ð¾Ñ ÑÑÑ , ÑайлÑÑ Ñе Ñе оÑвоÑи без гÑеÑка, но поÑÑебиÑелиÑе нÑма да Ð¼Ð¾Ð³Ð°Ñ Ð´Ð° ÑÑмиÑÐ°Ñ ÐºÐ¾Ð»Ð¾Ð½Ð¸Ñе, ÑÑй каÑо ÑÑойноÑÑиÑе Ñа запиÑани каÑо ÑекÑÑ Ð¸ Excel ги ÑÑеÑиÑа как еÑикеÑи без пÑедÑпÑеждение.
HotXLS е библиоÑека на ÑиÑÑ Object Pascal, коÑÑо запиÑва XLS и XLSX Ñайлове диÑекÑно Ð¾Ñ Delphi и C++Builder без Excel авÑомаÑизаÑиÑ. Ð¢Ñ Ð¿Ñедлага два наÑина за пÑеÑ
вÑÑлÑне на TDataset кÑм ÑабоÑна книга: ÑÑез гоÑÐ¾Ð²Ð¸Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ TDataToXLS или ÑÑез ÑÑÑно пÑогÑамиÑан ÑикÑл. Те не Ñа взаимозаменÑеми â?компоненÑÑÑ Ðµ пÑоекÑиÑан за VCL пÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¸ ползва XLS ÑаÑадаÑа, Ñака Ñе избоÑÑÑ Ð·Ð°Ð²Ð¸Ñи Ð¾Ñ ÑÑедаÑа на изпÑлнение и изиÑÐºÐ²Ð°Ð½Ð¸Ñ ÑоÑмаÑ. Ðо-Ð´Ð¾Ð»Ñ Ñазглеждаме и дваÑа подÑ
ода, гÑаниÑиÑе на компоненÑа и как да запазиÑе ÑиповеÑе данни.
ТиповеÑе данни каÑо оÑновно изиÑкване пÑи екÑпоÑÑ
ÐÑеди вÑÑко извикване деÑиниÑайÑе как ÑиповеÑе Ð¾Ñ Delphi Ñе запиÑÐ²Ð°Ñ Ð² клеÑкиÑе. ÐлеÑка, полÑÑаваÑа Delphi низ, оÑÑава ÑекÑÑов низ. HotXLS не пÑедполага, Ñе '1,234.50' е ÑиÑло, за да избегне гÑеÑки пÑи ÑегионалниÑе наÑÑÑойки на ÑÑÑвÑÑа. ÐÑепоÑÑÑиÑелно е да ползваÑе ÑипизиÑаниÑе меÑоди: AsFloat или AsCurrency за ÑиÑла, AsDateTime за даÑи (за да ÑÑдÑÑжа клеÑкаÑа Ñеален Excel ÑеÑиен Ð½Ð¾Ð¼ÐµÑ Ð·Ð° даÑа) и AsString Ñамо за ÑиÑÑ ÑекÑÑ.
ÐбÑабоÑкаÑа на пÑазни (NULL) ÑÑойноÑÑи изиÑква ÑÑзнаÑелно ÑеÑение. ÐÑеобÑазÑванеÑо Ñ VarToStr пÑевÑÑÑа SQL NULL в пÑазен низ (ÑекÑÑова клеÑка), докаÑо пÑопÑÑканеÑо на пÑиÑвоÑванеÑо оÑÑÐ°Ð²Ñ ÐºÐ»ÐµÑкаÑа пÑазна, коеÑо е пÑавилно за ÑоÑмÑли каÑо AVERAGE, COUNT и пивоÑни ÑаблиÑи. Ðа колони Ñ Ð¿Ð°ÑиÑни ÑÑми опÑеделеÑе дали NULL ознаÑава нÑла или липÑваÑа ÑÑойноÑÑ, ÑÑй каÑо Ñова пÑÐ¾Ð¼ÐµÐ½Ñ ÑÑмаÑниÑе ÑезÑлÑаÑи.
Ðзползване на TDataToXLS в VCL пÑиложениÑ
Ðа клаÑиÑеÑки VCL пÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ñ Ð²ÐµÑе конÑигÑÑиÑана заÑвка компоненÑÑÑ TDataToXLS е най-бÑÑзоÑо ÑеÑение. Той обÑ
ожда вÑеки наÑледник на TDataset (FireDAC, ADO, IBX и дÑ.) и генеÑиÑа ÑоÑмаÑиÑан ÑабоÑен лиÑÑ ÑÑÑ Ð·Ð°Ð³Ð»Ð°Ð²Ð¸Ñ, ÑÑиÑÑове, Ñамки, междинни ÑÑми и авÑомаÑиÑно ÑазделÑне на лиÑÑове пÑи големи маÑиви.
var
Exporter: TDataToXLS;
begin
Exporter := TDataToXLS.Create(nil);
try
Exporter.Dataset := OrdersQuery; // any TDataset descendant
Exporter.WorksheetName := 'Orders';
Exporter.HeaderSource := hsDisplayLabel; // captions, not raw column names
Exporter.GroupFields.Add('CustomerID'); // subtotal block per customer
Exporter.RowsPerSheet := 50000; // stay below the BIFF8 row ceiling
Exporter.OnlyVisible := True; // respect Field.Visible
Exporter.SaveDatasetAs('orders.xls');
finally
Exporter.Free;
end;
end;
Ðве ÑвойÑÑва Ð¸Ð¼Ð°Ñ Ð²Ð°Ð¶Ð½Ð¾ знаÑение ÑÑк. HeaderSource := hsDisplayLabel запиÑва ÑвойÑÑвоÑо DisplayLabel на вÑÑко поле вмеÑÑо имеÑо Ð¼Ñ Ð² SQL заÑвкаÑа (напÑÐ¸Ð¼ÐµÑ âÐмÐ?на клиенÑâ?вмеÑÑо CUST_NM). RowsPerSheet Ñе използва, заÑоÑо компоненÑÑÑ Ð·Ð°Ð¿Ð¸Ñва BIFF8 ÑоÑмаÑ, койÑо е огÑаниÑен до 65 536 Ñеда â?задаванеÑо на ÑÑойноÑÑ ÐºÐ°Ñо 50 000 ÑÐ°Ð·Ð´ÐµÐ»Ñ Ð´Ð°Ð½Ð½Ð¸Ñе на лиÑÑове пÑед доÑÑигане на лимиÑа. ÐÑнÑниÑÑ Ð²Ð¸Ð´ Ñе конÑÑолиÑа Ð¾Ñ ÑвойÑÑваÑа за ÑÑиÑÑове на заглавиеÑо и данниÑе, ÑвеÑовеÑе на гÑÑпиÑе и ÑÑиловеÑе на ÑамкиÑе. Ðа поÑÑебиÑелÑко ÑоÑмаÑиÑане ÑÑбиÑиÑÑа AfterCell и AfterRow пÑедоÑÑавÑÑ Ð´Ð¾ÑÑÑп до запиÑÐ°Ð½Ð¸Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½.
ÐгÑаниÑÐµÐ½Ð¸Ñ Ð½Ð° компоненÑа TDataToXLS
ТÑи оÑновни огÑаниÑÐµÐ½Ð¸Ñ ÑÑÑбва да Ñе Ð²Ð·ÐµÐ¼Ð°Ñ Ð¿Ñедвид пÑи избоÑа на TDataToXLS:
- Това е изÑÑло VCL компоненÑ. ÐеговиÑÑ Ð¼Ð¾Ð´Ñл изиÑква
Forms,ControlsиDialogs, коеÑо вÑвежда VCL завиÑимоÑÑи в конзолни пÑогÑами или Windows ÑÑлÑги. ЯдÑоÑо на библиоÑекаÑа не изиÑква VCL и Ñе нÑждае Ñамо Ð¾Ñ Ð±Ð°Ð·Ð¾Ð²Ð¸ ÑиÑÑемни модÑли. - Той е изгÑаден вÑÑÑ
Ñ XLS ÑаÑадаÑа. ÐомпоненÑÑÑ Ð¿Ð¾Ð¿Ñлва
IXLSWorkbookи запиÑва .xls (BIFF8) без опÑÐ¸Ñ Ð·Ð° диÑекÑен OOXML Ð¸Ð·Ñ Ð¾Ð´. - СÑбиÑиÑÑа Ð¼Ñ Ð¿Ð¾Ð»Ð·Ð²Ð°Ñ XLS диалекÑ. ÐаÑамеÑÑÑÑÑ
Cell: IXLSRangeвAfterCellе ÑаÑÑ Ð¾Ñ XLS модела, Ñака Ñе пÑомениÑе в клеÑкиÑе Ñе опиÑÐ²Ð°Ñ Ð¿Ð¾ пÑавилаÑа на по-ÑÑаÑÐ¸Ñ ÑоÑмаÑ.
ÐенеÑиÑане на .xlsx Ð¾Ñ Ð¸Ð·Ñ Ð¾Ð´Ð° на компоненÑа
Ðко Ñе изиÑква .xlsx изÑ
од, но логикаÑа веÑе ползва TDataToXLS, моÑÑÑÑ Ð² модÑла lxXlsxExport конвеÑÑиÑа запиÑанаÑа книга Ñ ÐµÐ´Ð½Ð¾ извикване:
uses lxXlsxExport;
Exporter.SaveDatasetAs('orders.xls');
// the component exposes the IXLSWorkbook it populated
SaveXLSWorkbookAsXLSX(Exporter.Workbook, 'orders.xlsx');
РазглеждайÑе Ñози моÑÑ ÐºÐ°Ñо инÑÑÑÑÐ¼ÐµÐ½Ñ Ð·Ð° пÑÐµÐ½Ð¾Ñ Ð½Ð° ÑаблиÑни данни, а не за пÑлно пÑеобÑазÑване. Той копиÑа ÑÑойноÑÑи, ÑоÑмÑли, ÑоÑмаÑи, ÑвеÑове, ÑÑиÑÑове и ÑазмеÑи на колониÑе, но не поддÑÑжа Ñамки, обединени клеÑки, коменÑаÑи, диагÑами или ÑÑловно ÑоÑмаÑиÑане. Ðа Ñложни оÑÑеÑи е по-добÑе да генеÑиÑаÑе XLSX Ñайла диÑекÑно.
Ð ÑÑен ÑикÑл за ÑÑлÑги и авÑомаÑизиÑани задаÑи
СÑÑвÑÑниÑÑ ÐºÐ¾Ð´ ÑÑÑбва да използва диÑекÑно TXLSXWorkbook. ÐбÑÑнеÑе внимание на ÑазликаÑа в Ð¶Ð¸Ð·Ð½ÐµÐ½Ð¸Ñ ÑикÑл на дваÑа ÑоÑмаÑа: TXLSWorkbook е инÑеÑÑейÑен Ð¾Ð±ÐµÐºÑ Ñ Ð¾Ð±ÑаÑно бÑоене и не Ñе оÑвобождава ÑÑÑно, докаÑо TXLSXWorkbook е ноÑмален ÐºÐ»Ð°Ñ Ð¸ изиÑква блок try..finally Free. СмеÑванеÑо им води до изÑиÑане на Ð¿Ð°Ð¼ÐµÑ Ð¸Ð»Ð¸ ÑÑив.
procedure ExportOrders(Q: TDataSet; const FileName: string);
var
Book: TXLSXWorkbook;
Sheet: TXLSXWorksheet;
Row: Integer;
begin
Book := TXLSXWorkbook.Create;
try
Sheet := Book.Sheets.Add('Orders');
Sheet.Cells[1, 1].Value := 'Order No';
Sheet.Cells[1, 2].Value := 'Customer';
Sheet.Cells[1, 3].Value := 'Ordered';
Sheet.Cells[1, 4].Value := 'Amount';
Row := 2;
Q.First;
while not Q.Eof do
begin
Sheet.Cells[Row, 1].Value := Q.FieldByName('OrderNo').AsInteger;
Sheet.Cells[Row, 2].Value := Q.FieldByName('Customer').AsString;
if not Q.FieldByName('Ordered').IsNull then
Sheet.Cells[Row, 3].Value := Q.FieldByName('Ordered').AsDateTime;
Sheet.Cells[Row, 4].Value := Q.FieldByName('Amount').AsFloat;
Inc(Row);
Q.Next;
end;
Book.StreamingWrite := True; // stream sheet XML straight into the zip
Book.SaveAs(FileName);
finally
Book.Free;
end;
end;
ÐнÑÑÑÑкÑииÑе за ÑипизиÑано пÑиÑвоÑване и пÑовеÑка за IsNull гаÑанÑиÑÐ°Ñ ÐºÐ¾ÑекÑноÑÑ Ð½Ð° данниÑе. ÐадаванеÑо на StreamingWrite := True ÑÑÑиймва XML данниÑе диÑекÑно в ZIP аÑÑ
ива пÑи запиÑ, вмеÑÑо да ги ÑÑбиÑа пÑÑво в памеÑÑа, коеÑо намалÑва пиковеÑе пÑи голÑм бÑой Ñедове. ÐÑеки меÑод за Ð·Ð°Ð¿Ð¸Ñ Ð¿Ð¾Ð´Ð´ÑÑжа и поÑоÑи (TStream), коеÑо позволÑва изпÑаÑане по HTTP без запиÑване на диÑка. Този модел е Ñазгледан в запиÑване на поÑоÑи и авÑомаÑизиÑани задаÑи, а меÑодиÑе за опÑимизаÑÐ¸Ñ Ð¿Ñи много големи обеми Ñа опиÑани в пÑоизводиÑелноÑÑ Ð¿Ñи големи ÑабоÑни книги.
Този ÑÑÑен ÑикÑл е Ð¿Ð¾Ð´Ñ Ð¾Ð´ÑÑ Ð¸ за многониÑкови ÑÑеди. РдваÑа модÑла Ñа напиÑани изÑÑло на Object Pascal и не завиÑÑÑ Ð¾Ñ COM обекÑи или Excel лиÑензи на ÑÑÑвÑÑа. Това позволÑва паÑалелна ÑабоÑа в оÑделни ниÑки, каÑо вÑÑка ниÑка ÑÑÑбва да използва ÑобÑÑвена ÑабоÑна книга. ÐбекÑиÑе не Ñа ниÑково безопаÑни (thread-safe) за Ñподелено ползване.
Ð XLSX ÑоÑмаÑа ÑедовеÑе Ñа огÑаниÑени до 1 048 576, Ñака Ñе ÑазделÑнеÑо на лиÑÑове е ÑÑдко Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾. Ðа много големи обеми Ð¾Ñ Ð´Ð°Ð½Ð½Ð¸ CSV ÑоÑмаÑÑÑ Ðµ по-Ð¿Ð¾Ð´Ñ Ð¾Ð´ÑÑ, каÑо подÑобноÑÑи за изÑиÑлÑванеÑо на ÑоÑмÑли и BOM маÑкеÑиÑе Ñа Ñазгледани в екÑпоÑÑиÑане в CSV и TSV.
ÐÐ·Ð±Ð¾Ñ Ð½Ð° Ð¿Ð¾Ð´Ñ Ð¾Ð´
Ðко ÑазÑабоÑваÑе VCL деÑкÑоп пÑиложение и .xls ÑоÑмаÑÑÑ Ðµ пÑиемлив, използвайÑе TDataToXLS Ñ Ð½ÐµÐ³Ð¾Ð²Ð°Ñа поддÑÑжка на междинни ÑÑми. ÐоÑÑÑÑ Ð¿Ñез SaveXLSWorkbookAsXLSX е налиÑен пÑи нÑжда Ð¾Ñ .xlsx. Ðа ÑÑÑвÑÑни ÑÑлÑги или ÑвÑÑдо изиÑкване за .xlsx изÑ
од напиÑеÑе ÑÑÑен ÑикÑл. ÐваÑа подÑ
ода Ñе доÑÑавÑÑ Ñ ÑабоÑеÑи пÑимеÑи в пакеÑа на HotXLS Component.