using OfficeOpenXml; using OfficeOpenXml.Style; using System; using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Reflection; namespace Syc.Basic.Web.WMS { public static class ExcelExporter { /// /// EPPlus 8.0+ 导出 List 数据为 Excel 内存流(带样式美化) /// /// 数据模型类型 /// 要导出的数据集合 /// Excel 工作表名称 /// 自定义表头(key:模型属性名,value:Excel 表头文本) /// Excel 内存流(需手动释放) public static string ExportToExcelStream( List dataList, string sheetName = "数据报表", string filePath = null, Dictionary headerMap = null) { // 1. 配置 EPPlus 许可证(非商业用途,商业需购买许可证) //ExcelPackage.License = License.NonCommercial; // 2. 初始化 Excel 包和工作表 using var package = new ExcelPackage(); var worksheet = package.Workbook.Worksheets.Add(sheetName); // 3. 处理表头(支持自定义列名,无自定义则用模型属性名) PropertyInfo[] properties = typeof(T).GetProperties(); int colIndex = 1; // 写入表头 foreach (var prop in properties) { string headerText = headerMap?.ContainsKey(prop.Name) ?? false ? headerMap[prop.Name] : prop.Name; // 优先用自定义表头,否则用属性名 worksheet.Cells[1, colIndex].Value = headerText; colIndex++; } // 4. 写入数据(逐行逐列绑定) int rowIndex = 2; // 第1行是表头,从第2行开始写数据 foreach (var data in dataList) { colIndex = 1; foreach (var prop in properties) { var value = prop.GetValue(data); // 特殊类型处理(避免日期/布尔值格式异常) switch (value) { case DateTime date: worksheet.Cells[rowIndex, colIndex].Value = date.ToString("yyyy-MM-dd HH:mm:ss"); break; case bool b: worksheet.Cells[rowIndex, colIndex].Value = b ? "是" : "否"; break; case decimal d: worksheet.Cells[rowIndex, colIndex].Value = d; worksheet.Cells[rowIndex, colIndex].Style.Numberformat.Format = "0.00"; // 金额保留2位小数 break; default: worksheet.Cells[rowIndex, colIndex].Value = value ?? string.Empty; break; } colIndex++; } rowIndex++; } // 5. 样式美化(表头加粗+背景色、自动列宽) var headerRange = worksheet.Cells[1, 1, 1, properties.Length]; headerRange.Style.Font.Bold = true; // 表头加粗 headerRange.Style.Fill.PatternType = ExcelFillStyle.Solid; headerRange.Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.LightSkyBlue); // 表头背景色 worksheet.Cells[worksheet.Dimension.Address].AutoFitColumns(); // 自动调整所有列宽 // 6. 保存到内存流并返回 //var stream = new MemoryStream(); package.SaveAs(filePath); // stream.Position = 0; // 重置流指针(关键:否则下载的文件为空) return filePath; } } }