在.NET中有效地生成一个非常大的Excel文件?

时间:2014-09-12 23:34:44

标签: c# asp.net excel out-of-memory

我需要从ASP.NET MVC站点生成一个非常大的Excel文件,但是使用Open XML SDK会遇到内存限制。是否有一种内存有效的方法来生成这样的文件?

作为参考,我试图生成一个包含大约500,000行的电子表格,每行20列。数据集本身很适合内存,但Open XML SDK会快速占用我所有的可用内存。

1 个答案:

答案 0 :(得分:1)

您可以以相当有效的方式使用Open XML SDK,诀窍是使用OpenXmlWriter类(在this CodeProject article中,您有更多详细信息)

我遇到了一个内存问题,生成了91列x 164,000行的文件。使用OpenXmlWriter,我从2GB的内存消耗增加到120MB,对我来说足够了:-)

通过代码示例查看它:

标准(且未优化)方式:

// Table header
Row headerRow = new Row();
foreach (string fieldName in fields)
{
    Cell cell = new Cell();
    cell.DataType = CellValues.String;
    cell.CellValue = new CellValue(fieldName);
    headerRow.AppendChild(cell);
}
sheetData.AppendChild(headerRow);

// Table rows
while (dataReader.Read())
{
    Row dataRow = new Row();

    foreach (string fieldName in fields)
    {
        Cell cell = new Cell();
        cell.DataType = CellValues.String;
        cell.CellValue = new CellValue(reader[fieldName].ToString());
        dataRow.AppendChild(cell);
    }

    sheetData.AppendChild(dataRow);
}

OpenXmlWriter方式:

using (var writer = OpenXmlWriter.Create(worksheetPart))
{
    writer.WriteStartElement(new Worksheet());
    writer.WriteStartElement(new SheetData());

    // Table header
    writer.WriteStartElement(new Row());
    foreach (string fieldName in fields)
    {
        writer.WriteStartElement(new Cell() { DataType = CellValues.String });
        writer.WriteElement(new CellValue(fieldName));
        writer.WriteEndElement();        
    }
    writer.WriteEndElement(); //end of Row tag

    // Table rows
    while (dataReader.Read())
    {
        writer.WriteStartElement(new Row());

        foreach (string fieldName in fields)
        {
            writer.WriteStartElement(new Cell() { DataType = CellValues.String });
            writer.WriteElement(new CellValue(dataReader[fieldName].ToString()));
            writer.WriteEndElement();        
        }

        writer.WriteEndElement(); //end of Row tag
    }

    writer.WriteEndElement(); //end of SheetData
    writer.WriteEndElement(); //end of worksheet
    writer.Close();
}