电竞比分网-中国电竞赛事及体育赛事平台

分享

Excel開發(fā)入門(C#和C 實(shí)例)

 悟靜 2012-06-15

Excel 開發(fā)文檔

              這篇文章的例子采用 Office 2003 英文版。首先打開一個(gè) Excel2003 程序,然后選擇菜單 Help Microsoft Excel Help, 如下圖:

              這樣,右邊會(huì)出現(xiàn)一個(gè)幫助子窗口,如下:

              選擇 Table of Contents ,會(huì)出現(xiàn)下圖。

              最后一行 Microsoft Excel Visual Basic Reference 就是我們要找的文檔。該文檔基本描述了 Excel 的主要對(duì)象的屬性和方法。

 

              如果你安裝了 MSDN FOR VS.NET 2005 英文版 , 你可以在下面的地址找到 Excel 的例子程序:

ms-help://MS.MSDNQTR.v80.en/MS.MSDN.v80/MS.VisualStudio.v80.en/dv_fxsamples/l ocal/sampleexecutables/Technologies/Interop/Applications/Office/Excel.zip

              MSND 也包含了一個(gè)專題: Office Solutions Development 。

Excel Application 對(duì)象

概念

              Application 對(duì)象代表的是 Excel 程序。 為了更好的理解 Application 是什么,我們可以先啟動(dòng)一個(gè) Excel 程序 ,然后選擇菜單欄最右邊的關(guān)閉按鈕,這樣就可以關(guān)掉默認(rèn)創(chuàng)建的空文檔對(duì)象。 現(xiàn)在出現(xiàn)在我們眼前的就是 Application 對(duì)象:

 

              Excel 是一個(gè) MDI 程序。 MDI Mutiple Document Interface 多文檔界面)怎么理解呢?

熟悉微軟歷史悠久的 MFC 開發(fā)知識(shí)的程序員就知道:每一個(gè) MDI 窗口應(yīng)用程序都有一個(gè)主框架窗口,主框架 窗口可以擁有多 個(gè)子框架窗口 ,每個(gè)子框架窗口管理一個(gè) Document 對(duì)象 ( 文檔對(duì)象負(fù)責(zé)管理數(shù)據(jù) ) 和一個(gè) View 對(duì)象(視圖對(duì)象負(fù)責(zé)顯示數(shù)據(jù),接受用戶事件)。 實(shí)際上后來 MDI 概念只是代表一種風(fēng)格,即一個(gè)主框架窗口允許同時(shí)顯示多個(gè)子窗口 ,是否有 Document 對(duì)象已經(jīng)不重要。

              現(xiàn)在我們可以清楚地知道 Excel Application 對(duì)象就代表了 MDI 風(fēng)格窗口的主框架。

示例

              示例的目的是描述如何使用多種語言來創(chuàng)建一個(gè) Excel 程序。 為了簡(jiǎn)化篇幅, 如何使用 IDE 的內(nèi)容不作詳細(xì)描述。

C# 代碼

              首先創(chuàng)建一個(gè) C# Console 工程。我這里使用的總是 Visual Studio.net 2005 英文版。 然后右鍵選擇工程,選擇 Add Reference ,在彈出的對(duì)話框中選擇 COM 一欄,選中如下的組件:

請(qǐng)注意下面的代碼:

using System.Reflection; // For Missing.Value and BindingFlags

using System.Runtime.InteropServices; // For COMException

using Microsoft.Office.Interop.Excel;

 

namespace ExcelApplicationSample

{

    class Program

    {

        static void Main ( string [] args)

        {

            try

            {

                Application app = new Application ();

                app.Visible = true ;

                app.Quit();

                                            app=null; // 這句話可以使垃圾回收器關(guān)閉Excel進(jìn)程

            }

            catch ( COMException e)

            {

                Console .WriteLine(e.Message);

            }

        }

    }

}

              Application app = new Application (); 創(chuàng)建了一個(gè)Excel的Application對(duì)象。 app.Visible = true ; 設(shè)置窗口狀態(tài)為顯示。 app .Quit(); 關(guān)閉Application對(duì)象。注意,如果出錯(cuò)會(huì)拋出COMException異常。 如果我們將斷點(diǎn)放在app.Quit()這一行,我們會(huì)看到程序會(huì)打開一個(gè)只有主框架的Excel程序。就像前面的圖示一樣。

C++ 代碼

              創(chuàng)建一個(gè) Win32 Console 工程 ExcelApplicationSampleCPlus 。然后選擇添加 ATL 支持,如下圖:

             

             

              源代碼如下:

 

#include "stdafx.h"

#include

using namespace std;

 

#import "C:Program FilesCommon FilesMicrosoft SharedOFFICE11mso.dll" rename( "RGB" , "MSRGB" )

 

#import "C:Program FilesCommon FilesMicrosoft SharedVBAVBA6VBE6EXT.OLB"  

rename( "Reference" , "ignorethis" ), rename( "VBE" , "JOEVBE" )

 

#import "C:Program FilesMicrosoft OfficeOFFICE11excel.exe" exclude( "IFont" , "IPicture" )

rename( "RGB" , "ignorethis" ), rename( "DialogBox" , "ignorethis" ), rename( "VBE" , "JOEVBE" ),

rename( "ReplaceText" , "JOEReplaceText" ), rename( "CopyFile" , "JOECopyFile" ),

rename( "FindText" , "JOEFindText" ), rename( "NoPrompt" , "JOENoPrompt" )

 

using namespace Office;

using namespace VBIDE;

using namespace Excel ;

 

#include "WindowsError.h"

 

 

class AppartmentWrapper

{

public :

              AppartmentWrapper()

              {

                            ::CoInitialize(NULL);

              }

 

              ~AppartmentWrapper()

              {

                            ::CoUninitialize();

              }

};

 

 

int _tmain( int argc, _TCHAR* argv[])

{

              try

              {

                            AppartmentWrapper appartment;

                            _ApplicationPtr ptr=NULL;

                            HRESULT hr=ptr.CreateInstance( "Exce2l.Application" );

                            if (FAILED(hr))

                            {

                                          cout<<

                                          return 1;

                            }

                            ptr->PutVisible (0,VARIANT_TRUE);

                            hr=ptr->Quit();

                            if (FAILED(hr))

                            {

                                          cout<<

                                          return 1;

                            }

              }

              catch (_com_error const & e)

              {

                            cout<<

                            return 1;

              }

              return 0;

}

 

              VC++ 的代碼要比 C# 復(fù)雜得多,主要在于:

  1. 引入組件庫(kù)的時(shí)候需要重命名一些類,避免重名
  2. 錯(cuò)誤信息的獲取沒有 C# COMException 異常對(duì)象來支持,需要自己處理。 CWindowsError::getOfficeError 方法是我自己花了一個(gè)小時(shí)才編寫好的。代碼如下:

#pragma once

 

#include

#include

 

class CWindowsError

{

public :

              static std::string getLastError()

              {

                            char szBuf[80];

                            void * lpMsgBuf=NULL;

                            DWORD dw = GetLastError();

 

                            FormatMessageA(

                                          FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,

                                          NULL,

                                          dw,

                                          MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),

                                          ( char *) &lpMsgBuf,

                                          0,

                                          NULL);

 

 

                            wsprintfA(szBuf, "error %d: %s" ,dw, lpMsgBuf);

 

                            LocalFree(lpMsgBuf);

                            return szBuf;

              }

 

              static std::string getOfficeError(HRESULT hr)

              {

                            char buf[256]={0};

                            FormatMessageA(

                                          FORMAT_MESSAGE_FROM_SYSTEM,

                                          NULL,

                                          hr,

                                          MAKELANGID(LANG_ NEUTRAL, SUBLANG_DEFAULT),

                                          &buf[0],

                                          256,

                                          NULL);

                            std::stringstream stream;

                            stream<< "error " <


<< ": " <

                            return stream.str();

              }

};

  1. 另外你需要對(duì) COM 有所了解,這點(diǎn)對(duì)很多 VC 程序員難度都不小。

              由于 .Net 是通過 Interop 方式間接調(diào)用 Office 組件(整個(gè) Office 程序都是由 COM 組件編寫的),因此比起 C++ 直接調(diào)用 IDispatch 接口方式要慢得多。不過一般情況下,使用 Office 的程序性能要求不會(huì)很苛刻, .Net 技術(shù)可以讓我們的生活更加輕松許多。

             

Work b ooks Work b ook 對(duì)象

              WorkBook 對(duì)象代表了一個(gè) Excel 程序可以打開的一個(gè) 工作簿。如下圖中標(biāo)題為 Book1 的子窗口就是一個(gè) Workbook 對(duì)象。

 

              由于 Excel MDI 程序,所以可以同時(shí)打開多個(gè) WorkBook 對(duì)象作為子窗口。如下圖中的 Book1 Book2 窗口。

 

              代表框架窗口的 Application 對(duì)象管理著 WorkBooks 對(duì)象, WorkBooks 對(duì)象是 WorkBook 對(duì)象的集合。

 

創(chuàng)建一個(gè)空 Work b ook 對(duì)象

C# 代碼

              我們對(duì)前面的 C# 代碼進(jìn)行了 一些修改,代碼如下:

    class Program

    {

        static void Main ( string [] args)

        {

             Application app= null ;

            try

            {

                app = new Application ();

                Workbook book=CreateDocument(app);

                app.Visible = true ;

            }

            catch ( COMException e)

            {

                Console .WriteLine(e.Message);

            }

            finally

            {

                app.Quit();

            }

        }

 

        static Workbook CreateDocument( Application app)

        {

            return app.Workbooks.Add( XlWBATemplate .xlWBATWorksheet);

        }

    }

              注意CreateDocument方法的實(shí)現(xiàn)代碼 XlWBATemplate 枚舉類型 的值 指定了 要?jiǎng)?chuàng)建的 Workb ook的類型。

xlWBATChart 代表 Chart.

xlWBATExcel IntlMacroSheet 代表 Excel version 4 macro.

xlWBATExcel4MacroSheet 代表 Excel version 4 international macro.

xlWBATWorksheet 代表 Worksheet.

              Worksheet 的概念下面一個(gè)章節(jié)會(huì)講到,這里需要知道的是當(dāng)創(chuàng)建一個(gè) WorkBook 對(duì)象的時(shí)候 , 總是會(huì) 自動(dòng) 創(chuàng)建一個(gè) Worksheet 對(duì)象。

C++ 代碼

             

_WorkbookPtr createWorkbook(_ApplicationPtr app)

{

              WorkbooksPtr books=app->GetWorkbooks();

              _variant_t v(xlWorksheet);

              return books->Add(v);

}

 

 

int _tmain( int argc, _TCHAR* argv[])

{

              try

              {

                            AppartmentWrapper appartment;

                            _ApplicationPtr ptr=NULL;

                            HRESULT hr=ptr.CreateInstance( "Excel.Application" );

                            if (FAILED(hr))

                            {

                                          cout<< CWindowsError::getOfficeError(hr)<<endl;

                                          return 1;

                            }

                            _WorkbookPtr workbook=createWorkbook(ptr);

                            ptr->PutVisible (0,VARIANT_TRUE);

                            hr=ptr->Quit();

                            if (FAILED(hr))

                            {

                                   cout<<CWindowsError::getOfficeError(hr)<<endl;

 

                                          return 1;

                            }

              }

              catch (_com_error const & e)

              {

                             cout<<CWindowsError::getOfficeError(hr)<<endl;

                            return 1;

              }

              return 0;

}

 

C++ 中的 Workbook 類型的枚舉定義為:

enum XlSheetType

{

    xlChart = -4109,

    xlDialogSheet = -4116,

    xlExcel4IntlMacroSheet = 4,

    xlExcel4MacroSheet = 3,

    xlWorksheet = -4167

};

打開一個(gè)已經(jīng)存在的 WorkBook 對(duì)象

C# 代碼

        static Workbook OpenDocument( Application app, String fileName)

        {

            return app.Workbooks.Open(fileName, Type .Missing, Type .Missing, Type .Missing, Type .Missing, Type .Missing, Type .Missing, Type .Missing,

                Type .Missing, Type .Missing, Type .Missing, Type .Missing, Type .Missing, Type .Missing, Type .Missing);

        }

C++ 代碼

_WorkbookPtr openWorkbook(_ApplicationPtr app,string const & fileName)

{

              WorkbooksPtr books=app->GetWorkbooks();

              return books->Open(_bstr_t(fileName.c_str()));

}

WorkSheets WorkSheet 對(duì)象

              每一個(gè) Workbook 對(duì)象都擁有一個(gè)或者多個(gè) Worksheet 對(duì)象。每個(gè) Worksheet 對(duì)象代表了一張表格。如下圖:

              這里有 Sheet1,Sheet2,Sheet3 三張表格, 他們都是 Worksheet 對(duì)象。 當(dāng)前的 Workbook 對(duì)象代表了這個(gè)子窗口,并且用有成員 Worksheets 對(duì)象。 Worksheets 對(duì)象是三個(gè) Worksheet 對(duì)象的集合。

 

讀取某表格實(shí)際使用的行數(shù)和列數(shù)

              Worksheet sheet = ( Worksheet )book.Sheets[ "Sheet1" ];

     int rowCount=sheet.UsedRange.Rows.Count;

     int colCount = sheet.UsedRange.Columns.Count;

讀取某 表格指定位置的數(shù)據(jù)

                  static String G etValue( Worksheet sheet, int row, int col)

        {

            Range cell=( Range )sheet.UsedRange.Cells[row, col];

            return cell.Text.ToString();

        }

注意,行和列的索引總是從1開始。

改寫某 表格指定位置的數(shù)據(jù)

                  static void S etValue( Worksheet sheet, int row, int col, String value)

        {

            Range cell = ( Range )sheet.UsedRange.Cells[row, col];

            cell.Value2 = value; ;

        }

插入 行到某 表格中

                  // 插行(在指定 WorkSheet 指定行上面插入指定數(shù)量行)

        static void InsertRows(Excel. Worksheet wst, int rowIndex, int count)

        {

            Excel. Range range = (Excel. Range )wst.Rows[rowIndex, Type .Missing];

 

            for ( int i = 0; i < count; i++)

            {

                range.Insert(Excel. XlDirection .xlDown, Type .Missing);

            }

       

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多