Magicodes.IE之导入导出筛选器
总体设计

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;
}
}
通过上述代码,我们编写了一些测试:
- 实现了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即可。导入导出特性均已支持。
Magicodes.IE之导入导出筛选器的更多相关文章
- 创建、导入、导出、复制以及粘贴 WMI 筛选器
TechNet 库 Deployment Forefront Identity and Access Management 基础结构优化 浏览器 Microsoft Dynamics Products ...
- ASP.NET 开源导入导出库Magicodes.IE 完成Csv导入导出
Magicodes.IE Csv导入导出 说明 本章主要说明如何使用Magicodes.IE.Csv进行Csv导入导出. 主要步骤 1.安装包Magicodes.IE.Csv Install-Pack ...
- Magicodes.IE 在100万数据量下导入导出性能测试
原文作者:HueiFeng 前言 目前Magicodes.IE更新到了2.2.3,感谢大家的支持,同时建议大家在使用过程中如果遇到一些问题或者说需要一些额外的功能可以直接提issues,当然更建议大家 ...
- @程序员,你们还在用网上乱找的方法导入导出Excel么,我们给你造了个轮子!!!!!
程序员的显著特点 有一天跟一位同事跟我闲聊,讨论起过去若干年软件行业的感受,他问了个问题:你觉得一个好的软件工程师最显著的特点是什么? 我想了一会,说:大概是坐得住吧. 某种意义上来说,在互联网技术飞 ...
- 【Magicodes.IE 2.0.0-beta1版本发布】已支持数据表格、列筛选器和Sheet拆分
为了更好的完善Magicodes.IE,春节期间我们会进行一次大的重构.由于精力有限,急缺文档和翻译(将文档翻译为英文文档)支持,诚邀各位加入.同时在功能方便也做了相关规划,有兴趣的朋友可以参与提交P ...
- 开源导入导出库Magicodes.IE 导出教程
要点 导出特性 如何导出Excel表头 如何导出数据.如何进行数据的切割.如何使用筛选器 导出特性 ExporterAttribute Name: 名称(当前Sheet 名称) HeaderFontS ...
- 开源导入导出通用库Magicodes.ExporterAndImporter发布
导入导出通用库 Magicodes.ExporterAndImporter为心莱团队封装的导入导出通用库,并且仍在跟随项目不断地打磨. GitHub地址: https://github.com/xin ...
- ASP.NET 开源导入导出库Magicodes.IE 完成Excel图片导入导出
Magicodes.IE Excel图片导入导出 为了更好的根据实际功能来迭代,从2.2的里程碑规划开始,我们将结合社区的建议和意见来进行迭代,您可以点此链接来提交您的意见和建议: https://g ...
- ASP.NET 开源导入导出库Magicodes.IE 导出Pdf教程
基础教程之导出Pdf收据 说明 本教程主要说明如何使用Magicodes.IE.Pdf完成Pdf收据导出 要点 导出PDF数据 自定义PDF模板 导出单据 如何批量导出单据 导出特性 PdfExpor ...
随机推荐
- 如何配置 SSH 密钥连接 Git 仓库
SSH 是 Secure Shell 的缩写,由 IETF 的网络小组(Network Working Group)所制定:是建立在应用层基础上的安全协议. SSH 是目前较可靠,专为远程登录会话和其 ...
- python 报错错误集合——更新中
1. #!/usr/bin/env python # -*- coding:utf-8 -*- 'one #报错 File "C:\Users\shuxiu\Desktop\test.py& ...
- python编程入门笔记
一.作用域 在python中,作用域分为两种:全局作用域和局部作用域. 全局作用域是定义在文件级别的变量,函数名.而局部作用域,则是定义函数内部. 关于作用域,我们要理解两点: a.在全局不能访问到局 ...
- python自动化测试中的数据驱动unittest+ddt
ddt是一个unittest的插件,用来实现uniitest的数据驱动 本文以python自动化测试中的数据驱动为原则,记录学习ddt的过程 一.数据的传递规则
- #企业项目实战 .Net Core + Vue/Angular 分库分表日志系统六 | 最终篇-通过AOP自动连接数据库-完成日志业务
教程预览 01 | 前言 02 | 简单的分库分表设计 03 | 控制反转搭配简单业务 04 | 强化设计方案 05 | 完善业务自动创建数据库 06 | 最终篇-通过AOP自动连接数据库-完成日志业 ...
- ES5和ES6的继承对比
ES5的继承实现,这里以最佳实践:寄生组合式继承方式来实现.(为什么是最佳实践,前面有随笔讲过了,可以参考) function Super(name) { this.name = name; } Su ...
- Python3网络爬虫之requests动态爬虫:拉钩网
操作环境: Windows10.Python3.6.Pycharm.谷歌浏览器目标网址: https://www.lagou.com/jobs/list_Python/p-city_0?px=defa ...
- 【Gin-API系列】Gin中间件之鉴权访问(五)
在完成中间件的介绍和日志中间件的代码后,我们的程序已经基本能正常跑通了,但如果要上生产,还少了一些必要的功能,例如鉴权.异常捕捉等.本章我们介绍如何编写鉴权中间件. 鉴权访问,说白了就是给用户的请求增 ...
- oeasy教你玩转linux010104灵魂之问whatis
灵魂之问whatis 回忆上节课 我们上次在系统里面乱转
- NGUI 优化
1. Update Ngui 组件继承关系是 UIWidget : UIRect : MonoBehaviour. 因此由每个组件的独自调用update变更为,由某个更新点,统一调用会效率提升.并且 ...