简体   繁体   English

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

[英]Efficiently generate a very large Excel file in .NET?

I need to generate a very large Excel file from an ASP.NET MVC site, but am running into memory limitations using the Open XML SDK.我需要从 ASP.NET MVC 站点生成一个非常大的 Excel 文件,但使用 Open XML SDK 遇到内存限制。 Is there a memory efficient way to generate such a file?有没有一种内存有效的方法来生成这样的文件?

For reference, I'm trying to generate a spreadsheet with about 500,000 rows with 20 columns each.作为参考,我正在尝试生成一个包含大约 500,000 行、每行 20 列的电子表格。 The data set itself fits into memory just fine, but the Open XML SDK quickly eats up all of my available memory.数据集本身很适合内存,但是 Open XML SDK 很快就耗尽了我所有的可用内存。

You can use Open XML SDK in reasonably efficiently way, the trick is to use the OpenXmlWriter class (in this CodeProject article you have more details)您可以以合理有效的方式使用 Open XML SDK,诀窍是使用OpenXmlWriter类(在这篇 CodeProject 文章中您有更多详细信息)

I had a memory issue generating a file of 91 columns x 164,000 rows.我在生成一个 91 列 x 164,000 行的文件时遇到了内存问题。 Using OpenXmlWriter I went from 2GB of RAM consumption to 120MB, enough for me :-)使用 OpenXmlWriter,我的 RAM 消耗从 2GB 增加到 120MB,对我来说足够了:-)

Seeing it with a code example:看一个代码示例:

Standard (and unoptimized) way:标准(和未优化)方式:

// 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 way: 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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM