使用C#格式化Excel文件

Bellowfunction用于合成excel文件,但运行该function后应用程序Excel不是从Try …(不能杀死应用程序)closures请帮助我

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(); } } 

您需要释放您所引用的所有 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"; } 

应该是类似的(为了简单起见,不要尝试/最后)

 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。

尝试使用以下命令结束您的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文件,但与显示的代码,它closures了所有的时间。

当然,如果程序在到达代码之前崩溃了,那么就用debugging器检查你的代码。

在你的情况:书 – > OBook,应用程序 – > OExcel,表 – > OSheet。

拿走这些线:

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

我想你正在释放你的Excel对象,然后等于null之后,你正在做一些Excel的事情,在你的机器上启动一个新的实例。

释放对象后,不需要将variables设置为null,或者运行GC.Collect(); ,垃圾收集器将为您处理这个问题,我想在这个例子中试图自己清理pipe理对象(在正确地清理了非托pipe的Excel对象之后)实际上正在导致您的问题。

我有同样的问题与Excel互操作。 这个问题应该是由这种线(至less是在我的情况):

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

最后,您将重新创buildoBook,但是这是在这里发生的事情:为了使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); 

当然,这必须为这种types的每一行(例如oBook.Worksheets.get_Item(...)nRng.EntireColumn.Insert(...)等)进行。