前言

时间过得好快,在之前升级到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,来写第一个方法(这里只做说明展示吧)。

  1. public class ExcelUtil
  2. {
  3. /// <summary>
  4. /// 读取Excel多Sheet数据
  5. /// </summary>
  6. /// <param name="filePath">文件路径</param>
  7. /// <param name="sheetName">Sheet名</param>
  8. /// <returns></returns>
  9. public static DataSet ReadExcelToDataSet(string filePath, string sheetName = null)
  10. {
  11. if (!File.Exists(filePath))
  12. {
  13. LogUtil.Debug($"未找到文件{filePath}");
  14. return null;
  15. }
  16. //获取文件信息
  17. FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
  18. IWorkbook workbook = WorkbookFactory.Create(fs);
  19. //获取sheet信息
  20. ISheet sheet = null;
  21. DataSet ds = new DataSet();
  22. if (!string.IsNullOrEmpty(sheetName))
  23. {
  24. sheet = workbook.GetSheet(sheetName);
  25. if (sheet == null)
  26. {
  27. LogUtil.Debug($"{filePath}未找到sheet:{sheetName}");
  28. return null;
  29. }
  30. DataTable dt = ReadExcelFunc(workbook, sheet);
  31. ds.Tables.Add(dt);
  32. }
  33. else
  34. {
  35. //遍历获取所有数据
  36. int sheetCount = workbook.NumberOfSheets;
  37. for (int i = 0; i < sheetCount; i++) {
  38. sheet = workbook.GetSheetAt(i);
  39. if (sheet != null)
  40. {
  41. DataTable dt = ReadExcelFunc(workbook, sheet);
  42. ds.Tables.Add(dt);
  43. }
  44. }
  45. }
  46. return ds;
  47. }
  48. /// <summary>
  49. /// 读取Excel信息
  50. /// </summary>
  51. /// <param name="workbook">工作区</param>
  52. /// <param name="sheet">sheet</param>
  53. /// <returns></returns>
  54. private static DataTable ReadExcelFunc(IWorkbook workbook, ISheet sheet)
  55. {
  56. DataTable dt = new DataTable();
  57. //获取列信息
  58. IRow cells = sheet.GetRow(sheet.FirstRowNum);
  59. int cellsCount = cells.PhysicalNumberOfCells;
  60. int emptyCount = 0;
  61. int cellIndex = sheet.FirstRowNum;
  62. List<string> listColumns = new List<string>();
  63. bool isFindColumn = false;
  64. while (!isFindColumn)
  65. {
  66. emptyCount = 0;
  67. listColumns.Clear();
  68. for (int i = 0; i < cellsCount; i++)
  69. {
  70. if (string.IsNullOrEmpty(cells.GetCell(i).StringCellValue))
  71. {
  72. emptyCount++;
  73. }
  74. listColumns.Add(cells.GetCell(i).StringCellValue);
  75. }
  76. //这里根据逻辑需要,空列超过多少判断
  77. if (emptyCount == 0)
  78. {
  79. isFindColumn = true;
  80. }
  81. cellIndex++;
  82. cells = sheet.GetRow(cellIndex);
  83. }
  84. foreach (string columnName in listColumns)
  85. {
  86. if (dt.Columns.Contains(columnName))
  87. {
  88. //如果允许有重复列名,自己做处理
  89. continue;
  90. }
  91. dt.Columns.Add(columnName, typeof(string));
  92. }
  93. //开始获取数据
  94. int rowsCount = sheet.PhysicalNumberOfRows;
  95. cellIndex += 1;
  96. DataRow dr = null;
  97. for (int i = cellIndex; i < rowsCount; i++) {
  98. cells = sheet.GetRow(i);
  99. dr = dt.NewRow();
  100. for (int j = 0; j < dt.Columns.Count; j++)
  101. {
  102. //这里可以判断数据类型
  103. switch (cells.GetCell(j).CellType)
  104. {
  105. case CellType.String:
  106. dr[j] = cells.GetCell(j).StringCellValue;
  107. break;
  108. case CellType.Numeric:
  109. dr[j] = cells.GetCell(j).NumericCellValue.ToString();
  110. break;
  111. case CellType.Unknown:
  112. dr[j] = cells.GetCell(j).StringCellValue;
  113. break;
  114. }
  115. }
  116. dt.Rows.Add(dr);
  117. }
  118. return dt;
  119. }
  120. }

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

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

  • 导出

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

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

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

  1. /// <summary>
  2. /// 导出Excel文件
  3. /// </summary>
  4. /// <typeparam name="T">数据类型</typeparam>
  5. /// <param name="entities">数据实体</param>
  6. /// <param name="dicColumns">列对应关系,如Name->姓名</param>
  7. /// <param name="title">标题</param>
  8. /// <returns></returns>
  9. public static byte[] ExportExcel<T>(List<T> entities,Dictionary<string,string> dicColumns, string title = null)
  10. {
  11. if (entities.Count <= 0)
  12. {
  13. return null;
  14. }
  15. //HSSFWorkbook => xls
  16. //XSSFWorkbook => xlsx
  17. IWorkbook workbook = new XSSFWorkbook();
  18. ISheet sheet = workbook.CreateSheet("test");//名称自定义
  19. IRow cellsColumn = null;
  20. IRow cellsData = null;
  21. //获取实体属性名
  22. PropertyInfo[] properties = entities[0].GetType().GetProperties();
  23. int cellsIndex = 0;
  24. //标题
  25. if (!string.IsNullOrEmpty(title))
  26. {
  27. ICellStyle style = workbook.CreateCellStyle();
  28. //边框
  29. style.BorderBottom = BorderStyle.Dotted;
  30. style.BorderLeft = BorderStyle.Hair;
  31. style.BorderRight = BorderStyle.Hair;
  32. style.BorderTop = BorderStyle.Dotted;
  33. //水平对齐
  34. style.Alignment = HorizontalAlignment.Left;
  35. //垂直对齐
  36. style.VerticalAlignment = VerticalAlignment.Center;
  37. //设置字体
  38. IFont font = workbook.CreateFont();
  39. font.FontHeightInPoints = 10;
  40. font.FontName = "微软雅黑";
  41. style.SetFont(font);
  42. IRow cellsTitle = sheet.CreateRow(0);
  43. cellsTitle.CreateCell(0).SetCellValue(title);
  44. cellsTitle.RowStyle = style;
  45. //合并单元格
  46. sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(0, 1, 0, dicColumns.Count - 1));
  47. cellsIndex = 2;
  48. }
  49. //列名
  50. cellsColumn = sheet.CreateRow(cellsIndex);
  51. int index = 0;
  52. Dictionary<string, int> columns = new Dictionary<string, int>();
  53. foreach (var item in dicColumns)
  54. {
  55. cellsColumn.CreateCell(index).SetCellValue(item.Value);
  56. columns.Add(item.Value, index);
  57. index++;
  58. }
  59. cellsIndex += 1;
  60. //数据
  61. foreach (var item in entities)
  62. {
  63. cellsData = sheet.CreateRow(cellsIndex);
  64. for (int i = 0; i < properties.Length; i++)
  65. {
  66. if (!dicColumns.ContainsKey(properties[i].Name)) continue;
  67. //这里可以也根据数据类型做不同的赋值,也可以根据不同的格式参考上面的ICellStyle设置不同的样式
  68. object[] entityValues = new object[properties.Length];
  69. entityValues[i] = properties[i].GetValue(item);
  70. //获取对应列下标
  71. index = columns[dicColumns[properties[i].Name]];
  72. cellsData.CreateCell(index).SetCellValue(entityValues[i].ToString());
  73. }
  74. cellsIndex++;
  75. }
  76. byte[] buffer = null;
  77. using (MemoryStream ms = new MemoryStream())
  78. {
  79. workbook.Write(ms);
  80. buffer = ms.GetBuffer();
  81. ms.Close();
  82. }
  83. return buffer;
  84. }

测试

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

导入这里前面也说了没做界面上传什么的,就是一个文件路径,直接执行,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. Failed to execute goal on project e3-manager: Could not resolve dependencies for project cn.e3mall:e3-manager:pom:0.0.1-SNAPSHOT: Could not find artifact cn.e3mall:e3-parent:jar:0.0.1-SNAPSHOT

    新建好工程后一定要记得从底层开始clean和install 在启动新建的工程时到最后一步出现了这个问题: Failed to execute goal on project e3-manager-we ...

  2. 【原创】我们还需要学jQuery吗?

    引言 最近撸Vue的项目,感觉的有点心累.恰巧近日,有读者来信,就是想咨询一下 烟哥,现在还有必要学习jQuery么? 我明白,现在MVVM框架逐渐占据了主要市场,很多老项目也逐渐的从jQuery转向 ...

  3. soap get/post请求

    pom.xml依赖: <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactI ...

  4. Flink cep的初步使用

    一.CEP是什么 在应用系统中,总会发生这样或那样的事件,有些事件是用户触发的,有些事件是系统触发的,有些可能是第三方触发的,但它们都可以被看做系统中可观察的状态改变,例如用户登陆应用失败.用户下了一 ...

  5. 使用broker进行Datagurd主备切换报ORA-12514异常

    在使用Datagurd broker进行Datagurd主备切换时报ORA-12514监听异常, 详细信息如下: DGMGRL> switchover to xiaohe; Performing ...

  6. [Linux] linux下vim对于意外退出的文档的再次开启

    转载自博客:https://blog.csdn.net/ljp1919/article/details/48372615 1.对于同一个文件如果上次已经打开,而未关闭的情况下,又打开该文件进行编辑时, ...

  7. el-table合并行并自定义某一列或几列

    在el-table的官方组件中并没有看到具体的合并行或者列及自定义表格内容,于是就自己写了一个效果如下所示. 这种对左侧内容要求比较高,要求行合并,并要自定义一些内容.下面说一下具体方法及代码写法. ...

  8. .NET Core使用NPOI导出复杂Word详解

    前言: 最近使用NPOI做了个导出Word文档的功能,关于使用.NET Core 导出Word文档的方式有很多.最终我为什么选择了NPOI来实现了这个功能,首先是NPOI是一个开源,免费且容易上手的第 ...

  9. Intellij IDEA 2019 + Java Spring MVC + Hibernate学习笔记(1)

    之前的技术栈一直是围绕.net 做的,现在.net 技术栈的使用越来越少,越来越窄.好多原来的同事都转Java开发了. 最近公司变动,自己需要重新找个坑,压力山大.好多要求Java技术栈的根本没机会进 ...

  10. FP-Tree算法详细过程(Java实现)

    我就不说FP-Tree的作用.优点什么的了,直接用例子来解释构建FP-Tree和找出所有频繁项集,第一次写博客,不对之处还请指出. 输入文件: testInput.txt T1 T2 T3 T4 T5 ...