要把查询出的数据全部导出,大概上万条记录,要等好久,有什么快速导出方法吗?
请高手赐教

解决方案 »

  1.   

    上万条记录要是用execl.application这种方法的话,是太慢了。容易死机。
    我现在基本都用一个dbgrideh控件,把这上万条记录显示出来。然后用它提供的导出函数,大概几秒种。
      

  2.   

    我看不少朋友都是连接了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;
    这种导入数据的方式绝对很快,可是是一般导入方式的几十甚至上百倍.
      

  3.   

    hxshaou(晓子) 能再说详细点吗,俺也越到搂住这样的问题了。数据一多就等吧。
    谢谢hxshaou(晓子) 了。
      

  4.   

    Tod707070(幸福的秋天)的方法也可以,但是还有点慢,4000条数据要10多秒,我现在每次起码要导出2万条记录,并且格式也有点乱,能否可以调整格式hxshaou(晓子) 能再说详细点吗?我现在也是用的这个控件,但是没有你们说的函数啊?
    请赐教。
      

  5.   

    如果有格式,快速导入就有麻烦,没有格式,我使用TdxDbGrid提供的导入速度也不错。我想知道的是有格式的情况下,如何控制格式,速度又快
      

  6.   

    思路可以再扩展点,为何要一条条导入呢。如果能将表格中数据直接复制,然后执行一个粘贴不就很快了。哈哈。JSP的就可以这么干,但delphi的没尝试过。路过
      

  7.   

    如果你使用DBGRIDEH控件可以使用下列过程导出:
     {
    * ********************************************************************************************************************** *
    * * 函数: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;
      

  8.   

    to must0001(飞鸟) 
    你这种方法是不是还有引用什么单元
      

  9.   

    blogkevin(中土):
    我的方法不慢呀,如果要是说瓶颈主要是从DataSet里面把数据写入文件的过程,使用这个过程的时候一定要先执行DataSet.DisableControls,一般我即使倒十万条数据也就不到10秒
      

  10.   

    下载一个 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('没有数据表格可供导出') ;