基于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

  • [x] 无参导出
  • [ ] 合并相同的导入配置
  • [ ] 考虑添加错误处理
  • [ ] 测试性能问题
  • [ ] 根据配置生成导入导出配置
    • 根据泛型的属性生成配置
    • 根据attribute生成配置
    • 可以可存入一般关系型数据库的数据生成配置

基于EPPlus和NPOI实现的Excel导入导出的更多相关文章

  1. 基于 POI 封装 ExcelUtil 精简的 Excel 导入导出

    注 本文是使用 org.apache.poi 进行一次简单的封装,适用于大部分 excel 导入导出功能.过程中可能会用到反射,如若有对于性能有极致强迫症的同学,看看就好. 序 由于 poi 本身只是 ...

  2. 【NPOI】.NET EXCEL导入导出开发包

    1.导出 //工作簿HSSFWorkbook HSSFWorkbook hssfworkbook = new HSSFWorkbook(); //ISheet页 ISheet sheet1 = hss ...

  3. 一个基于POI的通用excel导入导出工具类的简单实现及使用方法

    前言: 最近PM来了一个需求,简单来说就是在录入数据时一条一条插入到系统显得非常麻烦,让我实现一个直接通过excel导入的方法一次性录入所有数据.网上关于excel导入导出的例子很多,但大多相互借鉴. ...

  4. Excel导入导出帮助类

    /// <summary>    /// Excel导入导出帮助类    /// 记得引入 NPOI    /// 下载地址   http://npoi.codeplex.com/rele ...

  5. Mego(04) - NET简单实现EXCEL导入导出

    前言 相信做过信息系统的朋友都会遇到EXCEL导入导出的相关开发,做过不少EXCEL导入导出后总结起来大致有如下几种方式实现: ADO.NET的OldDb或ODBC连接EXCEL使用DataTable ...

  6. 土制Excel导入导出及相关问题探讨

    转载请注明出处https://www.cnblogs.com/funnyzpc/p/10392085.html 新的一年,又一个开始,不见收获,却见年龄,好一个猪年,待我先来一首里尔克的诗: < ...

  7. 利用反射实现通用的excel导入导出

    如果一个项目中存在多种信息的导入导出,为了简化代码,就需要用反射实现通用的excel导入导出 实例代码如下: 1.创建一个 Book类,并编写set和get方法 package com.bean; p ...

  8. Excel导入导出的业务进化场景及组件化的设计方案(上)

    1:前言 看过我文章的网友们都知道,通常前言都是我用来打酱油扯点闲情的. 自从写了上面一篇文章之后,领导就找我谈话了,怕我有什么想不开. 所以上一篇的(下)篇,目前先不出来了,哪天我异地二次回忆的时候 ...

  9. 关于Excel导入导出的用例设计

    目前,为方便操作,很多系统都会增加批量导入导出的功能.文件导入导出一般格式都是excel.由于用户直接在excel在填写内容,无法控制填写的格 式,加上excel解析比较困难,所以一般涉及到excel ...

随机推荐

  1. RabbitMQ 3.9.7 镜像模式集群与Springboot 2.5.5 整合

    1. 概述 老话说的好:做人要懂得变通,善于思考,有时稍微转个弯,也许问题就解决了. 言归正传,之前我们聊了 RabbitMQ 3.9.7 镜像模式集群的搭建,今天我们来聊聊 RabbitMQ 3.9 ...

  2. 国庆七天假 不如来学学Vue-Router

    Vue-Router 基本介绍 Vue-Router是Vue全家桶中至关重要的一个扩展化插件,使用它能够让我们的组件切换更加的方便,更加容易的开发前后端分离项目,目前Vue-Router版本已更新到4 ...

  3. JVM 面试题,安排上了!!!

    肝了一篇非常硬核的 JVM 基础总结,写作不易,小伙伴们赶紧点赞.转发安排起来! 原文链接 据说看完这篇 JVM 要一小时 JVM 的主要作用是什么? JVM 就是 Java Virtual Mach ...

  4. 升级了 Windows 11 正式版,有坑吗?

    今天磊哥去公司上班,惊喜的发现 Windows 提示更新了,并且是 Windows 11 正式版,这太让人开心了,二话不说"先升为敬". ​ 下载更新 下载完咱就重启更新呗. Wi ...

  5. Elasticsearch 存储成本省 60%,稿定科技干货分享

    背景 稿定科技旗下稿定设计产品是一个聚焦商业设计的多场景在线设计平台,打破了软硬件间的技术限制,汇集创意内容与设计工具于一体,为不同场景下的设计需求提供优质的解决方案,满足图片.视频等全类型媒介的设计 ...

  6. dp凸优化/wqs二分学习笔记(洛谷4383 [八省联考2018]林克卡特树lct)

    qwq 安利一个凸优化讲的比较好的博客 https://www.cnblogs.com/Gloid/p/9433783.html 但是他的暴力部分略微有点问题 qwq 我还是详细的讲一下这个题+这个知 ...

  7. 洛谷3195 [HNOI2008]玩具装箱TOY(斜率优化+dp)

    qwq斜率优化好题 第一步还是考虑最朴素的\(dp\) \[dp=dp[j]+(i-j-1+sum[i]-sum[j])^2 \] 设\(f[i]=sum[i]+i\) 那么考虑将上述柿子变成$$dp ...

  8. SpringBoot入门05-全局配置文件

    springboot全局配置文件作用是设置或修改默认设置 springboot全局配置文件有下面两种方式 application.xml配置文件 示例 server.port=8088 server. ...

  9. 【转】简述C和C++的学习历程

    简述C和C++的学习历程(转) --by:肖舸老师总是被同学们问到,如何学习C和C++才不茫然,才不是乱学,想了一下,这里给出一个总的回复. 一家之言,欢迎拍砖哈. 1.可以考虑先学习C. 大多数时候 ...

  10. Java中的函数式编程(五)Java集合框架中的高阶函数

    写在前面 随着Java 8引入了函数式接口和lambda表达式,Java 8中的集合框架(Java Collections Framework, JCF)也增加相应的接口以适应函数式编程.   本文的 ...