'OutOfMemoryException while saving/creating/exporting excel sheet

Develop environment :

  • OS - Windows 7 64bit
  • CPU - i5 460M
  • RAM - 8GB
  • .NET framework - 4.0
  • Excel-Interop - Microsoft Excel 14.0 Object Library

I'm using Excel-Interop to export excel file from DataGridView (dgv).

When I save more than about 150,000 rows

OutOfMemoryException

is thrown.

{
    object[,] valueObjArray = new object[rowCnt, colCnt];
    int rowCnt = dgv.Rows.Count;
    int colCnt = dgv.Columns.Count;

    for (int rowIndex = 0; rowIndex < rowCnt; rowIndex++)
    {
        for (int colIndex = 0; colIndex < colCnt; colIndex++)
        {
            valueObjArray[rowIndex, colIndex] = dgv[colIndex, rowIndex].Value;
        }
    }

    _workSheet.get_Range("A1", Convert.ToChar(colCnt + 64).ToString() + "1").Value2 = headerObjArray;                
    _workSheet.get_Range("A2", Convert.ToChar(colCnt + 64).ToString() + (rowCnt + 1).ToString()).Value2 = valueObjArray;
    _workSheet.get_Range("B2", "B" + (rowCnt+1).ToString()).NumberFormat = "yyyy-mm-dd hh:mm";

    _workBook.SaveAs(path);
}

This is best way to speed up that I known.

But, After monitoring RAM I think it causes memory increase. Exception is thrown when memory usage reached about 900Mb.

How do I catch this Exception?



Solution 1:[1]

Try to do it in batches:

//We will call SaveAs method many times and we don't want to be asked
//if a file should be overwritten every time.
xlApp.DisplayAlerts = false

int rowCnt = dgv.Rows.Count;
int colCnt = dgv.Columns.Count;

int batchSize = 100000; //Try to experiment with other values
int currentRow = 0;

object[,] valueObjArray = new object[batchSize, colCnt];

_workSheet.get_Range("A1", Convert.ToChar(colCnt + 64).ToString() + "1").Value2 = headerObjArray;     

while (currentRow < rowCnt)
{
    for (int rowIndex = 0; rowIndex < batchSize && currentRow + rowIndex < rowCnt; rowIndex++)
    {
        for (int colIndex = 0; colIndex < colCnt; colIndex++)
        {
            valueObjArray[rowIndex, colIndex] =             
            dgv[colIndex, currentRow + rowIndex].Value;
        }
    }

    ws.get_Range("A2", Convert.ToChar(colCnt + 64).ToString() + (currentRow + batchSize + 1).ToString()).Value2 = valueObjArray;
    ws.get_Range("B2", "B" + (currentRow + batchSize + 1).ToString()).NumberFormat = "yyyy-mm-dd hh:mm";

    wb.SaveAs("a.xlsx");

    currentRow += batchSize;
}

I was able to save 1 million rows in this way. I tested it with fake data so some minor changes / fixes might be requried.

Solution 2:[2]

Try do this....

I have large amount of data 2 lakhs and above. First i am using excel package and Microsoft.Office.Interop.Excel Local system is working fine , but iis(static ip address) hosting after (worksheet.cells/worksheet.range) OutOfMemoryeException error thorw. So i am using StreamWriter and write to .xls file. After .xls convert to .xlsx file and delete .xls file. Its working for me. My english is not good . please understand it.

  private void ExportxlFile(DataTable dt)
    {
        try
        {
            //open file
            //non english not support(ex: Bangla Language)"?????????? ?????";
            // StreamWriter wr = new StreamWriter(@"D:\TestBook.xls");

            //non english support(ex: Bangla Language)
            StreamWriter wr = new StreamWriter(@"D:\TestBook.xls", true, Encoding.Unicode); // Encoding.Unicode or Encoding.UTF32

            for (int i = 0; i < dt.Columns.Count; i++)
            {
                wr.Write(dt.Columns[i].ToString().ToUpper() + "\t");
            }

            wr.WriteLine();

            //write rows to excel file
            for (int i = 0; i < (dt.Rows.Count); i++)
            {
                for (int j = 0; j < dt.Columns.Count; j++)
                {
                    if (dt.Rows[i][j] != null)
                    {
                        wr.Write(Convert.ToString(dt.Rows[i][j]) + "\t");
                    }
                    else
                    {
                        wr.Write("\t");
                    }
                }
                //go to next line
                wr.WriteLine();
            }
            //close file
            wr.Close();

            //xls to xlsx convertion
            Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application();
            Microsoft.Office.Interop.Excel.Workbook wb = app.Workbooks.Open(@"D:\TestBook.xls", Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
            wb.SaveAs(@"D:\TestBook.xlsx", Microsoft.Office.Interop.Excel.XlFileFormat.xlOpenXMLWorkbook, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
            wb.Close();
            app.Quit();

            //delete xls file
            System.IO.File.Delete(@"D:\TestBook.xls");
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 MahalingaM SubramaniyaM