总体设计

 

Magicodes.IE是一个导入导出通用库,支持Dto导入导出以及动态导出,支持Excel、Word、Pdf、Csv和Html。在本篇教程,笔者将讲述如何使用Magicodes.IE的导入导出筛选器。在开始之前,我们需要先了解Magicodes.IE目前支持的筛选器:

接口 说明
IImportResultFilter 导入结果筛选器,可以修改导入结果包括验证错误信息(比如动态修改错误标注)
IImportHeaderFilter 导入列头筛选器,可以修改列名、值映射集合等等
IExporterHeaderFilter 导出列头筛选器,可以修改列头、索引、值映射等等

导入结果筛选器(IImportResultFilter)的使用

导入结果筛选器可以修改导入结果包括验证错误信息(比如动态修改错误标注),非常适合对导入数据和错误验证内容进行二次动态加工,比如加入自定义校验逻辑、验证消息多语言翻译等等。接下来我们开始实战:

准备导入文件

如下图所示,我们准备了如下Excel导入文件:

下载地址

准备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)的使用

导入列头筛选器可以修改列名、验证属性、值映射集合等等,非常适合动态修改列名、验证逻辑、值映射等等。和前面的一样,我们先得准备一个导入文件。

准备导入文件

下载地址

准备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;
}
}

通过上述代码,我们编写了一些测试:

  1. 实现了IImportHeaderFilter
  2. 将属性名称为“Name”的列的列头修改为“Student”
  3. 将属性名称为“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>();
}

然后就尽情使用吧。值得注意的是:

  1. 注入的筛选器类型的优先级高于特性指定的筛选器类型,也就是当两者并存时,优先会使用注入的筛选器
  2. 注入的筛选器是全局的,当注入多种类型的筛选器时,均会执行,接下来我们还会支持更多细节控制
  3. 如果某个逻辑需要禁用所有筛选器,请参考下面部分
  4. 此功能需要2.4.0-beta2或以上版本才支持

使用IsDisableAllFilter属性禁用所有的筛选器

如果某段导入导出需要禁用所有的筛选器,我们该如何处理?仅需将IsDisableAllFilter设置为true即可。导入导出特性均已支持。

Magicodes.IE之导入导出筛选器的更多相关文章

  1. 创建、导入、导出、复制以及粘贴 WMI 筛选器

    TechNet 库 Deployment Forefront Identity and Access Management 基础结构优化 浏览器 Microsoft Dynamics Products ...

  2. ASP.NET 开源导入导出库Magicodes.IE 完成Csv导入导出

    Magicodes.IE Csv导入导出 说明 本章主要说明如何使用Magicodes.IE.Csv进行Csv导入导出. 主要步骤 1.安装包Magicodes.IE.Csv Install-Pack ...

  3. Magicodes.IE 在100万数据量下导入导出性能测试

    原文作者:HueiFeng 前言 目前Magicodes.IE更新到了2.2.3,感谢大家的支持,同时建议大家在使用过程中如果遇到一些问题或者说需要一些额外的功能可以直接提issues,当然更建议大家 ...

  4. @程序员,你们还在用网上乱找的方法导入导出Excel么,我们给你造了个轮子!!!!!

    程序员的显著特点 有一天跟一位同事跟我闲聊,讨论起过去若干年软件行业的感受,他问了个问题:你觉得一个好的软件工程师最显著的特点是什么? 我想了一会,说:大概是坐得住吧. 某种意义上来说,在互联网技术飞 ...

  5. 【Magicodes.IE 2.0.0-beta1版本发布】已支持数据表格、列筛选器和Sheet拆分

    为了更好的完善Magicodes.IE,春节期间我们会进行一次大的重构.由于精力有限,急缺文档和翻译(将文档翻译为英文文档)支持,诚邀各位加入.同时在功能方便也做了相关规划,有兴趣的朋友可以参与提交P ...

  6. 开源导入导出库Magicodes.IE 导出教程

    要点 导出特性 如何导出Excel表头 如何导出数据.如何进行数据的切割.如何使用筛选器 导出特性 ExporterAttribute Name: 名称(当前Sheet 名称) HeaderFontS ...

  7. 开源导入导出通用库Magicodes.ExporterAndImporter发布

    导入导出通用库 Magicodes.ExporterAndImporter为心莱团队封装的导入导出通用库,并且仍在跟随项目不断地打磨. GitHub地址: https://github.com/xin ...

  8. ASP.NET 开源导入导出库Magicodes.IE 完成Excel图片导入导出

    Magicodes.IE Excel图片导入导出 为了更好的根据实际功能来迭代,从2.2的里程碑规划开始,我们将结合社区的建议和意见来进行迭代,您可以点此链接来提交您的意见和建议: https://g ...

  9. ASP.NET 开源导入导出库Magicodes.IE 导出Pdf教程

    基础教程之导出Pdf收据 说明 本教程主要说明如何使用Magicodes.IE.Pdf完成Pdf收据导出 要点 导出PDF数据 自定义PDF模板 导出单据 如何批量导出单据 导出特性 PdfExpor ...

随机推荐

  1. 第七天Scrum冲刺博客

    1.会议照片 2.项目进展 团队成员 昨日计划任务 今日计划任务 梁天龙  学习课程页面  建议页面 黄岳康  定义个人课程  登陆页面 吴哲翰  完成页面的与后端的沟通交流  继续保持确认功能齐全 ...

  2. Java 实例 - 获取本机ip地址及主机名

    package guyu.day0824; import java.net.InetAddress; /** * @Author: Fred * @Date: 2020/8/24 09:39 */ p ...

  3. java23种设计模式——八、组合模式

    目录 java23种设计模式-- 一.设计模式介绍 java23种设计模式-- 二.单例模式 java23种设计模式--三.工厂模式 java23种设计模式--四.原型模式 java23种设计模式-- ...

  4. C++ strcmp与strncmp的比较

    C++ strcmp与strncmp的比较(转载)  原文链接:https://www.cnblogs.com/ybqjymy/p/12565444.html strcmp与strncmp都是用来比较 ...

  5. Flutter —布局系统概述

    老孟导读:此篇文章非常详细的讲解了 Flutter 布局系统的工作原理. 翻译自:https://itnext.io/flutter-layout-system-overview-c70bbe9ba9 ...

  6. Spring源码分析 手写简单IOC容器

    Spring的两大特性就是IOC和AOP. IOC Container,控制反转容器,通过读取配置文件或注解,将对象封装成Bean存入IOC容器待用,程序需要时再从容器中取,实现控制权由程序员向程序的 ...

  7. Educational Codeforces Round 68 (Rated for Div. 2)-C-From S To T

    You are given three strings ss, tt and pp consisting of lowercase Latin letters. You may perform any ...

  8. 如何编写一个简单的Linux驱动(一)

    前言 最近在学习Linux驱动,记录下自己学习的历程. 驱动的基本框架 Linux驱动的基本框架包含两部分,“模块入口.出口的注册”和“模块入口.出口函数的实现”,如下方代码. static int ...

  9. 「面向 offer 学算法」笔面试大杀器 -- 单调栈

    目录 前言 单调栈 初入茅庐 小试牛刀 打怪升级 出师试炼 前言 单调栈是一种比较简单的数据结构.虽然简单,但在某些题目中能发挥很好的作用. 最近很多大厂的笔试.面试中都出现了单调栈的题目,而还有不少 ...

  10. centos开放指定端口

    1.开启防火墙      systemctl start firewalld 2.开放指定端口       firewall-cmd --zone=public --add-port=1935/tcp ...