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

ASP.NET Core Web API:EPPlus Excel上传之成功记录插入与失败信息展示

ASP.NET Core 6 Web API Excel导入校验与分批处理实现方案

1. 定义校验结果DTO

创建用于区分成功/失败记录的DTO,确保返回结果结构清晰:

// 存储单条校验失败的记录及错误原因
public class FailureItem<T>
{
    public T Record { get; set; }
    public List<string> ErrorMessages { get; set; } = new();
}

// 整体导入结果返回模型
public class ImportResult<T>
{
    public List<T> SuccessRecords { get; set; } = new();
    public List<FailureItem<T>> FailedRecords { get; set; } = new();
}

2. 抽离业务校验逻辑

单独编写校验方法,聚焦业务规则,避免与导入逻辑耦合:

private List<string> ValidateLeaveApplication(LeaveApplication leaveApp)
{
    var errors = new List<string>();

    // 必填字段校验
    if (string.IsNullOrWhiteSpace(leaveApp.EmployeeId))
    {
        errors.Add("员工ID不能为空");
    }
    // 日期合法性校验
    if (leaveApp.StartDate == DateTime.MinValue || leaveApp.EndDate == DateTime.MinValue)
    {
        errors.Add("日期格式无效,请输入正确的日期");
    }
    else if (leaveApp.StartDate >= leaveApp.EndDate)
    {
        errors.Add("开始日期必须早于结束日期");
    }
    // 枚举合法性校验
    if (!Enum.IsDefined(typeof(LeaveType), leaveApp.LeaveType))
    {
        errors.Add($"请假类型无效,可选值:{string.Join(", ", Enum.GetNames(typeof(LeaveType)))}");
    }
    // 可扩展其他业务规则,比如请假时长限制、员工状态校验等

    return errors;
}

3. 改造Excel导入方法

使用EPPlus读取Excel内容,逐条校验后拆分成功/失败记录,仅将通过校验的记录插入数据库:

[HttpPost("import-leaves")]
public async Task<IActionResult> ImportLeaveApplications(IFormFile file)
{
    if (file == null || file.Length == 0)
    {
        return BadRequest("请选择有效的Excel文件");
    }

    var importResult = new ImportResult<LeaveApplication>();

    using var package = new ExcelPackage(file.OpenReadStream());
    var worksheet = package.Workbook.Worksheets.First();
    var totalRows = worksheet.Dimension?.Rows ?? 0;

    // 从第2行开始读取(跳过表头行)
    for (int row = 2; row <= totalRows; row++)
    {
        // 映射Excel行数据到实体类
        var leaveApp = new LeaveApplication
        {
            EmployeeId = worksheet.Cells[row, 1].Text.Trim(),
            StartDate = DateTime.TryParse(worksheet.Cells[row, 2].Text, out var startDate) ? startDate : DateTime.MinValue,
            EndDate = DateTime.TryParse(worksheet.Cells[row, 3].Text, out var endDate) ? endDate : DateTime.MinValue,
            LeaveType = Enum.TryParse<LeaveType>(worksheet.Cells[row, 4].Text.Trim(), out var leaveType) ? leaveType : default,
            Reason = worksheet.Cells[row, 5].Text.Trim()
        };

        // 执行校验
        var validationErrors = ValidateLeaveApplication(leaveApp);
        if (!validationErrors.Any())
        {
            importResult.SuccessRecords.Add(leaveApp);
        }
        else
        {
            importResult.FailedRecords.Add(new FailureItem<LeaveApplication>
            {
                Record = leaveApp,
                ErrorMessages = validationErrors
            });
        }
    }

    // 批量插入校验通过的记录
    if (importResult.SuccessRecords.Any())
    {
        _dbContext.LeaveApplications.AddRange(importResult.SuccessRecords);
        await _dbContext.SaveChangesAsync();
    }

    // 返回结构化的导入结果
    return Ok(new
    {
        TotalSuccess = importResult.SuccessRecords.Count,
        TotalFailed = importResult.FailedRecords.Count,
        SuccessData = importResult.SuccessRecords,
        FailedData = importResult.FailedRecords.Select(item => new
        {
            item.Record,
            ErrorDetails = item.ErrorMessages
        })
    });
}

4. 额外配置说明

如果使用EPPlus 5及以上版本,需在Program.cs中配置许可上下文(非商用场景):

builder.Services.AddSingleton(new ExcelPackage.LicenseContext(LicenseContext.NonCommercial));

前端展示建议

前端接收到返回结果后,可分别渲染成功列表和失败列表:

  • 成功列表展示已插入数据库的请假申请信息
  • 失败列表展示每条记录的字段内容及对应的错误原因,方便用户修改后重新上传

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 20:20:48