如何访问C#中已经打开的Excel文件?

我有一个Excel工作簿通过在Windows资源pipe理器中双击打开,但无法在代码中访问它

Excel.Application xlApp = (Application)Marshal.GetActiveObject("Excel.Application"); Excel.Workbooks xlBooks = xlApp.Workbooks; 

xlBooks.Count等于0,为什么它不是引用我打开的工作簿?

编辑

以下是各种情况和发生的情况:

情况1:如果文件尚未打开

  • 代码打开工作簿,我很高兴。

scheme2:如果文件最初是从代码打开的,我closures并重新打开该应用程序

  • 代码引用文件就好了xlBooks.Count等于1,我很高兴。

场景3 :如果文件最初不是从代码打开的,而是通过在浏览器中双击它

  • 代码打开文件的另一个实例xlBooks.Count等于0, 我很愤怒!

这是现在的整个代码

 using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices; using Microsoft.Office.Interop.Excel; public class ExcelService : IExcelService { const string _filePath = @"C:\Somewhere"; const string _fileName = @"TestFile.xlsb"; string _fileNameAndPath = Path.Combine(_filePath, _fileName); Application xlApp; Workbooks xlBooks; Workbook xlBook; Worksheet xlSheet; public ExcelService() { try { xlApp = (Application)Marshal.GetActiveObject("Excel.Application"); xlBooks = xlApp.Workbooks; var numBooks = xlBooks.Count; Log.Info("Number of workbooks: {0}".FormatWith(numBooks)); if (numBooks > 0) { xlBook = xlBooks[1]; Log.Info("Using already opened workbook"); } else { xlBook = xlBooks.Open(_fileNameAndPath); Log.Info("Opening workbook: {0}".FormatWith(_fileNameAndPath)); } xlSheet = (Worksheet)xlBook.Worksheets[1]; // test reading a named range string value = xlSheet.Range["TEST"].Value.ToString(); Log.Info(@"TEST: {0}".FormatWith(value)); xlApp.Visible = true; } catch (Exception e) { Log.Error(e.Message); } } ~ExcelService() { GC.Collect(); GC.WaitForPendingFinalizers(); try { Marshal.FinalReleaseComObject(xlSheet); } catch { } try { Marshal.FinalReleaseComObject(xlBook); } catch { } try { Marshal.FinalReleaseComObject(xlBooks); } catch { } try { Marshal.FinalReleaseComObject(xlApp); } catch { } } } 

如果所有工作簿都在同一个Excel实例中打开(可以通过检查是否可以使用Alt-Tab从一个切换到另一个来检查)。 您可以使用Workbooks("[FileName]")简单地引用其他对象。 所以,例如:

 Dim wb as Workbook //for C#, type Excel.Workbook wb = null; Set wb = Workbooks("MyDuperWorkbook.xlsx") //for C#, type wb = Excel.Workbooks["MyDuperWorkbook.xlsx"]; wb.Sheets(1).Cells(1,1).Value = "Wahou!" 

我知道这个线程有点旧了,但是我发现了另外一个方法。 当您创build新的Excel.Application对象时,您必须创buildWorkBooks对象。 当你访问一个已经打开的Excel文件时, WorkBooks对象已经被创build,所以你只需要添加一个新的WorkBook到现有的。 @Tipx的解决scheme工作得很好,如果你有权限访问WorkBook名字,但是在我的情况下,当前的WorkBook名字总是随机的。 这是我想出来解决这个问题的解决scheme:

 Excel.Application excelApp = null; Excel.Workbooks wkbks = null; Excel.Workbook wkbk = null; bool wasFoundRunning = false; Excel.Application tApp = null; //Checks to see if excel is opened try { tApp = (Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application"); wasFoundRunning = true; } catch (Exception)//Excel not open { wasFoundRunning = false; } finally { if (true == wasFoundRunning) { excelApp = tApp; wkbk = excelApp.Workbooks.Add(Type.Missing); } else { excelApp = new Excel.Application(); wkbks = excelApp.Workbooks; wkbk = wkbks.Add(Type.Missing); } //Release the temp if in use if (null != tApp) { Marshal.FinalReleaseComObject(tApp); } tApp = null; } //Initialize the sheets in the new workbook 

可能不是最好的解决scheme,但它符合我的需求。 希望这有助于某人。 🙂