Magicodes.IE之导入导出筛选器
總體設計
Magicodes.IE是一個導入導出通用庫,支持Dto導入導出以及動態導出,支持Excel、Word、Pdf、Csv和Html。在本篇教程,筆者將講述如何使用Magicodes.IE的導入導出篩選器。
在開始之前,我們需要先了解Magicodes.IE目前支持的篩選器:
| IImportResultFilter | 導入結果篩選器,可以修改導入結果包括驗證錯誤信息(比如動態修改錯誤標注) | 
| IImportHeaderFilter | 導入列頭篩選器,可以修改列名、值映射集合等等 | 
| IExporterHeaderFilter | 導出列頭篩選器,可以修改列頭、索引、值映射等等 | 
導入結果篩選器(IImportResultFilter)的使用
導入結果篩選器可以修改導入結果包括驗證錯誤信息(比如動態修改錯誤標注),非常適合對導入數據和錯誤驗證內容進行二次動態加工,比如加入自定義校驗邏輯、驗證消息多語言翻譯等等。接下來我們開始實戰:
準備導入文件
如下圖所示,我們準備了如下Excel導入文件:
下載地址:
https://github.com/dotnetcore/Magicodes.IE/blob/master/src/Magicodes.ExporterAndImporter.Tests/TestFiles/Errors/%E6%95%B0%E6%8D%AE%E9%94%99%E8%AF%AF.xlsx
準備Dto
Excel準備好了,我們需要準備一個Dto:
[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
接下來我們就創建一個類并實現IImportResultFilter接口:
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”。接下來,我們需要編寫導入代碼:
編寫導入代碼
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);}
打開上述代碼所示的標注文件路徑,就可以看到驗證提示被我們改成了英文:
導入列頭篩選器(IImportHeaderFilter)的使用
導入列頭篩選器可以修改列名、驗證屬性、值映射集合等等,非常適合動態修改列名、驗證邏輯、值映射等等。和前面的一樣,我們先得準備一個導入文件。
準備導入文件
下載地址:
https://github.com/dotnetcore/Magicodes.IE/blob/master/src/Magicodes.ExporterAndImporter.Tests/TestFiles/Import/%E5%AF%BC%E5%85%A5%E5%88%97%E5%A4%B4%E7%AD%9B%E9%80%89%E5%99%A8%E6%B5%8B%E8%AF%95.xlsx
準備Dto
/// <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屬性指定了列頭篩選器類型。接下來,我們需要完成相關實現:
創建類并實現接口IImportHeaderFilter
/// <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;}}通過上述代碼,我們編寫了一些測試:
實現了IImportHeaderFilter
將屬性名稱為“Name”的列的列頭修改為“Student”
將屬性名稱為“Gender”的列的列映射改為男女映射
接下來我們繼續編寫導入邏輯:
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屬性,同時將男女轉換為了枚舉:
導出列頭篩選器(IExporterHeaderFilter)的使用
導出列頭篩選器可以修改列頭、索引、值映射,非常適合動態修改導出邏輯,比如列頭的中英轉換,值映射動態邏輯等等。接下來我們一起來實戰:
準備Dto并編寫導出代碼
[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屬性指定了導出列頭篩選器。
實現篩選器IExporterHeaderFilter
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;}}如何使用容器注入篩選器
篩選器主要是為了滿足大家能夠在導入導出時支持動態處理,比如值映射等等。但是通過特性指定篩選器的話,那么如何支持依賴注入呢?不要慌,針對這個場景,我們也有考慮。
在ASP.NET Core的啟動類(StartUp)注冊容器
參考代碼如下:
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>(); }然后就盡情使用吧。值得注意的是:
注入的篩選器類型的優先級高于特性指定的篩選器類型,也就是當兩者并存時,優先會使用注入的篩選器
注入的篩選器是全局的,當注入多種類型的篩選器時,均會執行,接下來我們還會支持更多細節控制
如果某個邏輯需要禁用所有篩選器,請參考下面部分
此功能需要2.4.0-beta2或以上版本才支持
使用IsDisableAllFilter屬性禁用所有的篩選器
如果某段導入導出需要禁用所有的篩選器,我們該如何處理?僅需將IsDisableAllFilter設置為true即可。導入導出特性均已支持。
轉載是一種動力 分享是一種美德
如果喜歡作者的文章,請關注【麥扣聊技術】訂閱號以便第一時間獲得最新內容。本文版權歸作者和湖南心萊信息科技有限公司共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。
文檔官網:docs.xin-lai.com
QQ群:
編程交流群<85318032>?
產品交流群<897857351>
總結
以上是生活随笔為你收集整理的Magicodes.IE之导入导出筛选器的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 跟我一起学.NetCore之中间件(Mi
- 下一篇: 谈了千百遍的缓存数据的一致性问题
