Magicodes.IE是一个导入导出通用库,支持Dto导入导出以及动态导出,支持Excel、Word、Pdf、Csv和Html。在本篇教程,笔者将讲述如何使用Magicodes.IE的导入导出筛选器。在开始以前,咱们须要先了解Magicodes.IE目前支持的筛选器:html
接口 | 说明 |
---|---|
IImportResultFilter | 导入结果筛选器,能够修改导入结果包括验证错误信息(好比动态修改错误标注) |
IImportHeaderFilter | 导入列头筛选器,能够修改列名、值映射集合等等 |
IExporterHeaderFilter | 导出列头筛选器,能够修改列头、索引、值映射等等 |
导入结果筛选器能够修改导入结果包括验证错误信息(好比动态修改错误标注),很是适合对导入数据和错误验证内容进行二次动态加工,好比加入自定义校验逻辑、验证消息多语言翻译等等。接下来咱们开始实战:git
以下图所示,咱们准备了以下Excel导入文件:github
下载地址app
Excel准备好了,咱们须要准备一个Dto:async
[ExcelImporter(ImportResultFilter = typeof(ImportResultFilterTest), IsLabelingError = true)] public class ImportResultFilterDataDto1 { /// <summary> /// 产品名称 /// </summary> [ImporterHeader(Name = "产品名称")] public string Name { get; set; } /// <summary> /// 产品代码 /// 长度验证 /// 重复验证 /// </summary> [ImporterHeader(Name = "产品代码", Description = "最大长度为20", AutoTrim = false, IsAllowRepeat = false)] public string Code { get; set; } }
如上述代码所示,咱们建立了名为“ImportResultFilterDataDto1”的Dto,使用ExcelImporter特性中的ImportResultFilter属性指定了导入结果筛选器的类型。测试
接下来咱们就建立一个类并实现IImportResultFilter接口:ui
public class ImportResultFilterTest : IImportResultFilter { /// <summary> /// 本示例修改数据错误验证结果,可用于多语言等场景 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="importResult"></param> /// <returns></returns> public ImportResult<T> Filter<T>(ImportResult<T> importResult) where T : class, new() { var errorRows = new List<int>() { 5,6 }; var items = importResult.RowErrors.Where(p => errorRows.Contains(p.RowIndex)).ToList(); for (int i = 0; i < items.Count; i++) { for (int j = 0; j < items[i].FieldErrors.Keys.Count; j++) { var key = items[i].FieldErrors.Keys.ElementAt(j); var value = items[i].FieldErrors[key]; items[i].FieldErrors[key] = value?.Replace("存在数据重复,请检查!所在行:", "Duplicate data exists, please check! Where:"); } } return importResult; } }
如上述代码所示,咱们将重复错误的验证提示修改成了“Duplicate data exists, please check! Where”。接下来,咱们须要编写导入代码:spa
public async Task ImportResultFilter_Test() { var filePath = Path.Combine(Directory.GetCurrentDirectory(), "TestFiles", "Errors", "数据错误.xlsx"); var labelingFilePath = Path.Combine(Directory.GetCurrentDirectory(), $"{nameof(ImportResultFilter_Test)}.xlsx"); var result = await Importer.Import<ImportResultFilterDataDto1>(filePath, labelingFilePath); }
打开上述代码所示的标注文件路径,就能够看到验证提示被咱们改为了英文:翻译
导入列头筛选器能够修改列名、验证属性、值映射集合等等,很是适合动态修改列名、验证逻辑、值映射等等。和前面的同样,咱们先得准备一个导入文件。设计
/// <summary> /// 导入学生数据Dto /// IsLabelingError:是否标注数据错误 /// </summary> [ExcelImporter(IsLabelingError = true, ImportHeaderFilter = typeof(ImportHeaderFilterTest))] public class ImportHeaderFilterDataDto1 { /// <summary> /// 姓名 /// </summary> [ImporterHeader(Name = "姓名", Author = "雪雁")] [Required(ErrorMessage = "学生姓名不能为空")] [MaxLength(50, ErrorMessage = "名称字数超出最大限制,请修改!")] public string Name { get; set; } /// <summary> /// 性别 /// </summary> [ImporterHeader(Name = "性别")] [Required(ErrorMessage = "性别不能为空")] public Genders Gender { get; set; } }
如上述代码所示,咱们经过ImportHeaderFilter属性指定了列头筛选器类型。接下来,咱们须要完成相关实现:
/// <summary> /// 导入列头筛选器测试 /// 1)测试修改列头 /// 2)测试修改值映射 /// </summary> public class ImportHeaderFilterTest : IImportHeaderFilter { public List<ImporterHeaderInfo> Filter(List<ImporterHeaderInfo> importerHeaderInfos) { foreach (var item in importerHeaderInfos) { if (item.PropertyName == "Name") { item.Header.Name = "Student"; } else if (item.PropertyName == "Gender") { item.MappingValues = new Dictionary<string, dynamic>() { {"男",0 }, {"女",1 } }; } } return importerHeaderInfos; } }
经过上述代码,咱们编写了一些测试:
接下来咱们继续编写导入逻辑:
public async Task ImportHeaderFilter_Test() { var filePath = Path.Combine(Directory.GetCurrentDirectory(), "TestFiles", "Import", "导入列头筛选器测试.xlsx"); var import = await Importer.Import<ImportHeaderFilterDataDto1>(filePath); }
以下图所示,咱们成功的将Excel列名为“Student”的列导入到了Dto的Name属性,同时将男女转换为了枚举:
导出列头筛选器能够修改列头、索引、值映射,很是适合动态修改导出逻辑,好比列头的中英转换,值映射动态逻辑等等。接下来咱们一块儿来实战:
[Exporter(Name = "测试", TableStyle = "Light10", ExporterHeaderFilter = typeof(TestExporterHeaderFilter1))] public class ExporterHeaderFilterTestData1 { [ExporterHeader(DisplayName = "加粗文本", IsBold = true)] public string Text { get; set; } [ExporterHeader(DisplayName = "普通文本")] public string Text2 { get; set; } [ExporterHeader(DisplayName = "忽略", IsIgnore = true)] public string Text3 { get; set; } [ExporterHeader(DisplayName = "数值", Format = "#,##0")] public decimal Number { get; set; } [ExporterHeader(DisplayName = "名称", IsAutoFit = true)] public string Name { get; set; } }
如上述Dto代码所示,咱们经过导出特性Exporter的ExporterHeaderFilter属性指定了导出列头筛选器。
public class TestExporterHeaderFilter1 : IExporterHeaderFilter { /// <summary> /// 表头筛选器(修更名称) /// </summary> /// <param name="exporterHeaderInfo"></param> /// <returns></returns> public ExporterHeaderInfo Filter(ExporterHeaderInfo exporterHeaderInfo) { if (exporterHeaderInfo.DisplayName.Equals("名称")) { exporterHeaderInfo.DisplayName = "name"; } return exporterHeaderInfo; } }
如上述代码所示,咱们实现了导出筛选器,并将显示名为“名称”的列修改成了“name”。
//导出 IExporter exporter = new ExcelExporter(); //使用GenFu生成测试数据 var data1 = GenFu.GenFu.ListOf<ExporterHeaderFilterTestData1>(); var result = await exporter.Export(filePath, data1);
使用上述代码导出后,咱们来验证导出结果:
是否是So easy呢?固然咱们还能够作一些其余的事情,好比修改忽略列:
public class TestExporterHeaderFilter2 : IExporterHeaderFilter { /// <summary> /// 表头筛选器(修改忽略列) /// </summary> /// <param name="exporterHeaderInfo"></param> /// <returns></returns> public ExporterHeaderInfo Filter(ExporterHeaderInfo exporterHeaderInfo) { if (exporterHeaderInfo.ExporterHeaderAttribute.IsIgnore) { exporterHeaderInfo.ExporterHeaderAttribute.IsIgnore = false; } return exporterHeaderInfo; } }
筛选器主要是为了知足你们可以在导入导出时支持动态处理,好比值映射等等。可是经过特性指定筛选器的话,那么如何支持依赖注入呢?不要慌,针对这个场景,咱们也有考虑。
参考代码以下:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { AppDependencyResolver.Init(app.ApplicationServices); //添加注入关系 services.AddSingleton<IImportResultFilter, ImportResultFilterTest>(); services.AddSingleton<IImportHeaderFilter, ImportHeaderFilterTest>(); services.AddSingleton<IExporterHeaderFilter, TestExporterHeaderFilter1>(); }
而后就尽情使用吧。值得注意的是:
若是某段导入导出须要禁用全部的筛选器,咱们该如何处理?仅需将IsDisableAllFilter设置为true便可。导入导出特性均已支持。