【问题标题】:OutOfMemoryException while trying to read big Excel file into DataTable尝试将大 Excel 文件读入 DataTable 时出现 OutOfMemoryException
【发布时间】:2019-02-15 16:45:22
【问题描述】:

我正在使用 SSIS 包清理 .Xlsx 文件中的数据并将其加载到 SQL Server 表中。 我还必须突出显示 .Xlsx 文件中包含错误数据的单元格,为此我必须根据列名和行 ID(我的数据电子表格中有女巫)获取列和行索引。为此,我将我的第一个电子表格 (Error_Sheet) 中的每个列名与我在第二个电子表格中添加的列的行进行比较,并对行执行相同的操作,如果我有相同的单元格值,我将返回该列并我的数据电子表格的行索引,并根据该列和行索引突出显示单元格。该脚本运行良好,但在尝试从服务器运行它后,我遇到了内存异常,并且在我之前运行良好的工作站上也出现了异常。

我试图将我从 AC1:AC10000 获取数据的范围缩小到 AC1:AC100,它仅在第一次编译后才起作用,但它仍然再次抛出异常。

string strSQLErrorColumns = "Select * From [" + Error_Sheet + "AC1:AC100]";
OleDbConnection cn = new OleDbConnection(strCn);

OleDbDataAdapter objAdapterErrorColumns = new OleDbDataAdapter(strSQLErrorColumns, cn);
System.Data.DataSet dsErrorColumns = new DataSet();
objAdapterErrorColumns.Fill(dsErrorColumns, Error_Sheet);
System.Data.DataTable dtErrorColumns = dsErrorColumns.Tables[Error_Sheet];
dsErrorColumns.Dispose();
objAdapterErrorColumns.Dispose();

foreach (DataColumn ColumnData in dtDataColumns.Columns){
    ColumnDataCellsValue = dtDataColumns.Columns[iCntD].ColumnName.ToString();
    iCntE = 0;

    foreach (DataRow ColumnError in dtErrorColumns.Rows){
        ColumnErrorCellsValue = dtErrorColumns.Rows[iCntE].ItemArray[0].ToString();

        if (ColumnDataCellsValue.Equals(ColumnErrorCellsValue)){

            ColumnIndex = ColumnData.Table.Columns[ColumnDataCellsValue].Ordinal;
            iCntE = iCntE + 1;
            break;
            }
        }

        iCntD = iCntD + 1;
    }

ColumnIndexHCell = ColumnIndex + 1;          
RowIndexHCell = RowIndex + 2;

Range rng = xlSheets.Cells[RowIndexHCell, ColumnIndexHCell] as Excel.Range;
rng.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Yellow);

还有其他方法可以在 DataTable 中加载数据以获取列和行索引,而无需使用大量内存或使用Excel.Range.Cell 而不是数据集和 DataTable 从 xlsx 文件中获取单元格值、列和行索引吗?

我没有展示整个代码,因为它很长。如果需要更多信息,请随时通知我。

【问题讨论】:

  • 我很困惑,如果您不使用 SSIS 读取数据,为什么这会被标记为 SSIS? SSIS Excel 连接管理器将处理行的缓存和缓冲,因此不需要 C#。
  • @M.ECH 问题解决了吗??
  • @JWeezy,如前所述,我正在使用 SSIS 清理 .Xlsx 文件中的数据并将其加载到 SQL Server 表中,然后使用脚本任务突出显示包含不匹配数据的单元格。
  • @Yahfoufi,是的,但我没有按照@Hadi 的建议使用Paging,因为我没有足够的时间来应用它,所以我使用了Excel.Range 来处理它。谢谢关心。

标签: c# excel ssis etl script-task


【解决方案1】:

当尝试从具有大量行的 Excel 中读取数据时,最好按块读取数据(在 OleDbDataAdapter 中,您可以使用分页选项来实现)

int result = 1;
int intPagingIndex = 0;
int intPagingInterval = 1000;

while (result > 0){

    result = daGetDataFromSheet.Fill(dsErrorColumns,intPagingIndex, intPagingInterval , Error_Sheet);
    System.Data.DataTable dtErrorColumns = dsErrorColumns.Tables[Error_Sheet];

    //Implement your logic here

    intPagingIndex += intPagingInterval ;

}

这将防止 OutOfMemory 异常。并且不再需要指定AC1:AC10000 之类的范围

参考文献

【讨论】:

  • 抱歉,今天之前无法回答。我实际上使用了Interop 而不是Paging 应用它花了我更少的时间。但是一旦我下次有更多的可用性,我会使用它并特别了解它。再次感谢您一如既往的宝贵帮助。
猜你喜欢
  • 2020-02-20
  • 2017-01-28
  • 2012-11-22
  • 2021-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多