Skip to main content
Table of Contents

Import & export (JSON)

Load a JSON file, stream, or string directly into the grid. Map the JSON object structure to grid columns by supplying the key names that contain your row array and column values.

Overview

JSON import is built into the core grid. There is no separate JSON export (use CSV for round-trip data transfer); the JSON import is designed for loading data from REST APIs or configuration files.

Operation Method
Load from file Grid.LoadFromJSONData(FileName)
Load from stream Grid.LoadFromJSONStreamData(Stream)
Load from string Grid.LoadFromJSONTextData(Text)

All three share the same optional mapping parameters:

Parameter Type Purpose
ARowDataName string Key whose value is the JSON array of rows. Pass '' if the root is already an array.
AColumnDataName string Key inside each row object whose value is the array of column values. Pass '' for flat row objects.
AColumnNames TTMSFNCDataGridDataJSONNamesArray Maps JSON property names to specific column indices.

Step by step

Flat array of objects

The most common shape — a JSON array at the root, each element an object with one property per column:

JSON
[
  { "id": 1, "name": "Alice", "country": "DE" },
  { "id": 2, "name": "Bob",   "country": "US" }
]
Inline example 1PascalC++
Grid.ColumnCount   := 3;
Grid.FixedRowCount := 1;
Grid.Cells[0, 0] := 'ID';
Grid.Cells[1, 0] := 'Name';
Grid.Cells[2, 0] := 'Country';

// Map JSON keys to columns in order
Grid.LoadFromJSONTextData(JsonText, '', '',
  ['id', 'name', 'country']);     // AColumnNames: key → column order
Grid->ColumnCount   = 3;
Grid->FixedRowCount = 1;
Grid->Cells[0][0] = L"ID";
Grid->Cells[1][0] = L"Name";
Grid->Cells[2][0] = L"Country";

// Map JSON keys to columns in order
Grid->LoadFromJSONTextData(JsonText, L"", L"",
  [L"id", L"name", L"country"]);     // AColumnNames: key → column order

AColumnNames is an array of property name strings; their position in the array corresponds to the grid column index.

Nested structure with a wrapper key

When the JSON has a wrapper object with a named array inside:

JSON
{
  "data": [
    { "id": 1, "name": "Alice" },
    { "id": 2, "name": "Bob"   }
  ]
}
Inline example 2PascalC++
Grid.LoadFromJSONData('customers.json', 'data', '',
  ['id', 'name']);     // ARowDataName = 'data'
Grid->LoadFromJSONData(L"customers->json", L"data", L"",
  [L"id"][L"name"]);     // ARowDataName = L"data"

Array of arrays (columnar data)

When each row is a JSON array of values rather than an object:

JSON
{
  "rows": [
    { "cols": [1, "Alice", "DE"] },
    { "cols": [2, "Bob",   "US"] }
  ]
}
Inline example 3PascalC++
Grid.LoadFromJSONData('data.json',
  'rows',              // ARowDataName
  'cols',              // AColumnDataName — key inside each row object
  nil);                // no name mapping needed; columns are positional
Grid->LoadFromJSONData(L"data->json",
  L"rows",              // ARowDataName
  L"cols",              // AColumnDataName — key inside each row object
  nullptr);                // no name mapping needed; columns are positional

Load from a stream (REST response)

Inline example 4PascalC++
var Response := TMemoryStream.Create;
try
  HttpClient.Get('https://api.example.com/data', Response);
  Response.Position := 0;
  Grid.LoadFromJSONStreamData(Response, '', '', ['id', 'name', 'value']);
finally
  Response.Free;
end;
var Response = TMemoryStream->Create;
try
  HttpClient->Get(L"https://api->example->com/data", Response);
  Response->Position = 0;
  Grid->LoadFromJSONStreamData(Response, L"", L"", [L"id", L"name", L"value"]);
finally
  Response->Free;
}

Load from a string (TRestResponse)

Inline example 5PascalC++
Grid.LoadFromJSONTextData(RESTResponse1.Content, 'data', '',
  ['id', 'name', 'value']);
Grid->LoadFromJSONTextData(RESTResponse1->Content, L"data", L"",
  [L"id", L"name", L"value"]);

Transform values during import

OnLoadCellData fires for every cell as it is populated from the JSON, letting you convert or replace the parsed value before it is stored in the grid:

Transform values during JSON importPascalC++
procedure TForm1.GridLoadCellData(Sender: TObject;
  AColumn, ARow: Integer;
  var AValue: TTMSFNCDataGridCellValue);
begin
  // JSON may deliver numbers as strings; convert to TDateTime where needed
  if AColumn = DateColumn then
  begin
    var D: TDateTime;
    if TryStrToDateTime(AValue.AsString, D) then
      AValue := TValue.From<TDateTime>(D);
  end;
end;
void __fastcall TForm1::GridLoadCellData(TObject *Sender,
  int AColumn, int ARow,
  TTMSFNCDataGridCellValue &AValue)
{
  // JSON may deliver numbers as strings; convert to TDateTime where needed
  if (AColumn == DateColumn)
  {
    TDateTime D;
    if (TryStrToDateTime(AValue.ToString(), D))
      AValue = TValue::From<TDateTime>(D);
  }
}

Combining JSON loading and value transforms

JSON from a REST API or configuration file seldom arrives in the exact types the grid should store: dates are strings, numbers may be quoted, and flags can be text. Combine the JSON import methods with the load transform event so each value is converted as the grid reads it, instead of fixing every cell in a second pass. Use this pattern when the same payload feeds both display and calculations. The example below prepares headers, hooks the load event, and loads a wrapped JSON array from a string, converting the date column while the rows are imported.

Combining JSON loading and value transformsPascalC++
procedure TForm1.LoadJSONButtonClick(Sender: TObject);
const
  JsonText = '{"data":[{"id":1,"name":"Alice","since":"2024-05-01"},' +
             '{"id":2,"name":"Bob","since":"2023-11-15"}]}';
begin
  Grid.ColumnCount := 3;
  Grid.FixedRowCount := 1;
  Grid.Cells[0, 0] := 'ID';
  Grid.Cells[1, 0] := 'Name';
  Grid.Cells[2, 0] := 'Since';

  // Convert values while they are imported
  Grid.OnLoadCellData := GridLoadCellData;

  // The rows live under the wrapper key "data"
  Grid.LoadFromJSONTextData(JsonText, 'data', '');
end;

procedure TForm1.GridLoadCellData(Sender: TObject; AColumn, ARow: Integer;
  var AValue: TTMSFNCDataGridCellValue);
var
  D: TDateTime;
begin
  if (AColumn = 2) and TryStrToDateTime(AValue.AsString, D) then
    AValue := TValue.From<TDateTime>(D);
end;
void __fastcall TForm1::LoadJSONButtonClick(TObject *Sender)
{
  System::UnicodeString JsonText =
    "{\"data\":[{\"id\":1,\"name\":\"Alice\",\"since\":\"2024-05-01\"},"
    "{\"id\":2,\"name\":\"Bob\",\"since\":\"2023-11-15\"}]}";

  Grid->ColumnCount = 3;
  Grid->FixedRowCount = 1;
  Grid->Strings[0][0] = "ID";
  Grid->Strings[1][0] = "Name";
  Grid->Strings[2][0] = "Since";

  // Convert values while they are imported
  Grid->OnLoadCellData = GridLoadCellData;

  // The rows live under the wrapper key "data"
  Grid->LoadFromJSONTextData(JsonText, "data", "");
}

void __fastcall TForm1::GridLoadCellData(TObject *Sender, int AColumn, int ARow,
  TTMSFNCDataGridCellValue &AValue)
{
  TDateTime D;
  if ((AColumn == 2) && TryStrToDateTime(AValue.ToString(), D))
    AValue = TValue::From<TDateTime>(D);
}
  • Grid.LoadFromJSONData(AFileName, ARowDataName, AColumnDataName, AColumnNames)
  • Grid.LoadFromJSONStreamData(AStream, ARowDataName, AColumnDataName, AColumnNames)
  • Grid.LoadFromJSONTextData(AText, ARowDataName, AColumnDataName, AColumnNames)
  • TTMSFNCDataGridDataJSONNamesArray — TArray<string> of JSON key names mapped to column indices
  • OnLoadCellData — transform a cell value as it is read from the JSON source.

See also