我看不少朋友都是连接了excel以后一行一行往excel里面倒入,这样非常没有效率,我一般使用ExcelTableQuery控件,批量倒入,只要设定好了倒入的格式,倒入速度可以提高几十倍.我在使用delphi倒出excel方面使用的是TQueryTable控件,这个控件的作用相当于excel里面的"数据"---->"获取外部数据"---->"倒入文本文件",这种倒入方式主要思路是先把要保存的数据写到一个文本文件里面,然后使用TQueryTable将文本文件倒入到excel里面,这种方式倒入的速度是一条一条倒入的几十倍,效率非常快. 具体的实现是: (一)把DataSet中的数据写入一个文本 function TComm.ReadyFile(Fn: string; Ds: TDataSet): Boolean; var i,rowcount:integer; line:string; begin Result:=False; if not Ds.Active then exit; rowcount:=Ds.FieldCount; AssignFile(F,Fn); try try ReWrite(F); line:=Ds.Fields[0].DisplayName; for i:=1 to rowcount-1 do line:=line+''+Ds.Fields[i].DisplayName;//先准备好标题 Writeln(F,line); Ds.First;//下面是一条一条的写入数据到文本文件,每行一条记录,每字段之间使用Tab间隔 while not Ds.Eof do begin line:=Ds.Fields[0].AsString; for i:=1 to rowcount-1 do line:=line+''+Ds.Fields[i].AsString;//注意,这里的''是Tab键 Writeln(F,line); Ds.Next; end; Result:=True; except Result:=False; exit; end; finally CloseFile(F); end; end; (二)还要准备一个OleVariant参数,这个参数是一个整数变量,这个参数的目的是为了在倒入excel的时候正确区分列是文本还是数字,如果不准备这个参数,例如0000111这样的文本导入后就会成为111这样的数字. function TComm.InitFormatA(DataSet: TDataSet): OleVariant; var i:integer; A:Variant; begin A:=VarArrayCreate([0,DataSet.Fields.Count-1],varVariant); for i:=0 to DataSet.FieldCount-1 do if DataSet.Fields[i].DataType=ftStringthen A[i]:=2 else A[i]:=1;//如果是文本,元素就是2,否则就是1 InitFormatA:=A; end; (三)文本准备好了,格式参数也准备好了,就可以连接excel使用ExcelQueryTable控件导入数据了.ReadyFile('c:\tmp',Query1);//把Query1里面的数据导入到c:\tmp2这个文本文件里面 Text2Excel_Format:=InitFormatA(Query1);//通过分析Query1获得导入excel的格式参数 try ExcelApplication1.Connect; ExcelApplication1.Visible[0]:=True; ExcelApplication1.Workbooks.Add(NULL,0); ExcelWorkbook1.ConnectTo(ExcelApplication1.Workbooks[ExcelApplication1.Workbooks.Count]); ExcelWorksheet1.ConnectTo(ExcelWorkbook1.Sheets[1] as _WorkSheet); //开始连接EXCELQueryTables ExcelWorkSheet1.QueryTables.Add('TEXT;'+'C:\tmp',ExcelWorkSheet1.Range['A1','A1'],EmptyParam);//设置Excel需要导入的数据是c:\tmp的文本 ExcelQueryTable1.ConnectTo(ExcelWorkSheet1.QueryTables[1] as _QueryTable); ExcelQueryTable1.TextFileColumnDataTypes:=Text2Excel_Format;//设置导入格式 ExcelQueryTable1.Refresh;//刷新以后就获得数据了. finally ExcelQueryTable1.Disconnect; ExcelWorkSheet1.Disconnect; ExcelWorkBook1.Disconnect; ExcelApplication1.Disconnect; end; 这种导入数据的方式绝对很快,可是是一般导入方式的几十甚至上百倍.
下载一个 dbgrideh3.0控件 USES DbGridEhImpExp; if dbgrideh1 <> nil then begin if saveDialog1.Execute then begin SaveDBGridEhToExportFile(TDBGridEhExportAsXLS,dbgrideh1,savedialog1.filename+'.xls',true); showmessage('成功导出到'+ savedialog1.filename+'.xls'); end; end else showmessage('没有数据表格可供导出') ;
我现在基本都用一个dbgrideh控件,把这上万条记录显示出来。然后用它提供的导出函数,大概几秒种。
具体的实现是:
(一)把DataSet中的数据写入一个文本
function TComm.ReadyFile(Fn: string; Ds: TDataSet): Boolean;
var i,rowcount:integer;
line:string;
begin
Result:=False;
if not Ds.Active then exit;
rowcount:=Ds.FieldCount;
AssignFile(F,Fn);
try
try
ReWrite(F);
line:=Ds.Fields[0].DisplayName;
for i:=1 to rowcount-1 do line:=line+''+Ds.Fields[i].DisplayName;//先准备好标题
Writeln(F,line);
Ds.First;//下面是一条一条的写入数据到文本文件,每行一条记录,每字段之间使用Tab间隔
while not Ds.Eof do
begin
line:=Ds.Fields[0].AsString;
for i:=1 to rowcount-1 do line:=line+''+Ds.Fields[i].AsString;//注意,这里的''是Tab键
Writeln(F,line);
Ds.Next;
end;
Result:=True;
except
Result:=False;
exit;
end;
finally
CloseFile(F);
end;
end;
(二)还要准备一个OleVariant参数,这个参数是一个整数变量,这个参数的目的是为了在倒入excel的时候正确区分列是文本还是数字,如果不准备这个参数,例如0000111这样的文本导入后就会成为111这样的数字.
function TComm.InitFormatA(DataSet: TDataSet): OleVariant;
var i:integer;
A:Variant;
begin
A:=VarArrayCreate([0,DataSet.Fields.Count-1],varVariant);
for i:=0 to DataSet.FieldCount-1 do
if DataSet.Fields[i].DataType=ftStringthen A[i]:=2 else A[i]:=1;//如果是文本,元素就是2,否则就是1
InitFormatA:=A;
end;
(三)文本准备好了,格式参数也准备好了,就可以连接excel使用ExcelQueryTable控件导入数据了.ReadyFile('c:\tmp',Query1);//把Query1里面的数据导入到c:\tmp2这个文本文件里面
Text2Excel_Format:=InitFormatA(Query1);//通过分析Query1获得导入excel的格式参数
try
ExcelApplication1.Connect;
ExcelApplication1.Visible[0]:=True;
ExcelApplication1.Workbooks.Add(NULL,0);
ExcelWorkbook1.ConnectTo(ExcelApplication1.Workbooks[ExcelApplication1.Workbooks.Count]);
ExcelWorksheet1.ConnectTo(ExcelWorkbook1.Sheets[1] as _WorkSheet);
//开始连接EXCELQueryTables
ExcelWorkSheet1.QueryTables.Add('TEXT;'+'C:\tmp',ExcelWorkSheet1.Range['A1','A1'],EmptyParam);//设置Excel需要导入的数据是c:\tmp的文本
ExcelQueryTable1.ConnectTo(ExcelWorkSheet1.QueryTables[1] as _QueryTable);
ExcelQueryTable1.TextFileColumnDataTypes:=Text2Excel_Format;//设置导入格式
ExcelQueryTable1.Refresh;//刷新以后就获得数据了.
finally
ExcelQueryTable1.Disconnect;
ExcelWorkSheet1.Disconnect;
ExcelWorkBook1.Disconnect;
ExcelApplication1.Disconnect;
end;
这种导入数据的方式绝对很快,可是是一般导入方式的几十甚至上百倍.
谢谢hxshaou(晓子) 了。
请赐教。
{
* ********************************************************************************************************************** *
* * 函数:GridExport * 功能描述:DBGRIDEH的数据导出 * 最后修改日期:2005.9.5
* * * 输入参数: sourstr DBGRIDEH控件
* * * *
* ********************************************************************************************************************** *
}
Procedure GridExport(AGrid: TDBGridEh;_filename:string); //列表框导出
var ExpClass:TDBGridEhExportClass;
Ext:String;
SaveDialog1:TSaveDialog;
begin
SaveDialog1:=TSaveDialog.Create(nil);
SaveDialog1.FileName := _filename;
SaveDialog1.Filter:='EXCEL文件格式 (*.xls) |*.xls |文本文件格式 (*.txt)|*.txt |网页格式(*.htm)|*.htm';
SaveDialog1.DefaultExt:='xls';
if SaveDialog1.Execute then
begin
case SaveDialog1.FilterIndex of
2: begin ExpClass := TDBGridEhExportAsText; Ext := 'txt'; end;
4: begin ExpClass := TDBGridEhExportAsCSV; Ext := 'csv'; end;
3: begin ExpClass := TDBGridEhExportAsHTML; Ext := 'htm'; end;
5: begin ExpClass := TDBGridEhExportAsRTF; Ext := 'rtf'; end;
1: begin ExpClass := TDBGridEhExportAsXLS; Ext := 'xls'; end;
else
ExpClass := nil; Ext := '';
end; if ExpClass <> nil then
begin
if UpperCase(Copy(SaveDialog1.FileName,Length(SaveDialog1.FileName)-2,3)) <>
UpperCase(Ext) then
SaveDialog1.FileName := SaveDialog1.FileName + '.' + Ext;
SaveDBGridEhToExportFile(ExpClass,AGrid,SaveDialog1.FileName,True)
end;
shellexecute(0, 'open', pchar(SaveDialog1.FileName), nil, nil, SW_MAXIMIZE);
end;
end;如果将数据集中的数据导出的EXCEL中,可以使用以下过程:
uses ComObj;
{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
MSExcel:Variant;
i,j:integer;
begin
SaveDialog1.Filter:='*.XLS|*.XLS';
SaveDialog1.DefaultExt:='XLS';
if SaveDialog1.Execute then
begin
MsExcel:=createOLEobject('excel.application');
MsExcel.workBooks.add;
Msexcel.visible:=false;
with DataSource1.Dataset do
begin
first;
for i:=0 to fieldcount-1 do
begin
Msexcel.cells[1,i+1].value:=fields[i].DisplayLabel ;
end;
j:=2;
while not eof do
begin
for i:=0 to fieldcount-1 do
begin
Msexcel.cells[j,i+1].numberformat:='@';
Msexcel.cells[j,i+1].value:=fields[i].AsString ;
end;
inc(j);
next;
end;
end;
MSExcel.ActiveWorkBook.SaveAs(SaveDialog1.FileName);
MSExcel.ActiveWorkBook.Saved:=True;
MSExcel.Quit;
end;
end;
你这种方法是不是还有引用什么单元
我的方法不慢呀,如果要是说瓶颈主要是从DataSet里面把数据写入文件的过程,使用这个过程的时候一定要先执行DataSet.DisableControls,一般我即使倒十万条数据也就不到10秒
USES DbGridEhImpExp;
if dbgrideh1 <> nil then
begin
if saveDialog1.Execute then
begin
SaveDBGridEhToExportFile(TDBGridEhExportAsXLS,dbgrideh1,savedialog1.filename+'.xls',true);
showmessage('成功导出到'+ savedialog1.filename+'.xls');
end;
end
else
showmessage('没有数据表格可供导出') ;