MoneyTree.DataExport 数据导出
📋 概述
MoneyTree.DataExport 提供声明式数据导出能力,通过 [ExportColumn] 特性标记实体属性,自动生成 Excel(基于 ClosedXML)和 CSV 格式的导出文件。支持大数据量流式写入、自定义列格式化、列合计和进度回调。
| 属性 |
说明 |
| NuGet 包 |
MoneyTree.DataExport |
| 外部依赖 |
MoneyTree.Core、ClosedXML |
| 定位 |
声明式 Excel/CSV 数据导出 |
🏗️ 项目文件结构
MoneyTree.DataExport/
├── MoneyTree.DataExport.csproj
├── GlobalUsings.cs
├── Abstractions/
│ └── IDataExporter.cs # 统一数据导出接口 + ExportFormat 枚举
├── Attributes/
│ └── ExportColumnAttribute.cs # 导出列标记特性
├── Core/
│ ├── ExportOptions.cs # 全局配置选项
│ ├── ExportRequest.cs # 导出请求模型
│ ├── ExportResult.cs # 导出结果模型
│ ├── ExportColumnInfo.cs # 导出列信息模型
│ └── ExportRow.cs # 导出数据行模型
├── Providers/
│ ├── ExcelExporter.cs # Excel 导出(ClosedXML)
│ └── CsvExporter.cs # CSV 导出
└── Extensions/
├── DataExportBuilder.cs # 流畅配置构造器
└── DataExportExtensions.cs # DI 注册扩展
🎯 核心特性
| 特性 |
说明 |
| 声明式列定义 |
[ExportColumn] 特性标记,无需手动配置 |
| 大数据量流式写入 |
逐行写入避免 OOM |
| 自定义格式化 |
日期、金额、枚举等自定义格式化字符串 |
| 列合计 |
ShowSubtotal 自动计算数值列合计 |
| 表头样式 |
Excel 支持加粗、背景色 |
| 列宽自适应 |
Excel 自动计算最佳列宽 |
| 进度回调 |
实时反馈导出进度 |
| 双格式 |
支持 Excel (.xlsx) 和 CSV (.csv) |
🚀 快速开始
基础注册
// Program.cs
using MoneyTree.DataExport.Extensions;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddMoneyTreeDataExport();
📖 使用示例
声明式导出
// 定义 DTO
public class OrderExportDto
{
[ExportColumn("订单号", Order = 1, Width = 20)]
public string OrderNumber { get; set; } = string.Empty;
[ExportColumn("客户", Order = 2, Width = 15)]
public string CustomerName { get; set; } = string.Empty;
[ExportColumn("金额", Order = 3, Format = "¥#,##0.00", ShowSubtotal = true)]
public decimal Amount { get; set; }
[ExportColumn("状态", Order = 4)]
public string Status { get; set; } = string.Empty;
[ExportColumn("创建时间", Order = 5, Format = "yyyy-MM-dd HH:mm")]
public DateTime CreatedAt { get; set; }
[ExportColumn(Ignore = true)] // 不导出
public string InternalNote { get; set; } = string.Empty;
}
// 在服务中使用
[Inject] public IDataExporter Exporter { get; private set; } = default!;
public async Task<IResult> ExportOrdersAsync()
{
var orders = await _db.Orders
.Select(o => new OrderExportDto { /* 映射 */ })
.ToListAsync();
var bytes = await Exporter.ExportToBytesAsync(orders, new ExportRequest
{
Format = ExportFormat.Excel,
Title = "订单列表",
SheetName = "订单"
});
return Results.File(bytes,
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"订单列表.xlsx");
}
[ExportColumn] 特性参数
| 参数 |
类型 |
默认值 |
说明 |
Title |
string |
属性名 |
列标题名称 |
Order |
int |
0 |
列顺序(升序排列) |
Format |
string? |
null |
格式化字符串(如 ¥#,##0.00、yyyy-MM-dd) |
Width |
int |
0 |
列宽(0 为自适应) |
ShowSubtotal |
bool |
false |
是否在末尾显示该列的合计值 |
Ignore |
bool |
false |
是否忽略该列(不导出) |
Alignment |
ExportColumnAlignment |
Left |
列对齐方式 |
自定义列导出
不使用特性标记,通过代码动态指定导出列:
var bytes = await Exporter.ExportToBytesAsync(orders, new ExportRequest
{
Format = ExportFormat.Excel,
Title = "订单列表",
Columns = new List<ExportColumnInfo>
{
new() { PropertyName = "OrderNumber", Title = "订单号", Order = 1 },
new() { PropertyName = "Amount", Title = "金额", Order = 2, ShowSubtotal = true }
}
});
CSV 导出
var bytes = await Exporter.ExportToBytesAsync(orders, new ExportRequest
{
Format = ExportFormat.Csv,
Title = "订单列表"
});
📊 导出格式对比
| 维度 |
Excel |
CSV |
| 格式 |
.xlsx |
.csv |
| 表格样式 |
✅ 加粗、背景色、合并单元格 |
❌ 纯文本 |
| 列宽自适应 |
✅ |
❌ |
| 大数据量 |
○ 受 ClosedXML 内存限制 |
✅ 流式写入更高效 |
| 列合计 |
✅ |
✅ |
| 中文兼容 |
✅ |
✅ UTF-8 BOM |