用SQL查出的结果显示在DBGrid里,并把DBGride里的内容输出到Excel,每次给出的条件不同,所以每次查出来的结果也就不同,但是我想把每次查出来的结果都保存在同一个Excel文件里并且是把记录追加进去,这样怎么才能做到?我输出到Excel的方法是用的servers组里的:
ExcelApplication
ExcelWorkbook
ExcelWorksheet        三个控件小弟不才,望高手指教,问题解决马上给分。

解决方案 »

  1.   

    用OLE技术,自己用循环写进去,
    interface部分文件包含:ComObj代码:
    var
      ex:Variant;
    begin
      ex:=CreateOleObject('Excel.Application');
      ex.WorkBooks.Open('文件名.xls');
      ex.WorkBooks[1].WorkSheets[1].Activate;
      ex.ActiveSheet.Range['A1'].Value:='值';
      //或者用ex.ActiveSheet.Cells[1,1]:='值';
      ex.WorkBooks[1].Save;
      ex.WorkBooks[1].Close;
      ex.Quit;
      ex:=Unassigned;
    end;
    最好自己用一下异常处理try一下子,
    以免出错,出错可是会被Excel占用至少十多M内存的。
      

  2.   

    上面是写进EXCEL的方法,
    自己用循环,控制一下数据集,
    写进去,
    上面的Range[]和Cells[]里参数都是可以用变量控制的。给你发一段详细的控制代码吧。
    unit MainForm;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ComObj, StdCtrls, Excel2000;type
      TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
    var
      ex,wb:Variant;
    begin
      //更多内容请参考Microsoft VBA帮助(关于Excel的VBA帮助在Office安装目录下
      //文件名为VBAXLx.CHM(x为版本号,office2000为9,officexp为10))  //建立Excel对象之前应该包含ComObj和Excel2000单元,因ComObj中定义了Excel服务器,
      //Excel2000中定义了很多VBA用的常量。  //请使用try..catch结构捕捉运行期间错误,避免在内存中残留Excel实例。  //建立Excel应用程序对象
      try
        ex:=CreateOleObject('Excel.Application');
      except
        MessageBox(Form1.Handle,'您没有安装Excel或Excel出错!!!程序将退出!','警告!',MB_OK);
        Exit;
      end;
      //Open方法打开工作薄(即一个Excel文件),Add方法可以增加一个工作表,(未保存之前)在内存中。
      wb:=ex.WorkBooks.Open(ExtractFilePath(Application.ExeName)+'ole.xls');
      //可以开始对一个Excel文件进行操作.
      ex.Visible:=true;  //让Excel应用程序可见,默认是后台操作。
      //激活工作表中的一个工作蒲,可以用名称或索引,索引起点为1
      wb.WorkSheets[2].Activate;
      //激活工作薄后才可以对单元进行操作。
      //wb.ActiveSheet.Range['C1'].Value:='C1';
      //将值写入单元格或合并区域(指定最左上角的地址)
      wb.ActiveSheet.Range['C1:D2'].Merge;
      //合并单元格,并保留最左上角的值。对应有UnMerge方法解除合并。
      if wb.ActiveSheet.Range['C1'].MergeCells then
      begin
        ShowMessage('"C1"是合并的单元格');
      end;
      //判断地址是否在合并区域中。
      ShowMessage(wb.ActiveSheet.Range['C1'].Address);
      //返回地址的绝对地址,形式:'$C$1'
      ShowMessage(wb.ActiveSheet.Range['C1'].MergeArea.Address);
      //MergeArea返回一个Range对象,如上,如果C1不是合并单元格,则返回Range['C1'],
      //反之,返回合并过的地址,如上显示的是'$C$1:$D$2'(注意返回格式)
      ex.ActiveSheet.Range['E1'].Select;
      ex.Selection.HorizontalAlignment:=xlHAlignCenter;
      //水平对齐方向,有以下值:xlHAlignCenter、xlHAlignDistributed、
      //xlHAlignJustify、xlHAlignLeft 或者 xlHAlignRight。另外,
      //对于 Range 或 Style 对象,可以将此属性设置为
      //xlHAlignCenterAcrossSelection、xlHAlignFill 或 xlHAlignGeneral
      //或用数字表示1为无格式,2为居左,3为居中,4为居右:  //同上VerticalAlignment可以设置垂直对齐方式,值可以为
      //: xlVAlignBottom、xlVAlignCenter、xlVAlignDistributed、
      //xlVAlignJustify 或 xlVAlignTop  wb.ActiveSheet.Rows.RowHeight:=12;
      //设置活动工作蒲中所有行的高,
      wb.ActiveSheet.Rows[1].RowHeight:=12;
      //设置活动工作薄中某一行的高度,以磅为单位,1磅=0.035厘米,若想用厘米,可用
      //n*1/0.035,n为厘米数。
      ShowMessage(wb.ActiveSheet.Range['C1:D2'].Column);
      //返回区域的第一列的索引。
      ShowMessage(wb.ActiveSheet.Range['C1:D2'].Row);
      //返回区域的第一行索引。
      wb.ActiveSheet.Columns[1].ColumnWidth:=20;
      //设置列宽,以英文字符为单位,同上可以设置活动工作薄中所有列宽。  //wb.ActiveSheet.Rows[1].Insert;
      //在某一行之前插入一行。  //wb.ActiveSheet.Columns[1].Insert;
      //在某一列之前插入新列。  //wb.ActiveSheet.Rows[1].Delete;
      //删除相应行,同理,可删除相应列。  //wb.ActiveSheet.Range['C1:D2'].Borders[3].Weight:=4;  //上
      //wb.ActiveSheet.Range['C1:D2'].Borders[4].Weight:=4;  //下
      //wb.ActiveSheet.Range['C1:D2'].Borders[1].Weight:=4;  //左
      //wb.ActiveSheet.Range['C1:D2'].Borders[2].Weight:=4;  //右
      //5-斜( \ ) 6-斜( / )  
      //设置区域格式,边框粗  wb.ActiveSheet.Columns[1].UseStandardWidth:=true;
      //使用标准列宽。  //wb.ActiveSheet.PrintOut;
      //打印工作薄.  wb.ActiveSheet.Range['C1:D2'].Copy;
      wb.ActiveSheet.Range['E2'].PasteSpecial;
      //拷贝区域,从指定地址开始粘贴(粘贴所有内容(包括公式、值和格式))。
      //如果公式为相对地址,则粘贴相对地址,若公式为绝对地下,则粘贴为绝对地址。  Wb.ActiveSheet.UsedRange.Copy;
      //拷贝活动工作薄中使用过区域。  ShowMessage(IntToStr(wb.ActiveSheet.UsedRange.Rows.Count));
      //返回活动工作薄中使用过区域中的行数。
      //wb.ActiveSheet.UsedRange.Rows返回活动工作薄中所用区域行对象
      //wb.ActiveSheet.UsedRange.Columns返回活动工作薄中所用区域列对象  ex.Caption:='asdfafdsafd';
      //Excel应用程序的标题,如上设置后会显示:"asfdasdfa-ole.xls",后一部分为文件名。  //wb.ActiveSheet.Rows[5].PageBreak:=1;
      //在某一行之前添加分页符。设置PageBreak:=0可删除分页。  wb.ActiveSheet.Range['C1:D2'].ClearContents;
      //删除区域公式。  wb.ActiveSheet.Range['D4'].Formula:='=B4+C4';
      //向单元格中写入公式,可用公式请参照VBA帮助。
      //绝对引用'=$B$1+$C$4'
      
      wb.ActiveSheet.Rows[1].Font.Name := '隶书';
      wb.ActiveSheet.Rows[1].Font.Color := clBlue;
      wb.ActiveSheet.Rows[1].Font.Bold := True;
      wb.ActiveSheet.Rows[1].Font.UnderLine := True;
      //设置字体属性。  wb.ActiveSheet.Rows[10].ShrinkToFit:=true;
      //缩写,正好充满整个单元格。  wb.ActiveSheet.Rows[10].WrapText:=true;
      //单元格内数据自动换行,如果行宽太小,则会隐藏,看不到。  //报表设置:
        wb.ActiveSheet.PageSetup.CenterHeader := '报表演示';
        //设置页眉    ex.ActiveSheet.PageSetup.CenterFooter := '第&P页';
        //设置页脚。页眉页脚中可以使用的变量参照VBA帮助。    //c.页眉到顶端边距2cm: (内置单位为磅,需换算成厘米。)
        ex.ActiveSheet.PageSetup.HeaderMargin := 2/0.035;
        //d.页脚到底端边距3cm:
        ex.ActiveSheet.PageSetup.HeaderMargin := 3/0.035;
        //e.顶边距2cm:
        ex.ActiveSheet.PageSetup.TopMargin := 2/0.035;
        //f.底边距2cm:
        ex.ActiveSheet.PageSetup.BottomMargin := 2/0.035;
        //g.左边距2cm:
        ex.ActiveSheet.PageSetup.LeftMargin := 2/0.035;
        //h.右边距2cm:
        ex.ActiveSheet.PageSetup.RightMargin := 2/0.035;
        //i.页面水平居中:
        ex.ActiveSheet.PageSetup.CenterHorizontally := 2/0.035;
        //j.页面垂直居中:
        ex.ActiveSheet.PageSetup.CenterVertically := 2/0.035;
        //k.打印单元格网线:
        ex.ActiveSheet.PageSetup.PrintGridLines := True;   wb.ActiveSheet.PrintPreview;
      //打印预览。
      wb.Save;
      //关闭Excel文件,Saveas(fullfilename)方法可以另存这个工作薄。
      wb.Saved:=true;
      //放弃存盘,即设置已经存盘。
      ex.DisplayAlerts:=false;
      //在退出或操作Excel时不显示任何提示,如没有保存,
      //之类的警告信息。
      wb.Close;
      wb:=Unassigned;  //将Variant变量清空
      //退出Excel程序.
      ex.Quit;
      ex:=Unassigned;  //将Variant变量清空
    end;end.
      

  3.   

    //你参考一下吧!!unit Unit7_16;interfaceuses Windows, Classes, Graphics, Forms, Controls, DB, DBGrids,
      DBTables, Grids, StdCtrls, ExtCtrls, ComCtrls, Dialogs, OleCtrls,
      OleCtnrs, OleServer, Excel2000;type
      TOLE_Form1 = class(TForm)
        Panel1: TPanel;
        InsertBtn: TButton;
        Table1: TTable;
        Table1NAME: TStringField;
        Table1SIZE: TSmallintField;
        Table1WEIGHT: TSmallintField;
        Table1AREA: TStringField;
        Table1BMP: TBlobField;
        ExcelApplication1: TExcelApplication;
        OleContainer1: TOleContainer;
        procedure InsertBtnClick(Sender: TObject);
      end;var
      OLE_Form1: TOLE_Form1;implementationuses ComObj;{$R *.DFM}procedure TOLE_Form1.InsertBtnClick(Sender: TObject);
    var
      aSheet, aChart, series: Variant;
      i: integer;
    begin
      // 显示MS-Excel的运行过程
      ExcelApplication1.Visible[0] := True;  // 创建一个 WorkBook
      ExcelApplication1.WorkBooks.Add(xlWBATWorksheet,0);  // 获取 WorkBook 中的一页 WorkSheet
      aSheet:=ExcelApplication1.Worksheets.Item[1];  // 将Animals.dbf的数据填入Sheet的Cells二维数组内
      aSheet.Cells[1,1].Value:='姓名';
      aSheet.Cells[1,2].Value:='大小';
      aSheet.Cells[1,3].Value:='体重';
      i := 2;
      with Table1 do begin
        Open;
        First;
        while not eof do begin
           aSheet.Cells[i, 1].Value:=FieldByName('Name').AsString;
           aSheet.cells[i, 2].Value:=FieldByName('Size').AsString;
           aSheet.cells[i, 3].Value:=FieldByName('Weight').AsString;
           i:=i+1;
           Next;
        end;
      end;    // 将数据存成Excel格式的文件
      aSheet.SaveAs('C:\a.xls');  // 把 Excel 文件 Insert 到 OleContainer
      OleContainer1.CreateObjectFromFile('C:\a.xls',False);  // 结束MS-Excel的运行
      aSheet.Application.Quit;
    end;end.
      

  4.   

    转贴希望有帮助
    在日常办公中,用得最多的是Word和Excel,而Excel对数据报表的处理尤为方便(操作公式、打印格式等),如果我们将数据导入到Excel中后,再靠我们平时对Excel熟练的操作很快编辑好我们有用的数据(如领导报表等),通过对Excel的控制,我们可以自动编缉好我们想要的格式和外观。
    一、调用Excel的方法:一般情况下有两种方法调用Excel:
    1、 直接使用Delphi自带的组件:在Form中分别放入ExcelApplication, ExcelWorkbook和ExcelWorksheet。
    2、动态创建Excel文件:首先创建 Excel 对象,使用ComObj,Excel2000:
    var ExcelApp: Variant;
    ExcelApp := CreateOleObject( 'Excel.Application' );
    二、导入数据:在程序中,我们可以将查询到的数据(SQL、Access、)导入到Excel中。例如:用Adoquery查询Access中的数据:
    1、先查到所需的数据;
    2、导入:i:=1;
    Adoquery.First;
    while not Adoquery.Eof do
    Begin
    ExcelApp.WorkSheets[1].Cells[i,1].Value := i;//添加序号的值
    ExcelApp.WorkSheets[1].Cells[i,2].Value := Adoquery.FieldByName('cp_name').AsString;
    ……
    Inc(i);
    Adoquery.Next;
    End;
    当然也可以把Adotable、Adoquery、Table、Query等组件的数据导入到Excel中。
    三、Excel的处理:如果在你已知Excel格式的情况下,可以控制Excel,如下:
    1、 显示当前窗口:ExcelApp.Visible := True;
    2、 更改 Excel 标题栏:ExcelApp.Caption := '标题内容';
    3、 添加新工作簿:ExcelApp.WorkBooks.Add;
    4、 设置第2个工作表为活动工作表:ExcelApp.WorkSheets[2].Activate;
    5、 给单元格赋值:ExcelApp.Cells[1,1].Value := '第一行第一列';
    6、 设置指定列的宽度(单位:字符个数),以第一列为例:
    ExcelApp.ActiveSheet.Columns[1].ColumnsWidth := 5;
    7、 设置指定行的高度(单位:磅)(1磅=0.035厘米),以第二行为例:
    ExcelApp.ActiveSheet.Rows[2].RowHeight := 1/0.035; // 1厘米
    8、文字水平居中:Excelid.worksheets[1].Rows[1].HorizontalAlignment := $FFFFEFF4;
    文字垂直居中:Excelid.worksheets[1].Rows[1].VerticalAlignment := $FFFFEFF4;
    9、 插入一行或一列:a. ExcelApp.ActiveSheet.Rows[2].Insert;
    b. ExcelApp.ActiveSheet.Columns[1].Insert;
    10、 删除一行或一列:a. ExcelApp.ActiveSheet.Rows[2].Delete;
    b. ExcelApp.ActiveSheet.Columns[1].Delete;
    11、合并单元格:ExcelApp.worksheets[1].range[A1:F8'].Merge(abc);注:要声明变量abc: Variant;
    12、竖行显示文字:ExcelApp.worksheets[1].Cells.Item[1,1].Orientation:= xlVertical;
    13、单元格加边线:ExcelApp.worksheets[1].Range[A1:F8].Borders.LineStyle := 1;
    14、在第8行之前插入分页符:ExcelApp.WorkSheets[1].Rows[8].PageBreak := 1;
    15、在第4列之前删除分页符:ExcelApp.ActiveSheet.Columns[4].PageBreak := 0;
    16、指定边框线宽度:ExcelApp.ActiveSheet.Range[ 'B3:D4' ].Borders[2].Weight := 3;
    1-左 2-右 3-顶 4-底 5-斜( \ ) 6-斜( / )
    17、拷贝操作:a.拷贝整个工作表:ExcelApplication1.ActiveSheet.Used.Range.Copy;
    b.拷贝指定区域:ExcelApplication1.ActiveSheet.Range[ 'A1:E2' ].Copy;
    c.从A1位置开始粘贴:ExcelApplication1.ActiveSheet.Range.[ 'A1' ].PasteSpecial;
    d.从文件尾部开始粘贴:ExcelApplication1.ActiveSheet.Range.PasteSpecial;
    18、清除第一行第四列单元格公式:ExcelApp.ActiveSheet.Cells[1,4].ClearContents;
    19、工作表保存:if not ExcelApp.ActiveWorkBook.Saved then
    ExcelApp.ActiveSheet.PrintPreview;
    20、工作表另存为:ExcelApp.SaveAs( 'C:\Excel\Demo1.xls' );
    21、放弃存盘:ExcelApp.ActiveWorkBook.Saved := True;
    22、关闭工作簿:ExcelApp.WorkBooks.Close;
    23、退出 Excel:ExcelApp.Quit;
    下面是有关打印页面控制的语句:
    24、设置第一行字体属性:ExcelApp.ActiveSheet.Rows[1].Font.Name := '隶书';
    ExcelApp.ActiveSheet.Rows[1].Font.Color := clBlue;
    ExcelApp.ActiveSheet.Rows[1].Font.Bold := True;
    ExcelApp.ActiveSheet.Rows[1].Font.UnderLine := True;
    ExcelApp.ActiveSheet.Rows[1].Font.size:=10;
    25、进行页面设置:a.页眉:ExcelApp.ActiveSheet.PageSetup.CenterHeader := '报表演示';
    b.页脚:ExcelApp.ActiveSheet.PageSetup.CenterFooter := '共&N页 第&P页';
    c.页眉到顶端边距2cm:ExcelApp.ActiveSheet.PageSetup.HeaderMargin := 2/0.035;
    d.页脚到底端边距3cm:ExcelApp.ActiveSheet.PageSetup.HeaderMargin := 3/0.035;
    e.顶边距2cm:ExcelApp.ActiveSheet.PageSetup.TopMargin := 2/0.035;
    f.底边距2cm:ExcelApp.ActiveSheet.PageSetup.BottomMargin := 2/0.035;
    g.左边距2cm:ExcelApp.ActiveSheet.PageSetup.LeftMargin := 2/0.035;
    h.右边距2cm:ExcelApp.ActiveSheet.PageSetup.RightMargin := 2/0.035;
    i.页面水平居中:ExcelApp.ActiveSheet.PageSetup.CenterHorizontally := 2/0.035;
    j.页面垂直居中:ExcelApp.ActiveSheet.PageSetup.CenterVertically := 2/0.035;
    k.打印单元格网线:ExcelApp.ActiveSheet.PageSetup.PrintGridLines := True;
    26、打印预览工作表:ExcelApp.ActiveSheet.PrintPreview;
    27、打印输出工作表:ExcelApp.ActiveSheet.PrintOut;
    对Excel的其他控制:
    28、excel的多单元格合计功能:ExcelApp..Cells[ARow, ACol].Formula
    := '= SUM($+IntToStr(BeginRow) +:$ + IntToStr(EndRow) +');
    注:声明变量ARow, ACol: Integer;
    29、打开已经存在的Excel文件: ExcelApplication1.Workbooks.Open (c:\a.xls
    EmptyParam,EmptyParam,EmptyParam,EmptyParam,
    EmptyParam,EmptyParam,EmptyParam,EmptyParam,
    EmptyParam,EmptyParam,EmptyParam,EmptyParam,0);
    在实际当中还有很多的控制分类,如(Excle二维图等,这里不讲了),这里是一些常用的分类,在这希望同行们没给于指正、补充!
    注:在数据倒入Excel时不要边倒入边修改,这样会使倒入到Excel的时间加长,一般最好是在倒入完数据后再调Excel的格式(例如页边距、单元个属性、文字属性)。
      

  5.   

    那样写的话速度会很慢
    以前写过类似的程序
    给你看一下可以借鉴一下
    var
    asheet,range:variant;
    i,K,M,N,y :integer;
    ls_FileName:string;
    tsList  :TStringList;
    s       :string;
    begin
    if SaveDialog1.Execute then begin
    Screen.Cursor:=crHourGlass;
    ls_FileName:=SaveDialog1.FileName;
    ExcelApplication1.Visible[0]:=False;
    ExcelApplication1.Workbooks.Add(xlWBATWorksheet,0);
    asheet:=ExcelApplication1.Worksheets.Item[1];
    i:=DBGrid1.DataSource.DataSet.FieldCount;
    range:=asheet.range[asheet.cells[1,1],asheet.cells[1,i]];
    range.merge;
    range.HorizontalAlignment:=xlCenter;
    range.Font.Size:=14;
    frmDataModule.TMstatement.Locate('Flags',1,[]);
    range.value:=Trim(frmDataModule.TMstatement.FieldByName('sqlName').Value);
    for i:=0 to DBGrid1.Columns.Count-1 do
    asheet.cells[2,i+1].value:=Trim(DBGrid1.Columns.Items[i].Title.Caption);
    K:=1;
    N:=DBGrid1.Columns.count;
    I:=DBGrid1.DataSource.DataSet.RecordCount;
    tsList:=TStringList.Create;
    try
    DBGrid1.DataSource.DataSet.first;
    while not DBGrid1.DataSource.DataSet.Eof do
    begin
                        s:='';
                        for y:=0 to n-1 do
                        begin
                            s:=s+Trim(DBGrid1.DataSource.DataSet.Fields[y].AsString)+#9;
                            Application.ProcessMessages;
                        end;
                        tsList.Add(s);
                        DBGrid1.DataSource.DataSet.next;
                    end;
                Clipboard.AsText:=tsList.Text;
        finally
            tsList.Free;
        end;
        ExcelApplication1.Disconnect;
        asheet.cells[3,1].select;
        aSheet.Paste;
        range:=asheet.range[asheet.cells[2,1],asheet.cells[DBGrid1.DataSource.DataSet.RecordCount+2,DBGrid1.DataSource.DataSet.FieldCount]];
        range.select;
        range.borders.linestyle:=1;
        for i:=1 to DBGrid1.DataSource.DataSet.FieldCount do begin
        range:=asheet.range[asheet.cells[1,i],asheet.cells[DBGrid1.DataSource.DataSet.RecordCount,i]];
        range.EntireColumn.AutoFit;
        end;
        aSheet.Saveas(ls_FileName);
        MessageBox(Application.Handle,'数据导出完毕!','系统提示',MB_ICONINFORMATION or MB_OK);
        Screen.Cursor:=crDefault;
        ExcelApplication1.Quit;
        ExcelApplication1.Disconnect;
        aSheet:=Unassigned; //释放VARIANT变量
        DBGrid1.DataSource.DataSet.First;end;
    end;如果追加的话,可以打开你所保存的那个文件然后,先判断一下CELLS是否为空,如果为空就开始接着写
    打开的代码:Workbooks.Open Filename:="路径"