Excel开发入门(C#和C++实例)

 

Excel 开发文档

              这篇文章的例子采用 Office 2003 英文版。首先打开一个 Excel2003 程序,然后选择菜单 Help Microsoft Excel Help, 如下图:

              这样,右边会出现一个帮助子窗口,如下:

Excel开发入门(C#和C++实例)

              选择 Table of Contents ,会出现下图。

Excel开发入门(C#和C++实例)

              最后一行 Microsoft Excel Visual Basic Reference 就是我们要找的文档。该文档基本描述了 Excel 的主要对象的属性和方法。

 

              如果你安装了 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 也包含了一个专题: Office Solutions Development

Excel Application 对象

概念

              Application 对象代表的是 Excel 程序。 为了更好的理解 Application 是什么,我们可以先启动一个 Excel 程序 ,然后选择菜单栏最右边的关闭按钮,这样就可以关掉默认创建的空文档对象。 现在出现在我们眼前的就是 Application 对象:

Excel开发入门(C#和C++实例)

 

              Excel 是一个 MDI 程序。 MDI Mutiple Document Interface 多文档界面)怎么理解呢?

熟悉微软历史悠久的 MFC 开发知识的程序员就知道:每一个 MDI 窗口应用程序都有一个主框架窗口,主框架 窗口可以拥有多 个子框架窗口 ,每个子框架窗口管理一个 Document 对象 ( 文档对象负责管理数据 ) 和一个 View 对象(视图对象负责显示数据,接受用户事件)。 实际上后来 MDI 概念只是代表一种风格,即一个主框架窗口允许同时显示多个子窗口 ,是否有 Document 对象已经不重要。

              现在我们可以清楚地知道 Excel Application 对象就代表了 MDI 风格窗口的主框架。

示例

              示例的目的是描述如何使用多种语言来创建一个 Excel 程序。 为了简化篇幅, 如何使用 IDE 的内容不作详细描述。

C# 代码

              首先创建一个 C# Console 工程。我这里使用的总是 Visual Studio.net 2005 英文版。 然后右键选择工程,选择 Add Reference ,在弹出的对话框中选择 COM 一栏,选中如下的组件:

Excel开发入门(C#和C++实例)

请注意下面的代码:

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; // 这句话可以使垃圾回收器关闭Excel进程

            }

            catch ( COMException e)

            {

                Console .WriteLine(e.Message);

            }

        }

    }

}

              Application app = new Application (); 创建了一个Excel的Application对象。 app.Visible = true ; 设置窗口状态为显示。 app .Quit(); 关闭Application对象。注意,如果出错会抛出COMException异常。 如果我们将断点放在app.Quit()这一行,我们会看到程序会打开一个只有主框架的Excel程序。就像前面的图示一样。

C++ 代码

              创建一个 Win32 Console 工程 ExcelApplicationSampleCPlus 。然后选择添加 ATL 支持,如下图:

              Excel开发入门(C#和C++实例)

             

              源代码如下:

 

#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# 复杂得多,主要在于:

  1. 引入组件库的时候需要重命名一些类,避免重名
  2. 错误信息的获取没有 C# COMException 异常对象来支持,需要自己处理。 CWindowsError::getOfficeError 方法是我自己花了一个小时才编写好的。代码如下:

#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. 另外你需要对 COM 有所了解,这点对很多 VC 程序员难度都不小。

              由于 .Net 是通过 Interop 方式间接调用 Office 组件(整个 Office 程序都是由 COM 组件编写的),因此比起 C++ 直接调用 IDispatch 接口方式要慢得多。不过一般情况下,使用 Office 的程序性能要求不会很苛刻, .Net 技术可以让我们的生活更加轻松许多。

             

Work b ooks Work b ook 对象

              WorkBook 对象代表了一个 Excel 程序可以打开的一个 工作簿。如下图中标题为 Book1 的子窗口就是一个 Workbook 对象。

Excel开发入门(C#和C++实例)

 

              由于 Excel MDI 程序,所以可以同时打开多个 WorkBook 对象作为子窗口。如下图中的 Book1 Book2 窗口。

Excel开发入门(C#和C++实例)

 

              代表框架窗口的 Application 对象管理着 WorkBooks 对象, WorkBooks 对象是 WorkBook 对象的集合。

 

创建一个空 Work b ook 对象

C# 代码

              我们对前面的 C# 代码进行了 一些修改,代码如下:

    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方法的实现代码 XlWBATemplate 枚举类型 的值 指定了 要创建的 Workb ook的类型。

xlWBATChart 代表 Chart.

xlWBATExcel IntlMacroSheet 代表 Excel version 4 macro.

xlWBATExcel4MacroSheet 代表 Excel version 4 international macro.

xlWBATWorksheet 代表 Worksheet.

              Worksheet 的概念下面一个章节会讲到,这里需要知道的是当创建一个 WorkBook 对象的时候 , 总是会 自动 创建一个 Worksheet 对象。

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

};

打开一个已经存在的 WorkBook 对象

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 对象

              每一个 Workbook 对象都拥有一个或者多个 Worksheet 对象。每个 Worksheet 对象代表了一张表格。如下图:

Excel开发入门(C#和C++实例)

              这里有 Sheet1,Sheet2,Sheet3 三张表格, 他们都是 Worksheet 对象。 当前的 Workbook 对象代表了这个子窗口,并且用有成员 Worksheets 对象。 Worksheets 对象是三个 Worksheet 对象的集合。

 

读取某表格实际使用的行数和列数

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

     int rowCount=sheet.UsedRange.Rows.Count;

     int colCount = sheet.UsedRange.Columns.Count;

读取某 表格指定位置的数据

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

        {

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

            return cell.Text.ToString();

        }

注意,行和列的索引总是从1开始。

改写某 表格指定位置的数据

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

        {

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

            cell.Value2 = value; ;

        }

插入 行到某 表格中

                  // 插行(在指定 WorkSheet 指定行上面插入指定数量行)

        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);

            }

        }

 

 

5

 

 


原文链接: http://blog.csdn.net/sheismylife/article/details/4618961

你可能感兴趣的:(Excel开发入门(C#和C++实例))