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

在.Net core 使用NPOI首先必须先安装DotNetCore.NPOI,第一种方法可以在管理Nuget包中安装,如图:

直接搜索DotNet.NPOI 安装就可以了。

第二种方法就是在Nuget程序包控制台中输入 Install-Package DotNetCore.NPOI  然后回车就可以了。

首先导出,和网上很多例子一样,我的想法一开始是用datatable导出到Excel中,但是感觉datatable的性能不够好,而且局限比较大,不过一开始我还是用datatable导出来了。

代码如下:

public static byte[] Output(DataTable dataTable, string[] tableTitle)
{
NPOI.SS.UserModel.IWorkbook workbook = new NPOI.XSSF.UserModel.XSSFWorkbook();
NPOI.SS.UserModel.ISheet sheet = workbook.CreateSheet("sheet");
IRow Title = null;
IRow rows = null;
for (int i = ; i <= dataTable.Rows.Count; i++)
{
//创建表头
if (i - == )
{
Title = sheet.CreateRow();
for (int k = ; k < tableTitle.Length + ; k++)
{
Title.CreateCell().SetCellValue("序号");
Title.CreateCell(k).SetCellValue(tableTitle[k - ]);
}
continue;
}
else
{
rows = sheet.CreateRow(i - );
for (int j = ; j <= dataTable.Columns.Count; j++)
{
rows.CreateCell().SetCellValue(i - );
rows.CreateCell(j).SetCellValue(dataTable.Rows[i - ][j - ].ToString());
}
}
} byte[] buffer = new byte[ * ];
using (MemoryStream ms = new MemoryStream())
{
workbook.Write(ms);
buffer = ms.ToArray();
ms.Close();
}
return buffer;
}

这里返回的是byte数组是为了方便在控制器调用方法后中返回一个文件给客户端。

return File(buffer, "application/ms-excel", "list.xlsx");   

这样客户端直接会有一个文件下载。

当然别忘了引用

using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;

这里XSSF是适用于xlsx,如果是xls的话引用using NPOI.HSSF.UserModel;

可以发现这里的数据源是datatable类型的,对于使用EF Core 操作数据库不是特别方便,所以还是改用list泛型去导出会方便很多。

代码如下:

public static byte[] OutputExcel(List<T> entitys, string[] title)
{
IWorkbook workbook = new XSSFWorkbook();
ISheet sheet = workbook.CreateSheet("sheet");
IRow Title = null;
IRow rows = null;
Type entityType = entitys[].GetType();
PropertyInfo[] entityProperties = entityType.GetProperties(); for (int i = ; i <= entitys.Count; i++)
{
if (i == )
{
Title = sheet.CreateRow();
for (int k = ; k < title.Length + ; k++)
{
Title.CreateCell().SetCellValue("序号");
Title.CreateCell(k).SetCellValue(title[k - ]);
} continue;
}
else
{
rows = sheet.CreateRow(i);
object entity = entitys[i - ];
for (int j = ; j <= entityProperties.Length; j++)
{
object[] entityValues = new object[entityProperties.Length];
entityValues[j - ] = entityProperties[j - ].GetValue(entity);
rows.CreateCell().SetCellValue(i);
rows.CreateCell(j).SetCellValue(entityValues[j - ].ToString());
}
}
} byte[] buffer = new byte[ * ];
using (MemoryStream ms = new MemoryStream())
{
workbook.Write(ms);
buffer = ms.ToArray();
ms.Close();
} return buffer;
}

因为list<T>可以直接得出行数,所以得出行数很方便,但是不知道list<T>有多少列,这个时候需要用到反射,记得引用System.Reflection 。通过获取list<T>类型去获取list<T>的属性。

然后通过 entityProperties.Length 获取列数。当然这里要留意第一列是表头,第二列才是数据,导出的时候从第二列开始。

通用引用类型去获取一行的值object entity = entitys[i - 1];然后通过属性数组去获取每一列的值,这里的逻辑有点乱,细心一点就一目了然了。object[] entityValues = new object[entityProperties.Length]; entityValues[j - 1] = entityProperties[j - 1].GetValue(entity);

这里是先写到内存中再导出,可能数据多了的时候会慢,不过一般是不会的。导出在这里就结束了。

然后是导入:

还是因为EF Core的原因,感觉还是导入成List<T>最方便,因为是公共方法,所以根据实体类型不同,要兼容所有实体类型,泛型似乎是最好的选择。

在网上找了很多资料,也看到了很多方法实现,不过不是特别适合我现在所在的项目,所以还是自己结合网上的重写,忘了借鉴了的文章的作者,若有侵权,马上删除。

代码如下:

 /// <summary>
/// 导入Excel
/// </summary>
/// <param name="file">导入文件</param>
/// <returns>List<T></returns>
public static List<T> InputExcel(IFormFile file)
{
List<T> list = new List<T> { }; MemoryStream ms = new MemoryStream();
file.CopyTo(ms);
ms.Seek(, SeekOrigin.Begin); IWorkbook workbook = new XSSFWorkbook(ms);
ISheet sheet = workbook.GetSheetAt();
IRow cellNum = sheet.GetRow();
var propertys = typeof(T).GetProperties();
string value = null;
int num = cellNum.LastCellNum; for (int i = ; i <= sheet.LastRowNum; i++)
{
IRow row = sheet.GetRow(i);
var obj = new T();
for (int j = ; j < num; j++)
{
value = row.GetCell(j).ToString();
string str = (propertys[j].PropertyType).FullName;
if (str == "System.String")
{
propertys[j].SetValue(obj, value, null);
}
else if (str == "System.DateTime")
{
DateTime pdt = Convert.ToDateTime(value, CultureInfo.InvariantCulture);
propertys[j].SetValue(obj, pdt, null);
}
else if (str == "System.Boolean")
{
bool pb = Convert.ToBoolean(value);
propertys[j].SetValue(obj, pb, null);
}
else if (str == "System.Int16")
{
short pi16 = Convert.ToInt16(value);
propertys[j].SetValue(obj, pi16, null);
}
else if (str == "System.Int32")
{
int pi32 = Convert.ToInt32(value);
propertys[j].SetValue(obj, pi32, null);
}
else if (str == "System.Int64")
{
long pi64 = Convert.ToInt64(value);
propertys[j].SetValue(obj, pi64, null);
}
else if (str == "System.Byte")
{
byte pb = Convert.ToByte(value);
propertys[j].SetValue(obj, pb, null);
}
else
{
propertys[j].SetValue(obj, null, null);
}
} list.Add(obj);
} return list;
}

数据源是IFormFile类型的,因为前端导入文件的方法是用layui的。所以是IFormFile。

同样我们也不知道list<T>是什么类型的,所以我们还是得用反射去获取类型,而且这里还是写到内存里面,就不会在服务器上留下文件,不过服务器内存小的要注意一下。

然后我们也不知道属性是什么类型的,所以要 string str = (propertys[j].PropertyType).FullName; 

判断属性的数据类型,然后在从Excel中遍历每一个单元格,输出到list中就可以了,记得要留意下数据在第二行开始导入进去。

大致的问题就是这些,重点就是反射去获取list<T>的类型。关于Excel的操作,这里就不详细说明了。

总的来说,NPOI可以脱离微软Excel操作Excel实在是非常方便,oledb真的非常不好用。

最后,我还需要学习的很多,有什么错误请指出。谢谢大家!

.Net core NPOI导入导出Excel的更多相关文章

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

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

  2. NPOI导入导出Excel

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

  3. Npoi导入导出Excel操作

    之前公司的一个物流商系统需要实现对订单的批量导入和导出,翻阅了一些资料,最后考虑使用NPOI实现这个需求. 在winform上面实现excel操作:http://www.cnblogs.com/Cal ...

  4. .net mvc利用NPOI导入导出excel

    1.导出Excel :首先引用NPOI包(Action一定要用FileResult) /// <summary> /// 批量导出需要导出的列表 /// </summary> ...

  5. NPOI 导入导出excel 支持 03 07

    因为微软的office成本太高了,所以开发项目的时候电脑上没安装office,而是安装了wps.但开发语言用的是C#,所以直接调用微软的office组件是很方便的,但一方面慢,一方面成本高,所以从网上 ...

  6. ASP.Net MVC利用NPOI导入导出Excel

    因近期项目遇到所以记录一下: 首先导出Excel: 首先引用NPOI包 http://pan.baidu.com/s/1i3Fosux (Action一定要用FileResult) /// <s ...

  7. Excel操作--使用NPOI导入导出Excel为DataTable

    1.ExcelHelper封装 namespace NPOI操作Excel { public class ExcelHelper { /// <summary> /// DataTable ...

  8. 使用NPOI导入导出Excel(xls/xlsx)数据到DataTable中

    using System; using System.Collections.Generic; using System.Text; using System.IO; using NPOI.SS.Us ...

  9. NPOI导入导出EXCEL通用类,可直接使用在WinForm项目中

    由于XSSFWorkbook类型的Write方法限制,Write完成后就自动关闭流数据,所以无法很好的支持的Web模式,网上目前也未找到好的解决方案. 注意:若直接使用在WinForm项目中,必需先下 ...

随机推荐

  1. 解决python3缺少zlib的问题

    解决python3缺少zlib的问题 Table of Contents 1. 安装zlib 2. 重新编译安装python 3. 补充说明 在使用python3运行spark时,报缺少zlib的错误 ...

  2. java集合框架(一):HashMap

    有大半年没有写博客了,虽然一直有在看书学习,但现在回过来看读书基本都是一种知识“输入”,很多时候是水过无痕.而知识的“输出”会逼着自己去找出没有掌握或者了解不深刻的东西,你要把一个知识点表达出来,自己 ...

  3. .NET开源工作流RoadFlow-表单设计-保存与发布

    表单的过程中可以随时保存,以便下次继续设计. 表单设计完成后即可点击发布按钮,发布表单,发布表单后即可在流程设计时选定该表单.

  4. ARM 中可用性集使用的注意事项

    Azure 目前有两种部署模型:经典部署模型 (ASM) 和资源管理器 (ARM).如果您之前使用过 ASM 模式下的可用性集,那么很可能在使用 ARM 模式下的可用性集时,会遇到一些问题或者疑惑.这 ...

  5. SQL Server ->> Transparent Data Encryption(透明化数据加密)

    Comming later... 参考文献: Transparent Data Encryption (TDE)

  6. 将CSV文件中的数据导入到SQL Server 数据库中

    导入数据时,需要注意 CSV 文件中的数据是否包含逗号以及双引号,存在时,导入会失败 选择数据库 -> 右键 -> 任务 -> 导入数据 ,然后根据弹出的导入导出向导(如下图)中的提 ...

  7. django模板templates详解(二)

    1 总体结构 ​ Django是MTV结构,即:Model, Template, View Model:定义数据的存储格式,并且提供了数据库访问的API. View:定义那些数据被显示,是业务逻辑处理 ...

  8. wcf 实现多契约 z

    我们知道,WCF服务端是先定义服务协定,其实就是一个接口,然后通过实现接口来定义服务类.那么,有一个问题,如果一个服务类同时实现N个接口(也就是有N个协定)呢?结果会如何? 不必猜,我们还是通过实验来 ...

  9. OFFICE_EXCEL_Combine text from two or more cells into one cell.

    Excel   Enter and format data   Layout   Combine text from two or more cells into one cell Combine t ...

  10. File not Found:DockForm.dcu的解决办法

    安装控件时,如果引用了dsgnintf单元,那么就会提示找不到proxy.pas 或者DockForm.dcu的错误,只需在安装控件包时添加“lib\DesignIde.dcp”即可