如何在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的核心代码
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
相关产品推荐
相关产品推荐

