diff --git a/.gitignore b/.gitignore index b9197f4b..036a2b58 100644 --- a/.gitignore +++ b/.gitignore @@ -272,3 +272,4 @@ src/Shentun.Peis.Blazor.Server.Tiered/Logs/* /src/Shentun.Peis.HttpApi.Host/CloudFilm/2025 /src/Shentun.Peis.HttpApi.Host/photo/2020/1/1 /src/Shentun.Peis.HttpApi.Host/CloudFilm/2024/12/30 +/src/Shentun.Peis.HttpApi.Host/Exports diff --git a/src/Shentun.Peis.Application.Contracts/CustomerReports/GetPositivePatientRegisterReportReduceDto.cs b/src/Shentun.Peis.Application.Contracts/CustomerReports/GetPositivePatientRegisterReportReduceDto.cs index 31b5e698..f8389c24 100644 --- a/src/Shentun.Peis.Application.Contracts/CustomerReports/GetPositivePatientRegisterReportReduceDto.cs +++ b/src/Shentun.Peis.Application.Contracts/CustomerReports/GetPositivePatientRegisterReportReduceDto.cs @@ -28,6 +28,17 @@ namespace Shentun.Peis.CustomerReports /// public int FemaleCount { get; set; } + /// + /// 登记男性人数 + /// + public int RegisterMaleCount { get; set; } + + + /// + /// 登记女性人数 + /// + public int RegisterFemaleCount { get; set; } + public List Details { get; set; } = new List(); diff --git a/src/Shentun.Peis.Application.Contracts/ExcelExports/ExportStandardInputDto.cs b/src/Shentun.Peis.Application.Contracts/ExcelExports/ExportStandardInputDto.cs new file mode 100644 index 00000000..2af766a7 --- /dev/null +++ b/src/Shentun.Peis.Application.Contracts/ExcelExports/ExportStandardInputDto.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Shentun.Peis.ExcelExports +{ + public class ExportStandardInputDto + { + /// + /// 列名集合(显示在 Excel 表头) + /// + public List Columns { get; set; } + + /// + /// 数据集合(强类型列表) + /// + public List Data { get; set; } = new List(); + } +} diff --git a/src/Shentun.Peis.Application/ExcelExports/ExcelExportAppService.cs b/src/Shentun.Peis.Application/ExcelExports/ExcelExportAppService.cs new file mode 100644 index 00000000..59966d90 --- /dev/null +++ b/src/Shentun.Peis.Application/ExcelExports/ExcelExportAppService.cs @@ -0,0 +1,169 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using MiniExcelLibs; +using NPOI.SS.Formula.Functions; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.Application.Services; + +namespace Shentun.Peis.ExcelExports +{ + + /// + /// 导出excel + /// + [ApiExplorerSettings(GroupName = "Work")] + [Authorize] + public class ExcelExportAppService : ApplicationService + { + + public ExcelExportAppService() + { + } + + + /// + /// 导出标准版本 + /// + /// + [HttpPost("api/app/ExcelExport/ExportStandard")] + public async Task ExportStandardAsync(ExportStandardInputDto input) + { + + try + { + // 验证参数 + if (input.Columns == null || input.Columns.Count == 0) + throw new UserFriendlyException("列名不能为空"); + + // 构建 Excel 数据 + var excelData = BuildExcelDataFromObjectList(input.Columns, input.Data); + + // 导出到内存流 + using var memoryStream = new MemoryStream(); + await MiniExcel.SaveAsAsync(memoryStream, excelData); + memoryStream.Position = 0; + + // 转换为 Base64 + var fileBytes = memoryStream.ToArray(); + var base64String = Convert.ToBase64String(fileBytes); + + return base64String; + + + //// 生成文件名(使用时间戳避免重名) + //var fileName = $"Export_{DateTime.Now:yyyyMMddHHmmssfff}.xlsx"; + + //// 指定保存路径(可以根据需要修改) + //var savePath = Path.Combine(Directory.GetCurrentDirectory(), "Exports", fileName); + + //// 确保目录存在 + //var directory = Path.GetDirectoryName(savePath); + //if (!Directory.Exists(directory)) + //{ + // Directory.CreateDirectory(directory); + //} + + //// 直接保存到文件 + //await MiniExcel.SaveAsAsync(savePath, excelData); + + //return savePath; // 返回文件保存路径 + + } + catch (Exception ex) + { + throw new UserFriendlyException($"导出失败: {ex.Message}"); + } + + + } + + /// + /// 从 object 列表构建 Excel 数据(不包含表头) + /// + private IEnumerable> BuildExcelDataFromObjectList( + List columns, + List data) + { + if (data == null || data.Count == 0) + yield break; + + // 直接返回数据行,不返回表头 + foreach (var item in data) + { + var row = new Dictionary(); + + if (item != null) + { + // 获取数据中的所有值(按顺序) + var values = GetValuesInOrder(item); + + // 按顺序映射:第i列对应第i个值 + for (int i = 0; i < columns.Count && i < values.Count; i++) + { + var columnName = columns[i]; + var value = values[i] ?? string.Empty; + row[columnName] = value; + } + } + + yield return row; + } + } + + /// + /// 按顺序获取对象中的所有值 + /// + private List GetValuesInOrder(object obj) + { + var values = new List(); + + if (obj == null) + return values; + + // 处理 JsonElement 类型 + if (obj is System.Text.Json.JsonElement jsonElement) + { + if (jsonElement.ValueKind == System.Text.Json.JsonValueKind.Object) + { + foreach (var property in jsonElement.EnumerateObject()) + { + values.Add(GetJsonElementValue(property.Value)); + } + } + return values; + } + + // 处理 Dictionary 类型 + if (obj is IDictionary dict) + { + foreach (var key in dict.Keys) + { + values.Add(dict[key]); + } + return values; + } + + return values; + } + + private object GetJsonElementValue(System.Text.Json.JsonElement element) + { + return element.ValueKind switch + { + System.Text.Json.JsonValueKind.String => element.GetString(), + System.Text.Json.JsonValueKind.Number => element.GetRawText(), + System.Text.Json.JsonValueKind.True => true, + System.Text.Json.JsonValueKind.False => false, + System.Text.Json.JsonValueKind.Null => null, + _ => element.GetRawText() + }; + } + } +} diff --git a/src/Shentun.Peis.Application/Shentun.Peis.Application.csproj b/src/Shentun.Peis.Application/Shentun.Peis.Application.csproj index 2cd96e01..959ea95f 100644 --- a/src/Shentun.Peis.Application/Shentun.Peis.Application.csproj +++ b/src/Shentun.Peis.Application/Shentun.Peis.Application.csproj @@ -31,6 +31,7 @@ +