מאמר טכני

ייצוא נתוני מסד נתונים לדוחות Excel מ-Delphi עם HotXLS

HotXLS מציע שני נתיבים לייצוא שאילתות מסד נתונים לגיליונות Excel: TDataToXLS — רכיב VCL מוכן לשימוש — ולולאה ידנית עם TXLSXWorkbook עבור שירותים. ההבחנה בין השניים אינה קוסמטית; היא קובעת אילו שדות עוברים נכון ואיפה ה-XLSX מגיע

TDataToXLS: רכיב VCL בלבד, חזית XLS בלבד

TDataToXLS הוא רכיב VCL שמייצא TDataSet ישירות לקובץ XLS. הוא עובד אך ורק בסביבת VCL ורק עם חזית ה-XLS (BIFF8). אין תמיכה ישירה ב-XLSX. ניתן לגשר בין שני הפורמטים ע"י SaveXLSWorkbookAsXLSX, אך הגשר מעתיק ערכים ופורמטים בסיסיים בלבד — גבולות, מיזוגים, הערות ותרשימים לא יעברו

שיוך שדות נכון: AsFloat, AsDateTime לעומת AsString

ב-TDataToXLS, שדות מספריים צריכים להישלח ע"י AsFloat ושדות תאריך ע"י AsDateTime — לא ע"י AsString. שימוש ב-AsString לשדה מספרי יפיק תא טקסט בגיליון ב-Excel, שמתנהג שונה מתא מספרי (לא ניתן לסכם, לא ממוין נכון ועוד)

לולאה ידנית עם TXLSXWorkbook לשירותים

שירותי Delphi שאינם VCL לא יכולים להשתמש ב-TDataToXLS. הנתיב הנכון הוא לולאה ידנית עם TXLSXWorkbook: פתח את הגיליון, עבור בלולאה על שורות ה-DataSet, וכתוב כל שדה לתא המתאים. זה מאפשר שליטה מלאה על סגנון, כותרות ועמודות מחושבות

StreamingWrite לאצוות גדולות

עבור דוחות עם מאות אלפי שורות, הגדר Book.StreamingWrite := True לפני SaveAs. ה-flag מעביר את כתיבת ה-XML ישירות ל-zip stream במקום לאגד אותה בזיכרון קודם, מה שמונע spike בצריכת הזיכרון בעת שמירה. הפרטים של מצב זה מוסברים במאמר כתיבת streaming לעבודות batch בשרת

HotXLS קומפל לתוך אפליקציית Delphi או C++Builder ללא תלויות חיצוניות; מהדורות ורישוי זמינים בדף HotXLS Component

דוגמאות קוד נוספות

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;
uses lxXlsxExport;

Exporter.SaveDatasetAs('orders.xls');
// the component exposes the IXLSWorkbook it populated
SaveXLSWorkbookAsXLSX(Exporter.Workbook, 'orders.xlsx');
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;