一、引言 EXCEL在處理中文報表時功能非常強大,EXCEL報表訪問也是信息系統開發中的一個重要內容,本文總結以往開發中所用到的幾中EXCEL文件訪問方法,在實際工作中也得到了很好的驗證,本文列舉了其中四種方法的實例與讀者共享,程序已在WINDOWS2000操作系統、OFFFICE2000應用軟件和DELPHI7環境下調試通過。 二、ADO方式訪問EXCEL文件 ADO方式訪問EXCEL文件時,將EXCEL文件看作一個等同Oracle、MS SQLServer等數據庫的一個ODBC數據源本文應用示例主要功能是打開EXCEL文件,並實現對EXCEL文件的編輯修改功能。實現過程及主要源代碼如下: 1.在工程中新建窗口類TfrmADOEXCEL,在窗口中定義私有變量類型為TADOConnection的組件Conn,加入TADOTable組件ADOTabXLS、TDataSource組件DSXLS、TDBNavigator組件NavXLS 、TDBGrid組件GridXLS和TButton組件btnOpen,使用btnOpen可以打開EXCEL文件,使用NavXLS可以瀏覽編輯EXCEL文件數據。 2.編寫btnOpen組件的OnClick事件。需要注意兩點,Conn組件的Extend Properties屬性要定義成excel 8.0,另外,EXCEL文件中的表單名“人員信息表”作為表明時要寫成“[人員信息表$]”。 procedure TfrmADOEXCEL.btnOpenClick(Sender: TObject); //打開EXCEL文件代碼 begin Conn:=TADOConnection.Create(nil); Conn.ConnectionString:='Provider=Microsoft.Jet.OLEDB.4.0;Data Source='+ExtractFileDir(Application.ExeName)+'/PersonData.xls;Extended Properties=excel 8.0;Persist Security Info=False'; Conn.LoginPrompt:=false; Conn.Connected:=true; ADOTabXLS.Connection:=Conn; ADOTabXLS.TableName:='['+'人員信息表'+'$]'; ADOTabXLS.Active:=true; DSXLS.DataSet:=ADOTabXLS; GridXLS.DataSource:=DSXLS; except; FreeAndNil(Conn); end; end; 三、COM方式動態訪問EXCEL文件 COM方式動態訪問EXCEL文件時,基本方法是利用組件復用技術調用Office軟件平台提供的COM服務組件,充分利用COM組件提供的方法操縱EXCEL文件。本文應用示例簡單演示了如何利用COM技術將DataSet數據集的數據輸出到EXCEL文件。實現過程及主要源代碼如下: 在工程中新建窗口類TfrmCOMEXCEL,在窗口中定義私有變量類型為TADOConnection的組件Conn,加入TADOTable組件ADOTabXLS和TButton組件btnOpen,使用btnOpen可以將數據輸出到EXCEL文件。編寫btnOpen組件的OnClick事件代碼如下: procedure TfrmCOMEXCEL.btnOpenClick(Sender: TObject); var XL: Variant; //打開EXCEL文件的Variant變量 Sheet: Variant;//指向EXCEL表單的Variant變量 RecNo,I: Integer;//記錄數據表的當前記錄號 begin try XL := CreateOleObject('Excel.Application'); XL.Visible := true; if FileExists(ExtractFileDir(Application.ExeName)+'/test.xls') then begin XL.WorkBooks.Open(ExtractFileDir(Application.ExeName)+'/test.xls'); end else XL.WorkBooks.Add; XL.WorkBooks[XL.WorkBooks.Count].WorkSheets[1].Name := 'test'; Sheet := XL.WorkBooks[XL.WorkBooks.Count].WorkSheets[Trim('test')]; RecNo := 1; ADOTabXLS.First; while not ADOTabXLS.Eof do begin for I := 0 to ADOTabXLS.FieldCount - 1 do if not (ADOTabXLS.Fields[I].DataType in [ftBlob, ftGraphic, ftParadoxOle, ftDBaseOle, ftTypedBinary, ftReference, ftDataSet, ftOraBlob, ftOraClob, ftInterface, ftIDispatch]) then begin Sheet.Cells.NumberFormat := '@'; Sheet.Cells[RecNo, I+1] := ADOTabXLS.Fields[I].AsString; end; Inc(RecNo); ADOTabXLS.Next; end; try XL.WorkBooks[XL.WorkBooks.Count].SaveAs(ExtractFileDir(Application.ExeName)+'/test.xls'); except ; end; end; 四、擴展OLEContainer方式訪問EXCEL文件 在使用OLE方式訪問EXCEL文件時,OLE容器在失去焦點會屏蔽正在訪問的EXCEL文件操作;另外,使用in_place方式激活OLE容器時,會另外打開一個窗口,程序執行顯得有些混亂,造成這些問題的主要原因是因為OLE容器響應了CM_UIDEACTIVATE消息,OLE容器不能始終保持激活狀態。為此可將此消息結果使OLE容器始終處於激活狀態。解決方法是重載OLE容器的CM_UIDEACTIVATE消息。在程序中臨時創建重載后擴展OLE容器OLEContainerEx。代碼如下: type TOleContainerEx=class(TOleContainer) private FJH: Boolean; //重寫CM_UIDEACTIVATE消息響應 procedure CMUIDeactivate(var Message: TMessage); message CM_UIDEACTIVATE; published property JH: Boolean read FJH write FJH; end; // 過程CMUIDeactivate的代碼實現 procedure TOleContainerEx.CMUIDeactivate(var Message: TMessage); begin if not JH then inherited; end; 在使用TOLEContainerEx時,可采用臨時創建的方式,也可進一步封裝成可安裝組建以便設計期使用。本文應用示例采用了臨時創建的方式。在工程中新建窗口類TfrmEXOLEEXCEL,並定義Public變量 OleCon,類型為: TOleContainerEx;在窗口中定一個Tpanel類型組件panel1和Tbutton類型變量btnOpen,編寫btnOpen的Click事件,主要源程序代碼如下: procedure TfrmEXOLEEXCEL.btnOpenClick(Sender: TObject); begin //創建並顯示擴展OLE類組件 OleCon := TOleContainerEx.Create(nil); OleCon.Parent := Panel1; OleCon.Align:=alClient; OleCon.allowactivedoc := true; OleCon.AllowInPlace := True; OleCon.AutoActivate := aaGetFocus; OleCon.Anchors := [akTop,akLeft,akRight,akBottom]; OleCon.Visible := True; OleCon.SizeMode := smClip; OleCon.CreateObjectFromFile(ExtractFileDir(Application.ExeName)+ '/PersonData.xls',false); TOleContainerEx(OleCon).JH := True; OleCon.SetFocus; end; 五、DELPHI標准組件訪問EXCEL文件 Delphi中封裝了一組Microsoft Office自動化對象(Automation servers)。它使得我們很容易地把Office中的應用程序(Excel等)當作一個COM應用服務器進行控制。使用這組VCL組件可以在設計時進行屬性設置,也可以在運行時動態訪問EXCEL。利用標准組件動態訪問EXCEL文件時,充分利用VCL組件提供的方法操縱EXCEL文件。本文應用示例簡單演示了如何利用VCL組件將DataSet數據集的數據輸出到EXCEL文件。實現過程及主要源代碼如下: 在工程中新建窗口類TfrmSTDCNTREXCEL,在窗口中加入TADOConnection組件ADOConnXLS,TADOTable組件ADOTabXLS、TButton組件btnOpen、TexcelApplication組件ExcelApplication1,TexcelWorkbook類組件ExcelWorkbook1和TExcelWorksheet1類組件ExcelWorksheet1,使用btnOpen可以將數據輸出到EXCEL文件。編寫btnOpen組件的OnClick事件代碼如下。 procedure TfrmSTDCNTREXCEL.btnOpenClick(Sender: TObject); var aWorksheet: _WorkSheet; tmpI,aRowIndex:integer; aStr:string; begin ADOConnXLS.ConnectionString:='Provider=Microsoft.Jet.OLEDB.4.0;Data Source='+ExtractFileDir(Application.ExeName)+'/PersonData.xls;Extended Properties=excel 8.0;Persist Security Info=False'; ADOConnXLS.LoginPrompt:=false; ADOConnXLS.Connected:=true; ADOTabXLS.Connection:=ADOConnXLS; ADOTabXLS.TableName:='[人員信息表$]'; ADOTabXLS.Active:=true; if ADOTabXLS.IsEmpty then exit; Try ExcelApplication1.Connect; Except MessageDlg('你還沒有安裝MicroSoft Excel,請先安裝MicroSoft Excel!',mtError, [mbOk], 0); Abort; End; ExcelApplication1.Visible[0]:=True; ExcelApplication1.Caption := '新建EXCEL文件'; ExcelWorkbook1.ConnectTo(ExcelApplication1.Workbooks.Add(EmptyParam,0)); aWorksheet:=ExcelWorkbook1.WorkSheets.Add(EmptyParam,EmptyParam,EmptyParam,EmptyParam,0) as _WorkSheet; ExcelWorkSheet1.ConnectTo(aWorksheet); aRowIndex:=1; while not ADOTabXLS.Eof do begin for tmpI:=0 to ADOTabXLS.FieldCount-1 do ExcelWorksheet1.Cells.Item[aRowIndex,tmpI+1]:=ADOTabXLS.FieldList[tmpI].AsString; aRowIndex:=aRowIndex+1; ADOTabXLS.Next; end; //保存EXCEL文件,並關閉EXCEL應用程序 Try aStr:=ExtractFileDir(Application.ExeName)+'/EXCEL文件.xls'; ExcelWorkbook1.SaveAs(aStr,EmptyParam,EmptyParam, EmptyParam,EmptyParam,EmptyParam , xlNoChange ,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,0); ExcelWorksheet1.Disconnect; ExcelWorkbook1.Disconnect; ExcelApplication1.Disconnect; ADOTabXLS.Active:=false; ADOConnXLS.Connected:=false; except ExcelWorksheet1.Disconnect; ExcelWorkbook1.Disconnect; ExcelApplication1.Disconnect; ADOTabXLS.Active:=false; ADOConnXLS.Connected:=false; End; end; 六、總結 綜上所講,本文分別舉例討論了EXCEL文件訪問的幾種方法,包括ADO、COM、擴展OLEContainer和DELPHI標准組件方式。在實際應用過程中,這幾種方法也各有特色。ADO方式訪問EXCEL文件適用於以數據庫訪問方式維護EXCEL文件,COM方式動態訪問編程設計與VBA訪問接口方式相似,此種方法適用於EXCEL文件數據維護和復雜報表輸出,擴展OLE方式訪問EXCEL文件時能夠保持EXCEL應用程序的友好界面,DELPHI標准組件訪問方式與COM訪問方式相似,但DELPHI對各類接口進行了更加友好的封裝,在對COM方式不是很長熟悉的情況下,使用這種方式訪問和輸出數據到EXCEL文件非常有效。