如何“清理”Microsoft.Office.Interop.Excel.Workbook

问题描述:

所以我有一个Microsoft.Office.Interop.Excel.Workbook对象。它基本上使用模板Excel文件来构建自己。 Excel文件包含结果部分的模板列颜色等,然后​​代码基本上只是打印在这些模板列上,它实际上并没有自定义文件本身的外观,只是将数据放入其中。如何“清理”Microsoft.Office.Interop.Excel.Workbook

但是,这是一个问题,因为完成后,我们的模板会占用最多的可用行数,但很多时间(大部分时间),我们甚至不使用其中的一半。

在创建文件后直接使用Microsoft.Office.Interop.Excel.Workbook对象,删除所有没有单元数据的行的最简单方法是什么?我们已经有了一个在创建后运行的“清理”方法,但是我想向其添加逻辑。这里是我们目前的清理:

private void CleanupExcel() 
     { 
      if (!_visible && _workbook != null) 
      { 
       _workbook.Close(false, Missing.Value, Missing.Value); 
      } 
      _workbook = null; 
      _sheet = null; 
      if (_excel != null) 
      { 
       System.Runtime.InteropServices.Marshal.ReleaseComObject(_excel); 
       // WW, 5/26/09: not sure if a problem here, but it probably is since the code was taken from here 
       // but in the indicator, Excel exists in the process even after the app is closed. The code here seems to fix it. 
       GC.Collect(); 
       GC.WaitForPendingFinalizers(); 
      } 
      _excel = null; 
     } 

P.S.这是该文档中两张表格中的第一张。如果这样做更容易,我也可以访问Microsoft.Office.Interop.Excel.Worksheet对象。

+1

不是针对您的实际问题,而是针对代码示例中的注释。你没有正确地清理东西,如果你这样做,你不需要`GC.Collect();`。您应该释放您在任何地方创建的所有对象(其中包括始终保留对创建的所有内容的引用)。看到这个问题的更多细节:http://*.com/questions/158706/how-to-properly-clean-up-excel-interop-objects-in-c – 2010-12-09 13:45:36

假设所有的空行是在表的底部,你应该能够选择他们作为一个范围,然后将它们全部删除,这样的事情,我认为:

Excel.Range range = _sheet.get_Range("A501", "A60000"); 
Excel.Range row = range.EntireRow; 
rowDelete(Type.Missing); 

如果他们”不要在底部,也许你可以做一个排序,以便他们都在底部,然后使用类似于我的代码。

+0

这是要删除只有行没有数据在他们中?因为所有的行都有颜色或标记,但没有数据。 – slandau 2010-12-09 14:03:46

+0

这会删除所有行,无论它看起来如何... – slandau 2010-12-09 14:07:40

请尝试以下操作。它基本上经历了一个范围(我已经硬编码为A1:A10),检查哪些行是空的,将它们标记为删除,然后扫描并删除它们。

 public void RemoveRows() 
     { 
      Excel.Range rng = Application.get_Range("A1", "A10"); 
      List<int> rowsMarkedForDeletion = new List<int>(); 

      for(int i = 0; i < rng.Rows.Count; i++) 
      { 
       if(Application.WorksheetFunction.CountA(rng[i + 1].EntireRow) == 0) 
       { 
        rowsMarkedForDeletion.Add(i + 1); 
       } 
      } 

      for(int i = rowsMarkedForDeletion.Count - 1; i >= 0; i--) 
      {     
       rng[rowsMarkedForDeletion[i]].EntireRow.Delete(); 
      } 
     } 

要充分的信用,使用COUNTA是一个技术,我从OzGrid教训。