MiniExcel:如何结合自定义模板使用动态列?
在ASP.NET Zero中用MiniExcel实现动态列+自定义表头的解决方案
方案一:分两次写入(自定义表头 + 动态数据)
这是最直接的方案,利用MiniExcel支持追加写入的特性,先写入自定义表头信息,再追加动态列数据,既保留动态列的配置,又能灵活添加任意自定义表头内容。
代码示例
using (var stream = new MemoryStream()) { // 1. 准备自定义表头内容(可根据需求调整行数和字段) var headerContent = new[] { new { 报表名称 = "用户行为统计报表", 生成日期 = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") }, new { 筛选条件 = $"用户等级:{selectedLevel} | 统计周期:{startDate:yyyy-MM-dd} 至 {endDate:yyyy-MM-dd}" }, new { } // 空行分隔表头和数据区域 }; // 写入自定义表头 await stream.SaveAsAsync(headerContent); // 2. 写入动态列数据(你的现有动态数据,比如IEnumerable<Dictionary<string, object>>) var dynamicTableData = GetUserDynamicTableData(); // 替换成你的动态数据获取方法 await stream.SaveAsAsync(dynamicTableData, append: true); // 返回给前端下载(ASP.NET Zero中AppService可通过FileResult返回) return File(stream.ToArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", $"报表_{DateTime.Now:yyyyMMdd}.xlsx"); }
关键说明
- 必须设置
append: true,否则第二次写入会覆盖表头内容 - 自定义表头可以根据需求自由调整行数、字段名,甚至可以添加多行描述信息
- 动态数据的列顺序和字段名完全沿用你之前构建的
Dictionary配置,不会丢失
方案二:动态构建模板字符串(适合需要模板复用的场景)
如果需要基于模板生成,又要保留动态列,可以通过动态拼接模板内容的方式,把动态列名嵌入模板中,再结合MiniExcel的模板渲染能力生成Excel。
代码示例
// 1. 获取动态列的字段名列表(假设你的动态数据非空) var dynamicData = GetUserDynamicTableData(); var columnNames = dynamicData.First().Keys.ToList(); // 2. 动态构建模板字符串 var templateBuilder = new StringBuilder(); // 自定义表头部分 templateBuilder.AppendLine("报表名称: {{ReportTitle}}"); templateBuilder.AppendLine("生成时间: {{GenerateTime}}"); templateBuilder.AppendLine("筛选条件: {{FilterInfo}}"); templateBuilder.AppendLine(); // 空行分隔 // 动态列的表头行 templateBuilder.AppendLine(string.Join("\t", columnNames)); // 动态数据行的循环模板 templateBuilder.AppendLine("{{Each item in Data}}"); templateBuilder.AppendLine(string.Join("\t", columnNames.Select(col => $"{{item.{col}}}"))); templateBuilder.AppendLine("{{EndEach}}"); // 3. 准备模板渲染所需的参数 var templateParams = new { ReportTitle = "用户行为统计报表", GenerateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), FilterInfo = $"用户等级:{selectedLevel} | 统计周期:{startDate:yyyy-MM-dd} 至 {endDate:yyyy-MM-dd}", Data = dynamicData }; // 4. 生成Excel using (var stream = new MemoryStream()) { await stream.SaveAsAsync(templateParams, template: templateBuilder.ToString()); return File(stream.ToArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", $"报表_{DateTime.Now:yyyyMMdd}.xlsx"); }
关键说明
- 确保
dynamicData不为空,否则无法获取列名列表(可提前判断,为空时返回空报表提示) - 模板中的
\t是单元格分隔符,MiniExcel会自动识别为不同单元格 - 这种方式既保留了模板的灵活性,又能适配动态变化的列配置
内容的提问来源于stack exchange,提问作者TB124
相关产品推荐
相关产品推荐

