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

时间:2010-12-09 13:37:07

标签: c# .net excel

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

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

在创建文件后直接使用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对象。

2 个答案:

答案 0 :(得分:0)

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

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

如果它们不在底部,也许你可以进行排序,以便它们最终都在底部,然后使用与我的代码类似的东西。

答案 1 :(得分:0)

尝试以下方法。它基本上经过一个范围(我已经硬编码为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学到的一种技巧。