You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#从Excel构建900个实体对象耗时过长,求优化方案

问题:批量创建900个entityDataObject耗时4分钟,求更快实现方式?

我需要创建约900个entityDataObject对象,但通过遍历Excel单元格逐个赋值的方式构建集合耗时约4分钟,请问有没有更快的实现方式?

实体类定义

public class entityDataObject
{
    public string var1{ get; set; }
    public string var2 { get; set; }
    public string var3 { get; set; }
    public string var4 { get; set; }
    public string var5 { get; set; }
    public string var6{ get; set; }
    public string var7{ get; set; }
    public string var8{ get; set; }
    public string var9{ get; set; }
    public string var10{ get; set; }
    public string var11{ get; set; }
    public string var12{ get; set; }
}

当前实现代码

for (int i = firstRow + 1; i <= lastRow; i++)
{
    entityDataObject newObject = (new entityDataObject()
    {
        var1= currentws.Cells[i, Column1].Value.ToString(),
        var2= currentws.Cells[i, Column2].Value.ToString(),
        var3= currentws.Cells[i, Column3].Value.ToString(),
        var4= currentws.Cells[i, Column4].Value.ToString(),
        var5= currentws.Cells[i, Column5].Value.ToString(),
        var6= currentws.Cells[i, Column6].Value.ToString(),
        var7= currentws.Cells[i, Column7].Value.ToString(),
        var8= currentws.Cells[i, Column8].Value.ToString(),
        var9= currentws.Cells[i, Column9].Value.ToString(),
        var10= currentws.Cells[i, Column10].Value.ToString(),
        var11= currentws.Cells[i, Column11].Value.ToString(),
        var12= currentws.Cells[i, Column12].Value.ToString(),
    });

    entityCollection.Add(newObject);
};

return entityCollection;

优化方案

1. 一次性读取整个数据区域到内存

当前代码每次访问currentws.Cells[i, ColumnX].Value都会和Excel进程交互,这是性能瓶颈的核心。建议直接读取整个目标数据区域到内存数组,后续从数组取值:

// 读取目标范围的所有数据到二维数组(假设Column1到Column12是连续列)
var dataRange = currentws.Cells[firstRow + 1, Column1, lastRow, Column12];
var dataArray = dataRange.Value as object[,];

// 预分配集合容量,避免多次扩容开销
var entityCollection = new List<entityDataObject>(lastRow - firstRow);

for (int i = 0; i < dataArray.GetLength(0); i++)
{
    var newObject = new entityDataObject
    {
        var1 = dataArray[i+1, 1]?.ToString() ?? string.Empty,
        var2 = dataArray[i+1, 2]?.ToString() ?? string.Empty,
        var3 = dataArray[i+1, 3]?.ToString() ?? string.Empty,
        var4 = dataArray[i+1, 4]?.ToString() ?? string.Empty,
        var5 = dataArray[i+1, 5]?.ToString() ?? string.Empty,
        var6 = dataArray[i+1, 6]?.ToString() ?? string.Empty,
        var7 = dataArray[i+1, 7]?.ToString() ?? string.Empty,
        var8 = dataArray[i+1, 8]?.ToString() ?? string.Empty,
        var9 = dataArray[i+1, 9]?.ToString() ?? string.Empty,
        var10 = dataArray[i+1, 10]?.ToString() ?? string.Empty,
        var11 = dataArray[i+1, 11]?.ToString() ?? string.Empty,
        var12 = dataArray[i+1, 12]?.ToString() ?? string.Empty,
    };
    entityCollection.Add(newObject);
}

注:不同Excel库的数组索引规则可能有差异(部分库从0开始),需根据实际使用的库调整索引。

2. 预分配集合容量

如果entityCollection是List<T>类型,默认初始容量很小,每次添加元素都会触发数组扩容(重新分配内存+复制元素)。提前用new List<entityDataObject>(预计元素数量)初始化,能完全避免这个额外开销。

3. 安全处理空值ToString()

原代码直接调用Value.ToString(),若单元格为空会抛出空引用异常,同时隐性的异常检查也会影响性能。用?.ToString() ?? string.Empty处理空值,既保证代码安全,又能减少不必要的性能损耗。

4. 利用映射库简化代码(可选)

如果实体类和Excel列的对应关系固定,可以用EPPlus、NPOI配合AutoMapper这类映射库,或者直接使用EPPlus的LoadFromCollection反向读取映射功能,这类库内部做了大量性能优化,同时能减少手动赋值的冗余代码。

5. 关闭Excel库的不必要特性

若使用EPPlus等库,确保关闭公式自动计算、格式校验等非必要特性,只读取原始单元格值,能进一步提升读取速度。

内容的提问来源于stack exchange,提问作者ThibaultKm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 17:27:30