专栏首页bluesummer基于NPOI的Excel导入导出类库

基于NPOI的Excel导入导出类库

概述

支持多sheet导入导出。导出字段过滤,合并行。特性配置导入验证,非空验证,唯一验证,错误标注等

用于基础配置和普通报表的导入导出,对于复杂需求,比如公式,导出图片等暂不支持

GitHub地址:

https://github.com/Mike-Zrw/ExcelHelper/tree/master

导出配置支持

  • HeaderStyleAttribute :列名样式,(颜色,字体,大小,加粗,对齐)
  • StringFormatterAttribute :格式化时间
  • ColumnWidthAttribute: 列宽,默认自适应,可通过这个特性配置最小列宽和最大列宽
  • RowMergedAttribute: 合并行,需要配合ExportPrimaryKey使用
  • ExportTitle:导出标题,标题可选,可设置居中,颜色字体等。
  • SheetName sheetName不设置默认为sheet1,sheet2等
  • FilterColumn :导出指定列。可根据选中的列名或者属性名导出指定的列

导入配置支持

  • ColumnRegexAttribute:正则判断,正则表达式判断单元格内容
  • ColumnRequiredAttribute:非空判断,对于不可为空的类型即使没有设置该特性,仍会进行非空判断,所以如果一个可以为空的int类型,请设置字段类型为int?
  • ColumnUniqueAttribute:唯一判断,若不加此特性,默认对所有列进行重复验证,可选择性的加在某几列上组合验证。通过ImportSheetNeedUniqueValidation可配置是否开启重复验证,UniqueValidationPrompt设置重复时的提示
  • ImportSheet.ValidateHandler : 业务逻辑判断,业务逻辑判断在所有判断之后执行,可以通过IsValidated属性判断该行是否通过了其他验证,SetError()用来追加单元格的错误提示
  • HeaderRowIndex:列名所在行
  • ImportBook.DataErrorForegroundColor: 错误前景色(红)
  • ImportBook.RepeatedErrorForegroundColor: 重复前景色(黄)
  • ImportBook.DefaultForegroundColor: 默认前景色(白),在验证未通过时,颜色处于错误或重复但验证通过的单元格颜色将重置为默认前景色。(即第一次导入错误,修改之后第二次部分导入正确,则正确的颜色会便会默认前景色)

导入结果说明

  • ImportSuccess :是否导入成功
  • GetSummaryErrorMessage() : excel中的所有错误文字展示
  • GetNotDisplayErrorMessage(): 无法在excel中标注的错误信息,比如sheet格式不正确,excel格式不正确等
  • outPutStream: 错误的单元格添加样式及标注输出到文件流中。如果不需要输出excel流,该参数可不传。

导出示例

 		var students = new List<ExportStudent>();
        var grades = new List<ExportGrade>();
        var schools = new List<ExportSchool>();
        for (int i = 0; i < 100; i++)
        {
            students.Add(new ExportStudent
            {
                Name = i % 6 == 1 ? null : ($"name{i}"),
                Age = i,
                Phone = i % 8 == 1 ? "adsf123" : $"{1}{new Random().Next(100, 999)}{1}{new Random().Next(100, 999)}{2}{new Random().Next(0, 9)}{3}",
                Birthday = i % 13 == 1 ? default(DateTime?) : DateTime.Now.AddDays(i),
                Money = Math.Round(new Random(i).NextDouble(), 2),
                SchoolDate = DateTime.Now.AddDays(i + 1),
            });
            grades.Add(new ExportGrade { Code = $"编码{i}", GradeName = $"{i}年级" });
            schools.Add(new ExportSchool { Name = $"{i}号学校", Address = $"学校地址{i}", Price = Math.Round(new Random().NextDouble(), 2) });
        }
        var exporter = new DefaultExcelExporter();

        var stream = new FileStream("D://export.xlsx", FileMode.Create, FileAccess.Write);
        //var stream = new MemoryStream();
        exporter.Export(new ExportBook()
        {
            Ext =ExtEnum.XLSX,
            Sheets = new List<ExportSheet> {
            new ExportSheet(){  SheetName="测试", Data=students},
            new ExportSheet(){   Data=grades},
            new ExportSheet(){   Data=schools,Title=new  ExportTitle("学校列表",true,18,default,Excel.Enums.HorizontalAlignEnum.Center),  FilterColumn=new List<string>(){ "学校名称","price" } },
            }
        }, stream);

        stream.Dispose();
		
		public class ExportStudent : ExportModel
        {
            [ColumnNameAttribute("名字")]
            public string Name { get; set; }
            [ColumnNameAttribute("年龄")]
            public int Age { get; set; }

            [ColumnNameAttribute("生日")]
            [StringFormatter("yyyy-MM-dd HH:mm:ss")]
            public DateTime? Birthday { get; set; }

            [ColumnStyle(FontName = "华文彩云")]
            [ColumnNameAttribute("入学时间")]
            [StringFormatter("yyyy-MM-dd")]
            public DateTime SchoolDate { get; set; }

            [ColumnStyle(FontColor = 211, IsBold = true)]
            [ColumnNameAttribute("零花钱")]
            public double Money { get; set; }

            [ColumnNameAttribute("电话")]
            public string Phone { get; set; }
        }

合并行导出示例

  public void ExportMergeRow()
    {
        var orders = new List<Order>();
        for (int i = 0; i < 100; i++)
        {
            var index = new Random(i).Next(i + 10, i + 13);
            var orderNumber = $"订单{index}";
            orders.Add(new Order()
            {
                Buyer = $"下单人{index}",
                Price = Math.Round(new Random(i).NextDouble(), 2),
                BuyQty = new Random(i).Next(1, 10),
                ProductName = $"商品{i}",
                OrderNumber = orderNumber,
                OrderNum2 = orderNumber,
                ExportPrimaryKey = orderNumber
            });
        }
        var exporter = new DefaultExcelExporter();

        var stream = new FileStream("D://exportorder.xlsx", FileMode.Create, FileAccess.Write);
        exporter.Export(new ExportBook()
        {
            Ext = ExtEnum.XLSX,
            Sheets = new List<ExportSheet> { new ExportSheet() { SheetName = "订单列表", Data = orders } }
        }, stream);

        stream.Dispose();
    }

导入示例

		var sheet1 = new ImportSheet<ImportStudent>
        {
            UniqueValidationPrompt = "零花钱不可重复",
            HeaderRowIndex = 0,
            SheetIndex = 0,
            ValidateHandler = (list) =>
            {
                foreach (ImportStudent model in list)
                {
                    if (model.IsValidated && model.Name == "name0")
                        model.SetError(nameof(model.Name), "名字不可为0");
                    if (model.IsValidated && model.Money < 0.5)
                        model.SetError(nameof(model.Money), "零花钱不可小于0.5");
                }
            }
        };
        var sheet2 = new ImportSheet<ImportGrade>
        {
            HeaderRowIndex = 0,
            SheetIndex = 1
        };
        var sheet3 = new ImportSheet<ImportSchool>
        {
            HeaderRowIndex = 1,
            SheetIndex = 2,
            ValidateHandler = (list) =>
            {

                foreach (var model in list)
                {
                    if (model.Price > 0.5)
                        model.SetError(nameof(model.Price), "学费不可大于0.5");
                }
            }
        };
        var import = new DefaultExcelImporter();
        using var inputStrem = new FileStream("D://export.xlsx", FileMode.OpenOrCreate, FileAccess.Read);
        using var outStrem = new FileStream("D://error.xlsx", FileMode.Create, FileAccess.Write);
        var bookmodel = new ImportBook();
        bookmodel.SetSheetModels(sheet1, sheet2, sheet3);
        var ret = import.ImportExcel(inputStrem, ExtEnum.XLSX, bookmodel, outStrem);
        var success = ret.ImportSuccess;
        var summaryErrorMsg = ret.GetSummaryErrorMessage();
        var notDisplayMsg = ret.GetNotDisplayErrorMessage();
        Output.WriteLine($"success:{success}");
        Output.WriteLine("summaryErrorMsg------------");
        Output.WriteLine(summaryErrorMsg);
        Output.WriteLine("notDisplayMsg------------");
        Output.WriteLine(notDisplayMsg);

		public class ImportStudent : ImportModel
	    {
	        [ColumnRequired("名字必填")]
	        [ColumnNameAttribute("名字")]
	        public string Name { get; set; }
	        [ColumnNameAttribute("年龄")]
	        public int Age { get; set; }
	
	        [ColumnRequired]
	        [ColumnNameAttribute("生日")]
	        public DateTime Birthday { get; set; }
	
	        [ColumnNameAttribute("入学时间")]
	        public DateTime SchoolDate { get; set; }
	
	        [ColumnUnique]
	        [ColumnNameAttribute("零花钱")]
	        public double Money { get; set; }
	
	        [ColumnNameAttribute("电话")]
	        [ColumnRegex(@"^[1]+[1-9]+\d{9}$", "电话格式不对")]
	        public string Phone { get; set; }
	    }

导出结果展示:

导入结果展示:

测试输出

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • IdentityServer4 手动验签及日志记录

    IdentityServer4的基础知识和使用方式网上有很多特别优秀的文章,如果有对其不了解的推荐阅读一下下面的两篇文章

    蓝夏
  • Windows下docker的安装,将ASP.NET Core程序部署在docker中

    参考文章: https://www.cnblogs.com/jRoger/p/aspnet-core-deploy-to-docker.html https...

    蓝夏
  • 利用Zookeeper实现分布式锁及服务注册中心

    对于Zookeeper的定义以及原理,网上已经有很多的优秀文章对其进行了详细的介绍,所以本文不再进行这方面的阐述。 本文主要介绍一些基本的准备工作以及zooke...

    蓝夏
  • Storm与Redis集成

    Storm-redis 提供了基本的 Bolt 实现:RedisLookupBolt,RedisStoreBolt 以及 RedisFilterBolt。

    smartsi
  • Flutter实现底部导航

    本文实例为大家分享了Flutter实现底部导航的具体代码,供大家参考,具体内容如下

    砸漏
  • Flash/Flex学习笔记(32):播放音乐并同步显示lyc歌词(适用于Silverlight)

    题外话:个别朋友总是问我同样的问题,做为一名c#/silverlight程序员为啥还要学flash ? 回 答:看日本片时,就不能对照看欧美的么? 不体会日本的...

    菩提树下的杨过
  • C#new关键字用法

    new 嘛 实例化一个类。 比如有一个类叫汽车。你现在想在程序中买一辆,所以你用new来买了一辆汽车,这辆车你得给你找个名字,比如宝马。呵呵所以就成 汽车...

    vv彭
  • task Scheduler

    在业务复杂的应用程序中,有时候会要求一个或者多个任务在一定的时间或者一定的时间间隔内计划进行,比如定时备份或同步数据库,定时发送电子邮件等,我们称之为计划任务。...

    阿新
  • RPC编程

    RPC全称Remote Procedure Call,即远程方法调用。它的表现形式是:

    小蜜蜂
  • 一篇文章入门Netty

    什么是Netty?Netty是一个框架。或者说是一个工具集。封装了网络编程方面java的API。

    爬蜥

扫码关注云+社区

领取腾讯云代金券