procedure DBGridToExcel(dbGrid: TDBGridEh ; fname: string);
const
msoScaleFromTopLeft = $00000000;
msoScaleFromMiddle = $00000001;
msoScaleFromBottomRight = $00000002;
msoTrue = $FFFFFFFF;
msoFalse = $00000000;
var
ExcelObj, WorkBook, Sheet : OleVariant;
OldCursor : TCursor;
Row,Col, FieldIndex:Integer;
dataset: TDataSet;
SaveDialog : TSaveDialog;
saveFileName: string;
begin
{ 如果数据集还未打开,就退出 }
if (dbGrid.DataSource.DataSet = nil) or (dbGrid.DataSource.DataSet.Active =False) or (dbGrid.DataSource.DataSet.RecordCount = 0) then
begin
MessageDlg('无数据!', mtWarning,[mbOK],0);
abort;
end;
SaveDialog:=TSaveDialog.Create(Nil);
saveDialog.FileName:= fname;
//SaveDialog.Filter := 'Microsoft Excel 文件|*.xls';
if SaveDialog.Execute then
begin
UpdateWindow(GetActiveWindow);
saveFileName:= SaveDialog.FileName;
SaveDialog.Free;
end else
begin
SaveDialog.Free;
exit;
end;
dataset:= dbGrid.DataSource.DataSet;
{ 保存当前的鼠标光标,
然后把鼠标光标变成等待光标,表示下面的操作可能要化点时间 }
OldCursor:=Screen.Cursor;
Screen.Cursor:=crHourGlass;
{ 准备转换所需的Excel对象,如果失败,弹出提示 }
try
ExcelObj := CreateOleObject('Excel.Sheet');
//ExcelObj.Application.Visible := Visible ; { 让Excel可不可见 }
{这里没有用ExcelObj.Application.ActiveWorkBook是为了解决
Delphi中的OleVariant对象和实际的Excel对象的生存期冲突 }
WorkBook := ExcelObj.Application.Workbooks.Add ;
Sheet:= WorkBook.Sheets[1];
Sheet.Cells.Font.Size:=9;
Sheet.Cells.Font.Name := 'Arial';
except
MessageBox(GetActiveWindow,'无法调用Mircorsoft Excel! '+chr(13)+chr(10)+
'请检查是否安装了Mircorsoft Excel。','提示',MB_OK+MB_ICONINFORMATION);
Screen.Cursor:=OldCursor;
Exit;
end;
try
{ 转换 : 通过循环,先转换标题,然后转换表内容 }
Sheet.Activate;
// 列标题
Row:=1;
Col:=1;
for FieldIndex:=0 to dbGrid.Columns.Count-1 do
begin
if (dbGrid.Columns[FieldIndex].Field <> nil) then
begin
Sheet.Cells[Row,Col]:=dbGrid.Columns[FieldIndex].Field.DisplayLabel;
Sheet.Cells[Row,Col].Interior.Color := RGB(191,191,191);
Inc(Col);
end;
end;
Sheet.Rows[1].Font.Bold := True;
// 表内容
DataSet.First;
while not DataSet.Eof do
begin
Row:=Row+1;
Col:=1;
for FieldIndex:=0 to dbGrid.Columns.Count-1 do
begin
if (dbGrid.Columns[FieldIndex].Field <> nil) then
begin
if (dbGrid.Columns[FieldIndex].Field.DataType = ftString)
or (dbGrid.Columns[FieldIndex].Field.DataType = ftUnknown)
or (dbGrid.Columns[FieldIndex].Field.DataType = ftWideString) then
begin
Sheet.Cells[Row,Col].NumberFormatLocal:='@'; //设置文本格式
if Length(dbgrid.Columns[FieldIndex].Field.AsString) > 30 then
Sheet.Cells[Row,Col].WrapText := True; //自动换行
end;
Sheet.Cells[Row,Col]:=dbgrid.Columns[FieldIndex].Field.AsString;
Inc(Col);
end;
end;
DataSet.Next;
end;
WorkBook.SaveAs(FileName:= saveFileName);
Application.MessageBox(' 数据已经成功导出到Excel中!','导出成功',MB_OK+MB_ICONINFORMATION);
finally
sheet:=UnAssigned;
{这里没有用ExcelObj.Application.ActiveWorkBook是为了解决
Delphi中的OleVariant对象和实际的Excel对象的生存期冲突 }
WorkBook := UnAssigned;
ExcelObj := UnAssigned;
Screen.Cursor:=OldCursor; { 所有工作已完成,把鼠标光标变为原来的样子 }
end;
end;