5 changed files with 201 additions and 0 deletions
-
1.gitignore
-
11src/Shentun.Peis.Application.Contracts/CustomerReports/GetPositivePatientRegisterReportReduceDto.cs
-
19src/Shentun.Peis.Application.Contracts/ExcelExports/ExportStandardInputDto.cs
-
169src/Shentun.Peis.Application/ExcelExports/ExcelExportAppService.cs
-
1src/Shentun.Peis.Application/Shentun.Peis.Application.csproj
@ -0,0 +1,19 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Text; |
||||
|
|
||||
|
namespace Shentun.Peis.ExcelExports |
||||
|
{ |
||||
|
public class ExportStandardInputDto |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 列名集合(显示在 Excel 表头)
|
||||
|
/// </summary>
|
||||
|
public List<string> Columns { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 数据集合(强类型列表)
|
||||
|
/// </summary>
|
||||
|
public List<object> Data { get; set; } = new List<object>(); |
||||
|
} |
||||
|
} |
||||
@ -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 |
||||
|
{ |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 导出excel
|
||||
|
/// </summary>
|
||||
|
[ApiExplorerSettings(GroupName = "Work")] |
||||
|
[Authorize] |
||||
|
public class ExcelExportAppService : ApplicationService |
||||
|
{ |
||||
|
|
||||
|
public ExcelExportAppService() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 导出标准版本
|
||||
|
/// </summary>
|
||||
|
/// <returns></returns>
|
||||
|
[HttpPost("api/app/ExcelExport/ExportStandard")] |
||||
|
public async Task<string> 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}"); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 从 object 列表构建 Excel 数据(不包含表头)
|
||||
|
/// </summary>
|
||||
|
private IEnumerable<Dictionary<string, object>> BuildExcelDataFromObjectList( |
||||
|
List<string> columns, |
||||
|
List<object> data) |
||||
|
{ |
||||
|
if (data == null || data.Count == 0) |
||||
|
yield break; |
||||
|
|
||||
|
// 直接返回数据行,不返回表头
|
||||
|
foreach (var item in data) |
||||
|
{ |
||||
|
var row = new Dictionary<string, object>(); |
||||
|
|
||||
|
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; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 按顺序获取对象中的所有值
|
||||
|
/// </summary>
|
||||
|
private List<object> GetValuesInOrder(object obj) |
||||
|
{ |
||||
|
var values = new List<object>(); |
||||
|
|
||||
|
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<string, object> 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() |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue