Delphi TQuery сохранить в CSV-файл - PullRequest
11 голосов
/ 15 апреля 2011

Я хочу экспортировать содержимое TQuery в файл CSV без использования компонента 3D-детали (Delphi 7). Насколько мне известно, это невозможно сделать с помощью стандартных компонентов Delphi.

Мое решение состояло в том, чтобы сохранить содержимое в StringList в формате CSV и сохранить его в файл.

Есть ли удобное решение?

PS: я не хочу использовать JvCsvDataSet или любой другой компонент. Вопрос в том, может ли это быть достигнуто только с помощью Delphi 7 или более высоких стандартных компонентов?

Заранее спасибо!

Ответы [ 4 ]

15 голосов
/ 15 апреля 2011

Конечно может.

Вам просто нужно выполнить работу для правильного вывода содержимого CSV (правильное цитирование, обработка встроенных кавычек и запятых и т. Д.). Вы можете легко записать вывод, используя TFileStream, и получить данные, используя TQuery.Fields и TQuery.FieldCount правильно.

Я оставлю вам необычные цитаты из CSV и специальную обработку для вас. Это позаботится о легкой части:

var
  Stream: TFileStream;
  i: Integer;
  OutLine: string;
  sTemp: string;
begin
  Stream := TFileStream.Create('C:\Data\YourFile.csv', fmCreate);
  try
    while not Query1.Eof do
    begin
      // You'll need to add your special handling here where OutLine is built
      OutLine := '';
      for i := 0 to Query.FieldCount - 1 do
      begin
        sTemp := Query.Fields[i].AsString;
        // Special handling to sTemp here
        OutLine := OutLine + sTemp + ',';
      end;
      // Remove final unnecessary ','
      SetLength(OutLine, Length(OutLine) - 1);
      // Write line to file
      Stream.Write(OutLine[1], Length(OutLine) * SizeOf(Char));
      // Write line ending
      Stream.Write(sLineBreak, Length(sLineBreak));
      Query1.Next;
    end;
  finally
    Stream.Free;  // Saves the file
  end;
end;
9 голосов
/ 16 апреля 2011

В первоначальном вопросе было предложено решение с использованием StringList. Так что было бы что-то вроде этого. Он будет работать с любым TDataSet, а не только с TQuery.

procedure WriteDataSetToCSV(DataSet: TDataSet, FileName: String);
var
  List: TStringList;
  S: String;
  I: Integer;
begin
  List := TStringList.Create;
  try
    DataSet.First;
    while not DataSet.Eof do
    begin
      S := '';
      for I := 0 to DataSet.FieldCount - 1 do
      begin
        if S > '' then
          S := S + ',';
        S := S + '"' + DataSet.Fields[I].AsString + '"';
      end;
      List.Add(S);
      DataSet.Next;
    end;
  finally
    List.SaveToFile(FileName);
    List.Free;
  end;
end;

Вы можете добавить опции для изменения типа разделителя или чего-либо еще.

1 голос
/ 15 октября 2015

Это похоже на решение Rob McDonell, но с некоторыми улучшениями: заголовок, escape-символы, вложение только при необходимости и ";"разделитель.Вы можете легко отключить это улучшение, если не требуется.

procedure SaveToCSV(DataSet: TDataSet; FileName: String);
const
  Delimiter: Char = ';'; // In order to be automatically recognized in Microsoft Excel use ";", not ","
  Enclosure: Char = '"';
var
  List: TStringList;
  S: String;
  I: Integer;
  function EscapeString(s: string): string;
  var
    i: Integer;
  begin
    Result := StringReplace(s,Enclosure,Enclosure+Enclosure,[rfReplaceAll]);
    if (Pos(Delimiter,s) > 0) OR (Pos(Enclosure,s) > 0) then  // Comment this line for enclosure in every fields
        Result := Enclosure+Result+Enclosure;
  end;
  procedure AddHeader;
  var
    I: Integer;
  begin
    S := '';
    for I := 0 to DataSet.FieldCount - 1 do begin
      if S > '' then
        S := S + Delimiter;
      S := S + EscapeString(DataSet.Fields[I].FieldName);
    end;
    List.Add(S);
  end;
  procedure AddRecord;
  var
    I: Integer;
  begin
    S := '';
    for I := 0 to DataSet.FieldCount - 1 do begin
      if S > '' then
        S := S + Delimiter;
      S := S + EscapeString(DataSet.Fields[I].AsString);
    end;
    List.Add(S);
  end;
begin
  List := TStringList.Create;
  try
    DataSet.DisableControls;
    DataSet.First;
    AddHeader;  // Comment if header not required
    while not DataSet.Eof do begin
      AddRecord;
      DataSet.Next;
    end;
  finally
    List.SaveToFile(FileName);
    DataSet.First;
    DataSet.EnableControls;
    List.Free;
  end;
end;
1 голос
/ 12 января 2013

Delphi не предоставляет никакого встроенного доступа к данным .csv. Однако, следуя парадигме VCL TXMLTransform, я написал помощник класса TCsvTransform, который будет преобразовывать структуру .csv в / из TClientDataSet. Что касается первоначального вопроса, который заключался в экспорте TQuery в .csv, простой TDataSetProvider установит связь между TQuery и TClientDataSet. Для более подробной информации о TCsvTransform, cf http://didier.cabale.free.fr/delphi.htm#uCsvTransform

...