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便可。導入導出特性均已支持。