如何提高sql server数据库用程序转存为excel格式的速度?

gardenyang 2003-06-26 09:17:12
客户要求我的程序出来结果能够自动转存到excel表格中,但是转的过程必须要进行数据处理,不能使用sql server的数据导出工具来实现,用程序控制后我发现我导出1000条数据需要30分钟,我的机器p4 2.4,肯定不是我的机器问题,大家有没有类似的经验或者由高效导出的方法?万分感谢!

我现在采用excelapplication,excelworkbook,excelworksheet的模式进行数据转存,我发现所有的数据都是在内存中完成的,另外一个系统采用水晶报表的自动转存方式只需要几秒钟就可以完成,为什么会有这么大的差距呢?谁能够给我解释一下?
...全文
1374 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
nmqhzh 2003-07-01
  • 打赏
  • 举报
回复
学习中!
我只会OLE方式。的确很慢!但因为OLE方式可以定义EXCEL表格式,所以还在用它。用户还得装EXCEL(并要注意EXCEL版本问题)。确实很烦。市面上倒是有些导入导出控件,但未见到可自定义表格式的。谁见了,贴个地址,大伙共享啊!:)
另:F417可将用友UFO表格式转成EXCEL(也可反向转化),不知是用了什么方法?
galaxyahn 2003-07-01
  • 打赏
  • 举报
回复
to:hardworder(苦命人)
请问用你说的方法怎么能限定数据的格式?
如:记录身份证号码,用字符记录.但一转到Excel中就会变为数字.
Forwardrun 2003-07-01
  • 打赏
  • 举报
回复
谢谢yzykjh(多米诺骨牌),你的方法very good,帮我解决了一个大难题
hardworder 2003-07-01
  • 打赏
  • 举报
回复
终于找到一种速度快而且简单的办法了!!!

不要Excel也可生成xls文件 ! dogbear2000(原作)

关键字 Excel xls 数据导出

不要Excel也可生成xls文件

无需Excel也可以把任何数据保存为一个Excel可以读取的xls文件。你可以用记事本生成一个Test.txt文件:

Name Age
Bell 24
Wang 34
Gates 43

然后存盘,把文件名改为Test.xls。注意字段之间用Tab键隔开,而不是空格。然后双击该文件,好事发生了,该文件被Excel打开了,并读出了其中的数据。每一个字段中的数据都放在了一个Cell中。(Excel2000)

事实上,字段分割符可以是任何字符,如分号,逗号,空格。不过,在这些情况下(分割符不是Tab),Excel会弹出数据导入向导对话框,问你以什么字符作为分割符,以及日期的转换格式等等。

结论:Excel对于纯文本内容的xls文件,会试图将其看作一个文本表格,每一行认为是一条记录,行中以分割符分开的各个部分认为是记录的各个字段的值。缺省的分割符是Tab制表符。

这样,任何数据集都可以简单地通过往一个文本文件中写数据,而生成一个Excel可读的xls文件了。在Delphi中,Tab制表符以#9表示,如:LineStr := Str1 + #9 + Str2 。

这样的优缺点:
1、导出数据无需Excel。
2、导出速度较快。
3、读取速度较慢。(Excel要转化数据格式)


gardenyang 2003-06-30
  • 打赏
  • 举报
回复
up
firetoucher 2003-06-29
  • 打赏
  • 举报
回复
还是建议用sqlserver的,不知道是要什么处理,在sqlserver里处理(用存储过程等)不行么?
或者在delphi中用sqldmo调用传输以后,然后再修改excel
gardenyang 2003-06-29
  • 打赏
  • 举报
回复
再给我发一遍把
Hank 2003-06-27
  • 打赏
  • 举报
回复
我可以很负责的告诉你:
1、用TExcelApplication不但速度慢,而且用户必须安装Excel,你能肯定这一点吗?
2、用我的方法测试你的程序,我相信1000条记录不会超出5秒钟
liuziwei_china 2003-06-27
  • 打赏
  • 举报
回复
to hardworder and gardenyang:

发过去了
myling 2003-06-27
  • 打赏
  • 举报
回复
这个没研究过


只能学习了
blueshu 2003-06-27
  • 打赏
  • 举报
回复
bcp比较快
ole特慢
yzykjh 2003-06-27
  • 打赏
  • 举报
回复
将SQL SERVER中查询到的数据导成一个Excel文件

-- ======================================================

T-SQL代码:

EXEC master..xp_cmdshell 'bcp 库名.dbo.表名out c:\Temp.xls -c -q -S"servername" -U"sa" -P""'

参数:S 是SQL服务器名;U是用户;P是密码

说明:还可以导出文本文件等多种格式



实例:EXEC master..xp_cmdshell 'bcp saletesttmp.dbo.CusAccount out c:\temp1.xls -c -q -S"pmserver" -U"sa" -P"sa"'



EXEC master..xp_cmdshell 'bcp "SELECT au_fname, au_lname FROM pubs..authors ORDER BY au_lname" queryout C:\ authors.xls -c -Sservername -Usa -Ppassword'



在VB6中应用ADO导出EXCEL文件代码:

Dim cn As New ADODB.Connection

cn.open "Driver={SQL Server};Server=WEBSVR;DataBase=WebMis;UID=sa;WD=123;"

cn.execute "master..xp_cmdshell 'bcp "SELECT col1, col2 FROM 库名.dbo.表名" queryout E:\DT.xls -c -Sservername -Usa -Ppassword'"

注意:参数区分大小写。
Drate 2003-06-27
  • 打赏
  • 举报
回复
利用剪贴板实现高速导出数据到Excel amei2000go(原作)

关键字 Excel



在很多的时候,我们需要将我们的数据导出到Excel中进行加工,在Access中有现成的工具可以实现
可是在Delphi中却偏偏没有,无论如何我们需要这么一个工具,那么,事不宜迟,细细一想,最好的方法莫过
于直接在程序中按照Excel的格式生成Excel文件,使用Ole技术直接调用Excel实例,由于第一种方法技术实现
过于复杂,好在一般的计算机上已经安装了Office,在此就第二种方法“抛一块砖”。
在此做一个示例以方便说明,我们考虑到导出数据有很多的情况是Master/Detail数据,因此就用两个
TQuery和一个TDataSource,如果有更多的层次,只需要增加TQuery和TDataSource即可,以下使用了两个TQuery
,分别是:qryMaster和qryDetail,一个TDataSource:dsSource;
步骤是:
1.建立一个Excel实例
2.创建一个工作表
3.创建一个TStringList,用来装数据
4.穷举数据表,将数据存入TStringList
5.将TStringList的数据复制到剪贴板
6.把剪贴板中的数据粘贴到Excel
本方法的优点在于:比逐条写入到Excel中的速度大大提高,我曾试过,在P3933,256M的机器上用普通
的方法,导出1000条数据大约需要2分钟,而该用本方法后只需要8秒。

function ToExcel():boolean;
var
y :integer;
tsList :TStringList;
s :string;
aSheet :Variant;
begin
result:=true;
Excel.Connect; // 打开Excel
Excel.Visible[0]:=true; // 显示Excel
Excel.Workbooks.Add(xlWBATWorksheet,0);
aSheet:=excel.Worksheets.Item[1];

tsList:=TStringList.Create;
try
try
with qryMaster do
begin
Open;
First;
While Not Eof do
begin
s:='';
for y:=0 to FieldCount-1 do
begin
s:=s+Fields[y].AsString+#9;
Application.ProcessMessages;
end;
tsList.Add(s);
// 从表
if qryDetail<>nil then
begin
with qryDetail do
begin
Open;
First;
while Not Eof do
begin
s:='';
for y:=0 to FieldCount-1 do
begin
s:=s+Fields[y].AsString+#9;
Application.ProcessMessages;
end;
tsList.Add(s);
next;
end;
end;
end;
next;
end;
Close;
end;
Clipboard.AsText:=tsList.Text;
except
result:=false;
end;
finally
tsList.Free;
end;

Excel.Disconnect;
aSheet.Paste;
MessageBox(Application.Handle,'数据导出完毕!','系统提示',MB_ICONINFORMATION or MB_OK);
end;



pandengzhe 2003-06-27
  • 打赏
  • 举报
回复
网上很多例子都不行?
bycong 2003-06-27
  • 打赏
  • 举报
回复
使用多线程吧!
:)
newsofter 2003-06-27
  • 打赏
  • 举报
回复
通过DBGRid直接导出到Excel,并且只导出DBGRid显示字段
Procedure TurnToExcel(TmpDBGrid:TDBGrid);
var
MyExcel: Variant;
WorkBook: OleVariant;
WorkSheet: OleVariant;
i,j:integer;
xlsfilename :string;
Savedialog1 :TSaveDialog;
begin
if Application.MessageBox('确认导出到Excel?',App_caption,MB_ICONQUESTION+MB_YESNO)=mrno then
Abort;
SaveDialog1 :=TSaveDialog.create(Application);
SaveDialog1.Filter := 'Excel文件(*.xls)|*.XLS';
if savedialog1.Execute then
if savedialog1.FileName <>'' then
begin
xlsfilename :=savedialog1.FileName;
try
MyExcel:=CreateOleObject('Excel.Application');
MyExcel.Application.WorkBooks.Add;
MyExcel.Caption:='将数据导入到EXCEL表中';
MyExcel.Application.Visible:=false;
WorkBook:=MyExcel.Application.workbooks[1];
worksheet:=workbook.worksheets.item[1];
except
Application.MessageBox('EXCEL不存在!',App_caption,MB_ICONERROR+MB_OK);
Savedialog1.Free;
workBook.Saved := True;
WorkBook.close;
MyExcel.Quit;//释放VARIANT变量
MyExcel:=Unassigned;
end;
i:=1;
Frm_system_progress :=TFrm_system_progress.create(Application);
Try
with TmpDBGrid.DataSource.DataSet do
begin
Open;
DisableControls;
with Frm_system_progress.ProgressBar_temp do
begin
min :=0;
max :=TmpDBGrid.Columns.Count*recordcount;
Position :=0;
end;
Frm_system_progress.label_progress.caption :='正在导出到Excel...';
Frm_system_progress.Show;
Frm_system_progress.update;
for j:=0 to TmpDBGrid.Columns.Count-1 do
begin
if TmpDBGrid.Columns[j].Visible=true then
worksheet.cells[1,j+1]:=TmpDBGrid.Columns[j].Title.Caption;
end;
First;
while not Eof do
begin
inc(i);
for j:=0 to TmpDBGrid.Columns.Count-1 do
begin
if TmpDBGrid.Columns[j].Visible=true then
begin
worksheet.cells[i,j+1].NumberFormatLocal :='@';
worksheet.cells[i,j+1]:=TmpDBGrid.Columns[j].Field.AsString ;
Frm_system_progress.ProgressBar_temp.StepIt;
end;
end;
next;
end;
EnableControls;
end;
WorkBook.saveas(XlsFileName);
Frm_system_progress.ProgressBar_temp.position :=TmpDBGrid.Columns.Count*TmpDBGrid.DataSource.DataSet.RecordCount;
Application.MessageBox('导出到Excel成功!',App_caption,MB_ICONINFORMATION+MB_OK);
Frm_system_progress.Free;
MyExcel.Quit;
MyExcel := Unassigned;
Savedialog1.Free;
except
Application.MessageBox('导出到Excel失败!',App_caption,MB_ICONWARNING+MB_OK);
workBook.Saved := True;
WorkBook.close;
MyExcel.Quit;//释放VARIANT变量
MyExcel:=Unassigned;
Frm_system_progress.Free;
Savedialog1.Free;
end;
end;

end;
gardenyang 2003-06-26
  • 打赏
  • 举报
回复
liuziwei_china(liuziwei) 能不能法导我的信箱里面?
yangmanyuan@sina.com
yangmanyuan@sohu.com
hardworder 2003-06-26
  • 打赏
  • 举报
回复
我也碰到了这个问题,情况挺惨,问题一直到现在还没解决!!!谁能来帮我一把,多谢了.
我采用excelapplication,excelworkbook,excelworksheet的模式进行数据转存,我发现所有的数据都是在内存中完成的,昨天程序在运行时需要将数据转出来,结果在将出到346条记录时程序就再也没动了,也没有报错,本人按ctrl+alt+del强行退出后,软件就再也进不去了,系统提示如下:
gnsalary 在0000:7fc39e61的模块
<末知>中导致无效页错误
Registers:
EAX=7fc39e61 CS=0167 EIP=7fc39e61 EFLGS=00010202
EBX=0071fe2c SS=016f ESP=00620080 EBP=00620330
ECX=00000000 DS=016f ESI=816273e0 FS=2b0f
EDX=c00309f8 ES=016f EDI=81627684 GS=0000
Bytes at CS:EIP

Stack dump
bff9e02c 00620340 00620408 81627640 0071fe2c 00000000 00000000 00000000 00000000
00000000 00000000 00000000 0000000000000000 00000000 00000000
liuziwei_china 2003-06-26
  • 打赏
  • 举报
回复
用excelapplication,excelworkbook,excelworksheet的格式当然很慢了
我这有直接写入文件的,不需要用到EXCEL,如果要就说一声
kingcollar 2003-06-26
  • 打赏
  • 举报
回复
可以参考Ehlib For D6中的dbgrideh提供的输入出功能。

2,498

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 数据库相关
社区管理员
  • 数据库相关社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧