导出到 Excel 内存不足 异常,并在数据网格视图计数大于 64000 时创建新工作表

本文关键字:创建 64000 大于 新工作 工作 视图 内存不足 异常 Excel 网格 数据网 | 更新日期: 2023-09-27 18:37:24

我正在使用以下代码导出到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");
}

导出到 Excel 内存不足 异常,并在数据网格视图计数大于 64000 时创建新工作表

如果要解决的问题很简单,我不是 Linq 杂耍的忠实粉丝。我已经消除了执行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 的更多特征。