ExportApplication.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. 
  2. using Hotline.Application.Tools;
  3. using Hotline.Share.Dtos.CallCenter;
  4. using Hotline.Share.Dtos.Order;
  5. using Hotline.Share.Enums.Article;
  6. using Hotline.Share.Tools;
  7. using Hotline.Tools;
  8. using Mapster;
  9. using MapsterMapper;
  10. using Microsoft.AspNetCore.Http;
  11. using Microsoft.AspNetCore.Mvc;
  12. using Microsoft.Extensions.DependencyInjection;
  13. using MiniExcelLibs;
  14. using System.Reflection;
  15. using XF.Domain.Dependency;
  16. using XF.Utility.EnumExtensions;
  17. namespace Hotline.Application.ExportExcel
  18. {
  19. public class ExportApplication : IExportApplication, IScopeDependency
  20. {
  21. private readonly IMapper _mapper;
  22. private readonly IHttpContextAccessor _httpContextAccessor;
  23. public ExportApplication(IMapper mapper, IHttpContextAccessor httpContextAccessor)
  24. {
  25. _mapper = mapper;
  26. _httpContextAccessor = httpContextAccessor;
  27. }
  28. /// <summary>
  29. /// 导出数据
  30. /// </summary>
  31. /// <typeparam name="T"></typeparam>
  32. /// <param name="list">数据集</param>
  33. /// <param name="name">导出文件名(不传则生成yyyyMMddhhmmss)</param>
  34. /// <returns></returns>
  35. public FileStreamResult ExportData<T>(IList<T> list, string? name)
  36. {
  37. var stream = new MemoryStream();
  38. stream.SaveAs(list);
  39. stream.Seek(0, SeekOrigin.Begin);
  40. return new FileStreamResult(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
  41. {
  42. FileDownloadName = !string.IsNullOrEmpty(name) ? DateTime.Now.ToString("yyyyMMddhhmmss") + ".xlsx" : name
  43. };
  44. }
  45. public Stream GetExcelStream<T, D>(ExportExcelDto<D> dto, IList<T> items, Func<IList<T>, T>? func = null)
  46. {
  47. if (items != null && items.Count > 0 && func != null)
  48. {
  49. items.Add(func.Invoke(items));
  50. }
  51. dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
  52. var dtos = items
  53. .Select(stu => _mapper.Map(stu, typeof(T), dynamicClass))
  54. .Cast<object>()
  55. .ToList();
  56. return ExcelHelper.CreateStream(dtos);
  57. }
  58. public FileStreamResult GetExcelFile<T, D>(ExportExcelDto<D> dto, IList<T> items, string fileName, Func<IList<T>, T>? func = null)
  59. {
  60. return GetExcelStream(dto, items, func).GetExcelFile(fileName);
  61. }
  62. public FileStreamResult GetExcelFile<T, D>(ExportExcelDto<D> dto, IList<T> items, string fileName, string totalName) where T : new()
  63. {
  64. var fieldsAll = typeof(T).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
  65. var fields = fieldsAll.Where(f => IsNumericType(f.FieldType)); // 只选择数值类型字段
  66. var totalField = fieldsAll.Where(m => m.Name.Contains(totalName)).First();
  67. var sumDict = new Dictionary<FieldInfo, dynamic>();
  68. foreach (var field in fields)
  69. {
  70. sumDict[field] = 0;
  71. }
  72. foreach (var item in items)
  73. {
  74. foreach (var field in fields)
  75. {
  76. var value = field.GetValue(item);
  77. if (value != null)
  78. {
  79. sumDict[field] += (dynamic)value; // 使用 dynamic 累加
  80. }
  81. }
  82. }
  83. var resultItem = new T();
  84. totalField.SetValue(resultItem, "合计");
  85. foreach (var field in fields)
  86. {
  87. field.SetValue(resultItem, sumDict[field]);
  88. }
  89. items.Add(resultItem);
  90. return GetExcelFile(dto, items, fileName);
  91. }
  92. private static bool IsNumericType(Type type)
  93. {
  94. return type == typeof(int) || type == typeof(float) || type == typeof(double) ||
  95. type == typeof(decimal) || type == typeof(long) || type == typeof(short) ||
  96. type == typeof(byte) || type == typeof(uint) || type == typeof(ulong) ||
  97. type == typeof(ushort) || type == typeof(sbyte);
  98. }
  99. }
  100. }