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

如何在EPPlus 6中按Vendor ID分组读取Excel数据(Blazor Server场景)

Blazor Server中使用EPPlus 6按Vendor ID分组读取Excel数据

已在Blazor Server应用中实现EPPlus 6上传Excel并保存数据到数据库的功能,现需按Vendor ID对Excel数据分组读取:同一Vendor ID下的所有商品数据对应创建一个订单(例如Vendor ID=1的4条商品数据生成1个订单)。

Excel数据示例

Excel示例截图

当前读取Excel的核心代码

var untrustedFileName = file.FileName;
var customerId = 0;

var trustedFileNameForDisplay = WebUtility.HtmlEncode(untrustedFileName);

try
{
    var trustedFileNameForFileStorage = Path.GetRandomFileName();
    var path = Path.Combine(env.ContentRootPath, env.EnvironmentName, "unsafe_uploads", trustedFileNameForFileStorage);

    await using FileStream fs = new(path, FileMode.Create);
    await file.CopyToAsync(fs);

    logger.LogInformation("{FileName} saved at {Path}", trustedFileNameForDisplay, path);
    
    var newfile = new FileInfo(file.FileName);
    var fileExtension = newfile.Extension;

    // 校验是否为Excel文件
    if (fileExtension.Contains(".xls"))
    {
        using var ms = new MemoryStream();
        await file.OpenReadStream().CopyToAsync(ms);

        // 非商用场景设置LicenseContext
        ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
        using ExcelPackage package = new ExcelPackage(ms);
        var workSheet = package.Workbook.Worksheets["Order"];
        var totalRows = workSheet.Dimension.Rows;

        var orderList = new List<Order>();
        List<OrderDetail> orderDetailList = null;

        var k = 0;

        for (var i = 2; i <= totalRows; i++)
        {
            // 原有读取逻辑...
        }

按Vendor ID分组的实现方案

替换原有for循环部分,改为先读取所有行数据到临时集合,再按Vendor ID分组处理:

// 先定义临时类存储Excel行数据(根据实际列调整属性)
public class ExcelOrderRow
{
    public int VendorId { get; set; }
    public string ProductName { get; set; }
    public int Quantity { get; set; }
    // 其他需要的字段...
}

// 替换原有for循环的代码:
var excelRows = new List<ExcelOrderRow>();

// 读取所有行数据到临时集合
for (var i = 2; i <= totalRows; i++)
{
    excelRows.Add(new ExcelOrderRow
    {
        VendorId = int.Parse(workSheet.Cells[i, 1].Value?.ToString() ?? "0"), // 对应Vendor ID列的位置
        ProductName = workSheet.Cells[i, 2].Value?.ToString(), // 对应商品名列
        Quantity = int.Parse(workSheet.Cells[i, 3].Value?.ToString() ?? "0"), // 对应数量列
        // 读取其他字段...
    });
}

// 按Vendor ID分组
var groupedByVendor = excelRows.GroupBy(r => r.VendorId);

// 遍历分组创建订单和订单详情
foreach (var vendorGroup in groupedByVendor)
{
    // 创建新订单
    var newOrder = new Order
    {
        VendorId = vendorGroup.Key,
        CustomerId = customerId,
        OrderDate = DateTime.Now,
        // 设置订单其他属性...
    };
    orderList.Add(newOrder);

    // 创建该订单下的所有商品详情
    var orderDetails = vendorGroup.Select(row => new OrderDetail
    {
        OrderId = newOrder.Id, // 假设订单Id已生成(若用EF可先Add再获取Id)
        ProductName = row.ProductName,
        Quantity = row.Quantity,
        // 设置订单详情其他属性...
    }).ToList();

    // 将订单详情加入集合(后续批量保存到数据库)
    // orderDetailList.AddRange(orderDetails);
}

// 后续执行保存订单和订单详情到数据库的逻辑...

注意事项

  • 需根据Excel实际列的位置调整workSheet.Cells[i, 列索引]的索引值
  • 若使用Entity Framework Core,建议先添加订单到DbContext,再获取自动生成的OrderId赋值给订单详情,最后批量SaveChanges
  • 可根据需求添加字段校验逻辑(如空值、格式转换异常处理)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 12:53:18