我想將TQuery的內容導出爲CSV文件,而不使用三維零件組件(Delphi 7)。據我所知,這不能用Delphi標準組件完成。Delphi TQuery保存爲csv文件
我的解決方案是將內容保存爲CSV格式的StringList,並將其保存到文件中。
有沒有什麼舒適的解決方案?我不想使用JvCsvDataSet或其他組件。問題是:這隻能使用Delphi 7或更高版本的標準組件才能實現?
預先感謝您!
我想將TQuery的內容導出爲CSV文件,而不使用三維零件組件(Delphi 7)。據我所知,這不能用Delphi標準組件完成。Delphi TQuery保存爲csv文件
我的解決方案是將內容保存爲CSV格式的StringList,並將其保存到文件中。
有沒有什麼舒適的解決方案?我不想使用JvCsvDataSet或其他組件。問題是:這隻能使用Delphi 7或更高版本的標準組件才能實現?
預先感謝您!
當然可以。
你只需要做的工作,以正確輸出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;
有關如何轉義sTemp的一些信息:http:// www.csvreader.com/csv_format.php – jachguate 2011-04-15 17:59:51
原始問題要求使用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;
您可以添加選項來更改分隔符類型或其他。
Delphi不提供對.csv數據的任何內置訪問。 但是,遵循VCL TXMLTransform範例,我編寫了一個TCsvTransform類幫助程序,它可以將.csv結構轉換爲TClientDataSet或從TClientDataSet轉換。 至於最初的問題是將TQuery導出爲.csv,一個簡單的TDataSetProvider將使TQuery和TClientDataSet之間的鏈接成爲可能。 有關TCsvTransform詳情,CF http://didier.cabale.free.fr/delphi.htm#uCsvTransform
這就好比羅布麥克唐納溶液但也有一些改進:報頭,逃生字符,外殼僅在需要時,和「;」分隔器。 如果不需要,您可以輕鬆禁用此增強功能。
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;
編寫CSV文件發射器非常簡單。由於您無法找到內置的功能,並且由於您不需要第三方解決方案,因此您可能需要沿着這條路線走下去。 – 2011-04-15 17:05:45
由於我們在談論CSV,因此有一篇關於設計模式的漂亮文章,使用CSV解析器作爲示例 - http://conferences.embarcadero.com/article/32129 – Najem 2011-04-16 17:10:28