zoukankan      html  css  js  c++  java
  • 基于EPPlus和NPOI实现的Excel导入导出

    基于EPPlus和NPOI实现的Excel导入导出

    CollapseNav.Net.Tool.Excel(NuGet地址)

    太长不看

    • 导入
      • excel 文件流将会转为 ExcelTestDto 类型的集合
      • var config = new ReadConfig<ExcelTestDto>()
        .Default(item => item.Field0, "233")
        .Require("Field1", item => item.Field1)
        .Add("Field3", item => item.Field3);
        IEnumerable<ExcelTestDto> data = await config.EPPlusExcelToEntityAsync(excelStream);
        
    • 导出
      • ExcelTestDto 类型的集合将会转为 excel 文件流
      • var config = new ExportConfig<ExcelTestDto>(datas);
        .Add("Field0", item => item.Field0)
        .Add("Field1", item => item.Field1)
        .Add("Field2", item => item.Field2 ? "Male" : "Female")
        .Add("Field3", item => item.Field3);
        Stream stream = await exportConfig.EPPlusExportAsync();
        

    简单的使用方式就是上面那样, 至少在我需要的使用场景下是work的

    NuGet包在上面

    前言

    为了方便自己处理一些有关 excel 的导入导出功能, 所以花了更长时间做了这个包

    主要是我觉得计算各个未知的下标位置, 计算那些 0 1 2 3 4 5 实在是太麻烦

    而且每换一个模板就要再搞一次, 可读性巨差

    我想摆脱这样的地狱, 然后奋力挣扎了几下

    思路可以看一下之前的文章

    本章就讲怎么用这个包

    Excel Data

    使用的表格数据Demo, 暂时只能处理单行表头的简单excel

    Field0 Field1 Field2 Field3
    233 23 Male 233.33
    1122 12 Female 123.23
    233 23 Male 233.33
    1122 12 Female 123.23
    ... ... ... ...

    How To Use

    导入(Import/Read/...)

    我碰到的使用场景中, 一般需要将Excel的数据转为系统中的某个实体

    比如导入一个商品列表Excel,将这个列表转为 Goods 对象, 然后使用现成的 AddRange(IEnumerable<Goods> datas) 方法存到数据库中

    基于以上这种 Excel-->Entitys 的使用场景设计了这一套东西

    性能怎么样我就没测试了, 可能很拉了

    假设我的实体长这样

    public class ExcelTestDto
    {
        public string Field0 { get; set; }
        public int Field1 { get; set; }
        public bool Field2 { get; set; }
        public double Field3 { get; set; }
    }
    

    1.BuildReadConfig

    第一步先创建一个 ReadConfig 作为excel的读取配置

    var config = new ReadConfig<ExcelTestDto>();
    

    这个配置决定了之后将以什么方式读取哪些列

    2.AddCellOptions

    有了 ReadConfig 之后就需要添加具体的配置了

    暂时提供了 Default Require Add 添加对 单个实体字段 的读取设置

    • Default
      • 不依赖表格数据,对 ExcelTestDto 中的属性统一添加默认值
      • config.Default(item => item.Field0, "233");
        
    • Require
      • 被 Require 的单元格不可为空, 否则在读取时会主动抛出异常
      • config.Require("Field1", item => item.Field1);
        
    • Add
      • 普通的添加单元格设置, 相对来说更加灵活一些
      • config.Add("Field3", item => item.Field3)
        

    所有的excel单元格都会被读成 string

    Require Add 都可以使用 Func<string, object> 委托自定义对读取单元格的处理

    由于是委托, 你可以做很多操作, 但比较容易影响性能, 最好不要写复杂的耗时的委托

    config.Add("Field1", item => item.Field1, item =>
    {
        var numCellData = int.Parse(item);
        numCellData += 2333;
        return numCellData;
    });
    

    以上操作都会返回 ReadConfig , 所以 强烈推荐 写成以下的调用

    var config = new ReadConfig<ExcelTestDto>()
    .Default(item => item.Field0, "233")
    .Require("Field1", item => item.Field1)
    .Add("Field3", item => item.Field3)
    ;
    

    同时提供了对应的 DefaultIf RequireIf AddIf 方法, 用来根据不同的条件添加不同的配置

    3.AddInit

    偶尔会有在一行数据读取完之后计算点什么的需求, 比如综合学生的各科成绩打个等第, 所以提供一个 AddInit 方法, 通过传入一个 Func<T, T> 来搞点事情

    config.AddInit(item =>
    {
        item.Field0 += "23333";
        // 一些属性的初始化也可以在这边做,代替 Default 也是可以的
        item.Field2 = false;
        return item;
    });
    

    4.ConvertExcel

    配置完成之后就可以使用 EPPlusExcelToEntityAsync 将对应的excel转为实体集合

    // 如果excel是个文件流
    IEnumerable<ExcelTestDto> data = await config.EPPlusExcelToEntityAsync(excelStream);
    

    除了流, 也支持其他的参数

    • string filepath
      • 简单质朴的物理文件路径, 将直接读取物理路径上的excel文件
    • ExcelPackage pack
      • EPPlusExcelPackage, 一般需要手动创建
    • ExcelWorksheet sheet
      • EPPlusExcelWorksheet, 一般需要手动创建

    导出(Export/...)

    有的时候总是会有人需要把系统里面的列表数据导出成 Excel

    然后像个傻逼一样再导回到系统里面去

    所以相对导入又做了个导出功能, 两者相似度比较高

    1.BuildExportConfig

    建个导出配置 ExportConfig

    // datas 为 ExcelTestDto集合
    var config = new ExportConfig<ExcelTestDto>(datas);
    

    由于导出比较简单粗暴, 所以提供了一个 GenDefaultConfig 可以直接 根据泛型生成 Config (大概不算好用)

    2.AddCellOption

    由于导出比较简单粗暴, 所以就只有一个 AddAddIf 方法添加单元格设置(虽然是两个)

    config
    .Add("Field0", item => item.Field0)
    .Add("Field1", item => item.Field1)
    .Add("Field2", item => item.Field2 ? "Male" : "Female")
    .Add("Field3", item => item.Field3);
    

    3.GenerateExcel

    使用 EPPlusExportAsync 生成 Excel

    // 新版本应该已经支持无参导出为流
    // Stream stream = await exportConfig.EPPlusExportAsync();
    Stream stream = await exportConfig.EPPlusExportAsync(someStream);
    

    方法会返回一个流, 拿到流之后可以去做你们想做的事情...

    也可以传入一个物理路径(string 类型), 这样就会在指定的位置生成excel

    TODO

      • 根据泛型的属性生成配置
      • 根据attribute生成配置
      • 可以可存入一般关系型数据库的数据生成配置
  • 相关阅读:
    如何运行vue项目
    java string型时间转long
    龙果学院dubbo
    百度网盘
    百度网盘资源搜索
    charles安装
    charles抓包
    lr报告分析
    一些缩写意思
    带有事务的进入首页、登录、登出脚本
  • 原文地址:https://www.cnblogs.com/CollapseNav/p/15562501.html
Copyright © 2011-2022 走看看