1

我阅读了很多关于如何从 C# 到 Excel 进行通信的内容,并看到了一些很好的参考资料。

问题是我正在寻找一种简单的方法来更新现有的 excel 文件,而它仍然处于打开状态,使用最先进的方式(例如 linq)而不是 OLEDB。

这应该是几行代码,描述了我如何读取当前单元格,更新他的值并考虑文件可能不存在,但如果它确实存在并打开,它只会更新文件而不给出文件通知已经存在。如果该文件不存在,它将创建一个新文件。

SO:1.连接到一个excel文件,检查它是否存在,如果不存在,则创建一个
2.从单元格读取
3.更新单元格
4.在excel表仍然可以打开的情况下执行此操作。

我已经去过以下几个地方:

http://social.msdn.microsoft.com/Forums/vstudio/en-US/ef11a193-54f3-407b-9374-9f5770fd9fd7/writing-to-excel-using-c

以编程方式更新 Excel 文档

使用 oledb 更新 excel 文件的特定单元格

我使用了以下代码:

   if (File.Exists(@"C:\\temp\\test.xls"))
        {
            Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();
            Microsoft.Office.Interop.Excel.Workbooks workBooks = excelApp.Workbooks;
            Microsoft.Office.Interop.Excel.Workbook workBook = workBooks.Open(@"C:\\temp\\test.xls");
            Microsoft.Office.Interop.Excel.Worksheet workSheet = workBook.Worksheets.get_Item(1);
            int nColumns = workSheet.UsedRange.Columns.Count;
            int nRows = workSheet.UsedRange.Rows.Count;

            for (int i = 2; i < nRows; i++)
            {
                workSheet.Columns["1","A"] = "test";
            }

            workBook.Save();
            workBook.Close();
        }
4

2 回答 2

4

所以我使用VSTO Contrib来帮助进行 COM 互操作和内存管理,这就是你看到.WithComCleanup().

要打开电子表格:

try
{
    using (var xlApp = new Microsoft.Office.Interop.Excel.Application().WithComCleanup())
    using (var wrkbooks = xlApp.Resource.Workbooks.WithComCleanup())
    using (var wrkbook = wrkbooks.Resource.Open(filePath, false, true).WithComCleanup())
    {

如果 excel 文件已经打开,那么要绕过只读,请遵循以下提示

wrkbooks.Resource.Open(filePath, false, FALSE).WithComCleanup())

以下是我遍历工作表的方式(请注意,一些 Excel 工作表是 ChartSheets):

foreach (object possibleSheet in xlApp.Resource.Sheets)
{
    Microsoft.Office.Interop.Excel.Worksheet aSheet = possibleSheet as Microsoft.Office.Interop.Excel.Worksheet;
    if (aSheet == null)
        continue;

以下是获取您感兴趣的工作表参考的快速方法:

activeSheet = wrkbook.Resource.Sheets[sheetToImport];

正如您所确定的那样,您可以读取和写入单元格:

for (int i = 2; i < nRows; i++)
{
  activeSheet.Columns["1","A"] = "test";
}

这是我关闭 Excel 的方法:

MathematicaAPI.XlHelper.CloseExcel((Worksheet)activeSheet, (Workbook)wrkbook.Resource , (Workbooks)wrkbooks.Resource);

public static void CloseExcel(Worksheet activeSheet, Workbook wrkbook, Workbooks wrkbooks)
{
    //http://support.microsoft.com/kb/317109 -> excel just wont close for some reason
    if (activeSheet != null)
    {
        Marshal.FinalReleaseComObject(activeSheet);
        activeSheet = null;
    }
    if (wrkbook != null)
    {
        wrkbook.Saved = true;
        wrkbook.Close(Microsoft.Office.Interop.Excel.XlSaveAction.xlDoNotSaveChanges);
    }
    if (wrkbooks != null)
    {
        wrkbooks.Close();
    }
    GC.Collect();
    GC.WaitForPendingFinalizers();
    GC.Collect();
    GC.WaitForPendingFinalizers();
}

有时 Excel 只是不会关闭,而您必须将其杀死(当然,在尝试正确关闭它之后) - 我不推荐这样做,但如果您无法追踪未处理的内存并且所有其他操作都失败,那么......

if (xlApp != null)
{
  ExcelDataSourceHelper.GetWindowThreadProcessId(new IntPtr(xlApp.Resource.Hwnd), ref excelProcessId);
}

if (excelProcessId > 0)
{
    XlHelper.KillProcess(excelProcessId);
}

public static void KillProcess(int excelProcessId)
{
    if (excelProcessId > 0)
    {
        System.Diagnostics.Process ExcelProc = null;
        try
        {
            ExcelProc = System.Diagnostics.Process.GetProcessById(excelProcessId);
            if (ExcelProc != null)
            {
                ExcelProc.Kill();
            }
        }
        catch
        { }
    }
}

注意:我通过将 VSTO Contrib 与Using's.

于 2013-09-10T06:53:09.297 回答
0

好的,谢谢大家尝试解决问题解决方案是使用Excel 2011/2013 Add-In,它可以将excel作为插件进行通信

为 Microsoft Office Excel 创建应用程序级加载项。无论打开哪些工作簿,您在此类解决方案中创建的功能都可供应用程序本身使用。

你可以访问MSDN

于 2013-09-10T08:29:12.413 回答