1.使用方法
Visual Studio 2005中默认提供了封装好的Microsoft Office 2003的.Net Excel编程模型。
大家可以看到名为“Microsoft Excel 12.0 Object Library”的COM组件。由于Excel的版本一直在升级,如果我们需要操作更新版本的Excel文件,但又没有安装最新的Office,这个时候我们就需要手工进行Excel COM组件的封装。我们需要使用 Framework v2.0 SDK tools中的一个工具tlbimp.exe-类型库导入程序(http://msdn2.microsoft.com/zh-cn/library/tt0cf3sx(VS.80).aspx),默认安装位置在。C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin 把需要封装的Excel的主程序(excel.exe)复制到 tlbimp工具所在目录下。
执行命令:
tlbimp excel.exe /out:excel.dll
生成封装好的excel.dll。然后就可对excel.dll进行引用。成功引用后,引用下会出现
1.Excel
2.Microsoft.Office.Core
3.Microsoft.Office.Interop.Excel
三个类库。
其中1为我们手工封装的Excel COM组件2、3为我们直接引用的安装在VS2005中的Excel COM组件。
如果使用VS2005内置COM组件,1将不会出现,如使用手工封装的COM组件2、3就不会出现。
3.使用的基本流程
a.建立一个Excel进程
Microsoft.Office.Interop.Excel.Application app1 = new Microsoft.Office.Interop.Excel.Application();
b.设置进程的界面是否可见
app1.Visible = true;
c.建立或打开一个 Workbook对象
生成新Workbook:
Workbook book1 = app1.Workbooks.Add(Type.Missing);
或打开已有Workbook
Workbook book1 = app1.Workbooks.Open("D:\test.xlsx", 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);
d.生成一个Sheet对象
Worksheet sheet1 = (Worksheet)book1.Sheets[1];
e.设置访问区域
Range rng1 = sheet1.get_Range(“A1:C3,E2:G6”, Type.Missing); //设置操作区域为个不连续区域
f.对访问区域进行操作
rng1.NumberFormatLocal = “@”; //格式设置为文本
rng1.Value2 = “2006147214E00045”; //对操作区域赋值
g.保存操作过程
app1.DisplayAlerts = false; //不显示保存对话框
book1.Save(); //保存修改
h.对于要处理多个Excel文件的程序还需要关闭book1并保存修改数据。
book1.Close(Type.Missing, "D:\test.xlsx", Type.Missing);
i.关闭Excel进程
app1.Quit();
4.完整的程序代码:
使用VS2005 编写,需.Net Framework 2.0支持
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.Office.Interop.Excel; //引用Excel的COM组件
namespace WinFormExcelWelcome
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Microsoft.Office.Interop.Excel.Application app1 = new Microsoft.Office.Interop.Excel.Application();
//在Windows中生成一个Excel.exe进程
app1.Visible = true; //运行时显示Excel主窗口
try
{
Workbook book1 = app1.Workbooks.Add(Type.Missing); //使用 app1生成一个book对象
Worksheet sheet1 = (Worksheet)book1.Sheets[1]; //从book1对象中生成Sheet对象并赋值
Range rng1 = sheet1.get_Range("A1", Type.Missing); //设置操作区域
rng1.Value2 = "Hello World!"; //对操作区域赋值
}
catch
{
app1.Quit();//结束进程
}
}
private void button2_Click(object sender, EventArgs e)
{
Microsoft.Office.Interop.Excel.Application app1 = new Microsoft.Office.Interop.Excel.Application();
app1.Visible = true; //运行时显示Excel主窗口
try
{
//打开一个已经存在的excel文件
Workbook book1 = app1.Workbooks.Open("D:\test.xlsx", 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);
Worksheet sheet1 = (Worksheet)book1.Sheets["Sheet1"];
Range rng1 = sheet1.get_Range("A1:C3,E2:G6", Type.Missing);//设置操作区域为2个不连续区域
rng1.NumberFormatLocal = "@";
rng1.Value2 = "2006147214E00045"; /对操作区域赋值
Range rng2 = sheet1.get_Range("F1:F6", Type.Missing);
rng2.Value2 = "2006147214E00045";
app1.DisplayAlerts = false; //不显示保存对话框
book1.Save(); //保存
}
catch
{
app1.Quit();//结束进程
}
}
private void button3_Click(object sender, EventArgs e)
{
Microsoft.Office.Interop.Excel.Application app1 = new Microsoft.Office.Interop.Excel.Application();
app1.Visible = false; //运行时不显示Excel主窗口
try
{
Workbook book1 = app1.Workbooks.Add(Type.Missing);
Worksheet sheet1 = (Worksheet)book1.Sheets[1];
app1.DisplayAlerts = true;
//将打开的Excel文件另存:D est.xlsx 格式 xlXMLSpreadsheet(xlsm)、xlOpenXMLWorkbook(xlsx)、 xlExcel12(xlsb)
book1.SaveAs("D:\test.xlsx", Microsoft.Office.Interop.Excel.XlFileFormat.xlOpenXMLWorkbook,
Type.Missing, Type.Missing,false,false,
Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange,
Microsoft.Office.Interop.Excel.XlSaveConflictResolution.xlLocalSessionChanges,
Type.Missing, Type.Missing, Type.Missing, Type.Missing);
book1.Close(Type.Missing, "D:\test.xlsx", Type.Missing);
}
catch
{
app1.Quit();
}
finally
{
app1.Quit();
}
}
}
}
附完整程序:
按钮1-在内存中建立一个空白Excel文件(界面中第一个按钮)
按钮2-打开一个Excel文件并做写入(界面中第三个按钮)
按钮3-在D:\新建一个Excel 2007格式的空白Excel文件(界面中第二个按钮)
进一步讨论:
Excel对象:
微软的Excel对象模型包括了128个不同的对象,从矩形,文本框等简单的对象到透视表,图表等复杂的对象.下面我们简单介绍一下其中最重要,也是用得最多的四个对象。
(1) Application对象。Application对象处于Excel对象层次结构的顶层,表示Excel自身的运行环境。
(2) Workbook对象。Workbook对象直接地处于Application对象的下层,表示一个Excel工作薄文件。
(3) Worksheet对象。Worksheet对象包含于Workbook对象,表示一个Excel工作表。
(4) Range对象。Range对象包含于Worksheet对象,表示Excel工作表中的一个或多个单元格。
C#中的受管代码和非受管代码 :
在.NET公用语言框架内运行的程序为受管代码。受管代码在程序中所有类型都受到严格检查,没有指针,对内存的管理完全由运行系统控制。受控状态下,编写程序更为容易,且更少出错,我们可以花更多的时间在解决实际问题上而不是在计算机语言问题上。相对而言,那些在.NET框架外运行的程序为非受管代码。比如:COM组件、ActiveX组件、Win32 API函数、指针运算等。C#编程中在某些特定情况下,需要运用非受管代码,例如,要利用一个成熟的COM组件,或者调用一个API函数,或者用指针去编写实时/高效程序等。
Visual C#中调用Excel的COM组件:
一个.NET组件事实上是一个.NET下的DLL,它包含的不仅是运行程序本身,更重要的是包含这个DLL的描述信息(Meta Data,即元数据),而一个COM组件是用其类库(TLB)储存其描述信息。这些COM组件都是非受管代码,要在Visual C#中使用这些非受管代码的COM组件,就必须把他们转换成受管代码的.NET组件。所以在用Visual C#调用Excel表格之前,必须完成从COM组件的非受管代码到受管代码的类库的转换。
1、将Excel的COM组件转换为.NET组件:
在项目中打开Add Reference对话框,选择COM栏,之后在COM列表中找到"Microsoft Excel 9.0 Object Library"(Office 2000),然后将其加入到项目的References中即可。Visual C#.NET会自动产生相应的.NET组件文件,以后即可正常使用.
2、Visual C#打开Excel表格:
事实上,在C#中使用一个经转换的COM组件和使用任何一个其它.NET组件完全一样。可以用new关键字创建一个经转换的COM组件,然后再像使用任何一个其它C#对象一样使用这个组件对象。在转换后的.NET组件中定义了一个命名空间Excel,在此命名空间中封装了一个类Application,这个类和启动Excel表格有非常重要的关系,在Visual C#中,只需要下列三行代码就可以完成打开Excel表格的工作,具体如下:
Excel.Application excel = new Excel.Application ();//引用Excel对象
excel.Application.Workbooks.Add ( true );//引用Excel工作簿
excel.Visible = true ;//使Excel可视
但此时的Excel表格是一个空的表格,没有任何内容,下面就来介绍如何往Excel表格中输入数据.
3、往Excel表格中输入数据:
在命名空间"Excel"中,还定义了一个类"Cell",这个类所代表的就是Excel表格中的一个单元格。通过给"Cell"赋值,从而实现往Excel表格中输入相应的数据,下列代码功能是打开Excel表格,并且往表格输入一些数据。
Excel.Application excel = new Excel.Application () ;
excel.Application.Workbooks.Add ( true ) ;
excel.Cells[ 1 , 1 ] = "First Row First Column" ;
excel.Cells[ 1 , 2 ] = "First Row Second Column" ;
excel.Cells[ 2 , 1 ] = "Second Row First Column" ;
excel.Cells[ 2 , 2 ] = "Second Row Second Column" ;
excel.Visible = true ;
4、实例:
下面实例在C#中连接Oracle数据库(Name),从表(TableName)中读取数据,并写入Excel。
string cnString="Provider=msdaora.1;Data source=Name; ";
cnString=cnString+"user id=UserName;password=Password";
try
{
OleDbConnection cn=new OleDbConnection (cnString);
cn.Open ();
try
{
string s="select * from Name.TableName";
OleDbCommand cmd=new OleDbCommand (s,cn);
OleDbDataReader dr=cmd.ExecuteReader ();
Excel.Application xlApp = new Excel.Application();
if(xlApp==null){MessageBox.Show ("Can't open Excel!");return;}
xlApp.Application .Workbooks .Add (true);
int row=2,fieldcount;
fieldcount=dr.FieldCount ;
for(int col=0;col<fieldcount;col++) xlApp.Cells [1,col+1]=dr.GetName(col);
while (dr.Read ())
{
for(int col=0;col<fieldcount;col++)
xlApp.Cells [row,col+1]=dr.GetValue(col).ToString();
row++;
}
xlApp.Visible =true;
xlApp=null;
}
catch(Exception ex ){MessageBox.Show (ex.Message );}
finally {cn.Close();}
}
catch(Exception ex){MessageBox.Show (ex.Message );}
}
}
5、安装一个使用COM组件的.NET程序:
如果要将这样的程序安装运行在另一台机器上,那么除了安装运行程序外,还做三件事。
首先,是安装.NET运行系统。因为任何一个.NET程序都不能离开.NET运行系统去独立运行。
其次,所调用的COM组件必须要安装在目标机器上。本例中大多数目标机器上都装有Microsoft Office的Excel,一般不会有这个问题。但如果是另一个用户自定义的COM组件,那么这个COM组件在运行.NET程序之前必须先安装好。
最后,转换后的.NET组件DLL文件要安装在目标机器上。因为.NET组件不需要在Windows Registry中注册,所以最简单的方法是将.NET组件DLL文件拷贝到运行程序目录下。如果此.NET组件被多个.NET程序共享,可以将其安装在.NET公用组件区中,从而可被任何一个.NET组件使用。只有当一个.NET组件参与了事务处理时,才需要将它注册为一个COM+组件。因为.NET仍然用传统的COM+机制来处理事务的提交、回滚等。
小结
通过以上讨论,我们知道了在C#中,如何使用Excel的COM组件。需要注意的是,Excel对象包含的许多内容我们没有介绍,在使用过程中需要我们不断学习。也使我们了解了在C#中如何使用COM组件。