如何在C#(.NET Core6)中实现Excel宏的两种场景执行?
需求与解决方案:Excel宏的复用执行场景处理
需求说明
- 执行Excel文件中的宏,宏每次执行会在同一工作簿新建工作表并填充数据,支持多次调用
- 两种执行场景:
- 若目标Excel文件已处于打开状态,直接在已打开的文件中调用宏,不新建Excel实例
- 若文件未打开,先打开文件再运行宏
现有问题
当前编写的代码会新建Excel实例并复制目标文件内容,不符合需求:
Application excel = new Application() { Visible = true }; excel.Workbooks.Open(pathToExcelXlsmFile); excel.Run("MyMacro", parameter);
尝试检测已打开工作簿的代码无法正常工作:
excel = (Application)Marshal2.GetActiveObject("Excel.Application"); excel.Workbooks[pathToExcelXlsmFile]; // 无法正常工作 excel.Workbooks.Items[pathToExcelXlsmFile]; // 无法正常工作 excel.Workbooks.get_Item[pathToExcelXlsmFile];// 无法正常工作
解决方案(.NET Core 6)
核心思路:先尝试获取已运行的Excel实例,遍历其打开的工作簿匹配目标文件路径;若找不到则新建实例并打开文件。
实现代码
using Microsoft.Office.Interop.Excel; using System.Runtime.InteropServices; using System; public void ExecuteExcelMacro(string targetFilePath, object macroParameter) { Application excelInstance = null; Workbook targetWorkbook = null; try { // 尝试获取当前活跃的Excel实例 excelInstance = (Application)Marshal.GetActiveObject("Excel.Application"); // 遍历所有已打开的工作簿,匹配完整文件路径 foreach (Workbook workbook in excelInstance.Workbooks) { // 忽略路径大小写差异,确保匹配准确 if (string.Equals(workbook.FullName, targetFilePath, StringComparison.OrdinalIgnoreCase)) { targetWorkbook = workbook; break; } } } catch (COMException) { // 无活跃Excel实例,创建新实例 excelInstance = new Application { Visible = true }; } // 若未找到已打开的工作簿,打开目标文件 if (targetWorkbook == null) { targetWorkbook = excelInstance.Workbooks.Open(targetFilePath); } // 调用指定宏 excelInstance.Run("MyMacro", macroParameter); // 注意:请勿随意关闭Excel实例或工作簿,避免干扰用户操作 // targetWorkbook.Close(SaveChanges: false); // excelInstance.Quit(); }
关键要点
- 正确匹配工作簿:不能直接用文件路径作为
Workbooks的索引,必须遍历所有已打开的工作簿,通过Workbook.FullName属性匹配完整路径(处理大小写和路径分隔符差异) - COM异常处理:当没有运行的Excel实例时,
Marshal.GetActiveObject会抛出COM异常,此时创建新实例即可 - 生命周期管理:执行宏后不要随意关闭Excel实例或工作簿,防止破坏用户正在进行的Excel操作
内容的提问来源于stack exchange,提问作者Harxish
相关产品推荐
相关产品推荐

