找了N久,都没找到完美的.
我自己现在用的是代码加模板.可以用但是速度不快.
网上很多要不就是速度慢要不就是解决不彻底,不能设格式或不能带标题.
那个破FASTREPORT3 还要手工调格子,晕死.
哪个能解决下子?
估计没人能完美解决,所以也不指望,放个20分大家看看吧!
我自己现在用的是代码加模板.可以用但是速度不快.
网上很多要不就是速度慢要不就是解决不彻底,不能设格式或不能带标题.
那个破FASTREPORT3 还要手工调格子,晕死.
哪个能解决下子?
估计没人能完美解决,所以也不指望,放个20分大家看看吧!
我目前用的是DBGRID输出到EXCEL,基本上可以控制格式(通过调入带格式的EXCEL文件)和标题栏,但是效果不是很好(特别是程序运行时有一个逐行读DBGRID的过程,数据少还好,多了就不中了)。
dbgrideh我看有的人说也不是很好用,况且又不是一个系统自带组件。
不过眼下也只能双管齐下,图简单就用导出,要精确就用FASTREPORT3了。
Var
ExcelApp, MyWorkBook: Variant;
i: Integer;
OutFileName: String;
begin
bmc_sel.Filter:='';
if (adot.Filter<>'') and (adot.Filtered=true) then
begin
bmc_sel.Filter:=adot.Filter;
bmc_sel.Filtered:=true;
end; //µ¼³öµ½Excel
bmc_sel.close;
bmc_sel.open;
if bmc_sel.Active and (bmc_sel.RecordCount > 0) then
begin
if SaveExlFile.Execute then
OutFileName := SaveExlFile.FileName
else
Exit;
Application.ProcessMessages;
try
ExcelApp := CreateOleObject('Excel.Application');
MyWorkBook := ExcelApp.WorkBooks.Add;
except
ShowMessage('»úÆ÷ÖÐδ°²×°Excel£¡');
Exit;
end;
ExcelApp.Cells[1, 1].Value := '񅧏';
ExcelApp.Cells[1, 2].Value := 'ÐÕÃû';
ExcelApp.Cells[1, 3].Value := 'ÐÔ±ð';
ExcelApp.Cells[1, 4].Value := '³öÉúÈÕÆÚ';
ExcelApp.Cells[1, 5].Value := 'Ä꼶';
ExcelApp.Cells[1, 6].Value := '°à¼¶';
ExcelApp.Cells[1, 7].Value := 'ÁªÏµµç»°';
ExcelApp.Cells[1, 8].Value := '¼Òͥסַ';
i:= 2;
bmc_sel.First;
while not bmc_sel.Eof do
begin ExcelApp.Cells[i, 1].Value := bmc_sel.FieldByName('񅧏').AsString;
ExcelApp.Cells[i, 2].Value := bmc_sel.FieldByName('ÐÕÃû').AsString;
ExcelApp.Cells[i, 3].Value := bmc_sel.FieldByName('ÐÔ±ð').AsString;
ExcelApp.Cells[i, 4].Value := bmc_sel.FieldByName('³öÉúÈÕÆÚ').AsString;
ExcelApp.Cells[i, 5].Value := inttostr(bmc_sel.FieldByName('Ä꼶').asinteger);
ExcelApp.Cells[i, 6].Value := inttostr(bmc_sel.FieldByName('°à¼¶').asinteger);
ExcelApp.Cells[i, 7].Value := bmc_sel.FieldByName('ÁªÏµµç»°').AsString;
ExcelApp.Cells[i, 8].Value := bmc_sel.FieldByName('¼Òͥסַ').AsString;
i := i + 1;
bmc_sel.Next;
application.ProcessMessages;
end;
end
else
Exit;
MyWorkBook.SaveAs(OutFileName);
ExcelApp := Unassigned;
MyWorkBook.Close;
application.MessageBox('Òѳɹ¦µ¼³öÊý¾Ý£¡','ÌáʾÐÅÏ¢',mb_ok+mb_iconasterisk+mb_defbutton1+mb_applmodal);
adot.First;
end;
具体的算法步骤我还是先写一下吧,代码比较乱
将数据写入到本地txt文件,使用tab健间隔每一个字段-->分析字段数据,根据每个字段类型准备一个Olevar的数组,如果某个字段类型是字符,相应的数组成员值是2,如果是日期,则配置5,如果是一般的,配置1--->使用Server面板上的QueryTables组件实现打开txt文件,并且以olevar数组来指定打开每个字段的格式.
这个其实就是模拟excel-->数据-->获取外部数据-->导入文本文件的模式,你可以在excel里面记录一下这个过程的宏,并稍加改写变成delphi执行的语句
我看不少朋友都是连接了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;
这种导入数据的方式绝对很快,可是是一般导入方式的几十甚至上百倍.
那个就很快的,不过好像格式不好控制