开发平台:Delphi7+Sql_Server2000
操作系统:windows2000
硬件配置:cpu为奔腾3,内存是256M,硬盘容量20G.(Acer 笔记本)
基本思路:运行主程序后,从数据库中将查出来的数据在主程序中列出,当有需要时,通过按钮触发导出数据到excel中,在这个过程时间太慢,主程序必须等该过程完成后才能正常运行,这样一来操作员不能做其它操作,严重影响效率及交通。
如:656条数据导出的时间在两三分钟以上( 配置是差了点,但也不至于这么慢吧)
解决办法:将导出这一过程放到后台处理,既可加快导出速度,又不影响操作员的其它操作。主要是通过创建线程来实现的,在这个线程中创建Excel应用的时候,发现只能创建Excel应用,却无法使用这个应用,总是说无法调用CoInitalire,不知道是什么原因
操作系统:windows2000
硬件配置:cpu为奔腾3,内存是256M,硬盘容量20G.(Acer 笔记本)
基本思路:运行主程序后,从数据库中将查出来的数据在主程序中列出,当有需要时,通过按钮触发导出数据到excel中,在这个过程时间太慢,主程序必须等该过程完成后才能正常运行,这样一来操作员不能做其它操作,严重影响效率及交通。
如:656条数据导出的时间在两三分钟以上( 配置是差了点,但也不至于这么慢吧)
解决办法:将导出这一过程放到后台处理,既可加快导出速度,又不影响操作员的其它操作。主要是通过创建线程来实现的,在这个线程中创建Excel应用的时候,发现只能创建Excel应用,却无法使用这个应用,总是说无法调用CoInitalire,不知道是什么原因
使用线程的方法也是用的这段代码,但在 ExcelApplication1.Connect;语句处出现错误提示,
提示说尚未调用CoInitialize,这是什么错误?procedure TCriminalForm.ExcelButtonClick(Sender: TObject);
var
ExcelApplication1: TExcelApplication;
ExcelWorksheet1: TExcelWorksheet;
ExcelWorkbook1: TExcelWorkbook;
i, j: integer;
filename: string;
begin File_SaveDlg.Filter:='Excel文件(*.xls)|*.xls';
if File_SaveDlg.Execute then begin
filename:=File_SaveDlg.filename;
if File_SaveDlg.FileName ='' then exit;
end else begin
exit;
end; { filename := concat(extractfilepath(application.exename), sName, '.xls'); }
try
ExcelApplication1 := TExcelApplication.Create(Application);
ExcelWorksheet1 := TExcelWorksheet.Create(Application);
ExcelWorkbook1 := TExcelWorkbook.Create(Application);
ExcelApplication1.Connect;
except
Application.Messagebox('Excel 没有安装!','Hello', MB_ICONERROR + mb_Ok);
Abort;
end;
try
ExcelApplication1.Workbooks.Add(EmptyParam, 0);
ExcelWorkbook1.ConnectTo(ExcelApplication1.Workbooks[1]);
ExcelWorksheet1.ConnectTo(ExcelWorkbook1.Worksheets[1] as _worksheet);
DBGrid_MSQuery.First;
for j := 0 to DBGrid_MSQuery.Fields.Count - 1 do
begin
ExcelWorksheet1.Cells.item[3, j + 1] := DBGrid_MSQuery.Fields[j].DisplayLabel;
ExcelWorksheet1.Cells.item[3, j + 1].font.size := '10';
end;
for i := 4 to DBGrid_MSQuery.RecordCount + 3 do
begin
for j := 0 to DBGrid_MSQuery.Fields.Count - 1 do
begin
ExcelWorksheet1.Cells.item[i, j + 1] :=
DBGrid_MSQuery.Fields[j].Asstring;
ExcelWorksheet1.Cells.item[i, j + 1].font.size := '10';
end;
DBGrid_MSQuery.Next;
end;
ExcelWorksheet1.Columns.AutoFit;
ExcelWorksheet1.Columns.NumberFormatLocal := '@';
ExcelWorksheet1.Columns.HorizontalAlignment := xlCenter;
ExcelWorksheet1.Cells.item[1, 2] := Title;
ExcelWorksheet1.Cells.Item[1, 2].font.size := '14';
ExcelWorksheet1.SaveAs(filename);
Application.Messagebox(pchar('数据成功导出' + filename), 'Hello',
mb_Ok);
finally
ExcelApplication1.Disconnect; ExcelApplication1.Quit;
ExcelApplication1.Free; ExcelWorksheet1.Free;
ExcelWorkbook1.Free;
end;// Form1.WriteExcel(DBGrid_MSQuery,'出逃人员基本情况表','出逃人员基本情况表');end;
导出excel最快的是使用流,有时间帮你改改代码,我的那么多记录,导出交叉excel(行列互换)也没有你这么慢!
代码的执行效率问题!
你这个方法是没有办法实现多线程的,这个是由于delphi调用excel后无法自动释放的原因。
在代碼的最前加一行 CoInitialize(nil);最後用:
CoUninitialize;試下看如何!uses ActiveX;
明天试试你说的办法,看行不行。to cobi
今天我看了一下,慢的最主要原因可能是双重循环的缘故,并且是以域为单位进行导出过程,能不能以记录为单位进行导出呢?但在做这个的时候才发现query控件只有一个getcurrentrecord函数可以将当前记录保存到缓冲区,但它是个虚函数,什么操作都不做,只返回一个false,想重载却无从下手,有谁能给个指导思想,比如说这个函数应该在哪重载。to caixiaoming
虽然只是短短几行,就已看出你是这行的高手,想来一定很忙,改代码也不好意思劳烦大侠了,能不能向你请教一下使用流的基本思路?使用流不需要excel相关控件吗?要不要建立excel应用?对于excel单元格式能不能起到控制的作用?如能解除疑问将不胜感激
Title: 快速导出数据到Excel(一):利用剪贴板http://blog.csdn.net/nhconch/archive/2005/03/04/310906.aspx
Title: 快速导出数据到Excel(二):利用临时文件http://blog.csdn.net/nhconch/archive/2005/03/06/312810.aspx
Title: 快速导出数据到Excel(三):利用Excel内置功能