Visual Studio 2010特性支持Office
要使用托管代码调用 Office 应用程序功能,必须使用互操作程序集。互操作程序集使托管代码可以与 Office 应用程序的基于 COM 的对象模型进行交互。所以在项目创建完成后,为了进行Office开发,我们需要在项目中添加Office互操作程序集的引用。在解决方案浏览器(Solution Explorer)中的项目节点上,我们单击右键,在弹出的上下文菜单中我们选择“添加引用(Add Reference)”。在弹出的对话框中,我们选中.NET标签页中的Microsoft.Office.Interop.Excel, version 12.0和Microsoft.Office.Interop.Word, version 12.0,单击“OK”将它们添加到刚刚创建的项目OfficeDev中。
图2 添加互操作程序集
2. 创建和准备银行账号类Account
在OfficeDev项目中,我们新建一个类Account,用来表示银行账号。我们将这个类实现如下:
public class Account {
public string Name { get; set; }
public double Balance { get; set; }
}
这里需要注意的是,为了简化后面的流程,我们没有将这个类定义在任何名字空间内。
接下来,为了进行Office开发,我们需要在代码中引入Office开发相关的名字空间。在Program.cs中添加如下代码以引入相应的名字空间:
using Microsoft.Office.Interop;
using Excel = Microsoft.Office.Interop.Excel;
using Word = Microsoft.Office.Interop.Word;
最后,我们用数据初始化Account类的对象,并将它们添加到容器中,以备后用。在主函数Main()中添加如下代码:
var checkAccounts = new List<Account> {
new Account {
Name = “陈良乔”,
Balance = 541.27
},
new Account {
Name = “贾玮”,
Balance = -127.44
}
};
这里我们用账号数据新创建了两个Account对象,并将它们添加到List容器checkAccounts中。
3. 在Excel中显示账号数据
上一步我们完成了数据的准备,下面我们将把这些数据显示到Excel表格中。我们定义一个DisplayInExcel()函数用于创建Excel表格,然后将容器中的账号数据填充到Excel表格中:
public static void DisplayInExcel(IEnumerable<Account> accounts,
Action<Account, Excel.Range> DisplayFunc)
{
var xl = new Excel.Application();
xl.Workbooks.Add();
xl.Visible = true;
xl.Cells[1, 1].Value2 = "Name";
xl.Cells[1, 2].Value2 = " Balance";
xl.Cells[2, 1].Select();
foreach (var ac in accounts)
{
DisplayFunc(ac, xl.ActiveCell);
xl.ActiveCell.get_Offset(1, 0).Select();
}
xl.get_Range("A1:B3").Copy();
}
然后,我们在Main()函数的底部,按照如下的方式调用DisplayInExcel()函数,最终完成Excel表格的创建和数据的填充:
DisplayInExcel(checkAccounts, (account, cell) =>
{
// This multiline lambda will set
// custom processing rules.
cell.Value2=account.Name;
cell.get_Offset(0, 1).Value2 = account.Balance;
if (account.Balance < 0)
{
cell.Interior.Color = 255;
cell.get_Offset(0, 1).Interior.Color = 255;
}
});
这里我们使用了Lambda表达式,由它来对数据填充的逻辑进行具体的定义,最终完成数据的填充。同时,它还会检查Balance的值,如果为负值,则将表格填充为红色,表示这个账号已经赤字了。最后,为了使得Excel表格更加美观,我们让Excel表格根据内容自动调整表格的宽度。在DisplayInExcel()函数的末尾,我们添加如下的代码:
xl.Columns[1].AutoFit();
xl.Columns[2].AutoFit();
在这里,有过Office开发经验的朋友可能会感到奇怪,AutoFit()函数可以被Columns的返回结果直接调用而无需进行类型转换吗?的确,在C# 3.0中,要想调用AutoFit()函数,必须对Columns的返回值进行类型转换,上面的代码应该写成:
// C# 3.0 code. Not necessary in C# 4.0!
((Range)xl.Columns[1]).AutoFit();
((Range)xl.Columns[2]).AutoFit();
但是在C# 4.0中,因为有了dynamic类型的支持,繁琐的类型转换将不再需要。在C# 4.0中,从COM接口返回的Object类型的对象,被自动当做dynamic类型来处理。我们前面曾经介绍过,因为动态类型的迟绑定特性(late binding),dynamic类型可以调用任何函数,所以无需再进行类型转换,也不会产生编译错误。在运行的时候,动态语言运行时(DLR)会动态查找对象真正的类型而调用相应的函数。