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

5
我需要从ASP.NET MVC网站生成一个非常大的Excel文件,但是使用Open XML SDK时遇到了内存限制。是否有一种内存高效的方法来生成这样的文件?
参考资料,我正在尝试生成一个带有约500,000行,每行有20列的电子表格。数据集本身可以很好地适应内存,但Open XML SDK会快速消耗所有可用内存。

1
你需要使用SAX策略。这是来自谷歌搜索的第一个结果:http://blogs.msdn.com/b/brian_jones/archive/2010/06/22/writing-large-excel-files-with-the-open-xml-sdk.aspx。 - Frédéric Hamidi
你为什么把那么多数据放进Excel里?你真的需要展示那么多数据吗?你可以考虑切换到像SqlExpress这样的数据库吗? - Scott Chamberlain
Frédéric - 我找了很久也没找到。我会去查一下,谢谢。 - Brian Vallelunga
Scott - 这是为了出口的目的。 - Brian Vallelunga
3
你需要将数据导出到哪里?导入数据的目标是否只接受Excel文件?它能接受CSV文件吗?还是XML?不要陷入“选择鞋子或玻璃瓶”的困境。 - Scott Chamberlain
显示剩余3条评论
1个回答

3

您可以以相对高效的方式使用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();
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接