如何访问 Office 互操作对象(C# 编程指南)
C# 具有一些功能,可简化对 Office API 对象的访问。 这些新功能包括命名实参和可选实参、名为 dynamic
的新类型,以及在 COM 方法中将实参传递为引用形参(就像它们是值形参)的功能。
在本主题中,你将利用这些新功能来编写创建并显示 Microsoft Office Excel 工作表的代码。 然后,你将编写添加包含链接到 Excel 工作表的图标的 Office Word 文档的代码。
若要完成本演练,你的计算机上必须安装 Microsoft Office Excel 2007 和 Microsoft Office Word 2007 或更高版本。
注意
以下说明中的某些 Visual Studio 用户界面元素在计算机上出现的名称或位置可能会不同。 这些元素取决于你所使用的 Visual Studio 版本和你所使用的设置。 有关详细信息,请参阅个性化设置 IDE。
创建新的控制台应用程序
启动 Visual Studio。
在 “文件” 菜单上,指向 “新建” ,然后单击 “项目” 。 此时将出现“新建项目”对话框。
在“已安装的模板”窗格中,展开“Visual C#”,然后单击“Windows”。
查看“新建项目”对话框的顶部,确保“.NET Framework 4”(或更高版本)选为目标框架。
在“模板”窗格中,单击“控制台应用程序”。
在“名称”字段中键入项目的名称。
单击 “确定” 。
新项目将出现在“解决方案资源管理器”中。
添加引用
在“解决方案资源管理器”中,右键单击你的项目名称,然后单击“添加引用”。 此时会显示“添加引用”对话框。
在“程序集”页上,在“组件名称”列表中选择“Microsoft.Office.Interop.Word”,然后按住 Ctrl 键并选择“Microsoft.Office.Interop.Excel”。 如果未看到程序集,你可能需要确保安装并将其显示出来。 请参阅如何:安装 Office 主互操作程序集。
单击 “确定” 。
添加必要的 using 指令
在“解决方案资源管理器”中,右键单击“Program.cs”文件,然后单击“查看代码”。
将以下
using
指令添加到代码文件的顶部:using Excel = Microsoft.Office.Interop.Excel; using Word = Microsoft.Office.Interop.Word;
创建银行帐户列表
将以下类定义粘贴到“Program.cs”中的
Program
类下。public class Account { public int ID { get; set; } public double Balance { get; set; } }
将以下代码添加到
Main
方法,以创建包含两个帐户的bankAccounts
列表。// Create a list of accounts. var bankAccounts = new List<Account> { new Account { ID = 345678, Balance = 541.27 }, new Account { ID = 1230221, Balance = -127.44 } };
声明将帐户信息导出到 Excel 的方法
将以下方法添加到
Program
类以设置 Excel 工作表。方法 Add 有一个可选参数,用于指定特定的模板。 如果希望使用形参的默认值,你可以借助可选形参以忽略该形参的实参。 由于以下代码中未发送任何参数,
Add
将使用默认模板并创建新的工作簿。 C# 早期版本中的等效语句要求提供一个占位符参数:ExcelApp.Workbooks.Add(Type.Missing)
。static void DisplayInExcel(IEnumerable<Account> accounts) { var excelApp = new Excel.Application(); // Make the object visible. excelApp.Visible = true; // Create a new, empty workbook and add it to the collection returned // by property Workbooks. The new workbook becomes the active workbook. // Add has an optional parameter for specifying a particular template. // Because no argument is sent in this example, Add creates a new workbook. excelApp.Workbooks.Add(); // This example uses a single workSheet. The explicit type casting is // removed in a later procedure. Excel._Worksheet workSheet = (Excel.Worksheet)excelApp.ActiveSheet; }
在
DisplayInExcel
的末尾添加以下代码。 代码将值插入工作表第一行的前两列。// Establish column headings in cells A1 and B1. workSheet.Cells[1, "A"] = "ID Number"; workSheet.Cells[1, "B"] = "Current Balance";
在
DisplayInExcel
的末尾添加以下代码。foreach
循环将帐户列表中的信息放入工作表连续行的前两列。var row = 1; foreach (var acct in accounts) { row++; workSheet.Cells[row, "A"] = acct.ID; workSheet.Cells[row, "B"] = acct.Balance; }
在
DisplayInExcel
的末尾添加以下代码以将列宽调整为适合内容。workSheet.Columns[1].AutoFit(); workSheet.Columns[2].AutoFit();
早期版本的 C# 要求显式强制转换这些操作,因为
ExcelApp.Columns[1]
返回Object
且AutoFit
为 Excel Range 方法。 以下各行显示强制转换。((Excel.Range)workSheet.Columns[1]).AutoFit(); ((Excel.Range)workSheet.Columns[2]).AutoFit();
C# 自动将返回的
Object
转换为dynamic
,前提是程序集由 EmbedInteropTypes 编译器选项引用,或 Excel 的“嵌入互操作类型”属性设置为 true。 True 是此属性的默认值。
运行项目
在
Main
的末尾添加以下行。// Display the list in an Excel spreadsheet. DisplayInExcel(bankAccounts);
按 Ctrl+F5。
出现包含两个帐户数据的 Excel 工作表。
添加 Word 文档
若要说明 C# 在其他哪些方面加强了 Office 编程,可以使用以下代码打开 Word 应用程序并创建链接到 Excel 工作表的图标。
将方法
CreateIconInWordDoc
(在此步骤后面提供)粘贴到Program
类中。CreateIconInWordDoc
使用命名参数和可选参数来降低对 Add 和 PasteSpecial 方法调用的复杂性。 这些调用合并了其他两项新功能,这两项新功能简化了具有引用参数的 COM 方法的调用。 首先,你可以将实参发送到引用形参,就像它们是值形参一样。 即,你可以直接发送值,而无需为每个引用参数创建变量。 编译器会生成临时变量以保存参数值,并将在你从调用返回时丢弃变量。 其次,你可以忽略参数列表中的ref
关键字。Add
方法有四个引用参数,所有引用参数都是可选的。 如果希望使用其默认值,可以忽略任何或所有形参的实参。PasteSpecial
方法可插入剪贴板的内容。 该方法有七个引用参数,所有引用参数都是可选的。 以下代码为其中两个形参指定实参:Link
用于创建指向剪贴板内容源的链接,DisplayAsIcon
用于将链接显示为图标。 可以对其中两个形参使用命名实参而忽略其他形参。 尽管这些是引用形参,你也不必使用ref
关键字,或者创建变量以实参形式发送。 你可以直接发送值。static void CreateIconInWordDoc() { var wordApp = new Word.Application(); wordApp.Visible = true; // The Add method has four reference parameters, all of which are // optional. Visual C# allows you to omit arguments for them if // the default values are what you want. wordApp.Documents.Add(); // PasteSpecial has seven reference parameters, all of which are // optional. This example uses named arguments to specify values // for two of the parameters. Although these are reference // parameters, you do not need to use the ref keyword, or to create // variables to send in as arguments. You can send the values directly. wordApp.Selection.PasteSpecial( Link: true, DisplayAsIcon: true); }
在
Main
的末尾添加以下语句。// Create a Word document that contains an icon that links to // the spreadsheet. CreateIconInWordDoc();
在
DisplayInExcel
的末尾添加以下语句。Copy
方法可将工作表添加到剪贴板。// Put the spreadsheet contents on the clipboard. The Copy method has one // optional parameter for specifying a destination. Because no argument // is sent, the destination is the Clipboard. workSheet.Range["A1:B3"].Copy();
按 Ctrl+F5。
将出现包含图标的 Word 文档。 双击该图标以将工作表置于前台。
设置嵌入互操作类型属性
当调用运行时不需要主互操作程序集 (PIA) 的 COM 类型时,可能实现其他增强。 删除 PIA 的依赖项可实现版本独立性并且更易于部署。 若要详细了解不使用 PIA 编程的优势,请参阅演练:嵌入托管程序集中的类型。
此外,由于可以通过使用类型
dynamic
(而非Object
)表示 COM 方法必需并返回的类型,因此更易于编程。 具有类型dynamic
的变量在运行时以前均不会计算,从而消除了显式强制转换的需要。 有关更多信息,请参见使用类型 dynamic。默认行为是嵌入类型信息,而不是使用 PIA。 由于该默认行为,因此不需要显式强制转换,之前的几个示例也得到简化。 例如,
worksheet
中DisplayInExcel
的声明会写为Excel._Worksheet workSheet = excelApp.ActiveSheet
而非Excel._Worksheet workSheet = (Excel.Worksheet)excelApp.ActiveSheet
。 在相同方法中对AutoFit
的调用还将要求在不进行默认行为的情况下显式强制转换,因为ExcelApp.Columns[1]
返回Object
,并且AutoFit
为 Excel 方法。 以下代码显示强制转换。((Excel.Range)workSheet.Columns[1]).AutoFit(); ((Excel.Range)workSheet.Columns[2]).AutoFit();
若要更改默认行为并使用 PIA 代替嵌入类型信息,请展开“解决方案资源管理器”中的“引用”节点,然后选择“Microsoft.Office.Interop.Excel”或“Microsoft.Office.Interop.Word”。
如果看不到“属性”窗口,请按“F4”。
在属性列表中找到“嵌入互操作类型”,将其值更改为“False”。 同样地,还可以通过在命令提示符处使用 References 编译器选项代替 EmbedInteropTypes 进行编译。
将其他格式添加到表格
将在
AutoFit
中对DisplayInExcel
的两个调用替换为以下语句。// Call to AutoFormat in Visual C# 2010. workSheet.Range["A1", "B3"].AutoFormat( Excel.XlRangeAutoFormat.xlRangeAutoFormatClassic2);
AutoFormat 方法有七个值参数,所有引用参数都是可选的。 使用命名自变量和可选自变量,你可以为这些自变量中的所有或部分提供自变量,也可以不为它们中的任何一个提供。 在上一条语句中,仅为其中一个形参
Format
提供实参。 由于Format
是参数列表中的第一个参数,因此无需提供参数名称。 但是,如果包含参数名称,语句则可能更易于理解,如以下代码所示。// Call to AutoFormat in Visual C# 2010. workSheet.Range["A1", "B3"].AutoFormat(Format: Excel.XlRangeAutoFormat.xlRangeAutoFormatClassic2);
按 Ctrl+F5 查看结果。 其他格式在 XlRangeAutoFormat 枚举中列出。
示例
以下代码显示完整示例。
using System;
using System.Collections.Generic;
using System.Linq;
using Excel = Microsoft.Office.Interop.Excel;
using Word = Microsoft.Office.Interop.Word;
namespace OfficeProgramminWalkthruComplete
{
class Walkthrough
{
static void Main(string[] args)
{
// Create a list of accounts.
var bankAccounts = new List<Account>
{
new Account {
ID = 345678,
Balance = 541.27
},
new Account {
ID = 1230221,
Balance = -127.44
}
};
// Display the list in an Excel spreadsheet.
DisplayInExcel(bankAccounts);
// Create a Word document that contains an icon that links to
// the spreadsheet.
CreateIconInWordDoc();
}
static void DisplayInExcel(IEnumerable<Account> accounts)
{
var excelApp = new Excel.Application();
// Make the object visible.
excelApp.Visible = true;
// Create a new, empty workbook and add it to the collection returned
// by property Workbooks. The new workbook becomes the active workbook.
// Add has an optional parameter for specifying a praticular template.
// Because no argument is sent in this example, Add creates a new workbook.
excelApp.Workbooks.Add();
// This example uses a single workSheet.
Excel._Worksheet workSheet = excelApp.ActiveSheet;
// Earlier versions of C# require explicit casting.
//Excel._Worksheet workSheet = (Excel.Worksheet)excelApp.ActiveSheet;
// Establish column headings in cells A1 and B1.
workSheet.Cells[1, "A"] = "ID Number";
workSheet.Cells[1, "B"] = "Current Balance";
var row = 1;
foreach (var acct in accounts)
{
row++;
workSheet.Cells[row, "A"] = acct.ID;
workSheet.Cells[row, "B"] = acct.Balance;
}
workSheet.Columns[1].AutoFit();
workSheet.Columns[2].AutoFit();
// Call to AutoFormat in Visual C#. This statement replaces the
// two calls to AutoFit.
workSheet.Range["A1", "B3"].AutoFormat(
Excel.XlRangeAutoFormat.xlRangeAutoFormatClassic2);
// Put the spreadsheet contents on the clipboard. The Copy method has one
// optional parameter for specifying a destination. Because no argument
// is sent, the destination is the Clipboard.
workSheet.Range["A1:B3"].Copy();
}
static void CreateIconInWordDoc()
{
var wordApp = new Word.Application();
wordApp.Visible = true;
// The Add method has four reference parameters, all of which are
// optional. Visual C# allows you to omit arguments for them if
// the default values are what you want.
wordApp.Documents.Add();
// PasteSpecial has seven reference parameters, all of which are
// optional. This example uses named arguments to specify values
// for two of the parameters. Although these are reference
// parameters, you do not need to use the ref keyword, or to create
// variables to send in as arguments. You can send the values directly.
wordApp.Selection.PasteSpecial(Link: true, DisplayAsIcon: true);
}
}
public class Account
{
public int ID { get; set; }
public double Balance { get; set; }
}
}