添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

C# 提供了改进 Microsoft Office 编程的功能。 有用的 C# 功能包括命名参数和可选参数以及类型为 dynamic 的返回值。 在 COM 编程中,可以省略 ref 关键字并获得索引属性的访问权限。

两种语言都支持嵌入类型信息,从而允许在不向用户的计算机部署主互操作程序集 (PIA) 的情况下部署与 COM 组件交互的程序集。 有关详细信息,请参见 演练:嵌入托管程序集中的类型

本演练演示 Office 编程上下文中的这些功能,但其中许多功能在常规编程中也极为有用。 本演练将使用 Excel 外接应用程序创建 Excel 工作簿。 然后,将创建包含工作簿链接的 Word 文档。 最后,将介绍如何启用和禁用 PIA 依赖项。

VSTO (Visual Studio Tools for Office) 依赖于 .NET Framework 。 COM 加载项也可以使用 .NET Framework 编写。 不能使用 .NET Core 和 .NET 5+ (最新版本的 .NET)创建 Office 加载项。 这是因为 .NET Core/.NET 5+ 无法在同一进程中与 .NET Framework 协同工作,并可能导致加载项加载失败。 可以继续使用 .NET Framework 编写适用于 Office 的 VSTO 和 COM 加载项。 Microsoft 不会更新 VSTO 或 COM 加载项平台以使用 .NET Core 或 .NET 5+。 可以利用 .NET Core 和 .NET 5+(包括 ASP.NET Core)创建 Office Web 加载项 的服务器端。

若要完成本演练,计算机上必须安装 Microsoft Office Excel 和 Microsoft Office Word。

以下说明中的某些 Visual Studio 用户界面元素在计算机上出现的名称或位置可能会不同。 这些元素取决于你所使用的 Visual Studio 版本和你所使用的设置。 有关详细信息,请参阅 个性化设置 IDE

设置 Excel 加载项应用程序

  • 启动 Visual Studio。
  • “文件” 菜单上,指向 “新建” ,然后选择 “项目”
  • 在“安装的模板”窗格中,展开“C#”,再展开“Office”,然后选择 Office 产品的版本年份。
  • 在“模板”窗格中,选择“Excel <version> 加载项”。
  • 查看“模板”窗格的顶部,确保“.NET Framework 4”或更高版本出现在“目标框架”框中。
  • 如果需要,在“名称”框中键入项目的名称。
  • 选择“确定”。
  • 新项目将出现在“解决方案资源管理器”中。
  • 在“解决方案资源管理器”中,右键单击你的项目名称,然后选择“添加引用”。 此时会显示“添加引用”对话框。
  • 在“程序集”选项卡上,在“组件名称”列表中选择“Microsoft.Office.Interop.Excel”版本 <version>.0.0.0 (有关 Office 产品版本号的键,请参阅 Microsoft 版本 ),然后按住 Ctrl 键并选择“Microsoft.Office.Interop.Word”, version <version>.0.0.0 。 如果未看到程序集,可能需要安装它们(请参阅 如何:安装 Office 主互操作程序集 )。
  • 选择“确定”。
  • 添加必要的 Imports 语句或 using 指令

    在“解决方案资源管理器”中,右键单击“ThisAddIn.cs”文件,然后选择“查看代码”。 将下列 using 指令 (C#) 添加到代码文件的顶部(如果它们尚不存在)。

    using System.Collections.Generic;
    using Excel = Microsoft.Office.Interop.Excel;
    using Word = Microsoft.Office.Interop.Word;
    

    创建银行帐户列表

    在“解决方案资源管理器”中,右键单击你的项目名称,选择“添加”,然后选择“类”。 将类命名为 Account.cs。 选择 添加 。 将 Account 类的定义替换为以下代码。 类定义使用自动实现的属性。

    class Account
        public int ID { get; set; }
        public double Balance { get; set; }
    

    若要创建包含两个帐户的 bankAccounts 列表,请将以下代码添加到 ThisAddIn.cs 中的 ThisAddIn_Startup 方法。 列表声明使用集合初始值设定项。

    var bankAccounts = new List<Account>
        new Account
            ID = 345,
            Balance = 541.27
        new Account
            ID = 123,
            Balance = -127.44
    

    将数据导出到 Excel

    在相同的文件中,将以下方法添加到 ThisAddIn 类。 该方法设置 Excel 工作薄并将数据导出到工作簿。

    void DisplayInExcel(IEnumerable<Account> accounts,
               Action<Account, Excel.Range> DisplayFunc)
        var excelApp = this.Application;
        // Add a new Excel workbook.
        excelApp.Workbooks.Add();
        excelApp.Visible = true;
        excelApp.Range["A1"].Value = "ID";
        excelApp.Range["B1"].Value = "Balance";
        excelApp.Range["A2"].Select();
        foreach (var ac in accounts)
            DisplayFunc(ac, excelApp.ActiveCell);
            excelApp.ActiveCell.Offset[1, 0].Select();
        // Copy the results to the Clipboard.
        excelApp.Range["A1:B3"].Copy();
    
  • 方法 Add 有一个可选参数,用于指定特定的模板。 如果希望使用形参的默认值,你可以借助可选形参以忽略该形参的实参。 由于上一个示例没有参数,Add 将使用默认模板并创建新的工作簿。 C# 早期版本中的等效语句要求提供一个占位符参数:excelApp.Workbooks.Add(Type.Missing)。 有关详细信息,请参阅命名参数和可选参数
  • Range 对象的 RangeOffset 属性使用“索引属性”功能。 此功能允许你通过以下典型 C# 语法从 COM 类型使用这些属性。 索引属性还允许你使用 Value 对象的 Range 属性,因此不必使用 Value2 属性。 Value 属性已编入索引,但索引是可选的。 在以下示例中,可选自变量和索引属性配合使用。
  • // Visual C# 2010 provides indexed properties for COM programming.
    excelApp.Range["A1"].Value = "ID";
    excelApp.ActiveCell.Offset[1, 0].Select();
    

    你不能创建自己的索引属性。 该功能仅支持使用现有索引属性。

    DisplayInExcel 的末尾添加以下代码以将列宽调整为适合内容。

    excelApp.Columns[1].AutoFit();
    excelApp.Columns[2].AutoFit();
    

    这些新增内容介绍了 C# 中的另一功能:处理从 COM 主机返回的 Object 值(如 Office),就像它们具有 dynamic 类型一样。 当嵌入互操作类型具有其默认值时,COM 对象将被自动视为 dynamic;当你使用 EmbedInteropTypes 编译器选项引用程序集时,该对象被视为 True 或等效值。 有关嵌入互操作类型的详细信息,请参阅本文后面部分的“查找 PIA 引用”和“还原 PIA 依赖项”程序。 有关 dynamic 的详细信息,请参阅 dynamic使用类型 dynamic

    调用 DisplayInExcel

    ThisAddIn_StartUp 方法的末尾添加以下代码。 对 DisplayInExcel 的调用包含两个参数。 第一个参数是已处理的帐户列表的名称。 第二个参数是定义如何处理数据的多行 Lambda 表达式。 每个帐户的 IDbalance 值都显示在相邻的单元格中,如果余额小于零,则相应的行显示为红色。 有关详细信息,请参阅 Lambda 表达式

    DisplayInExcel(bankAccounts, (account, cell) =>
    // This multiline lambda expression sets custom processing rules
    // for the bankAccounts.
        cell.Value = account.ID;
        cell.Offset[0, 1].Value = account.Balance;
        if (account.Balance < 0)
            cell.Interior.Color = 255;
            cell.Offset[0, 1].Interior.Color = 255;
    

    若要运行程序,请按 F5。 出现包含帐户数据的 Excel 工作表。

    添加 Word 文档

    ThisAddIn_StartUp 方法末尾添加以下代码,以创建包含指向 Excel 工作簿的链接的 Word 文档。

    var wordApp = new Word.Application();
    wordApp.Visible = true;
    wordApp.Documents.Add();
    wordApp.Selection.PasteSpecial(Link: true, DisplayAsIcon: true);
    

    此代码演示 C# 中的几个功能:在 COM 编程、命名参数和可选参数中省略 ref 关键字的功能。PasteSpecial 方法有七个参数,所有这些参数都是可选的引用参数。 通过命名实参和可选实参,你可以指定希望按名称访问的形参并仅将实参发送到这些形参。 在本示例中,实参指示创建指向剪贴板上工作簿的链接(形参 Link)并在 Word 文档中将该链接显示为图标(形参 DisplayAsIcon)。 C# 还允许忽略这些参数的 ref 关键字。

    运行应用程序

    按 F5 运行该应用程序。 Excel 启动并显示包含 bankAccounts 中两个帐户的信息的表。 然后,出现包含指向 Excel 表的 Word 文档。

    清理已完成的项目

    在 Visual Studio 中,选择“生成”菜单上的“清理解决方案”。 否则,每次在计算机上打开 Excel 时都会运行加载项。

    查找 PIA 引用

  • 再次运行应用程序,但不选择“清理解决方案”。
  • 选择“开始”。 找到“Microsoft Visual Studio <版本>”,然后打开开发人员命令提示。
  • 在“Visual Studio 的开发人员命令提示”窗口中键入 ildasm,然后按 Enter。 此时将出现 IL DASM 窗口。
  • 在 IL DASM 窗口的“文件”菜单上,选择“文件”>“打开”。 双击“Visual Studio <版本>”,然后双击“项目”。 打开项目的文件夹,在 bin/Debug 文件夹中查找项目名称.dll。 双击 项目名称.dll。 新窗口将显示项目的属性以及对其他模块和程序集的引用。 程序集包括命名空间 Microsoft.Office.Interop.ExcelMicrosoft.Office.Interop.Word。 在 Visual Studio 中,编译器默认将所需的类型从引用的 PIA 导入程序集。 有关详细信息,请参阅如何:查看程序集内容
  • 双击“清单”图标。 此时将出现包含程序集列表的窗口,这些程序集包含项目所引用的项。 Microsoft.Office.Interop.ExcelMicrosoft.Office.Interop.Word 不在列表中。 由于已将项目所需的类型导入程序集,因此无需安装对 PIA 的引用。 将类型导入程序集可简化部署。 用户计算机上不必存在 PIA。 应用程序不需要部署特定版本的 PIA。 应用程序可以使用多个版本的 Office,前提是所有版本中都存在必要的 API。 由于不再需要部署 PIA,你可以提前创建可与多个版本的 Office(包括之前的版本)配合使用的应用程序。 你的代码不能使用你正在使用的 Office 版本中不可用的任何 API。 特定 API 在早期版本中是否可用并不总是很清楚。 不建议使用早期版本的 Office。
  • 关闭清单窗口和程序集窗口。
  • 还原 PIA 依赖项

  • 在解决方案资源管理器中选择“显示所有文件”按钮。 展开“引用”文件夹并选择“Microsoft.Office.Interop.Excel”。 按 F4 以显示“属性”窗口。
  • 在“属性”窗口中,将“嵌入互操作类型”属性从“True”更改为“False”。
  • Microsoft.Office.Interop.Word 重复此程序中的步骤 1 和 2。
  • 在 C# 中,在 Autofit 方法的末尾注释掉对 DisplayInExcel 的两次调用。
  • 按 F5 以验证项目是否仍正确运行。
  • 重复上一个程序的步骤 1-3 以打开程序集窗口。 注意,Microsoft.Office.Interop.WordMicrosoft.Office.Interop.Excel 不再位于嵌入程序集列表中。
  • 双击“清单”图标并滚动引用程序集的列表。 Microsoft.Office.Interop.WordMicrosoft.Office.Interop.Excel 均位于列表中。 由于应用程序引用 Excel 和 Word PIA 并且“嵌入互操作类型”属性为“False”,因此最终用户的计算机上必须存在两个程序集。
  • 在 Visual Studio 中,选择“生成”菜单上的“清理解决方案”以清理完成的项目。
  • 自动实现的属性 (C#)
  • 对象和集合初始值设定项
  • Visual Studio Tools for Office (VSTO)
  • 命名参数和可选参数
  • dynamic
  • 使用类型 dynamic
  • Lambda 表达式 (C#)
  • 演练:在 Visual Studio 中嵌入 Microsoft Office 程序集中的类型信息
  • 演练:嵌入托管程序集中的类型
  • 演练:创建你的第一个 Excel VSTO 外接程序
  •