Files
Web_BLSKafka_Server_Prod/BLWLogServer/Controllers/UDPPackageController.cs
2025-11-21 08:48:01 +08:00

978 lines
37 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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<UDPPackage_db>("totalcount");
//构建查询条件
var filter = Builders<UDPPackage_db>.Filter.And(
Builders<UDPPackage_db>.Filter.Gt(x => x.RemoveTime, sst),
Builders<UDPPackage_db>.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<StepInfo_db>("zeroe_stepmonitor");
//构建查询条件
var filter = Builders<StepInfo_db>.Filter.And(
Builders<StepInfo_db>.Filter.Gt(x => x.TriggerTime, sst),
Builders<StepInfo_db>.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;
}
/// <summary>
/// 获取语音IOT平台的数据
/// </summary>
/// <param name="QueryData"></param>
/// <returns></returns>
[HttpPost()]
public ReturnInfo Get_IOTLog([FromBody] LogQuery q)
{
ReturnInfo info = new ReturnInfo();
info.isok = true;
try
{
List<IOTMonitorData_db> lg = new List<IOTMonitorData_db>();
string? st = q?.Start_Time;
string? et = q?.End_Time;
int PageSize = q.PageSize;
int PageIndex = q.PageIndex;
List<string> 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<IOTMonitorData_db> NNN = null;
var collection = _client.GetDatabase("udppackage").GetCollection<IOTMonitorData_db>("voiceiotlog");
var pipeline = collection.Aggregate();
NNN = pipeline.Match(s => s.CreateTime >= sst && s.CreateTime <= eet);
if (qqqq?.Count > 0)
{
var orConditions = new List<FilterDefinition<IOTMonitorData_db>>();
foreach (var item in qqqq)
{
if (!string.IsNullOrEmpty(item.HotelCode) && !string.IsNullOrEmpty(item.RoomNumber))
{
var andCondition = Builders<IOTMonitorData_db>.Filter.And(
Builders<IOTMonitorData_db>.Filter.Eq("HotelCode", item.HotelCode),
Builders<IOTMonitorData_db>.Filter.Eq("RoomNumber", item.RoomNumber)
);
orConditions.Add(andCondition);
}
else if (!string.IsNullOrEmpty(item.HotelCode) && string.IsNullOrEmpty(item.RoomNumber))
{
var andCondition = Builders<IOTMonitorData_db>.Filter.And(
Builders<IOTMonitorData_db>.Filter.Eq("HotelCode", item.HotelCode)
);
orConditions.Add(andCondition);
}
else
{
}
}
var orFilter = Builders<IOTMonitorData_db>.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<IOTMonitorData_db> lg = new List<IOTMonitorData_db>();
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<IOTMonitorData_db>("voiceiotlog");
//构建查询条件
if (q.IsQuery_Really)
{
IAggregateFluent<IOTMonitorData_db> 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<FilterDefinition<IOTMonitorData_db>>();
foreach (var item in qqqq)
{
if (!string.IsNullOrEmpty(item.HotelCode) && !string.IsNullOrEmpty(item.RoomNumber))
{
var andCondition = Builders<IOTMonitorData_db>.Filter.And(
Builders<IOTMonitorData_db>.Filter.Eq("HotelCode", item.HotelCode),
Builders<IOTMonitorData_db>.Filter.Eq("RoomNumber", item.RoomNumber)
);
orConditions.Add(andCondition);
}
else if (!string.IsNullOrEmpty(item.HotelCode) && string.IsNullOrEmpty(item.RoomNumber))
{
var andCondition = Builders<IOTMonitorData_db>.Filter.And(
Builders<IOTMonitorData_db>.Filter.Eq("HotelCode", item.HotelCode)
);
orConditions.Add(andCondition);
}
else
{
}
}
// 将 OR 条件添加到管道
var orFilter = Builders<IOTMonitorData_db>.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;
}
/// <summary>
///获取取电状态
/// </summary>
/// <param name="q"></param>
/// <returns></returns>
[HttpPost()]
public async Task<ReturnInfo> Get_TakeCardStatus([FromBody] LogQuery q)
{
ReturnInfo info = new ReturnInfo();
info.isok = true;
try
{
List<IOTMonitorData_db> lg = new List<IOTMonitorData_db>();
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<MTakeCardData_db>("takecardlog");
// 定义多个条件组合
// 动态条件列表
FilterDefinition<MTakeCardData_db> filter = Builders<MTakeCardData_db>.Filter.And(
Builders<MTakeCardData_db>.Filter.Gt(x => x.LastUpdateTime, sst1),
Builders<MTakeCardData_db>.Filter.Lt(x => x.LastUpdateTime, eet1)
);
var conditions = new List<FilterDefinition<MTakeCardData_db>>();
foreach (var item in qqqq)
{
if (!string.IsNullOrEmpty(item.HotelCode) && !string.IsNullOrEmpty(item.Key_HostNumber))
{
var q1 = Builders<MTakeCardData_db>.Filter.And(
Builders<MTakeCardData_db>.Filter.Eq("HotelCode", item.HotelCode),
Builders<MTakeCardData_db>.Filter.Eq("HostNUMBER", item.Key_HostNumber)
);
conditions.Add(q1);
}
else if (!string.IsNullOrEmpty(item.HotelCode))
{
var q1 = Builders<MTakeCardData_db>.Filter.And(
Builders<MTakeCardData_db>.Filter.Eq("HotelCode", item.HotelCode)
);
conditions.Add(q1);
}
else
{
}
}
// 组合所有 HotelCode 和 HostNUMBER 的条件为 OR
var combinedHotelHostFilter = conditions.Count > 0
? Builders<MTakeCardData_db>.Filter.Or(conditions)
: Builders<MTakeCardData_db>.Filter.Empty; // 如果没有条件,则不限制
// 最终条件:时间范围 AND (HotelCode + HostNUMBER 的 OR 组合)
var finalFilter = Builders<MTakeCardData_db>.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<ReturnInfo> 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<MTakeCardData_db>("takecardlog");
var collection2 = _client.GetDatabase("udppackage").GetCollection<OnOffLineData_db>("rcustatuslog");
FilterDefinition<MTakeCardData_db> filter1 = Builders<MTakeCardData_db>.Filter.And(
Builders<MTakeCardData_db>.Filter.Lt(x => x.LastUpdateTime, sst1),
Builders<MTakeCardData_db>.Filter.Eq(x => x.HotelCode, hotelcode),
Builders<MTakeCardData_db>.Filter.Eq(x => x.HostNUMBER, hostnumber)
);
var finalFilter1 = Builders<MTakeCardData_db>.Filter.And(filter1);
var dynamicResults1 = await collection1.Find(finalFilter1).SortByDescending(x => x.LastUpdateTime).Limit(1).FirstOrDefaultAsync();
FilterDefinition<OnOffLineData_db> filter2 = Builders<OnOffLineData_db>.Filter.And(
Builders<OnOffLineData_db>.Filter.Lt(x => x.CurrentTime, sst1),
Builders<OnOffLineData_db>.Filter.Eq(x => x.HotelCode, hotelcode),
Builders<OnOffLineData_db>.Filter.Eq(x => x.HostNumber, hostnumber)
);
var finalFilter2 = Builders<OnOffLineData_db>.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<QueryData> items, string hotelcode, string hostnumber)
{
List<bool> bools = new List<bool>();
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;
}
/// <summary>
/// RCU 连线,断线状态
/// </summary>
/// <param name="q"></param>
/// <returns></returns>
[HttpPost()]
public async Task<ReturnInfo> 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<OnOffLineData_db>("rcustatuslog");
FilterDefinition<OnOffLineData_db> filter = Builders<OnOffLineData_db>.Filter.And(
Builders<OnOffLineData_db>.Filter.Gt(x => x.CurrentTime, sst1),
Builders<OnOffLineData_db>.Filter.Lt(x => x.CurrentTime, eet1)
);
var conditions = new List<FilterDefinition<OnOffLineData_db>>();
conditions.Add(filter);
foreach (var item in qqq)
{
if (!string.IsNullOrEmpty(item.HotelCode) && string.IsNullOrEmpty(item.Key_HostNumber))
{
var q1 = Builders<OnOffLineData_db>.Filter.And(
Builders<OnOffLineData_db>.Filter.Eq("HotelCode", item.HotelCode)
);
conditions.Add(q1);
}
else if (!string.IsNullOrEmpty(item.HotelCode) && !string.IsNullOrEmpty(item.Key_HostNumber))
{
var q1 = Builders<OnOffLineData_db>.Filter.And(
Builders<OnOffLineData_db>.Filter.Eq("HotelCode", item.HotelCode),
Builders<OnOffLineData_db>.Filter.Eq("HostNumber", item.Key_HostNumber)
);
conditions.Add(q1);
}
else
{
}
}
// 组合所有条件为 AND 关系(时间范围 + 其他条件)
var finalFilter = Builders<OnOffLineData_db>.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/";
/// <summary>
/// 设置时间
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
[HttpPost()]
public async Task<ReturnInfo> 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;
}
/// <summary>
/// 间隔多久的数据会被丢弃
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
[HttpPost()]
public async Task<ReturnInfo> 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;
}
/// <summary>
/// UDP 几包数据丢一包
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
[HttpPost()]
public async Task<ReturnInfo> 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;
}
/// <summary>
/// 同时设置3个数据
/// </summary>
/// <param name="dataList"></param>
/// <returns></returns>
[HttpPost()]
public async Task<ReturnInfo> ConfigParameterSet(List<TTT> 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<UDPPackage_db>("totalcount");
// 构建查询条件
var filter = Builders<UDPPackage_db>.Filter.And(
Builders<UDPPackage_db>.Filter.Gt(x => x.RemoveTime, sst),
Builders<UDPPackage_db>.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<ExportDataRow> TransformDataForExport(List<UDPPackage_db> data)
{
// 提取所有唯一的commandType
var types = data.Select(item => item.CommandType).Distinct().ToList();
// 按分钟间隔分组
var groupedByTime = new Dictionary<string, ExportDataRow>();
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<ExportDataRow> 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<string, long> TypeValues { get; set; }
}
public class TTT
{
public string key { get; set; }
public int value { get; set; }
}
}