解析Excel碰到的OOM问题

        C#中使用NPOI解析xls,xlsx文件,对于小的文件没什么问题,但是文件一旦超过30M,经常出现OutOfMemory问题,尤其是连续导入多个大的excel文件,后面导的频繁出现OOM问题,于是手动调试看看哪一步使用导致内存大量被占用,仔细观察内存的变化,发现在创建WorkBook的时候,内存使用迅速上升,本来20多M的Excel,创建workbook内存消耗1.8G左右,在读取完成之后,内存并没有立即释放出来,而是等了大概1分多钟的样子,内存才渐渐释放出来,这样如果多次导入excel,后面导入的很可能就会出现OOM了,这可能是NPOI的问题吧。

        目前在网上看到MiniExcel,看起来很不错,不用把整个excel加载到内存,能有效避免OOM的问题,学习地址:MiniExcel学习文档

1、安装MiniExcel

在NuGet中搜索miniexcel,直接安装依赖包即可

2、获取excel中所有的sheet名字

var sheetNames = MiniExcel.GetSheetNames(path);

3、获取某个sheet中所有的行数据

var rows = MiniExcel.Query(path, true, sheetName);

4、获取某个sheet中的所有列名

var columns = MiniExcel.GetColumns(path, true, sheetName);

5、遍历所有数据

foreach (var row in _rows)
{
  DataRow dataRow = dataTable.NewRow();
  dataRow["A"] = row.A;
  dataRow["B"] = row.B;
  dataRow["C"] = row.C;
  dataRow["D"] = row.D;
  dataRow["E"] = row.E;
  dataRow["F"] = DBNull.Value;
  dataRow["G"] = row.G;
  dataRow["H"] = row.H;
  dataTable.Rows.Add(dataRow);
}

6、WinForm中实现数据解析进度条计算逻辑

先计算有多少个sheet,按100分成对应的等份,记为A,然后计算每个sheet的记录总数,假如按照100000条记录来分页,计算能分成多少页,再按照每个sheet所占的等份A,继续分成每页需要的等份,记为B,然后解析完一页数据,就将进度增加B,然后更新进度条控件的值就好了。

注意:在线程中更新进度条的操作是不允许的,可以通过控件的Invoke方法实现更新。

private void RefreshPercent(int percent)
{
    this.progressBar1.Invoke(new Action(() =>
    {
        this.progressBar1.Value = percent;
        this.labelper.Text = percent + "%";
        if (percent == 100) 
            this.dataImportBtn.Enabled = true;
    }));
}

这里数据批量保存采用存储过程的方式,代码端需要传递DataTable类型的参数,数据库端需要定义字段名称和个数一致的用户自定义表类型,用于接收参数,然后在存储过程写保存数据逻辑。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值