关于把DBGrid导出为Excel文件的问题,进来交流一下好吗?(200分)

  • 主题发起人 forgot2002
  • 开始时间
自己用这个写
aaa:=createobject("excel.appliction")
aaa.cell[x,y]:=dbgrideh.cell[x,y]
 
倒入数据其实很简单的,自己看看VBA,用DELPHI操作EXCEL也非常的方便。

不过借此俺也要问一个遗留问题,如何设置Rangs['A1:M1']中的常量为变参/
 
对这种问题,你可以通过录制宏来查看vba代码,转化到delphi中使用。。。
 
ExpressQuantumGrid
 
如何设置Rangs['A1:M1']中的常量为变参:
利用ASCII码来进行
 
我覺得還是自己寫,當然要偷懶要想對辦法:),我一般自己寫
 
从query或Table中利用OLE直接写入EXCEL不行吗?
 
写了一个将 DBGrid 到处到 Excel 的过程,功能简单,但也实用。
代码:
procedure ExportDBGridToExcel(Grid: TDBGrid; DisableScreenUpdating: Boolean);
const
  CLASS_ExcelApplication: TGUID = '{00024500-0000-0000-C000-000000000046}';

var
  ExcelApp: OleVariant;
  Unknown: IUnknown;
  Bm: TBookmarkStr;
  Col, Row: Integer;
  I: Integer;
begin
  if (Grid.DataSource <> nil) and (Grid.DataSource.DataSet <> nil) then
    with Grid.DataSource.DataSet do
    begin
      try
        if not Succeeded(GetActiveObject(CLASS_ExcelApplication, nil, Unknown)) then
          Unknown := CreateComObject(CLASS_ExcelApplication);
      except
        raise Exception.Create('不能启动 Microsoft Excel,请确认 Microsoft Excel 已正确安装在本机上');
      end;
      ExcelApp := Unknown as IDispatch;
      ExcelApp.Visible := True;
      ExcelApp.Workbooks.Add;
      if DisableScreenUpdating then
        ExcelApp.ScreenUpdating := False;
      DisableControls;
      try
        Bm := Bookmark;
        First;
        Row := 1;
        Col := 1;
        for I := 0 to Grid.Columns.Count - 1 do
        begin
          if Grid.Columns[I].Visible then
            ExcelApp.Cells[Row, Col] := Grid.Columns[I].Title.Caption;
          Inc(Col);
        end;
        Inc(Row);
        while not EOF do
        begin
          Col := 1;
          for I := 0 to Grid.Columns.Count - 1 do
          begin
              if Grid.Columns[I].Visible then
                ExcelApp.Cells[Row, Col] := Grid.Columns[I].Field.DisplayText;
              Inc(Col);
          end;
          Inc(Row);
          Next;
        end;
        Col := 1;
        for I := 0 to Grid.Columns.Count - 1 do
        begin
          if Grid.Columns[I].Visible then
            ExcelApp.Columns[Col].AutoFit;;
          Inc(Col);
        end;
        Bookmark := Bm;
      finally
        EnableControls;
        if not ExcelApp.ScreenUpdating then
          ExcelApp.ScreenUpdating := True;
      end;
    end;
end;

qiuliang
http://qiuliang.mycool.net
 
说了多少次了,不是把DBGrid导入Excel,而是DBGridEh导入Excel,而且要有标题列合并单元格
的功能。
 
FORGOT2002:兄弟在东莞哪儿?有空出来喝茶
 
楼上的兄弟怎么知道我在东莞?我在桥头,你呢?
 
我在莞城,QQ:21323154
 
我在莞城或茶山:
QQ 7177136
 
EXCEL的格式很少人研究透,不过你如果急于要实现这个功能的话可以这样,
先导出为HTML文件,然后用EXCEL打开,
如果导出的HTML文件语法正确的话,格式是不会丢的。

怎么这么多东莞的啊,我以前在东莞的时候怎么一个也见不到?呵呵。。
各位待遇怎么样?如果不错的话我也再跑出来算了。
 
/程序说明开始
//============================================================================//
// 单元: ExcelTools
// 编者: 孟宪宝
// 资料: 程序员Borlad专刊
//
// 功能设计: 保存数据集,如 TTable,TQuery,TClientDataSet,wwTable 等为Excel文
// 件包含标题,可以只将一部分字段导出这一点通过设置DataSet中要不导
// 出字段的Tag值大于一个值来处理
// 函数设计:1。DataSetToExcelSheet:把数据集转换到Sheet对象中,没有用户界面。
// 2。DataSetToExcel:调用DataSetToExcelSheet,把数据集转换到Excel
// 文件中。
// 具有用户界面,如弹出对话框,错误提示,显示Excel等。
// 调用方式:Function DataSetToExcel(
// Dataset:TDataSet;
// FieldTagMax:Integer;
// Visible:Boolean;
// ExcelFileName:String='' )
// 日期:2002/8/4.11:29
//============================================================================//

unit UnitExcelTools;

interface
uses
Classes,Comctrls,Stdctrls,Windows,Dialogs,Controls,Sysutils,Db,forms,DBClient,ComObj;
function DatasetToExcelsheet
(
DataSet:TDataSet;
FieldTagMax:integer; //字段的Tag值如果大于这个值,就不导出到Excel
Sheet:OleVariant
):Boolean;
function DatasetTOExcel
(
DataSet:TDataset; //要转换的数据集
FieldTagMax:Integer; //字段的Tag值如果大于这个值就不导出到Excel
Visible:Boolean; //时否让做转换工作的Excel可见
ExcelFileName:String='' //Excel文件名 *.xls
):Boolean;
implementation

function DataSetToExcelsheet(Dataset:Tdataset;FieldTagMax:Integer;
Sheet:OleVariant):boolean;
var
Row,col,FieldIndex:Integer;
BK:TBookMark;
begin
Result:=False;
{ TODO :如果数据集未打开,就退出 }
if Not DataSet.Active then exit;
{ TODO : 记录数据集当前记录位置 }
BK:=Dataset.GetBookmark;
DataSet.DisableControls;
{ TODO : 转换:通过循环,先转换标题,然后转换表内容。 }
Sheet.Activate;
try
{ TODO : 列标题 }
Row:=1;
Col:=1;
for FieldIndex:=0 to DataSet.FieldCount-1 do
begin
if DataSet.Fields[FieldIndex].Tag<=FieldTagMax then
begin
Sheet.Cells(Row,COl):=DataSet.Fields[FieldIndex].DisplayLabel;
Inc(Col);
end;
end;

{ TODO : 表内容 }
DataSet.First;
while not DataSet.Eof do
begin
Row:=Row+1;
Col:=1;
for FieldIndex:=0 to DataSet.FieldCount-1 do
begin
if DataSet.Fields[FieldIndex].Tag<=FieldTagMax then
begin
Sheet.Cells(Row,Col):=DataSet.Fields[FieldIndex].AsString;
Inc(Col);
end;
end;
DataSet.Next;
end;

Result:=True;
{ TODO : 最后回到数据集原来的位置,恢复显示控制的同步显示。 }
finally
DataSet.GotoBookmark(BK);
DataSet.EnableControls;
end;

end;


Function DataSetToExcel(
DataSet:TDataSet;FieldTagMax:Integer;
Visible:Boolean;
ExcelFilename:String=''):Boolean;
var
ExcelObj,WorkBook,Sheet:OleVariant;
OldCursor:TCursor;
SaveDiaLog:TsaveDialog;
begin
Result:=False;
{ TODO : 如果数据集还未打开,就退出 }
if not DataSet.Active then exit;
{ TODO :保存当前的鼠标光标,然后把鼠标光标变成等待光标,
表示下面的操作可能要花点时间 }
OldCursor:=Screen.Cursor;
Screen.cursor:=CrHourGlass;

{ TODO : 准备转换所需的Excel对象,如果失败,弹出提示 }
try
ExcelObj:=CreateOleObject('Excel.sheet');
ExcelObj.Application.Visible:=Visible; { TODO : 让Excel可不可见 }

{ TODO :这里没有用ExcelObj.Application.ActiveWorkBook是为了解决
Delphi中的OleVariant对象和实际的Excel对象的生存期冲突。 }
WorkBook:=ExcelObj.Application.Workbooks.Add;

Sheet:=WorkBook.Sheets[1];

except
MessageBox(GetActiveWindow,'无法调用Mircorsoft Excel!'+Chr(13)+Chr(10)+'请检查是否安装了Mircorsort Excel.','提示',
MB_OK+MB_ICONINFORMATION);
Screen.Cursor:=OldCursor;
Exit;
end;

{ TODO :如果Excel是不可见的,就要保存为文件,如果没有提供
文件名,就弹出文件保存对话框,让用户选择文件名。 }
if (not visible)and(ExcelFileName='')then
begin
SaveDialog:=TSaveDialog.Create(Nil);
SaveDialog.Filter:='Microsoft Excel 文件|*.xls';
SaveDialog.Execute;

UpDateWindow(GetActiveWindow);
ExcelFileName:=SaveDialog.FileName;
SaveDialog.Free;
end;

{ TODO : 转换!Excel这时可视或不可视 }
if(Visible or(ExcelFileName<>'' )) then
begin
{ TODO : 调用DataSetToExcelSheet函数 }
Result:=DataSetToExcelSheet(DataSet,FieldTagMax,Sheet);
end;

{ TODO : 如果不可视,且转换成功,就保存到文件夹中 }
if((not visible)and Result ) then
begin
WorkBook.SaveAs(Filename:=ExcelFilename);
WorkBook.Close;
end;

{ TODO : 所有工作已完成,把鼠标光标变成原来的样子 }
Screen.Cursor:=OldCursor;

end;

end.



实现
procedure TForm1.Button1Click(Sender: TObject);
begin
DataSetToExcel
(
Table1,
0,
true,
'Hello1.xls'
);
end;
 
补充 对于DBGridEh我也试验了 可以的,其实只是对数据集的改变,无论什么显示控件。
没有太大的关系!!!
 
对于dbgrid ,dataset-->Excel小弟也做过
一般采用ole,dde,写文件
写文件的话,一般不支持excel2000,M$没有公开格式,只能97或一下的版本格式
自己写代码也好,找控件也好,我最关心的就是---安全、稳定、全面
----东莞莞城涡岭
 
强烈建议使用dxDBGrid,可以导出Excel, XML格式, 并且能够解决以上提出的问题.
 
数据导入EXCEL
 


uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, Buttons, StdCtrls, ExtCtrls, DB, DBTables,Excel2000,OleServer,ComObj,
Grids, DBGrids, DBCtrls;


var
myexcel:variant;
workbook:eek:levariant;
worksheet:eek:levariant;
begin
try
myexcel:=createoleobject('excel.application');
myexcel.application.workbooks.add;
myexcel.caption:=q+'至'+w+'客情预订表';
myexcel.application.visible:=true;
workbook:=myexcel.application.workbooks[1];
worksheet:=workbook.worksheets.item[1];
except
showmessage('EXCEL不存在!');
end;
i:=1;
j:=4;
if q<>w then
worksheet.Cells(i,j):=q+'至'+w+'客情预订表'
else
worksheet.Cells(i,j):=q+'客情预订表';
i:=2; //EXECL表行号
n:=0;//query字段N序号
j:=1;//EXECL表列号
form23.Query1.First;
for n:=0 to form23.Query1.FieldCount -1 do
begin
worksheet.Cells(i,j):=form23.Query1.fields[n].DisplayLabel;
j:=j+1;
end;
i:=2; //EXECL表行号
n:=0;//query字段N序号
i:=2;//EXECL表行号

i:=2;
form23.query1.first;
while not form23.query1.eof do
begin
inc(i);
for j:=0 to form23.query1.fieldcount-1 do
worksheet.cells[i,j+1]:=form23.query1.fields[j].asstring;
form23.query1.next;
end;

 
顶部