导出excel内存不足异常并在datagridview计数大于64000时创建新工作表

时间:2016-03-05 05:10:50

标签: c# winforms out-of-memory export-to-excel

我使用以下代码导出到Excel。我有超过100,000条记录,因此我在每条64000条记录后创建新的工作表。但我的代码总是只返回64000条记录。并且给了我内存异常。怎么过来这个。

int rowcount = 0;
int sheetcount = 1;
int temprowcount = 0;
using (XLWorkbook wb = new XLWorkbook())
{

    foreach (DataRow row in dt.Rows)
    {
        rowcount++;
        if (rowcount == 64000)
        {
            DataTable tempdt = new DataTable();
            if (sheetcount == 1)
            {
                tempdt = dt.Rows.Cast<System.Data.DataRow>().Take(rowcount).CopyToDataTable();
            }
            if (sheetcount > 1)
            {
                temprowcount = temprowcount + rowcount;
                tempdt = dt.Rows.Cast<System.Data.DataRow>().Skip(temprowcount).Take(rowcount).CopyToDataTable();
            }
            wb.Worksheets.Add(tempdt, comboBox1.SelectedItem.ToString() + sheetcount.ToString());
            rowcount = 0;
            sheetcount++;
        }
    }
    wb.SaveAs(folderpath + "\\" + comboBox1.SelectedItem.ToString() + "_" + mydatetime.ToString("ddMMyyhhmmss") + ".xlsx");
}

1 个答案:

答案 0 :(得分:0)

如果要解决的问题是直截了当的话,我不是林奇杂耍所有人的忠实粉丝。我已经删除了执行TakeSkip的需要,并且只创建了一个数据表来保存工作簿中保存的64,000行。

您只获得了前64,000行,因为您忘记了在主循环结束时DataTable只能填充一半但尚未写入工作簿的事实。

int sheetcount = 1;
using (XLWorkbook wb = new XLWorkbook())
{
    // copy over the Columns as XmlSchema
    var ms = new MemoryStream();
    dt.WriteXmlSchema(ms);

    // read back the schema it the target 
    ms.Position = 0;
    DataTable tempdt = new DataTable();
    tempdt.ReadXmlSchema(ms);

    foreach (DataRow row in dt.Rows)
    {    
        tempdt.ImportRow(row);
        if (tempdt.Rows.Count == 64000)
        {
            wb.Worksheets.Add(tempdt, String.Format("{0}{1}", comboBox1.SelectedItem,  sheetcount));
            sheetcount++;    
            tempdt.Clear(); // reset to zero rows
        }
    }
    // copy final/left over rows of the DataTable
    if (tempdt.Rows.Count > 0) 
    {
        wb.Worksheets.Add(tempdt, String.Format("{0}{1}", comboBox1.SelectedItem,  sheetcount));
        sheetcount++;    
    }
    tempdt.Dispose(); 
    wb.SaveAs(String.Format("{0}\\{1}_{2:ddMMyyhhmmss}.xslx",folderpath, comboBox1.SelectedItem, mydatetime));
}

我确实尝试了很多列的大型集合,但无法重现内存不足异常。如果您仍然使用此代码遇到并且分享DataTable的更多特性,则需要提供精确的堆栈跟踪。