作为一个开发各种信息系统的程序员,写报表是家常便饭的事,以至于曾经写个一个为报表而报表的项目^_^ 我用过报表的控件不多,用过Quick Report,Rave Report还有以前用VB时用过十分低版本的Crystal Report,当然还有这篇文章的主角Excel。Excel做报表有什么好处与坏处。我就不说了,大家都明白。(写了浪费大家时间) 在Delphi中有专门的控件去调用Word、Excel等的Office组件。但这些控件的功能太多了,之间又有不少的联系,如果只是为调用Excel生成报表的话,我觉得还不如我自己这个类方便。 我先来介绍一下我这个类的用法,各位看官,主看以下代码:
procedure TForm1.FormCreate(Sender: TObject); begin AFER := TFlexExcelReport.Create; AFER.ModelFile := ExtractFilePath(Application.ExeName) + 'Book1.xls'; end; procedure TForm1.FormDestroy(Sender: TObject); begin AFER.Free; end; procedure TForm1.Button2Click(Sender: TObject); var p1, p2 : TPoint; begin p1.X := 2; p1.Y := 3; p2.X := 10; p2.Y := 20; AFER.Connect; AFER.Cells[1, 2] := 'FlexExcelReport Test'; AFER.SelectCell(1, 2); AFER.Copy; AFER.SelectRange(p1, p2); AFER.Paste; AFER.SelectCell(1, 2); AFER.Clear; AFER.SetPrintArea(p1, p2); end; 程序运行后,点击Button2,就会马上创建一个Excel的实例,这个实例是以Book1.xls为模板来打开的,打开后Excel会自动把这个文档命名为Book11。然后在1,2这个格里面填入内容,选择这个格子,复制,跟着选择2,3 -10,20这个区域,把刚才复制在剪贴板的内容复制进去。接下来就清除掉1,2中的内容,最后设置打印区域。 每次点击Button2都会重复上面的操作。反正用户点击多少次Button2,就会生成多少个Excel的实例。你不必担心,当你退出这个程序时,这些Excel都会随之关闭并释放对像。这里为什么要以Book1.xls为模板呢?原因是我懒,我不想用Delphi操纵VBScript,在空白的WorkSheet中画报表(这是一件会做死人的事)。而是先把报表的式样画好在Book1.xls中,这样每次只要用Delphi填内容就可以了。 是不是很简单呢?(我不是黄婆,不过还是要自夸一下!) 下面是整个FlexExcel Unit的内容: unit FlexExcel; interface uses SysUtils, Classes, Types, ComObj, Variants; type TFlexExcelReport = class(TObject) private FList: TList; FModelFile: string; function CoordsToXLS(ACol, ARow: integer): string; procedure SetCells(ACol, ARow: Integer; const Value: string); public constructor Create; destructor Destroy; override; procedure Clear; function Connect: Boolean; procedure Copy; procedure Paste; procedure SelectCell(ACol, ARow : integer); procedure SelectRange(TopLeft, RightBottom : TPoint); procedure SetPrintArea(TopLeft, RightBottom : TPoint); property Cells[ACol, ARow: Integer]: string write SetCells; property ModelFile: string read FModelFile write FModelFile; end; implementation type TFlexExcelHandle = class(TObject) private FConnected: Boolean; FXlsHandle: Variant; end; { ******************************* TFlexExcelReport ******************************* } constructor TFlexExcelReport.Create; begin FList := TList.Create; end; destructor TFlexExcelReport.Destroy; var i: Integer; hd: TFlexExcelHandle; begin for i := 0 to FList.Count - 1 do begin hd := FList[i]; if hd.FConnected then begin hd.FXlsHandle.DisplayAlerts := false; hd.FXlsHandle.Quit; hd.FXlsHandle := UnAssigned; end; hd.Free; end; FList.Free; inherited; end; procedure TFlexExcelReport.Clear; begin TFlexExcelHandle(FList[FList.Count - 1]).FXlsHandle.Selection.Clear; end; function TFlexExcelReport.Connect: Boolean; var hd: TFlexExcelHandle; begin result := false; hd := TFlexExcelHandle.Create; try hd.FXlsHandle := CreateOleObject('Excel.Application'); hd.FConnected := true; except on E : Exception do begin hd.Free; exit; end; end; hd.FXlsHandle.Visible := true; hd.FXlsHandle.Workbooks.Add [FModelFile]; FList.Add(hd); result := true; end; function TFlexExcelReport.CoordsToXLS(ACol, ARow: integer): string; var i: Integer; begin result := ''; i := (ACol - 1) div 26; if i > 0 then result := Chr(64 + i); i := (ACol - 1) mod 26; result := result + Chr(64 + i + 1) + IntToStr(ARow); end; procedure TFlexExcelReport.Copy; begin TFlexExcelHandle(FList[FList.Count - 1]).FXlsHandle.Selection.Copy; end; procedure TFlexExcelReport.Paste; begin TFlexExcelHandle(FList[FList.Count - 1]).FXlsHandle.ActiveWorkBook.ActiveSheet.PasteSpecial; end; procedure TFlexExcelReport.SelectCell(ACol, ARow : integer); begin TFlexExcelHandle(FList[FList.Count - 1]).FXlsHandle.ActiveWorkBook.ActiveSheet.Range[CoordsToXLS(ACol, ARow)].Select; end; procedure TFlexExcelReport.SelectRange(TopLeft, RightBottom : TPoint); begin if (TopLeft.X = RightBottom.X) and (TopLeft.Y = RightBottom.Y) then SelectCell(TopLeft.X, TopLeft.Y) else TFlexExcelHandle(FList[FList.Count - 1]).FXlsHandle.ActiveWorkBook.ActiveSheet.Range[CoordsToXLS(TopLeft.X, TopLeft.Y) + ':' + CoordsToXLS(RightBottom.X, RightBottom.Y)].Select; end; procedure TFlexExcelReport.SetCells(ACol, ARow: Integer; const Value: string); begin TFlexExcelHandle(FList[FList.Count - 1]).FXlsHandle.ActiveWorkBook.ActiveSheet.Cells[ARow, ACol] := Value; end; procedure TFlexExcelReport.SetPrintArea(TopLeft, RightBottom : TPoint); begin TFlexExcelHandle(FList[FList.Count - 1]).FXlsHandle.ActiveWorkBook.ActiveSheet.PageSetup.PrintArea := CoordsToXLS(TopLeft.X, TopLeft.Y) + ':' + CoordsToXLS(RightBottom.X, RightBottom.Y); end; end. 说明一下: function CoordsToXLS(ACol, ARow: integer): string; 这个函数的作用是把我们常用的坐标表 列1,行2 (1,2 )转换为Excel的表标方式A2,因为我查VBScript时只找到用, 如A2: C5这种方法去选择范围及设定打印区域。

|