前言

时间过得好快,在之前升级到3.0之后,就感觉好久没再动过啥东西了,之前有问到Swagger的中文汉化,虽说我觉得这种操作的意义不是太大,也是多少鼓捣了下,其实个人感觉就是元素内容替换,既然可以执行js了那不就是网页上随便搞了,所以就没往下再折腾,但是现在需要用到Excel的操作了,那就不得不提起这个NPOI了。

NPOI

在之前.net framework的时候,工程需要用到Excel的导入导出,当然用这个NPOI是偶然,也就是找了下这个看着可以就用了,之后遇到的各种问题也都找资料解决,什么多行合并啊,打开2007版本错误啊之类的,但是不得不说,用着还挺好,所以既然net core需要了,那就看看呗,刚好也是支持的。

Util我们来引入这个类库NPOI

  • 导入

在使用之前,我们先缕一下获取Excel数据需要哪些准备操作。

  1. 获取文件(这个就不多说)
  2. 获取sheet信息(考虑有可能多sheet操作)
  3. 根据sheet获取对应文件信息(多少行,当然有些还有合并)
  4. 根据合并行来判断第一行是否为标题
  5. 判断哪一行是列名(用于对应数据)
  6. 遍历每一行并根据每一行的数据格式来获取(有可能是公式/日期/数字/普通文本等等)

ok,大致上清楚了之后,我们就一步步来看吧,这里我创建一个ExcelUtil,来写第一个方法(这里只做说明展示吧)。

	public class ExcelUtil
{
/// <summary>
/// 读取Excel多Sheet数据
/// </summary>
/// <param name="filePath">文件路径</param>
/// <param name="sheetName">Sheet名</param>
/// <returns></returns>
public static DataSet ReadExcelToDataSet(string filePath, string sheetName = null)
{
if (!File.Exists(filePath))
{
LogUtil.Debug($"未找到文件{filePath}");
return null;
}
//获取文件信息
FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
IWorkbook workbook = WorkbookFactory.Create(fs);
//获取sheet信息
ISheet sheet = null;
DataSet ds = new DataSet();
if (!string.IsNullOrEmpty(sheetName))
{
sheet = workbook.GetSheet(sheetName);
if (sheet == null)
{
LogUtil.Debug($"{filePath}未找到sheet:{sheetName}");
return null;
}
DataTable dt = ReadExcelFunc(workbook, sheet);
ds.Tables.Add(dt);
}
else
{
//遍历获取所有数据
int sheetCount = workbook.NumberOfSheets;
for (int i = 0; i < sheetCount; i++) {
sheet = workbook.GetSheetAt(i);
if (sheet != null)
{
DataTable dt = ReadExcelFunc(workbook, sheet);
ds.Tables.Add(dt);
}
}
}
return ds;
} /// <summary>
/// 读取Excel信息
/// </summary>
/// <param name="workbook">工作区</param>
/// <param name="sheet">sheet</param>
/// <returns></returns>
private static DataTable ReadExcelFunc(IWorkbook workbook, ISheet sheet)
{
DataTable dt = new DataTable();
//获取列信息
IRow cells = sheet.GetRow(sheet.FirstRowNum);
int cellsCount = cells.PhysicalNumberOfCells;
int emptyCount = 0;
int cellIndex = sheet.FirstRowNum;
List<string> listColumns = new List<string>();
bool isFindColumn = false;
while (!isFindColumn)
{
emptyCount = 0;
listColumns.Clear();
for (int i = 0; i < cellsCount; i++)
{
if (string.IsNullOrEmpty(cells.GetCell(i).StringCellValue))
{
emptyCount++;
}
listColumns.Add(cells.GetCell(i).StringCellValue);
}
//这里根据逻辑需要,空列超过多少判断
if (emptyCount == 0)
{
isFindColumn = true;
}
cellIndex++;
cells = sheet.GetRow(cellIndex);
} foreach (string columnName in listColumns)
{
if (dt.Columns.Contains(columnName))
{
//如果允许有重复列名,自己做处理
continue;
}
dt.Columns.Add(columnName, typeof(string));
}
//开始获取数据
int rowsCount = sheet.PhysicalNumberOfRows;
cellIndex += 1;
DataRow dr = null;
for (int i = cellIndex; i < rowsCount; i++) {
cells = sheet.GetRow(i);
dr = dt.NewRow();
for (int j = 0; j < dt.Columns.Count; j++)
{
//这里可以判断数据类型
switch (cells.GetCell(j).CellType)
{
case CellType.String:
dr[j] = cells.GetCell(j).StringCellValue;
break;
case CellType.Numeric:
dr[j] = cells.GetCell(j).NumericCellValue.ToString();
break;
case CellType.Unknown:
dr[j] = cells.GetCell(j).StringCellValue;
break;
}
}
dt.Rows.Add(dr);
}
return dt;
}
}

文件的导入操作就不再演示了,之前有文件上传的相关操作方法net core WebApi——文件分片上传与跨域请求处理

导入的处理这里也只是大致演示下,具体需要的东西包括情况可能会比较复杂,但是终归数据还是那些,只是操作方法不同罢了(别说什么骚操作)。

  • 导出

相对于导入,导出的流程就比较简单了。

  1. 获取数据信息(sql或文件)
  2. 组成数据集合(List或DataTable)
  3. 创建sheet
  4. 设置相关样式等等
  5. 遍历赋值row
  6. 导出文件流

了解完,我们就继续来搞吧。

		/// <summary>
/// 导出Excel文件
/// </summary>
/// <typeparam name="T">数据类型</typeparam>
/// <param name="entities">数据实体</param>
/// <param name="dicColumns">列对应关系,如Name->姓名</param>
/// <param name="title">标题</param>
/// <returns></returns>
public static byte[] ExportExcel<T>(List<T> entities,Dictionary<string,string> dicColumns, string title = null)
{
if (entities.Count <= 0)
{
return null;
}
//HSSFWorkbook => xls
//XSSFWorkbook => xlsx
IWorkbook workbook = new XSSFWorkbook();
ISheet sheet = workbook.CreateSheet("test");//名称自定义
IRow cellsColumn = null;
IRow cellsData = null;
//获取实体属性名
PropertyInfo[] properties = entities[0].GetType().GetProperties();
int cellsIndex = 0;
//标题
if (!string.IsNullOrEmpty(title))
{
ICellStyle style = workbook.CreateCellStyle();
//边框
style.BorderBottom = BorderStyle.Dotted;
style.BorderLeft = BorderStyle.Hair;
style.BorderRight = BorderStyle.Hair;
style.BorderTop = BorderStyle.Dotted;
//水平对齐
style.Alignment = HorizontalAlignment.Left; //垂直对齐
style.VerticalAlignment = VerticalAlignment.Center; //设置字体
IFont font = workbook.CreateFont();
font.FontHeightInPoints = 10;
font.FontName = "微软雅黑";
style.SetFont(font); IRow cellsTitle = sheet.CreateRow(0);
cellsTitle.CreateCell(0).SetCellValue(title);
cellsTitle.RowStyle = style;
//合并单元格
sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(0, 1, 0, dicColumns.Count - 1));
cellsIndex = 2;
}
//列名
cellsColumn = sheet.CreateRow(cellsIndex);
int index = 0;
Dictionary<string, int> columns = new Dictionary<string, int>();
foreach (var item in dicColumns)
{
cellsColumn.CreateCell(index).SetCellValue(item.Value);
columns.Add(item.Value, index);
index++;
}
cellsIndex += 1;
//数据
foreach (var item in entities)
{
cellsData = sheet.CreateRow(cellsIndex);
for (int i = 0; i < properties.Length; i++)
{
if (!dicColumns.ContainsKey(properties[i].Name)) continue;
//这里可以也根据数据类型做不同的赋值,也可以根据不同的格式参考上面的ICellStyle设置不同的样式
object[] entityValues = new object[properties.Length];
entityValues[i] = properties[i].GetValue(item);
//获取对应列下标
index = columns[dicColumns[properties[i].Name]];
cellsData.CreateCell(index).SetCellValue(entityValues[i].ToString());
}
cellsIndex++;
} byte[] buffer = null;
using (MemoryStream ms = new MemoryStream())
{
workbook.Write(ms);
buffer = ms.GetBuffer();
ms.Close();
} return buffer;
}

测试

写完,免不了一通测试,这里不多说了,直接上图。

导入这里前面也说了没做界面上传什么的,就是一个文件路径,直接执行,Excel原文件我也会同步上传到代码仓库。

导出的话,这里也是用Swagger神器来测试。

数据库数据如下图。

带标题导出。

小结

最近真的是有点儿忙,一直在鼓捣opengl这类图形化的东西,各种矩阵转换模型转换,要么是用c++,qt写opengl,要么是用threejs搞opengl,唉,整的最近也只能是晚上回去摸索会儿net core,工作总是不那么尽如人意,但是身为程序猿的我们,不都是不断的摸索前进么?我们可以不会,但那不是我们不整的借口。

net core WebApi——使用NPOI导入导出操作的更多相关文章

  1. c# .Net :Excel NPOI导入导出操作教程之读取Excel文件信息及输出

    c# .Net :Excel NPOI导入导出操作教程之读取Excel文件信息及输出 using NPOI.HSSF.UserModel;using NPOI.SS.UserModel;using S ...

  2. c# .Net :Excel NPOI导入导出操作教程之List集合的数据写到一个Excel文件并导出

    将List集合的数据写到一个Excel文件并导出示例: using NPOI.HSSF.UserModel;using NPOI.SS.UserModel;using System;using Sys ...

  3. c# .Net :Excel NPOI导入导出操作教程之数据库表信息数据导出到一个Excel文件并写到磁盘示例分享

      string sql = @"select * from T_Excel"; ----------------DataTable Star----------------    ...

  4. C# .Net :Excel NPOI导入导出操作教程之将Excel文件读取并写到数据库表,示例分享

    using (FileStream fileReader = File.OpenRead(@"C:\Users\Administrator\Desktop\112.xls"))   ...

  5. .Net core NPOI导入导出Excel

    最近在想.net core NPOI 导入导出Excel,一开始感觉挺简单的,后来真的遇到很多坑.所以还是写一篇博客让其他人少走一些弯路,也方便忘记了再重温一遍.好了,多的不说,直接开始吧. 在.Ne ...

  6. NPOI导入导出Excel

    .net mvc利用NPOI导入导出excel 注意:如何导出的提交方式ajax导出是失效的! 解决方案是:js处理l两个表单的提交  代码:  第一步. 在页面里面加入2个隐藏的iframe, 如下 ...

  7. NPOI导入导出EXCEL通用类,供参考,可直接使用在WinForm项目中

    以下是NPOI导入导出EXCEL通用类,是在别人的代码上进行优化的,兼容xls与xlsx文件格式,供参考,可直接使用在WinForm项目中,由于XSSFWorkbook类型的Write方法限制,Wri ...

  8. Winform开发框架之通用数据导入导出操作的事务性操作完善

    1.通用数据导入导出操作模块回顾 在我的Winfrom开发框架里面,有一个通用的导入模块,它在默默处理这把规范的Excel数据导入到不同的对象表里面,一直用它来快速完成数据导入的工作.很早在随笔< ...

  9. 循序渐进开发WinForm项目(5)--Excel数据的导入导出操作

    随笔背景:在很多时候,很多入门不久的朋友都会问我:我是从其他语言转到C#开发的,有没有一些基础性的资料给我们学习学习呢,你的框架感觉一下太大了,希望有个循序渐进的教程或者视频来学习就好了. 其实也许我 ...

随机推荐

  1. 初步认识JWT

    前言: 现在越来越多的项目或多或少会用到JWT,为什么会出现使用JWT这样的场景的呢? 假设现在有一个APP,后台是分布式系统.APP的首页模块部署在上海机房的服务器上,子页面模块部署在深圳机房的服务 ...

  2. 在VMware中就显示lo回环IP:127.0.0.1的解决办法。

    在VMware时由于某些原因导致,在使用ifconfig只会显示lo,不显示其他的东西 步骤:1.sudo lshw -numeric -class network 2.sudo route -nv ...

  3. VS中一些提高编码效率的快捷键

    场景 新手入门,看见大神们在VS中只用键盘就可以完成一系列操作. 整理一些常用的能提高效率的快捷键. 关注公众号霸道的程序猿获取编程相关电子书.教程推送与免费下载. 大量编程视频教程:https:// ...

  4. HttpClient远程接口调用-实名认证

    1.HttpClient远程接口调用 1)用户注册 注册按钮button提交表单时,要return false form表单 <!-- action="http://localhost ...

  5. Asp.Net Core2.2 源码阅读系列——控制台日志源码解析

      为了让我们第一时间知道程序的运行状态,Asp.Net Core 添加了默认的日志输出服务.这看起来并没有什么问题,对于开发人员也相当友好,但如果不了解日志输出的细节,也有可能因为错误的日志级别配置 ...

  6. 脱离脚手架来配置、学习 webpack4.x (二)基础搭建loader 配置 css、scss

    序 上一篇已经把基本架子搭起来了,现在来增加css.scss.自动生成html.css 提前等方面的打包.webpack 默认只能处理js模块,所以其他文件类型需要做下转换,而loader 恰恰是做这 ...

  7. java枚举的应用

    最近的项目中,看前辈们用到的枚举比较多,由于自己之前对枚举这种类型不是很了解,遂花费心机看了下,整理记录下. 1.枚举常量 系统中定义的状态字段,用的比较多: public enum orderTyp ...

  8. java数据结构——二叉树(BinaryTree)

    前面我们已经学习了一些线性结构的数据结构和算法,接下来我们开始学习非线性结构的内容. 二叉树 前面显示增.删.查.遍历方法,完整代码在最后面. /** * 为什么我们要学习树结构. * 1.有序数组插 ...

  9. elasticsearch的分布式基础概念(1)

    Elasticsearch对复杂分布式机制的透明隐藏特性 Elasticsearch是一套分布式的系统,分布式是为了应对大数据量 隐藏了复杂的分布式机制 分片机制(随随便便就将一些document插入 ...

  10. 记一次Burp Suite的使用实例

       下载完的Bur是这样的,双击jar即可 最右边的键一直按,傻瓜式         先将要抓包的网页打开,此次以上传图片为例     第一步当然是先下载Burp Suite之后打开,查看设置代理地 ...