Delphi TQuery保存到csv文件

| 我想将TQuery的内容导出到CSV文件而不使用3d零件组件(Delphi 7)。据我所知,这不能用Delphi标准组件来完成。 我的解决方案是将内容保存为CSV格式的StringList,然后将其保存到文件中。 有什么舒适的解决方案吗? PS:我不想使用JvCsvDataSet或任何组件。问题是:仅使用Delphi 7或更高标准的组件才能实现吗? 先感谢您!     
已邀请:
当然可以。 您只需要做工作即可正确输出CSV内容(正确报价,处理嵌入的引号和逗号等)。您可以使用using0ѭ轻松写入输出,并使用
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;
    
最初的问题要求使用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;
您可以添加选项以更改定界符类型或其他任何内容。     
这类似于Rob McDonell解决方案,但具有一些增强功能:标头,转义字符,仅在需要时使用外壳以及\“; \”分隔符。 如果不需要,您可以轻松禁用此增强功能。
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;
    
Delphi不提供对.csv数据的任何内置访问。 但是,遵循VCL TXMLTransform范例,我编写了TCsvTransform类帮助程序,该帮助程序会将.csv结构转换为TClientDataSet或从TClientDataSet转换。 对于最初的问题,即将TQuery导出到.csv,一个简单的TDataSetProvider将在TQuery和TClientDataSet之间建立链接。 有关TCsvTransform的更多详细信息,请参见http://didier.cabale.free.fr/delphi.htm#uCsvTransform     

要回复问题请先登录注册