Skip to main content
The TBICSV class provides fast and flexible import of comma-separated (CSV) and tab-separated (TSV) text files. It automatically detects delimiters, headers, and data types.

Quick Start

uses BI.CSV, BI.DataItem;

var
  Data: TDataItem;
  
// Import CSV file
Data := TBICSV.FromFile('customers.csv');

// Import from text
var
  CSV: TBICSV;
CSV := TBICSV.Create;
try
  Data := CSV.ImportText('Name,Age' + #13#10 + 'John,30');
finally
  CSV.Free;
end;

Key Methods

FromFile

Import a single CSV file:
class function FromFile(const AFileName: String): TDataItem;
Example:
Data := TBICSV.FromFile('sales_data.csv');
BIGrid1.Data := Data;

ImportFile

Import with progress tracking:
function ImportFile(const AFileName: String): TDataArray;
Example:
var
  CSV: TBICSV;
  DataArray: TDataArray;
  
CSV := TBICSV.Create;
try
  CSV.OnProgress := ShowProgress;
  DataArray := CSV.ImportFile('large_file.csv');
  Data := TBISource.FromData(DataArray);
finally
  CSV.Free;
end;

ImportText

Import from string:
function ImportText(const AText: String): TDataItem;
Example:
var
  CSVText: String;
  
CSVText := 'Product,Price' + #13#10 +
           'Widget,19.99' + #13#10 +
           'Gadget,29.99';
           
Data := CSV.ImportText(CSVText);

Import from TStrings

function Import(const Strings: TStrings): TDataArray;
Example:
DataArray := CSV.Import(Memo1.Lines);

FromFolder

Import all CSV files from a folder:
class function FromFolder(const Folder: String): TDataItem;
Example:
Data := TBICSV.FromFolder('C:\\Data\\CSVFiles');

Configuration Options

Delimiter

Set or auto-detect the field delimiter:
var
  CSV: TBICSV;
  
CSV := TBICSV.Create;
CSV.Delimiter := ';'; // Use semicolon
// Or use automatic detection:
CSV.Delimiter := TBICSV.AutomaticDelimiter; // Default
Supported delimiters:
  • Comma: ,
  • Tab: #9
  • Semicolon: ;
  • Space:
  • Custom: any character

Quote Character

CSV.Quote := '"'; // Default is double-quote

Headers

Control header row detection:
type TTextHeaders = (Auto, Yes, No);

CSV.Header.Headers := TTextHeaders.Auto; // Default - auto-detect
CSV.Header.Headers := TTextHeaders.Yes;  // First row is headers
CSV.Header.Headers := TTextHeaders.No;   // No headers, generate names

// Number of header rows to skip
CSV.Header.Count := 1; // Default

Missing Values

CSV.MissingValue := ''; // Default empty string
CSV.MissingValue := 'N/A';

Advanced Examples

Custom Delimiter and Headers

var
  CSV: TBICSV;
  
CSV := TBICSV.Create;
try
  CSV.Delimiter := ';';
  CSV.Header.Headers := TTextHeaders.Yes;
  CSV.Header.Count := 2; // Skip first 2 rows
  
  Data := CSV.ImportFile('european_data.csv');
finally
  CSV.Free;
end;

Import with Filters

CSV.IncludePattern := '*.csv';
CSV.ExcludePattern := 'temp_*.csv';
Data := CSV.Import('C:\\Data', True); // Recursive

Using DataDefinition

uses BI.Persist;

var
  Def: TDataDefinition;
  CSV: TBICSV;
  
Def := TDataDefinition.Create;
try
  Def['Delimiter'] := ';';
  Def['Quote'] := '"';
  Def['HeaderCount'] := '1';
  Def['Headers'] := 'Yes';
  
  CSV := TBICSV.Create(Def);
  try
    Data := CSV.ImportFile('data.csv');
  finally
    CSV.Free;
  end;
finally
  Def.Free;
end;

Performance Tips

  1. Large Files: For files over 100MB, use the progress event to provide user feedback
  2. Memory: CSV import is optimized for speed with automatic capacity expansion
  3. Batch Processing: Use FromFolder to import multiple files efficiently
// Good for large files
CSV.OnProgress := procedure(Sender: TObject; Percent: Integer; var Cancel: Boolean)
  begin
    Application.ProcessMessages;
    if Percent mod 10 = 0 then
      ShowStatus('Loading: ' + IntToStr(Percent) + '%');
  end;

Export to CSV

Use TBICSVExport to save data back to CSV:
uses BI.CSV;

var
  Export: TBICSVExport;
  
Export := TBICSVExport.Create;
try
  Export.Data := MyData;
  Export.Delimiter := ',';
  Export.Quote := '"';
  Export.Header := True;
  
  Export.SaveToFile('output.csv');
finally
  Export.Free;
end;

File Format Detection

// Check if extension is supported
if TBICSV.Supports('.csv') then
  Data := TBICSV.FromFile(FileName);

// Get file filter for dialogs
OpenDialog1.Filter := TBICSV.FileFilter.ToString;
// Returns: 'CSV files|*.csv|TSV files|*.tsv|Text files|*.txt'

Common Issues

Set the delimiter explicitly:
CSV.Delimiter := ',';
Force header mode:
CSV.Header.Headers := TTextHeaders.Yes;
CSV.Header.Count := 1;
Check the quote character setting:
CSV.Quote := '"';

See Also

Build docs developers (and LLMs) love