前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Magicodes.IE之导入学生数据教程

Magicodes.IE之导入学生数据教程

作者头像
心莱科技雪雁
发布2019-12-05 10:13:50
5360
发布2019-12-05 10:13:50
举报
文章被收录于专栏:雪雁的专栏雪雁的专栏

基础教程之导入学生数据

说明

本教程主要说明如果使用Magicodes.IE.Excel完成学生数据的Excel导入。

要点

  • 本教程使用Magicodes.IE.Excel来完成Excel数据导入
  • 需要通过创建Dto来完成导入
  • Magicodes.IE.Excel可以根据Dto以及特性设置来自动生成导入的Excel模板,数据验证(包括重复验证),模板验证,读取设置,值约束和映射,输出Excel验证标注

主要步骤

1.安装包Magicodes.IE.Excel

在本篇教程中,我们仅演示使用Excel来完成学生数据的导入。我们需要在已准备好的工程中安装以下包,参考命令如下所示:

代码语言:javascript
复制
Install-Package Magicodes.IE.Excel

2.创建导入Dto

主要代码如下所示:

  • 学生数据Dto
代码语言:javascript
复制
/// <summary>
    /// 导入学生数据Dto
    /// IsLabelingError:是否标注数据错误
    /// </summary>
    [ExcelImporter(IsLabelingError = true)]
    public class ImportStudentDto
    {
        /// <summary>
        ///     序号
        /// </summary>
        [ImporterHeader(Name = "序号")]
        public long SerialNumber { get; set; }

        /// <summary>
        ///     学籍号
        /// </summary>
        [ImporterHeader(Name = "学籍号")]
        [MaxLength(30, ErrorMessage = "学籍号字数超出最大限制,请修改!")]
        public string StudentCode { get; set; }

        /// <summary>
        ///     姓名
        /// </summary>
        [ImporterHeader(Name = "姓名")]
        [Required(ErrorMessage = "学生姓名不能为空")]
        [MaxLength(50, ErrorMessage = "名称字数超出最大限制,请修改!")]
        public string Name { get; set; }

        /// <summary>
        ///     身份证号码
        /// </summary>
        [ImporterHeader(Name = "身份证号", IsAllowRepeat = false)]
        [Required(ErrorMessage = "身份证号不能为空")]
        [MaxLength(18, ErrorMessage = "身份证字数超出最大限制,请修改!")]
        public string IdCard { get; set; }

        /// <summary>
        ///     性别
        /// </summary>
        [ImporterHeader(Name = "性别")]
        [Required(ErrorMessage = "性别不能为空")]
        [ValueMapping("男", 0)]
        [ValueMapping("女", 1)]
        public Genders Gender { get; set; }

        /// <summary>
        ///     家庭地址
        /// </summary>
        [ImporterHeader(Name = "家庭住址")]
        [Required(ErrorMessage = "家庭地址不能为空")]
        [MaxLength(200, ErrorMessage = "家庭地址字数超出最大限制,请修改!")]
        public string Address { get; set; }

        /// <summary>
        ///     家长姓名
        /// </summary>
        [ImporterHeader(Name = "家长姓名")]
        [Required(ErrorMessage = "家长姓名不能为空")]
        [MaxLength(50, ErrorMessage = "家长姓名数超出最大限制,请修改!")]
        public string Guardian { get; set; }

        /// <summary>
        ///     家长联系电话
        /// </summary>
        [ImporterHeader(Name = "家长联系电话")]
        [MaxLength(20, ErrorMessage = "家长联系电话字数超出最大限制,请修改!")]
        public string GuardianPhone { get; set; }

        /// <summary>
        ///     学号
        /// </summary>
        [ImporterHeader(Name = "学号")]
        [MaxLength(30, ErrorMessage = "学号字数超出最大限制,请修改!")]
        public string StudentNub { get; set; }

        /// <summary>
        ///     宿舍号
        /// </summary>
        [ImporterHeader(Name = "宿舍号")]
        [MaxLength(20, ErrorMessage = "宿舍号字数超出最大限制,请修改!")]
        public string DormitoryNo { get; set; }

        /// <summary>
        ///     QQ
        /// </summary>
        [ImporterHeader(Name = "QQ号")]
        [MaxLength(30, ErrorMessage = "QQ号字数超出最大限制,请修改!")]
        public string QQ { get; set; }

        /// <summary>
        ///     民族
        /// </summary>
        [ImporterHeader(Name = "民族")]
        [MaxLength(2, ErrorMessage = "民族字数超出最大限制,请修改!")]
        public string Nation { get; set; }

        /// <summary>
        ///     户口性质
        /// </summary>
        [ImporterHeader(Name = "户口性质")]
        [MaxLength(10, ErrorMessage = "户口性质字数超出最大限制,请修改!")]
        public string HouseholdType { get; set; }

        /// <summary>
        ///     联系电话
        /// </summary>
        [ImporterHeader(Name = "学生联系电话")]
        [MaxLength(20, ErrorMessage = "手机号码字数超出最大限制,请修改!")]
        public string Phone { get; set; }

        /// <summary>
        ///     状态
        ///     测试可为空的枚举类型
        /// </summary>
        [ImporterHeader(Name = "状态")]
        public StudentStatus? Status { get; set; }

        /// <summary>
        ///     备注
        /// </summary>
        [ImporterHeader(Name = "备注")]
        [MaxLength(200, ErrorMessage = "备注字数超出最大限制,请修改!")]
        public string Remark { get; set; }

        /// <summary>
        ///     是否住校(宿舍)
        /// </summary>
        [ImporterHeader(IsIgnore = true)]
        public bool? IsBoarding { get; set; }

        /// <summary>
        ///     所属班级id
        /// </summary>
        [ImporterHeader(IsIgnore = true)]
        public Guid ClassId { get; set; }

        /// <summary>
        ///     学校Id
        /// </summary>
        [ImporterHeader(IsIgnore = true)]
        public Guid? SchoolId { get; set; }

        /// <summary>
        ///     校区Id
        /// </summary>
        [ImporterHeader(IsIgnore = true)]
        public Guid? CampusId { get; set; }

        /// <summary>
        ///     专业Id
        /// </summary>
        [ImporterHeader(IsIgnore = true)]
        public Guid? MajorsId { get; set; }

        /// <summary>
        ///     年级Id
        /// </summary>
        [ImporterHeader(IsIgnore = true)]
        public Guid? GradeId { get; set; }
    }

如上述代码所示,我们定义了以上学生数据Dto,主要注意事项如下:

  • ExcelImporter特性可以设置一些导入的全局设置,比如是否标注错误、导入Sheet名称(如不设置则自动获取第一个)、截止读取的列数、表头位置。
  • 支持常用的数据验证设置,比如必填、最大长度。
  • 支持数据重复校验,比如身份证号码。见ImporterHeader特性的IsAllowRepeat设置。
  • 支持列头设置,将ImporterHeader的Name属性。除此之外,ImporterHeader还支持自动过滤空格(默认启用)、处理掉所有的空格、列索引等。
  • 对数据列启用了忽略设置,见SchoolId的”[ImporterHeader(IsIgnore = true)]”。
  • 使用了值映射,见“Gender”属性。启用值映射之后,将不会从枚举定义中获取值映射。
  • 支持枚举,支持从枚举的Display、Description特性中获取值映射。枚举定义见下文。

  • 性别枚举

定义如下所示:

代码语言:javascript
复制
/// <summary>
///     性别
/// </summary>
public enum Genders
{
    /// <summary>
    ///     男
    /// </summary>
    Man = 0,

    /// <summary>
    ///     女
    /// </summary>
    Female = 1
}

注意上文中的第7点。

  • 学生状态枚举
代码语言:javascript
复制
///// <summary>
///     学生状态 正常、流失、休学、勤工俭学、顶岗实习、毕业、参军
/// </summary>
public enum StudentStatus
{
    /// <summary>
    ///     正常
    /// </summary>
    [Display(Name = "正常")] Normal = 0,

    /// <summary>
    ///     流失
    /// </summary>
    [Description("流水")] PupilsAway = 1,

    /// <summary>
    ///     休学
    /// </summary>
    [Display(Name = "休学")] Suspension = 2,

    /// <summary>
    ///     勤工俭学
    /// </summary>
    [Display(Name = "勤工俭学")] WorkStudy = 3,

    /// <summary>
    ///     顶岗实习
    /// </summary>
    [Display(Name = "顶岗实习")] PostPractice = 4,

    /// <summary>
    ///     毕业
    /// </summary>
    [Display(Name = "毕业")] Graduation = 5,

    /// <summary>
    ///     参军
    /// </summary>
    [Display(Name = "参军")] JoinTheArmy = 6
}

注意上文中的第7点。

3.生成导入模板并填充数据

导入之前是不是得准备一份模板?对于我们,手写模板?这是不存在的。Magicodes.IE.Excel封装了根据DTO自动生成Excel导入模板的方法,我们可以直接调用。这里我们来看下导入的相关方法:

代码语言:javascript
复制
/// <summary>
///     导入
/// </summary>
public interface IImporter
{
    /// <summary>
    ///     生成Excel导入模板
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    Task<TemplateFileInfo> GenerateTemplate<T>(string fileName) where T : class, new();

    /// <summary>
    ///     生成Excel导入模板
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns>二进制字节</returns>
    Task<byte[]> GenerateTemplateBytes<T>() where T : class, new();

    /// <summary>
    ///     导入模型验证数据
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="filePath"></param>
    /// <returns></returns>
    Task<ImportResult<T>> Import<T>(string filePath) where T : class, new();
}

通过以上方法中的GenerateTemplate,我们可以得到需要的导入模板。具体使用可以参考以下单元测试:

代码语言:javascript
复制
  public IImporter Importer = new ExcelImporter();

    [Fact(DisplayName = "生成学生数据导入模板(测试枚举生成模板)")]
    public async Task GenerateStudentImportTemplate_Test()
    {
        var filePath = Path.Combine(Directory.GetCurrentDirectory(),
            nameof(GenerateStudentImportTemplate_Test) + ".xlsx");
        if (File.Exists(filePath)) File.Delete(filePath);

        var result = await Importer.GenerateTemplate<ImportStudentDto>(filePath);
        result.ShouldNotBeNull();
        File.Exists(filePath).ShouldBeTrue();

        //TODO:读取Excel检查表头和格式
    }

以上DTO获取模板并填充数据后如下图所示:

Excel导入模板

注意:枚举会自动生成下拉选择,必填项列头会标红。

4.获取学生导入验证错误和数据

根据模板填充数据后,我们就可以进行数据导入了。通常情况下,我们有以下步骤:

  • 验证导入数据

通过Magicodes.IE.Excel导入数据会自动进行验证,并且输出验证结果,以便于前台显示。具体我们可以通过其导入的结果类来了解:

代码语言:javascript
复制
/// <summary>
///     导入结果
/// </summary>
public class ImportResult<T> where T : class
{
    /// <summary>
    /// </summary>
    public ImportResult()
{
        RowErrors = new List<DataRowErrorInfo>();
    }

    /// <summary>
    ///     导入数据
    /// </summary>
    public virtual ICollection<T> Data { get; set; }

    /// <summary>
    ///     验证错误
    /// </summary>
    public virtual IList<DataRowErrorInfo> RowErrors { get; set; }

    /// <summary>
    ///     模板错误
    /// </summary>
    public virtual IList<TemplateErrorInfo> TemplateErrors { get; set; }

    /// <summary>
    ///     导入异常信息
    /// </summary>
    public virtual Exception Exception { get; set; }

    /// <summary>
    ///     是否存在导入错误
    /// </summary>
    public virtual bool HasError => Exception != null ||
                                    (TemplateErrors?.Count(p => p.ErrorLevel == ErrorLevels.Error) ?? 0) > 0 ||
                                    (RowErrors?.Count ?? 0) > 0;
}

其中,

  • Data为数据结果
  • RowErrors为验证错误,比如必填、重复验证、文本长度等等。会给出行号、字段以及字段错误集合
  • 数据错误
  • TemplateErrors为模板错误,比如必填列缺失等错误信息。支持错误等级(警告、错误)
  • Exception为导入异常信息
  • HasError为是否存在错误(不包含警告)
  • 通过ImportResult,我们就可以很方便的拿到导入验证错误而无须额外编写代码。通常在导入时我们需要判断HasError属性并给前台返回具体的错误结果。
  • 数据导入参考代码如下所示:
  • [Fact(DisplayName = "学生基础数据导入")] public async Task StudentInfoImporter_Test() { var filePath = Path.Combine(Directory.GetCurrentDirectory(), "TestFiles", "Import", "学生基础数据导入.xlsx"); var import = await Importer.Import<ImportStudentDto>(filePath); import.ShouldNotBeNull(); if (import.Exception != null) _testOutputHelper.WriteLine(import.Exception.ToString()); if (import.RowErrors.Count > 0) _testOutputHelper.WriteLine(JsonConvert.SerializeObject(import.RowErrors)); import.HasError.ShouldBeFalse(); import.Data.ShouldNotBeNull(); import.Data.Count.ShouldBe(16); }
  • 获取验证标注

客户说虽然你提示了,但是我还是不知道哪里错了!!怎么办?!!

我们贴心的为你准备了导入数据的Excel文件的标注:

数据错误标注

多个错误

如何开启这个【史诗剧情】呢?仅需:

代码语言:javascript
复制
[ExcelImporter(IsLabelingError = true)]

开启后,我们将自动保存“{目标文件名称}_.xlsx”的标注文件到目标位置。

  • 获取导入数据

没有错误了?也就是HasError为false,那么我们就可以直接拿到Data为所欲为了!

最后

整个学生数据的导入教程就此结束了。相关库会一直更新,在功能体验上有可能会和本文教程有细微的出入,请以相关具体代码、版本日志、单元测试示例为准。

转载是一种动力 分享是一种美德

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-11-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 麦扣聊技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 基础教程之导入学生数据
  • 说明
    • 2.创建导入Dto
      • 3.生成导入模板并填充数据
        • 4.获取学生导入验证错误和数据
          • 最后
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档