网站备案 需要上传网站么,赣州信息港主页,wordpress php.ini路径,临沂网站制作页面使用 Microsoft.Office.Interop.Excel 虽然有速度慢的缺点#xff1b;但是作为自带引用#xff0c;兼容性最好#xff0c;而且是COM对象模型也很熟悉(Excel里直接录个宏#xff0c;很方便把VBA代码转成VB.NET)。所以处理几百上千条的小数据时还是很方便的。
而 Microsoft.…使用 Microsoft.Office.Interop.Excel 虽然有速度慢的缺点但是作为自带引用兼容性最好而且是COM对象模型也很熟悉(Excel里直接录个宏很方便把VBA代码转成VB.NET)。所以处理几百上千条的小数据时还是很方便的。
而 Microsoft.Office.Interop.Excel 用得不多的最大问题其实就是拿简单例子可以正确释放Excel做了大量操作后却发现在任务管理器中依然有多余Excel进程存在。
问题原因当然是COM对象映射到Interop交互对象之后.NET下的交互对象释放次序不符合COM对象预期导致不能正确释放。比如
Dim xlApp New Excel.Application() With {.Visible False}
Dim xlWorkbooks As Excel.Workbooks xlApp.Workbooks
Dim xlWorkbook As Excel.Workbook xlWorkbooks.Open(...)Dim value As Object xlWorkbook.Sheets(1).Cells(1,1).ValuexlWorkbook.Close()
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlWorkbook)
xlWorkbook Nothing
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlWorkbooks)
xlWorkbooks Nothing
xlApp.Quit()
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp)
xlApp Nothing
System.GC.Collect()中间取value这行代码看起来很正常没有保留任何交互对象。其实在整个对象访问路径上隐式使用了以下交互对象要靠GC来释放(通常是延后的————即调用Close()时交互对象未释放、工作簿关闭不了之后的Quit()Excel不会退出)
xlWorkbook.Sheets Excel.Sheets
xlWorkbook.Sheets(1) Excel.Worksheet
xlWorkbook.Sheets(1).Cells Excel.Range
xlWorkbook.Sheets(1).Cells(1,1) Excel.Range要做到正确释放要把这些交互对象全部在Close()前释放。为了方便使用把 Excel.Application 和 Excel.Workbook 封装在类中用 IDisposable 接口确保释放。用类似下面的属性封装访问 Public Property CellValue(sheetIndex As Object, rowNo As Integer, colNo As Integer) As ObjectGetDim xlSheets As Excel.Sheets m_xlWorkbook.SheetsDim xlSheet As Excel.Worksheet xlSheets.Item(sheetIndex)Dim xlCells As Excel.Range xlSheet.CellsDim xlCell As Excel.Range xlCells.Item(rowNo, colNo)Dim value As Object xlCell.ValueSystem.Runtime.InteropServices.Marshal.ReleaseComObject(xlCell)System.Runtime.InteropServices.Marshal.ReleaseComObject(xlCells)System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet)System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheets)System.GC.Collect(0)Return valueEnd GetSet(value As Object) 同理所有交互对象保留变量、释放End SetEnd Property上面的属性是通过行号、列号访问单元value如果需要通过A1格式访问单元又要定义属性如果需要访问单元text也要单独定义属性。 总之全部封装好后读写完Excel文件后就能正确释放不再有多余Excel进程残留。