using System; using CommonEntity; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using MongoDB.Driver; using MongoDB.Driver.Linq; using Newtonsoft.Json; using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; using RestSharp; namespace BLWLogServer.Controllers { [Route("api/[controller]/[action]")] [ApiController] public class UDPPackageController : ControllerBase { public IMongoClient _client; public UDPPackageController(IMongoClient mongo) { this._client = mongo; } [HttpPost()] public ReturnInfo GetUDPTotalAnalysis([FromBody] QueryDate query) { ReturnInfo r = new ReturnInfo(); try { int size = query.PageSize; int index = query.PageIndex; string st = query.Start_Time; string et = query.End_Time; DateTime sst = DateTime.Parse(st); DateTime eet = DateTime.Parse(et); var collection = _client.GetDatabase("udppackage").GetCollection("totalcount"); //构建查询条件 var filter = Builders.Filter.And( Builders.Filter.Gt(x => x.RemoveTime, sst), Builders.Filter.Lt(x => x.RemoveTime, eet) ); // 获取总记录数(可选,用于前端分页显示总页数) long totalCount = collection.CountDocuments(filter); // //执行查询 //var results = collection.Find(filter).Skip((index - 1) * size) // 跳过前面的记录 //.Limit(size).ToList(); // 限制返回的记录数.ToList(); var results = collection.Find(filter).ToList(); // 跳过前面的记录 r.isok = true; r.response = results; } catch (Exception ex) { r.isok = false; r.message = ex.Message; } return r; } [HttpPost()] public ReturnInfo GetUDPPackageTimeAnalysis([FromBody] QueryDate query) { ReturnInfo r = new ReturnInfo(); try { int size = query.PageSize; int index = query.PageIndex; string st = query.Start_Time; string et = query.End_Time; DateTime sst = DateTime.Parse(st); DateTime eet = DateTime.Parse(et); var collection = _client.GetDatabase("udppackage").GetCollection("zeroe_stepmonitor"); //构建查询条件 var filter = Builders.Filter.And( Builders.Filter.Gt(x => x.TriggerTime, sst), Builders.Filter.Lt(x => x.TriggerTime, eet) ); // 获取总记录数(可选,用于前端分页显示总页数) long totalCount = collection.CountDocuments(filter); // //执行查询 //var results = collection.Find(filter).Skip((index - 1) * size) // 跳过前面的记录 //.Limit(size).ToList(); // 限制返回的记录数.ToList(); // 使用聚合管道实现分组、排序和分页 //var aggregation = collection.Aggregate() // .Match(filter) // 先筛选时间范围内的文档 // .Group( // x => x.MessageId, // 按MessageId分组 // g => new // { // MessageId = g.Key, // 分组键 // Items = g.ToList() // 分组内的所有文档 // //Count = g.Count() // 每组的文档数 // }) // .Skip((index - 1) * size) // 分页跳过 // .Limit(size); // 分页限制 var results = collection.Find(filter).ToList().OrderByDescending(A => A.TriggerTime); // 跳过前面的记录 //var results = aggregation.ToList(); var USA = results.GroupBy(A => A.MessageId); r.isok = true; r.response = USA.ToList(); } catch (Exception ex) { r.isok = false; r.message = ex.Message; } return r; } /// /// 获取语音IOT平台的数据 /// /// /// [HttpPost()] public ReturnInfo Get_IOTLog([FromBody] LogQuery q) { ReturnInfo info = new ReturnInfo(); info.isok = true; try { List lg = new List(); string? st = q?.Start_Time; string? et = q?.End_Time; int PageSize = q.PageSize; int PageIndex = q.PageIndex; List c11 = q.CommandType; int AAA = (PageIndex - 1) * PageSize; DateTime sst = DateTime.Parse(st); DateTime eet = DateTime.Parse(et); string? st1 = q?.Start_Time_Really; string? et1 = q?.End_Time_Really; DateTime sst1 = DateTime.Parse(st1); DateTime eet1 = DateTime.Parse(et1); if (eet < sst) { info.isok = false; info.message = "结束时间不能大于开始时间"; return info; } var qqqq = q?.Data; IAggregateFluent NNN = null; var collection = _client.GetDatabase("udppackage").GetCollection("voiceiotlog"); var pipeline = collection.Aggregate(); NNN = pipeline.Match(s => s.CreateTime >= sst && s.CreateTime <= eet); if (qqqq?.Count > 0) { var orConditions = new List>(); foreach (var item in qqqq) { if (!string.IsNullOrEmpty(item.HotelCode) && !string.IsNullOrEmpty(item.RoomNumber)) { var andCondition = Builders.Filter.And( Builders.Filter.Eq("HotelCode", item.HotelCode), Builders.Filter.Eq("RoomNumber", item.RoomNumber) ); orConditions.Add(andCondition); } else if (!string.IsNullOrEmpty(item.HotelCode) && string.IsNullOrEmpty(item.RoomNumber)) { var andCondition = Builders.Filter.And( Builders.Filter.Eq("HotelCode", item.HotelCode) ); orConditions.Add(andCondition); } else { } } var orFilter = Builders.Filter.Or(orConditions); NNN = NNN.Match(orFilter); } var results = NNN.ToList().OrderByDescending(A => A.CreateTime); var Q = results.ToList(); DevMonitorIOTLogResult_WITH_Count c = new DevMonitorIOTLogResult_WITH_Count(); c.devMonitorLogResults = Q; c.TotalCount = Q.Count; info.response = c; } catch (Exception ex) { info.isok = false; info.message = ex.Message; } return info; } [HttpPost()] public ReturnInfo Get_IOTLogCount([FromBody] LogQuery q) { ReturnInfo info = new ReturnInfo(); info.isok = true; try { List lg = new List(); string? st1 = q?.Start_Time_Really; string? et1 = q?.End_Time_Really; DateTime sst1 = DateTime.Parse(st1); DateTime eet1 = DateTime.Parse(et1); if (eet1 < sst1) { info.isok = false; info.message = "结束时间不能大于开始时间"; return info; } var qqqq = q?.Data; //var h11 = qqqq?.Select(x => x.HotelCode).Distinct().Where(A => !string.IsNullOrEmpty(A)).ToList(); //var r11 = qqqq?.Select(x => x.RoomNumber).Distinct().Where(A => !string.IsNullOrEmpty(A)).ToList(); DevMonitorIOTLogResult_WITH_Count c = new DevMonitorIOTLogResult_WITH_Count(); var collection = _client.GetDatabase("udppackage").GetCollection("voiceiotlog"); //构建查询条件 if (q.IsQuery_Really) { IAggregateFluent NNN = null; var pipeline = collection.Aggregate(); NNN = pipeline.Match(s => s.CreateTime >= sst1 && s.CreateTime <= eet1); //if (h11.Count > 0 && r11.Count == 0) //{ // NNN = pipeline.Match(s => s.CreateTime >= sst1 && s.CreateTime <= eet1 && h11.Contains(s.HotelCode.ToString())); //} //if (h11.Count > 0 && r11.Count > 0) //{ // NNN = pipeline.Match(s => s.CreateTime >= sst1 && s.CreateTime <= eet1 && h11.Contains(s.HotelCode.ToString()) && r11.Contains(s.RoomNumber)); //} // 2. 动态生成 HotelCode 和 HostNUMBER 的 OR 条件 if (qqqq?.Count > 0) { var orConditions = new List>(); foreach (var item in qqqq) { if (!string.IsNullOrEmpty(item.HotelCode) && !string.IsNullOrEmpty(item.RoomNumber)) { var andCondition = Builders.Filter.And( Builders.Filter.Eq("HotelCode", item.HotelCode), Builders.Filter.Eq("RoomNumber", item.RoomNumber) ); orConditions.Add(andCondition); } else if (!string.IsNullOrEmpty(item.HotelCode) && string.IsNullOrEmpty(item.RoomNumber)) { var andCondition = Builders.Filter.And( Builders.Filter.Eq("HotelCode", item.HotelCode) ); orConditions.Add(andCondition); } else { } } // 将 OR 条件添加到管道 var orFilter = Builders.Filter.Or(orConditions); NNN = NNN.Match(orFilter); } var MMM = NNN.Group( s => s.RequestId, g => new { RequestId = g.Key, Count = g.Count(), ContainsFive = g.Any(x => x.Step == 5) } ) .SortByDescending(x => x.RequestId) .ToList(); var NotContainStep5 = MMM.Where(A => !A.ContainsFive).Count(); var C = MMM.Sum(A => A.Count); c.RequestIdCount = C; c.RequestNotContainerCount = NotContainStep5; } else { c.RequestIdCount = 0; } info.response = c; } catch (Exception ex) { info.isok = false; info.message = ex.Message; } return info; } /// ///获取取电状态 /// /// /// [HttpPost()] public async Task Get_TakeCardStatus([FromBody] LogQuery q) { ReturnInfo info = new ReturnInfo(); info.isok = true; try { List lg = new List(); string? st1 = q?.Start_Time; string? et1 = q?.End_Time; DateTime sst1 = DateTime.Parse(st1); DateTime eet1 = DateTime.Parse(et1); if (eet1 < sst1) { info.isok = false; info.message = "结束时间不能大于开始时间"; return info; } var qqqq = q?.Data; var collection = _client.GetDatabase("udppackage").GetCollection("takecardlog"); // 定义多个条件组合 // 动态条件列表 FilterDefinition filter = Builders.Filter.And( Builders.Filter.Gt(x => x.LastUpdateTime, sst1), Builders.Filter.Lt(x => x.LastUpdateTime, eet1) ); var conditions = new List>(); foreach (var item in qqqq) { if (!string.IsNullOrEmpty(item.HotelCode) && !string.IsNullOrEmpty(item.Key_HostNumber)) { var q1 = Builders.Filter.And( Builders.Filter.Eq("HotelCode", item.HotelCode), Builders.Filter.Eq("HostNUMBER", item.Key_HostNumber) ); conditions.Add(q1); } else if (!string.IsNullOrEmpty(item.HotelCode)) { var q1 = Builders.Filter.And( Builders.Filter.Eq("HotelCode", item.HotelCode) ); conditions.Add(q1); } else { } } // 组合所有 HotelCode 和 HostNUMBER 的条件为 OR var combinedHotelHostFilter = conditions.Count > 0 ? Builders.Filter.Or(conditions) : Builders.Filter.Empty; // 如果没有条件,则不限制 // 最终条件:时间范围 AND (HotelCode + HostNUMBER 的 OR 组合) var finalFilter = Builders.Filter.And( filter, combinedHotelHostFilter ); var dynamicResults = await collection.Find(finalFilter).ToListAsync(); info.response = dynamicResults; } catch (Exception ex) { info.isok = false; info.message = ex.Message; } return info; } [HttpPost()] public async Task Get_BeforeTakeCardStatus([FromBody] LogQuery q) { ReturnInfo info = new ReturnInfo(); info.isok = true; try { string? st1 = q?.Start_Time; string? et1 = q?.End_Time; DateTime sst1 = DateTime.Parse(st1); DateTime eet1 = DateTime.Parse(et1); if (eet1 < sst1) { info.isok = false; info.message = "结束时间不能大于开始时间"; return info; } var qqqq = q?.Data; if (qqqq.Count > 1) { info.isok = false; info.message = "只能查询单个房间"; return info; } string? hotelcode = qqqq.FirstOrDefault()?.HotelCode; string? hostnumber = qqqq.FirstOrDefault()?.Key_HostNumber; var collection1 = _client.GetDatabase("udppackage").GetCollection("takecardlog"); var collection2 = _client.GetDatabase("udppackage").GetCollection("rcustatuslog"); FilterDefinition filter1 = Builders.Filter.And( Builders.Filter.Lt(x => x.LastUpdateTime, sst1), Builders.Filter.Eq(x => x.HotelCode, hotelcode), Builders.Filter.Eq(x => x.HostNUMBER, hostnumber) ); var finalFilter1 = Builders.Filter.And(filter1); var dynamicResults1 = await collection1.Find(finalFilter1).SortByDescending(x => x.LastUpdateTime).Limit(1).FirstOrDefaultAsync(); FilterDefinition filter2 = Builders.Filter.And( Builders.Filter.Lt(x => x.CurrentTime, sst1), Builders.Filter.Eq(x => x.HotelCode, hotelcode), Builders.Filter.Eq(x => x.HostNumber, hostnumber) ); var finalFilter2 = Builders.Filter.And(filter2); var dynamicResults2 = await collection2.Find(finalFilter2).SortByDescending(A => A.CurrentTime).Limit(1).FirstOrDefaultAsync(); info.response = new { RCUStatus = dynamicResults2, TakeCardStatus = dynamicResults1 }; } catch (Exception ex) { info.isok = false; info.message = ex.Message; } return info; } private static bool CreatePredicate(List items, string hotelcode, string hostnumber) { List bools = new List(); foreach (var item in items) { bool KKK = item.HotelCode.Equals(hotelcode) && item.Key_HostNumber.Equals(hostnumber); bools.Add(KKK); } // 使用 Aggregate 将列表中的布尔值用 || 连接 bool result = bools.Aggregate((current, next) => current || next); return result; } /// /// RCU 连线,断线状态 /// /// /// [HttpPost()] public async Task Get_RCUStatus([FromBody] LogQuery q) { ReturnInfo info = new ReturnInfo(); info.isok = true; try { string? st1 = q?.Start_Time; string? et1 = q?.End_Time; DateTime sst1 = DateTime.Parse(st1); DateTime eet1 = DateTime.Parse(et1); if (eet1 < sst1) { info.isok = false; info.message = "结束时间不能大于开始时间"; return info; } var qqq = q?.Data; var collection = _client.GetDatabase("udppackage").GetCollection("rcustatuslog"); FilterDefinition filter = Builders.Filter.And( Builders.Filter.Gt(x => x.CurrentTime, sst1), Builders.Filter.Lt(x => x.CurrentTime, eet1) ); var conditions = new List>(); conditions.Add(filter); foreach (var item in qqq) { if (!string.IsNullOrEmpty(item.HotelCode) && string.IsNullOrEmpty(item.Key_HostNumber)) { var q1 = Builders.Filter.And( Builders.Filter.Eq("HotelCode", item.HotelCode) ); conditions.Add(q1); } else if (!string.IsNullOrEmpty(item.HotelCode) && !string.IsNullOrEmpty(item.Key_HostNumber)) { var q1 = Builders.Filter.And( Builders.Filter.Eq("HotelCode", item.HotelCode), Builders.Filter.Eq("HostNumber", item.Key_HostNumber) ); conditions.Add(q1); } else { } } // 组合所有条件为 AND 关系(时间范围 + 其他条件) var finalFilter = Builders.Filter.And(conditions); // 执行查询 var dynamicResults = await collection.Find(finalFilter).ToListAsync(); info.response = dynamicResults; } catch (Exception ex) { info.isok = false; info.message = ex.Message; } return info; } public static string BaseUrl = "https://www.boonlive-rcu.com/"; /// /// 设置时间 /// /// /// [HttpPost()] public async Task TongJiTimerIntervalSet(TimerData data) { ReturnInfo r = new ReturnInfo(); try { var options = new RestClientOptions(BaseUrl); var client = new RestClient(options); var request = new RestRequest("api/TongJiTimerIntervalSet"); request.AddParameter("interval_Minutes", data.interval_Minutes); RestResponse response = await client.PostAsync(request); string? str1 = response.Content; r.isok = true; r.response = str1; } catch (Exception ex) { r.isok = false; r.response = ex.Message; } return r; } /// /// 间隔多久的数据会被丢弃 /// /// /// [HttpPost()] public async Task UDPLostDataIntervalSet(TimerData data) { ReturnInfo r = new ReturnInfo(); try { var options = new RestClientOptions(BaseUrl); var client = new RestClient(options); var request = new RestRequest("api/DefineUDPLostDataInterval"); request.AddParameter("Interval", data.interval_Minutes); RestResponse response = await client.PostAsync(request); string? str1 = response.Content; r.isok = true; r.response = str1; } catch (Exception ex) { r.isok = false; r.response = ex.Message; } return r; } /// /// UDP 几包数据丢一包 /// /// /// [HttpPost()] public async Task UDPLostDataRateSet(TimerData data) { ReturnInfo r = new ReturnInfo(); try { var options = new RestClientOptions(BaseUrl); var client = new RestClient(options); var request = new RestRequest("api/DefineUDPLostDataRate"); request.AddParameter("LostHz", data.interval_Minutes); RestResponse response = await client.PostAsync(request); string? str1 = response.Content; r.isok = true; r.response = str1; } catch (Exception ex) { r.isok = false; r.response = ex.Message; } return r; } /// /// 同时设置3个数据 /// /// /// [HttpPost()] public async Task ConfigParameterSet(List dataList) { ReturnInfo r = new ReturnInfo(); try { var options = new RestClientOptions(BaseUrl); var client = new RestClient(options); foreach (var item in dataList) { string Key = item.key; int V = item.value; if (Key.Equals("超时08")) { var request = new RestRequest("api/DefineUDPLostDataInterval"); request.AddParameter("Interval", V); RestResponse response = await client.PostAsync(request); } if (Key.Equals("丢弃比例")) { var request = new RestRequest("api/DefineUDPLostDataRate"); request.AddParameter("LostHz", V); RestResponse response = await client.PostAsync(request); } if (Key.Equals("统计周期")) { var request = new RestRequest("api/TongJiTimerIntervalSet"); request.AddParameter("interval_Minutes", V); RestResponse response = await client.PostAsync(request); } } r.isok = true; r.response = "success"; } catch (Exception ex) { r.isok = false; r.response = ex.Message; } return r; } [HttpPost()] [HttpPost()] public IActionResult ExportUDPTotalAnalysis([FromBody] QueryDate query) { string tempFilePath = null; try { string st = query.Start_Time; string et = query.End_Time; DateTime sst = DateTime.Parse(st); DateTime eet = DateTime.Parse(et); var collection = _client.GetDatabase("udppackage").GetCollection("totalcount"); // 构建查询条件 var filter = Builders.Filter.And( Builders.Filter.Gt(x => x.RemoveTime, sst), Builders.Filter.Lt(x => x.RemoveTime, eet) ); // 获取所有记录 var allResults = collection.Find(filter).ToList(); if (allResults == null || allResults.Count == 0) { return NotFound("没有找到数据"); } // 转换数据为二维表格格式 var transformedData = TransformDataForExport(allResults); // 创建临时文件 tempFilePath = Path.GetTempFileName() + ".xlsx"; // 生成Excel文件到临时文件 using (var fileStream = new FileStream(tempFilePath, FileMode.Create, FileAccess.Write)) { var workbook = CreateExcelWorkbook(transformedData); workbook.Write(fileStream); } // 读取临时文件内容到内存流 var fileBytes = System.IO.File.ReadAllBytes(tempFilePath); var memoryStream = new MemoryStream(fileBytes); // 返回Excel文件 return File(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", $"UDP数据统计_{DateTime.Now:yyyyMMdd_HHmmss}.xlsx"); } catch (Exception ex) { return StatusCode(500, $"导出失败: {ex.Message}"); } finally { // 清理临时文件 if (tempFilePath != null && System.IO.File.Exists(tempFilePath)) { try { System.IO.File.Delete(tempFilePath); } catch { // 忽略删除失败的情况 } } } } // 数据转换方法(类似前端的transformData逻辑) private List TransformDataForExport(List data) { // 提取所有唯一的commandType var types = data.Select(item => item.CommandType).Distinct().ToList(); // 按分钟间隔分组 var groupedByTime = new Dictionary(); foreach (var item in data) { // 获取时间对象 var time = item.RemoveTime; // 精确到分钟的时间格式 var repTime = time.ToString("yyyy-MM-dd HH:mm"); if (!groupedByTime.ContainsKey(repTime)) { groupedByTime[repTime] = new ExportDataRow { RemoveTime = repTime, // 初始化所有类型为0L (使用long类型) TypeValues = types.ToDictionary(type => type, _ => 0L) }; } // 累加对应类型的值 - 使用long类型 if (groupedByTime[repTime].TypeValues.ContainsKey(item.CommandType)) { groupedByTime[repTime].TypeValues[item.CommandType] += item.TotalCount; } } // 排序时间(从最新到最早) return groupedByTime.Values .OrderByDescending(row => DateTime.Parse(row.RemoveTime)) .ToList(); } // 创建Excel工作簿 // 创建Excel工作簿 - 美化版本 private IWorkbook CreateExcelWorkbook(List data) { var workbook = new XSSFWorkbook(); // 创建单元格样式 var headerStyle = CreateHeaderStyle(workbook); var evenRowStyle = CreateCellStyle(workbook, IndexedColors.LightCornflowerBlue.Index); var oddRowStyle = CreateCellStyle(workbook, IndexedColors.White.Index); var dateStyle = CreateCellStyle(workbook, IndexedColors.White.Index, true); var sheet = workbook.CreateSheet("UDP数据统计"); // 获取所有唯一的命令类型 var allTypes = data.SelectMany(row => row.TypeValues.Keys).Distinct().ToList(); // 创建表头 var headerRow = sheet.CreateRow(0); headerRow.HeightInPoints = 20; // 设置行高 // 时间段列 var timeCell = headerRow.CreateCell(0); timeCell.SetCellValue("时间段"); timeCell.CellStyle = headerStyle; // 命令类型列 for (int i = 0; i < allTypes.Count; i++) { var cell = headerRow.CreateCell(i + 1); cell.SetCellValue(GetShortTypeName(allTypes[i])); cell.CellStyle = headerStyle; } // 填充数据 for (int i = 0; i < data.Count; i++) { var dataRow = sheet.CreateRow(i + 1); dataRow.HeightInPoints = 18; // 设置数据行高度 // 时间段单元格 var timeDataCell = dataRow.CreateCell(0); timeDataCell.SetCellValue(data[i].RemoveTime); timeDataCell.CellStyle = dateStyle; // 交替行颜色 - 斑马纹效果 var rowStyle = (i % 2 == 0) ? evenRowStyle : oddRowStyle; for (int j = 0; j < allTypes.Count; j++) { var type = allTypes[j]; var value = data[i].TypeValues.ContainsKey(type) ? data[i].TypeValues[type] : 0L; var dataCell = dataRow.CreateCell(j + 1); dataCell.SetCellValue(value); dataCell.CellStyle = rowStyle; } } // 设置列宽 - 更精确的自适应 sheet.SetColumnWidth(0, 20 * 256); // 时间段列固定宽度 for (int i = 0; i < allTypes.Count; i++) { // 根据列名长度设置宽度 var colName = GetShortTypeName(allTypes[i]); int width = Math.Max(10, Math.Min(25, colName.Length + 2)) * 256; sheet.SetColumnWidth(i + 1, width); } // 冻结表头行 sheet.CreateFreezePane(0, 1, 0, 1); return workbook; } // 创建表头样式 private ICellStyle CreateHeaderStyle(IWorkbook workbook) { var style = workbook.CreateCellStyle(); // 设置背景色 style.FillForegroundColor = IndexedColors.DarkBlue.Index; style.FillPattern = FillPattern.SolidForeground; // 设置字体 var font = workbook.CreateFont(); font.FontName = "Arial"; font.FontHeightInPoints = 11; font.Boldweight = (short)FontBoldWeight.Bold; font.Color = IndexedColors.White.Index; style.SetFont(font); // 设置边框 style.BorderBottom = BorderStyle.Medium; style.BorderLeft = BorderStyle.Medium; style.BorderRight = BorderStyle.Medium; style.BorderTop = BorderStyle.Medium; style.BottomBorderColor = IndexedColors.Black.Index; style.LeftBorderColor = IndexedColors.Black.Index; style.RightBorderColor = IndexedColors.Black.Index; style.TopBorderColor = IndexedColors.Black.Index; // 设置对齐方式 style.Alignment = HorizontalAlignment.Center; style.VerticalAlignment = VerticalAlignment.Center; return style; } // 创建单元格样式 private ICellStyle CreateCellStyle(IWorkbook workbook, short backgroundColor, bool isDateCell = false) { var style = workbook.CreateCellStyle(); // 设置背景色 style.FillForegroundColor = backgroundColor; style.FillPattern = FillPattern.SolidForeground; // 设置字体 var font = workbook.CreateFont(); font.FontName = "Arial"; font.FontHeightInPoints = 10; style.SetFont(font); // 设置边框 style.BorderBottom = BorderStyle.Thin; style.BorderLeft = BorderStyle.Thin; style.BorderRight = BorderStyle.Thin; style.BorderTop = BorderStyle.Thin; style.BottomBorderColor = IndexedColors.Grey40Percent.Index; style.LeftBorderColor = IndexedColors.Grey40Percent.Index; style.RightBorderColor = IndexedColors.Grey40Percent.Index; style.TopBorderColor = IndexedColors.Grey40Percent.Index; // 设置对齐方式 if (isDateCell) { style.Alignment = HorizontalAlignment.Left; } else { style.Alignment = HorizontalAlignment.Center; } style.VerticalAlignment = VerticalAlignment.Center; // 设置数据格式 if (!isDateCell) { var format = workbook.CreateDataFormat(); style.DataFormat = format.GetFormat("0"); // 数字格式,不显示小数 } return style; } // 获取简化的类型名称(类似前端的getShortType方法) private string GetShortTypeName(string type) { // 这里实现您的类型名称简化逻辑 // 例如,可以基于您的keyValueMap进行映射 if (type.Contains('_')) { return type.Split('_').Last(); } return type; } } // 导出数据行类 public class ExportDataRow { public string RemoveTime { get; set; } public Dictionary TypeValues { get; set; } } public class TTT { public string key { get; set; } public int value { get; set; } } }