uses
fpjson, DateUtils, base64;
function TForm1.DataSetToJson(ds: TDataSet; FormatJson: Boolean): String;
const
boolarr: array[Boolean] of String = ('false', 'true');
var
jarr: TJsonArray;
jobj: TJsonObject;
i, idx: Integer;
stream: TStream;
s: String;
begin
Result := '[]';
if not ds.Active or (ds.RecordCount = 0) then
exit;
jarr := TJsonArray.Create;
idx := ds.RecNo;
ds.DisableControls;
ds.First;
while not ds.EOF do
begin
jobj := TJsonObject.Create;
for i := 0 to ds.FieldCount - 1 do
begin
if ds.Fields[i].IsNull then
jobj.Nulls[ds.Fields[i].FieldName] := True
else
begin
case ds.Fields[i].DataType of
ftString, ftFixedChar, ftMemo: jobj.Add(ds.Fields[i].FieldName, ds.Fields[i].AsString);
ftSmallint, ftInteger, ftWord, ftLargeint, ftAutoInc: jobj.Add(ds.Fields[i].FieldName, ds.Fields[i].AsLargeInt);
ftFloat, ftCurrency{$IF FPC_FULLVERSION>30202}, ftSingle{$ENDIF}: jobj.Add(ds.Fields[i].FieldName, ds.Fields[i].AsFloat);
ftBoolean: jobj.Add(ds.Fields[i].FieldName, boolarr[ds.Fields[i].AsBoolean]);
ftDateTime: jobj.Add(ds.Fields[i].FieldName, DateToISO8601(ds.Fields[i].AsDateTime));
ftDate: jobj.Add(ds.Fields[i].FieldName, FormatDatetime('yyyy-mm-dd', ds.Fields[i].AsDateTime));
ftTime: jobj.Add(ds.Fields[i].FieldName, FormatDatetime('hh:nn:ss', ds.Fields[i].AsDateTime));
ftBlob:
begin
stream := ds.CreateBlobStream(ds.Fields[i], bmRead);
s := '';
if stream.Size > 0 then
begin
SetLength(s, stream.Size);
stream.Position := 0;
stream.Read(s[1], stream.Size);
s := EncodeStringBase64(s);
end;
stream.Free;
jobj.Add(ds.Fields[i].FieldName, s);
end;
end;
end;
end;
jarr.Add(jobj);
ds.Next;
end;
ds.RecNo := idx;
ds.EnableControls;
if FormatJson then
Result := jarr.FormatJSON([], 2)
else
Result := jarr.AsJSON;
jarr.Free;
end;