【问题标题】:Reading half million records from Excel workbook in a VSTO project在 VSTO 项目中从 Excel 工作簿中读取 50 万条记录
【发布时间】:2012-04-30 23:41:55
【问题描述】:

我正在尝试使用 VSTO 并通过创建 Visual Studio 2010 Office 工作簿项目在 Excel 中构建模拟工具。此工作簿中的一个工作表将包含大约 50 万条记录。理想情况下,我想阅读在模拟中使用它们的所有记录,然后输出一些统计数据。到目前为止,当我尝试获取整个范围然后将单元格一次性从中取出时,我遇到了OutOfMemory 异常。有没有人对我如何阅读所有数据或建议有其他想法?

这是我的代码:

Excel.Range range = Globals.shData.Range["A2:AX500000"];

Array values = (Array)range.Cells.Value;

【问题讨论】:

标签: c# excel vsto


【解决方案1】:

如何批量获取,并在内存中组装一个内存稍少的模型?

var firstRow = 2;
var lastRow = 500000;
var batchSize = 5000;
var batches = Enumerable
    .Range(0, (int)Math.Ceiling( (lastRow-firstRow) / (double)batchSize ))
    .Select(x => 
        string.Format(
            "A{0}:AX{1}",
            x * batchSize + firstRow,
            Math.Min((x+1) * batchSize + firstRow - 1, lastRow)))
    .Select(range => ((Array)Globals.shData.Range[range]).Cells.Value);

foreach(var batch in batches)
{
    foreach(var item in batch)
    {
        //reencode item into your own object collection.
    }
}

【讨论】:

  • 这是个好主意。我正在考虑使用 ADO.Net 来做到这一点。
【解决方案2】:

这不是 Excel 问题,而是一般 C# 问题。无需收集内存中的所有行,而是生成行并迭代计算统计信息。

例如

class Program
{
    static void Main(string[] args)
    {
        var totalOfAllAges = 0D;
        var rows = new ExcelRows();

        //calculate various statistics
        foreach (var item in rows.GetRow())
        {
            totalOfAllAges += item.Age;
        }

        Console.WriteLine("The total of all ages is {0}", totalOfAllAges);
    }
}

internal class ExcelRows
{
    private double rowCount = 1500000D;
    private double rowIndex = 0D;

    public IEnumerable<ExcelRow> GetRow()
    {
        while (rowIndex < rowCount)
        {
            rowIndex++;
            yield return new ExcelRow() { Age = rowIndex };
        }
    }
}
/// <summary>
/// represents the next read gathered by VSTO
/// </summary>

internal class ExcelRow
{
    public double Age { get; set; }
}

【讨论】:

  • 我实际上正在考虑将数据存储在 csv 中并使用 ADO 加载它,这样我就可以使用游标并一次运行一个块的模拟。
  • 这与光标具有相同的净效果,并且避免了对另一个文件的所有额外工作。
猜你喜欢
  • 1970-01-01
  • 2016-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多