Excel Interop加载模板到现有的工作簿中

如何将模板中的工作表加载到现有的Excel工作簿中(如果没有现有工作簿,则先创build一个空白工作簿)。

我努力了

Excel.Application.Workbooks.Open("path"); 

这个工程,但每次创build一个新的Excel会话,因为它正在创build一个新的工作簿。 我无法通过Googlefind任何有关如何将数据作为新表加载到现有书籍中的信息。

只要在工作簿上调用Open() ,就像您发现的那样,将创build一个新的Excel实例,而不是连接到当前正在运行的实例。 你需要的是更复杂的。 下面是我用来连接到一个工作簿的方法,这个工作簿的名字你已经知道了(你也可以调整它来允许用户select他们想打开的工作簿):

 private Excel.Workbook GetWorkbook(string workbookName) { Excel.Window window = null; // Excel window object from which application is grabbed Excel.Application app = null; // Excel instance from which we get all the open workbooks Excel.Workbooks wbs = null; // List of workbooks Excel.Workbook wb = null; // Workbook to return EnumChildCallback cb; // Callback routine for child window enumeration routine List<Process> procs = new List<Process>(); // List of processes // Get a full list of all processes that have a name of "excel" procs.AddRange(Process.GetProcessesByName("excel")); foreach (Process proc in procs) { // Make sure we have a valid handle for the window if ((int)proc.MainWindowHandle > 0) { // Get the handle of the child window in the current Excel process int childWindow = 0; cb = new EnumChildCallback(EnumChildProc); EnumChildWindows((int)proc.MainWindowHandle, cb, ref childWindow); // Make sure we got a valid handle if (childWindow > 0) { // Get the address of the child window so that we can talk to it and // get all the workbooks const uint OBJID_NATIVEOM = 0xFFFFFFF0; Guid IID_IDispatch = new Guid("{00020400-0000-0000-C000-000000000046}"); int res = AccessibleObjectFromWindow(childWindow, OBJID_NATIVEOM, IID_IDispatch.ToByteArray(), ref window); if (res >= 0) { app = window.Application; wbs = app.Workbooks; // Loop through all the workbooks within the current Excel window // to see if any match for (int i = 1; i <= wbs.Count; i++) { wb = wbs[i]; if (wb.Name == workbookName) { break; } wb = null; } } } } // If we've already found our workbook then there's no point in continuing // through the remaining processes if (wb != null) { break; } } Release(wbs); Release(app); Release(window); return wb; } 

上面调用的Release()方法只是简单地将引用设置为null,并在其上调用Marshal.FinalReleaseComObject() ,否则最终会导致无处不在的Excel实例。

您还需要执行以下操作以执行一些function来抓取窗口:

 private delegate bool EnumChildCallback(int hwnd, ref int lParam); [DllImport("User32.dll")] private static extern bool EnumChildWindows(int hWndParent, EnumChildCallback lpEnumFunc, ref int lParam); [DllImport("Oleacc.dll")] private static extern int AccessibleObjectFromWindow(int hwnd, uint dwObjectID, byte[] riid, ref Excel.Window ptr); private bool EnumChildProc(int hwndChild, ref int lParam) { // Get the name of the class that owns the passed-in window handle StringBuilder buf = new StringBuilder(128); GetClassName(hwndChild, buf, 128); // If the class name is EXCEL7 then we've got an valid Excel window if (buf.ToString() == "EXCEL7") { lParam = hwndChild; return false; } return true; } [DllImport("User32.dll")] private static extern int GetClassName(int hWnd, StringBuilder lpClassName, int nMaxCount); 

回答(感谢Jon49 @ NetOffice讨论区: http ://netoffice.codeplex.com/discussions/434906):

 Excel.Application.Sheets.Add(Type:="TemplateWorkbookPath") 

你可以从你当前工作的工作簿variables中完成:

 wkb.Application.Sheets.Add(Type:="TemplateWorkbookPath")