Excel性能问题和问题发布Excel

时间:2015-02-25 14:26:54

标签: c# excel

  1. 我正在使用Microsoft.Office.Interop.Excel(Visual Studio 2012)来填充我的电子表格,这很慢(插入3000行x 25列2分钟)。
  2. 发布Excel的问题...尽管发布了对象,我仍然在我的进程列表中看到Excel,有时多次。 (仅供参考:多个用户将同时创建电子表格,因此我无法终止所有Excel流程)
  3. 我正在加载的电子表格有多个带计算的标签...这会减慢我的流程吗?在更新之前,我正在设置Excel.XlCalculation.xlCalculationManual
  4. 以下是我的示例代码:

    Application AppExcel = null;
    Workbook ExcelBook = null;
    Worksheet ExcelSheet = null;
    
    try
    {
        string ExcelPath = @"c:\temp\test.xlsx";
    
        //-------------------------------------
        // create excel object
        //-------------------------------------
        AppExcel = new Microsoft.Office.Interop.Excel.Application();
        AppExcel.Visible = false;
        AppExcel.DisplayAlerts = false;
        AppExcel.ScreenUpdating = false;
    
        //-------------------------------------
        // open Excel Workbook
        //-------------------------------------
        ExcelBook = AppExcel.Application.Workbooks.Open(ExcelPath);
        ExcelBook.Activate();
        int WorksheetToUpdate = 1;
    
    
        AppExcel.Calculation = Microsoft.Office.Interop.Excel.XlCalculation.xlCalculationManual;
    
        ExcelSheet = ExcelBook.Worksheets[WorksheetToUpdate];
    
        // test data
        for (int ExcelRow = 2; ExcelRow <= 3000; ExcelRow++)
        {                 
            ExcelSheet.Cells[ExcelRow, 1] = "Client #1"
            ...
            ExcelSheet.Cells[ExcelRow, 25] = "10020";
    
        }
    
        AppExcel.Calculation = Microsoft.Office.Interop.Excel.XlCalculation.xlCalculationAutomatic; 
    
    
        //-------------------------------------
        // save WorkBook
        //-------------------------------------                
        ExcelBook.Save();
    
        //-------------------------------------
        // release worksheet
        //------------------------------------- 
        Marshal.ReleaseComObject(ExcelSheet);
    
        //-------------------------------------
        // close WorkBook
        //-------------------------------------    
        ExcelBook.Close(true);
        Marshal.ReleaseComObject(ExcelBook);
    
        //-------------------------------------
        // quit Excel
        //-------------------------------------                
        AppExcel.Quit();
    }
    catch(Exception ex)
    {}
    finally
    {
        Marshal.ReleaseComObject(AppExcel);
        GC.Collect();
        GC.WaitForPendingFinalizers();
    
        AppExcel = null;
        ExcelBook = null;
        ExcelSheet = null;
    }
    

2 个答案:

答案 0 :(得分:3)

代码中的性能问题与您从CLR调用Excel的调用次数有关;这些调用中的每一个都是跨越COM边界的行程,并且非常昂贵。

而不是这样做:

// test data
for (int ExcelRow = 2; ExcelRow <= 3000; ExcelRow++)
{                 
    ExcelSheet.Cells[ExcelRow, 1] = "Client #1"
    ...
    ExcelSheet.Cells[ExcelRow, 25] = "10020";

}

在工作表中创建范围,将数据集构建到数组中然后将该数组传递到范围会更有效。例如:

 Excel.Range r = ExcelSheet.Range["B2", "B4"];
 object[,] workingValues = new object[3, 1];
 for (int i = 0; i < 3; i++)
 {
      workingValues[i, 0] = i + 2;  // 2,3,4 
 }

 r.Value2 = workingValues;

您需要更改范围以匹配您正在使用的范围以及填充数据的循环,但希望您明白这一点。

答案 1 :(得分:1)

我会创建一个释放办公室对象的方法,例如下面的办公室对象。然后为您创建的每个office对象调用它。另外,在分配工作簿对象时,无需再次调用应用程序对象

ExcelBook = AppExcel.Application.Workbooks.Open(ExcelPath);

应该是

ExcelBook = AppExcel.Workbooks.Open(ExcelPath);

发布办公室对象

ReleaseOfficeObject(ExcelSheet);
ReleaseOfficeObject(ExcelBook);
ReleaseOfficeObject(AppExcel);


    private void ReleaseOfficeObject(object o)
    {
        Marshal.ReleaseComObject(o);
        GC.Collect();
        GC.WaitForPendingFinalizers();
        Marshal.FinalReleaseComObject(o);
        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();
    }