diff --git a/Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Application.Contracts/AppBase/IZbxBase.cs b/Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Application.Contracts/AppBase/IZbxBase.cs index fe6e7d4..019678b 100644 --- a/Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Application.Contracts/AppBase/IZbxBase.cs +++ b/Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Application.Contracts/AppBase/IZbxBase.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; using Volo.Abp.Application.Dtos; namespace Faster.Zheng.Winin.AppBase; @@ -11,4 +12,11 @@ public interface IZbxBase> GetPageListByFilterAsync(SfsRequestInputBase sfsRequestInputBase, bool includeDetails = false, CancellationToken cancellationToken = default); + + /// + /// 导出Excel + /// + /// + /// + Task ExportToExcelAsync(SfsRequestInputBase sfsRequestInputBase); } \ No newline at end of file diff --git a/Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Application.Contracts/Faster.Zheng.Winin.Application.Contracts.csproj b/Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Application.Contracts/Faster.Zheng.Winin.Application.Contracts.csproj index a104bd0..ee681df 100644 --- a/Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Application.Contracts/Faster.Zheng.Winin.Application.Contracts.csproj +++ b/Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Application.Contracts/Faster.Zheng.Winin.Application.Contracts.csproj @@ -13,6 +13,7 @@ + diff --git a/Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Application/AppBase/ZbxBase.cs b/Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Application/AppBase/ZbxBase.cs index a738d9b..3df92cf 100644 --- a/Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Application/AppBase/ZbxBase.cs +++ b/Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Application/AppBase/ZbxBase.cs @@ -264,44 +264,92 @@ public class ZbxBase /// 导出Excel /// - /// - /// + /// /// [HttpPost("api/[controller]/base/export-to-excel")] - public void ExportToExcel(IEnumerable data, string filePath) + public virtual async Task ExportToExcelAsync(SfsRequestInputBase sfsRequestInputBase) { + var data= (await GetPageListByFilterAsync(sfsRequestInputBase,true)).Items; + + var fileStream = new MemoryStream(); IWorkbook workbook = new XSSFWorkbook(); ISheet sheet = workbook.CreateSheet("Sheet1"); - // 获取泛型参数的类型 - var type = typeof(T); - var properties = type.GetProperties(); + // 获取主表和从表的属性 + var mainProperties = typeof(TEntityDto).GetProperties(); + var detailProperties = typeof(TEntityDto).GetProperty("Details").PropertyType.GetGenericArguments()[0].GetProperties(); // 创建表头 IRow headerRow = sheet.CreateRow(0); - for (int i = 0; i < properties.Length; i++) + for (int i = 0; i < mainProperties.Length; i++) + { + headerRow.CreateCell(i).SetCellValue(mainProperties[i].Name); + } + for (int i = 0; i < detailProperties.Length; i++) { - headerRow.CreateCell(i).SetCellValue(properties[i].Name); + headerRow.CreateCell(mainProperties.Length + i).SetCellValue(detailProperties[i].Name); } // 填充数据行 int rowIndex = 1; - foreach (var item in data) + foreach (var mainDto in data) { IRow dataRow = sheet.CreateRow(rowIndex); - for (int i = 0; i < properties.Length; i++) + + // 填充主表数据 + for (int i = 0; i < mainProperties.Length; i++) { - var value = properties[i].GetValue(item); + var value = mainProperties[i].GetValue(mainDto); dataRow.CreateCell(i).SetCellValue(value?.ToString()); } + + // 填充从表数据 + var detailList = (IEnumerable)mainProperties[0].GetValue(mainDto); + int detailCellIndex = mainProperties.Length; + foreach (var detailItem in detailList) + { + IRow detailRow; + if (rowIndex == 1) + { + // 创建新的行用于显示从表数据 + detailRow = sheet.CreateRow(detailCellIndex); + } + else + { + // 获取已创建的行用于显示从表数据 + detailRow = sheet.GetRow(detailCellIndex); + } + + for (int i = 0; i < detailProperties.Length; i++) + { + var value = detailProperties[i].GetValue(detailItem); + detailRow.CreateCell(mainProperties.Length + i).SetCellValue(value?.ToString()); + } + + detailCellIndex++; + } + rowIndex++; } - // 保存Excel文件 - using (FileStream fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write)) + // 自动调整列宽 + for (int i = 0; i < mainProperties.Length + detailProperties.Length; i++) { - workbook.Write(fileStream,true); + sheet.AutoSizeColumn(i); } + + // 保存Excel文件到MemoryStream + workbook.Write(fileStream,true); + fileStream.Position = 0; + + // 创建FileContentResult返回Excel文件 + var fileContentResult = new FileContentResult(fileStream.ToArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") + { + FileDownloadName = "export.xlsx" + }; + await Task.CompletedTask; + + return fileContentResult; } #endregion diff --git a/Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Web/WininWebModule.cs b/Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Web/WininWebModule.cs index 6357955..a6d24a9 100644 --- a/Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Web/WininWebModule.cs +++ b/Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Web/WininWebModule.cs @@ -107,6 +107,8 @@ public class WininWebModule : AbpModule //ǰ˷־ ConfigureExceptionHandling(); + //ÿڵ + ConfigureAddCors(); ConfigureSwaggerServices(context.Services); } @@ -220,6 +222,10 @@ public class WininWebModule : AbpModule app.UseCorrelationId(); app.UseStaticFiles(); app.UseRouting(); + + // + app.UseCors("CorsPolicy"); + app.UseAuthentication(); app.UseAbpOpenIddictValidation(); @@ -236,6 +242,8 @@ public class WininWebModule : AbpModule options.SwaggerEndpoint("/swagger/v1/swagger.json", "Winin API"); }); + + //app.UseAbpSwaggerUI(options => //{ // var apiDescriptionGroups = context.ServiceProvider.GetRequiredService().ApiDescriptionGroups.Items; @@ -292,5 +300,21 @@ public class WininWebModule : AbpModule } } + /// + /// ӿ + /// + protected virtual void ConfigureAddCors() + { + var origins = ServiceConfigurationContext.Services.GetConfiguration().GetSection("App:CorsOrigins").Get() ?? Array.Empty(); + Console.WriteLine($"CORS Origins:{string.Concat(origins)}"); + ServiceConfigurationContext.Services.AddCors(options => + { + options.AddPolicy("CorsPolicy", builder => + { + builder.SetIsOriginAllowed(_ => true).AllowAnyMethod().AllowAnyHeader().AllowCredentials(); + }); + }); + } + #endregion } diff --git a/Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Web/appsettings.json b/Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Web/appsettings.json index 356629c..3299c66 100644 --- a/Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Web/appsettings.json +++ b/Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Web/appsettings.json @@ -1,12 +1,19 @@ { "App": { - "SelfUrl": "https://localhost:44392" + "SelfUrl": "https://localhost:44392", + //跨域 + "CorsOrigins": [ + "http://localhost:9527", + "http://localhost:9528" + ] }, "ConnectionStrings": { "Default": "Server=.;Database=Faster.Zheng.Winin;uid=sa;pwd=sasa;timeout=6000;Encrypt=False" + //"Default": "Server=dev.ccwin-in.com,13319;Database=Faster.Zheng.Winin;uid=ccwin-in;pwd=Microsoft@2022;timeout=6000;Encrypt=False;" }, "StringEncryption": { "DefaultPassPhrase": "Aj66rJI3krHbVhS6" }, - "AlwaysAllowAuthorization": "True" + "AlwaysAllowAuthorization": "True", + "urls": "https://localhost:60069" } diff --git a/Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Web/sdf b/Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Web/sdf new file mode 100644 index 0000000..8c30370 Binary files /dev/null and b/Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Web/sdf differ