using Hotline.Application.Tools; using Hotline.Share.Dtos.CallCenter; using Hotline.Share.Dtos.Order; using Hotline.Share.Enums.Article; using Hotline.Share.Tools; using Hotline.Tools; using Mapster; using MapsterMapper; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; using MiniExcelLibs; using System.Reflection; using XF.Domain.Dependency; using XF.Utility.EnumExtensions; namespace Hotline.Application.ExportExcel { public class ExportApplication : IExportApplication, IScopeDependency { private readonly IMapper _mapper; private readonly IHttpContextAccessor _httpContextAccessor; public ExportApplication(IMapper mapper, IHttpContextAccessor httpContextAccessor) { _mapper = mapper; _httpContextAccessor = httpContextAccessor; } /// /// 导出数据 /// /// /// 数据集 /// 导出文件名(不传则生成yyyyMMddhhmmss) /// public FileStreamResult ExportData(IList list, string? name) { var stream = new MemoryStream(); stream.SaveAs(list); stream.Seek(0, SeekOrigin.Begin); return new FileStreamResult(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") { FileDownloadName = !string.IsNullOrEmpty(name) ? DateTime.Now.ToString("yyyyMMddhhmmss") + ".xlsx" : name }; } public Stream GetExcelStream(ExportExcelDto dto, IList items, Func, T>? func = null) { if (items != null && items.Count > 0 && func != null) { items.Add(func.Invoke(items)); } dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos); var dtos = items .Select(stu => _mapper.Map(stu, typeof(T), dynamicClass)) .Cast() .ToList(); return ExcelHelper.CreateStream(dtos); } public FileStreamResult GetExcelFile(ExportExcelDto dto, IList items, string fileName, Func, T>? func = null) { return GetExcelStream(dto, items, func).GetExcelFile(fileName); } public FileStreamResult GetExcelFile(ExportExcelDto dto, IList items, string fileName, string totalName) where T : new() { var fieldsAll = typeof(T).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); var fields = fieldsAll.Where(f => IsNumericType(f.FieldType)); // 只选择数值类型字段 var totalField = fieldsAll.Where(m => m.Name.Contains(totalName)).First(); var sumDict = new Dictionary(); foreach (var field in fields) { sumDict[field] = 0; } foreach (var item in items) { foreach (var field in fields) { var value = field.GetValue(item); if (value != null) { sumDict[field] += (dynamic)value; // 使用 dynamic 累加 } } } var resultItem = new T(); totalField.SetValue(resultItem, "合计"); foreach (var field in fields) { field.SetValue(resultItem, sumDict[field]); } items.Add(resultItem); return GetExcelFile(dto, items, fileName); } private static bool IsNumericType(Type type) { return type == typeof(int) || type == typeof(float) || type == typeof(double) || type == typeof(decimal) || type == typeof(long) || type == typeof(short) || type == typeof(byte) || type == typeof(uint) || type == typeof(ulong) || type == typeof(ushort) || type == typeof(sbyte); } } }