2

Bellow 函数用于格式化 excel 文件,但在运行该函数后,应用程序 Excel 没有从 Try 中关闭。(无法杀死应用程序)请帮我解决这个问题

private void FormateExcelFile()
{
    try
    {
        int nI = 0;//For Loop
        string nFieldName = string.Empty;
        nUserName=  WindowsIdentity.GetCurrent().Name; //Get Windows Login User
        string reportFilenPath = Application.StartupPath + "\\OutPutFiles\\" + "NewTempFile.xls";
        string connString = "provider=Microsoft.Jet.OLEDB.4.0;Data Source='" + reportFilenPath + "';Extended Properties=Excel 8.0;";
        DataTable parts = new DataTable();
        using (OleDbConnection conn = new OleDbConnection(connString))
        {
            string sqlParts = "Select * from [" + nSheetName + "]";
            OleDbDataAdapter adapter = new OleDbDataAdapter(sqlParts, conn);
            adapter.Fill(parts);
        }

        for (nI = 0; nI < parts.Columns.Count; nI++)
        {
            DataColumn column = parts.Columns[nI];
            if (nI == 0) { nFieldName = column.ColumnName; }
            else { nFieldName = nFieldName + "," + column.ColumnName; }
        }
        parts.Dispose(); parts = null;

        oExcel = new Excel.Application();
        oBook = oExcel.Workbooks.Open(reportFilenPath, 0, false, 5, "", "", false, Excel.XlPlatform.xlWindows, "", true, false, 0, true, false, false);
        oSheet = (Microsoft.Office.Interop.Excel.Worksheet)oBook.Worksheets.get_Item(nSheetName.Replace("$", ""));
        oExcel.DisplayAlerts = false;
        oExcel.Visible = true;



        //Check the Field Is Avilable in the Sheet if not then Add
        if (nFieldName.Contains("Sub Device") == false)
        {
            nRng = oSheet.get_Range("A1", oMissing);
            nRng.EntireColumn.Insert(Microsoft.Office.Interop.Excel.XlInsertShiftDirection.xlShiftToRight, false);
            oSheet.Cells[1, 1] = "Sub Device";
        }
        if (nFieldName.Contains("Brand") == false)
        {
            nRng = oSheet.get_Range("A1", oMissing);
            nRng.EntireColumn.Insert(Microsoft.Office.Interop.Excel.XlInsertShiftDirection.xlShiftToRight, false);
            oSheet.Cells[1, 1] = "Brand";
        }
        if (nFieldName.Contains("Model") == false)
        {
            nRng = oSheet.get_Range("A1", oMissing);
            nRng.EntireColumn.Insert(Microsoft.Office.Interop.Excel.XlInsertShiftDirection.xlShiftToRight, false);
            oSheet.Cells[1, 1] = "Model";
        }
        if (nFieldName.Contains("Product Details") == false)
        {
            nRng = oSheet.get_Range("A1", oMissing);
            nRng.EntireColumn.Insert(Microsoft.Office.Interop.Excel.XlInsertShiftDirection.xlShiftToRight, false);
            oSheet.Cells[1, 1] = "Product Details";
        }
        if (nFieldName.Contains("Price") == false)
        {
            nRng = (Excel.Range)oSheet.Cells[1, 1];
            //nRng = oSheet.get_Range("A1", oMissing);
            nRng.EntireColumn.Insert(Microsoft.Office.Interop.Excel.XlInsertShiftDirection.xlShiftToRight, false);
            oSheet.Cells[1, 1] = "Price";
        }

        oBook.Save();
        oBook.Close(false, oMissing, oMissing);
        oExcel.DisplayAlerts = true;
        releaseObject(oSheet);
        releaseObject(oBook);
        oExcel.Quit();
        releaseObject(oExcel);
        releaseObject(nRng);
        nRng = null;
        oExcel = null;
        oSheet = null;


    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
        releaseObject(oSheet);
        releaseObject(oBook);
        //oExcel.Quit();
        releaseObject(oExcel);
    }
}

private void releaseObject(object obj)
{
    try
    {
        System.Runtime.InteropServices.Marshal.ReleaseComObject(obj); obj = null;
    }
    catch (Exception ex)
    {
        obj = null;
        MessageBox.Show("Exception Occured while releasing object " + ex.ToString());
    }
    finally
    {
        GC.Collect();
    }
}
4

4 回答 4

1

您需要释放您引用的所有Excel 对象。例如:

if (nFieldName.Contains("Sub Device") == false)
{
    nRng = oSheet.get_Range("A1", oMissing);
    nRng.EntireColumn.Insert(Microsoft.Office.Interop.Excel.XlInsertShiftDirection.xlShiftToRight, false);
    oSheet.Cells[1, 1] = "Sub Device";
}

应该是这样的(为了简单起见,省略了 try/finally)

if (nFieldName.Contains("Sub Device") == false)
{
    nRng = oSheet.get_Range("A1", oMissing);
    var col = nRng.EntireColumn
    col.Insert(Microsoft.Office.Interop.Excel.XlInsertShiftDirection.xlShiftToRight, false);
    var cells = oSheet.Cells;
    var firstCell = cells[1,1];
    firstCell.Value = "Sub Device";

    Marshal.ReleaseComObject(nRng);
    Marshal.ReleaseComObject(col);
    Marshal.ReleaseComObject(cells);
    Marshal.ReleaseComObject(firstCell);

}

相似地:

oBook = oExcel.Workbooks.Open(reportFilenPath, 0, false, 5, "", "", false, Excel.XlPlatform.xlWindows, "", true, false, 0, true, false, false);
oSheet = (Microsoft.Office.Interop.Excel.Worksheet)oBook.Worksheets.get_Item(nSheetName.Replace("$", ""));

需要是:

oBooks = oExcel.Workbooks
oBook = oBooks.Open(...);
oSheets = oBook.Worksheets
oSheet = oSHeets.get_Item(...);

你需要发布 oBooks 和 oSheets。

于 2012-10-09T13:48:54.193 回答
0

去掉这些行:

nRng = null;
oExcel = null;
oSheet = null;

我认为您正在释放您的 Excel 对象,然后通过使其等于 null 之后您正在使用 Excel 执行某些操作,这会在您的计算机上启动一个新实例。

释放对象后,您不需要将变量设置为 null 或 run GC.Collect();,垃圾收集器会为您处理这个问题,我认为在这种情况下尝试自己清理托管对象(在正确清理非托管 Excel 对象)实际上是导致您的问题的原因。

于 2012-10-09T09:27:30.840 回答
0

尝试使用以下命令结束您的 excel 任务:

        Marshal.FinalReleaseComObject(sheet);
        app.DisplayAlerts = false; //Very important!
        range = null;
        sheet = null;
        // Garbage collecting
        GC.Collect();
        GC.WaitForPendingFinalizers();
        book.Close(false, Missing.Value, Missing.Value);
        Marshal.FinalReleaseComObject(book);
        book = null;
        app.Quit();
        Marshal.FinalReleaseComObject(app);
        app = null;

我在访问我的 excel 文件时遇到了同样的问题,但是使用显示的代码它一直关闭。

当然,如果程序在到达代码之前崩溃,请使用调试器检查您的代码。

在您的情况下:书籍-> oBook,应用程序-> oExcel,工作表-> oSheet。

于 2012-10-09T09:20:39.513 回答
0

我在使用 Excel 互操作时遇到了同样的问题。问题应该是由这种线引起的(至少在我的情况下):

oBook = oExcel.Workbooks.Open(reportFilenPath, 0, false, 5, "", "", false, Excel.XlPlatform.xlWindows, "", true, false, 0, true, false, false); 

最后,您获得了 oBook,但这就是这里真正发生的事情:为了让 oBook 指向您打开的工作簿,您访问了一个 Workbooks 对象(使用oExcel.Workbooks)。这永远不会发布,并防止 Excel 退出。

我通过将该行重写为:

Microsoft.Interop.Excel.Workbooks oBooks = oExcel.Workbooks;
oBook = oBooks.Open(reportFilenPath, 0, false, 5, "", "", false, Excel.XlPlatform.xlWindows, "", true, false, 0, true, false, false); 
releaseObject(oBooks);

当然,对于这种类型的每一行(例如oBook.Worksheets.get_Item(...)nRng.EntireColumn.Insert(...)等)都必须这样做。

于 2012-10-09T13:32:35.693 回答