使用微软提供的接口来操纵office系列是很有趣的,这里以编程操纵Excel为例
实现目标:把数据集中的数据导出到Excel中
实现思路:利用com技术,创建com对象,通过com对象提供的接口操作office系列。
实现方法:在Delphi下实现数据的导出到Excel功能
开发心得:很多人实现此类功能时匆匆从网上下载现有的代码来交差,功能实现了,但是不知道真正的原理,下次遇到此类问题还是上网查找源代码,其实此类问题不难,只要理解面向对象的意义以及com技术相关就可以了,微软的应用很多都是用com技术,只要你理解其实现原理很多应用领域都可以做到,遇到问题也不会手忙脚乱,起码知道从哪里查找问题。
之前我看过一本书叫com组件开发,本次做这个小程序我从微软提供dll入手的,在office的安装目录下有Microsoft Office/Office12/excel.exe(oxc,dll),用delphi打开此exe后就能看到微软公布的所有com的 coclass 以及相关的类(.net中有所不同,因为.net平台在此基础上再进行了封装),还可以到msdn查看说明。
源代码:
1.当前类声明变量
ExcelApp: variant;
WorkBooks: variant;
WorkBook: variant;
Sheets: variant;
2.自己编写导出函数
procedure TForm1.fillExcel(lSheet: variant; DataSet: TDataSet;DbGrid: TDBGrid);
var
i,j,row: Integer;
begin
try
row := 1;
for i:= 0 to DbGrid.Columns.Count-1 do
begin
lSheet.cells[row,i+1] := DbGrid.Columns[i].Title.Caption;
//控制格式
lSheet.cells[row,i+1].Font.Color := clBlue;
lSheet.cells[row,i+1].Font.Name := 'Arial';
lSheet.cells[row,i+1].Font.Size := 12;
lSheet.cells[row,i+1].Font.Bold := true;
//lSheet.columns[i+1].columnwidth := DbGrid.Columns[i].Width;
end;
inc(row);
if (DataSet.IsEmpty) or (not DataSet.Active) then exit;
DataSet.First;
if not pnlDown.Visible then pnlDown.Visible := not pnlDown.Visible;
RzPBDown.TotalParts := DataSet.RecordCount;
for i:= 0 to DataSet.RecordCount -1 do
begin
RzPBDown.PartsComplete := i+1;
for j:= 0 to DataSet.Fields.Count -1 do
begin
lSheet.cells[i+2,j+1] := DataSet.Fields[j].Value;
end;
DataSet.Next;
end;
except
on e:Exception do
begin
showMessage(e.Message);
end;
end;
end;
3.导出数据按钮事件
var
i: Integer;
lSheet: variant;
begin
//to excel
ExcelApp := CreateOleObject('Excel.Application');
try
//ExcelApp.Visible := true;
ExcelApp.Caption := '医院数据';
WorkBooks := ExcelApp.WorkBooks;
WorkBook := WorkBooks.add;
Sheets := WorkBook.sheets;
for i:=1 to Sheets.count do
begin
lSheet := Sheets.item[i];
case i of
1:
begin
lSheet.name := '医院数据';
pnlDown.Visible := True;
RzPBDown.PartsComplete := 0;
pnlText.Caption := '导出医院数据...';
application.ProcessMessages;
fillExcel(lSheet,self.dsNative,self.dbgrdNative);
end;
2:
begin
lSheet.name := '中心数据';
pnlDown.Visible := True;
RzPBDown.PartsComplete := 0;
pnlText.Caption := '导出中心数据...';
application.ProcessMessages;
fillExcel(lSheet,self.dsDown,self.dbgrdDown);
end
else
begin
lSheet.name := 'Name ' + InttoStr(i);
end;
end;
end;
ExcelApp.Visible := true;
ExcelApp.WindowState := 3 ;
finally
pnlDown.Visible := false;
end;
end;