【问题标题】:Efficiently generate a very large Excel file in .NET?在 .NET 中有效地生成一个非常大的 Excel 文件?
【发布时间】:2014-11-07 05:29:01
【问题描述】:

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

作为参考,我正在尝试生成一个包含大约 500,000 行、每行 20 列的电子表格。数据集本身可以很好地放入内存,但 Open XML SDK 很快就会耗尽我所有的可用内存。

【问题讨论】:

  • First hit on Google。您需要 SAX 策略。
  • 你为什么要把这么多数据放到 Excel 中,你真的要呈现这么多数据吗?可以切换到SqlExpress之类的数据库吗?
  • Frédéric - 我搜索了很长时间没有找到。我去看看,谢谢。
  • Scott - 用于出口目的。
  • @BrianVallelunga 导出到什么?导入数据的东西是否只接受 Excel 文件?它会接受 CSV 文件吗?它会接受 XML 吗?不要卡在choosing a shoe or glass bottle之间!

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


【解决方案1】:

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

我在生成 91 列 x 164,000 行的文件时遇到了内存问题。使用 OpenXmlWriter,我的 RAM 消耗从 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();
}

【讨论】:

    猜你喜欢
    • 2016-01-05
    • 2011-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多