整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

老牌开源Office操作组件NPOI现已支持.NET Core

天在微信群里听到老牌Excel开发利器NPOI的作者瞿总说4.6.1版本的NPOI已经支持.NET Standard 2.0了,这也就意味着你可以在.NET Core中使用NPOI了。

写在前面

曾经的.NET Framework时代就很喜欢使用这个组件来对Excel的进行操作,可是随着.NET Core时代的到来以及NPOI不支持.NET Core所以就找到了园子里的大神杨晓东对NPOI的.NET Core的移植版,可是使用的过程中的如果对这个移植的插件进行深入的使用的话还是有部分问题,可能正如杨晓东大神自己所说:“去年的那个版本是针对于 .NET Core 1.0 的,从发布截止现在在 NuGet 大概有 2K 多的下载量,说明还是有很多同学在使用 NPOI 的,社区中也得到了很多同学的推广。 但是上一个移植的版本也有诸多缺陷和 bug,在 Github 上也收到了一些 Issue 进行反馈,很多 Bug 可能是移植过程中的bug,但是对于这些 Bug 可能我也无能为力,因为 NPOI 的代码是非常庞大和复杂的。”

不过也再次特别感谢下杨晓东大神对NPOI的.NET Core版本的移植也才能让我们在.NET Core1.0以及.NET Core2.0的一段时间内继续使用这个NPOI。

有兴趣的小伙伴可以看下杨晓东大神的版本这里是介绍《NET Core 2.0 开源Office组件 NPOI》

因此在得知NPOI的作者瞿总已经完成对NPOI的升级并支持.NET Standard 2.0后特此把这个好消息告诉全体.NET Core开发者们。自此我们又可以尽情的在.NET Core中继续使用这个开源的老牌Office组件了!反正我表示挺开心的!而且如果你在使用的过程中有任何问题都可以在GitHub上对作者提issue,作者也会以迅雷不及掩耳之势之势进行修复

什么是NPOI

说了半天NPOI已经可以在.NET Core中使用了,可能对于新手朋友还是不知道这玩意究竟是什么?其实你可以看看百度百科《NPOI》里面有详细的讲述。我只能跟你说使用 NPOI 你就可以在没有安装 Office 或者相应环境的机器上对 WORD/EXCEL 文档进行读写操作,十分方便。

另外NPOI的原作者的GitHub地址是:https://github.com/tonyqus/npoi

里面也有详尽的描述

如何使用

通过Nuget直接添加NPOI的最新引用即可使用

Install-Package NPOI -Version 2.4.1

然后你就可用像之前一样进行操作了!

但是如果你想运行在Linux上可能需要注意一下:

由于NPOI使用System.Drawing.Common,因此必须在Linux系统上安装libgdiplus和libc6。

Ubuntu 16.04及以上

apt-get install libgdiplus libc6-dev
ln -s /usr/lib/libgdiplus.so /usr/lib/gdiplus.dll

然后就可以在Linux系统上跑起来了!

例子

我们有很多例子可供您学习如何使用NPOI。

请查看https://github.com/tonyqus/npoi/tree/master/examples。

文件夹名称示例描述HSSF有关Excel 97-2003格式的示例(* .xls)XSSF有关Excel 2007+格式的示例(* .xlsx)XWPF有关Word 2007+格式(* .docx)的示例POIFS关于OLE2文档/ ActiveX文档的示例OOXML有关OpenXML文件的示例

第三方博客

使用NPOI - C#和WEB API导出到Excel

使用NPOI在.NET中构建漂亮的XLS文档

如何使用NPOI阅读Excel 2007文档

如何使用NPOI创建Excel电子表格

NPOI 2.0 - 将Excel XLS文档转换为HTML格式

NPOI与Excel表和动态图表

总结

今天给大家介绍了一款.NET Core Office开发利器NPOI已经支持.NET Core了!希望对大家有所帮助!今后我们的实战教程之CMS系统里面对Excel的操作也将使用这个组件,届时我讲实战讲解如何使用这个组件,最后感谢大家的阅读。

sp.net为了缩短开发周期,搭建了一个快速开发平台。



如果是做OA、CRM、ERP一类的管理系统,如果为了缩短开发周期,搭建一个快速开发平台,再配合一些快速开发的组件开发效率能提高很多。



1.框架用到的技术

(1)前台技术:ajax+Jquery+jqgrid+Bootstrap

(2)开发环境:VS2015-VS2019

(3)数据库:SQL Server,Oracle、Mysql

(5)后台技术:ASP.NET MVC,TinyIoc(IoC容器),EF(ORM框架),layui框架或vue,Log4Net,NPOI等

2.框架主要功能展示

手机端是通过html做前端开发,通过ajax与后台webapi接口做交互。开发完成后可以打包成应用提供给用户下载

近在做一个需求是导出较大的excel,本文是记录我在做需求过程中遇到的几个问题和解题方法,给大家分享一下,一来可以帮助同样遇到问题的朋友,二呢,各位大神也许有更好的方法可以指点小弟一下,让我顺便学习一下。

背景::工头:“小钟啊,xx界面加个导出excel功能03以后的格式,需要能支持到excel的最大行,同时需要5个并发就行”

我:“收到,但是数据大的时候速度可能比较慢。”

工头:“你先做后续客户反馈了在给他加进度条。”

Npoi神器介绍:SXSSFWorkbook 专门用来导出大数据用,他会把数据先写入C盘的临时目录;不会所有 都留在内存里;更详细介绍请百度或者参考(http://poi.apache.org/components/spreadsheet/how-to.html#sxssf

有了这层基础开始劈里啪啦一段操作写代码;(以下代码非生产代码只是我为了帖子写重现问题的测试代码)

首先开个线程模拟并发

编写导出方法:记录时间、创建SXSSFWorkbook 代码如图:

启动运行;

好!第一口锅已造好,看这个提示,前面说了SXSSFWorkbook 是会先把缓存数据写入Windows临时文件里头的,这个目录正好是Windows的临时文件夹虽然是个错误但是验证了刚刚的说法;至于这个错误看提示 我们有个大胆的想法是文件占用问题,应该是创建文件的时候文件已经存在了,这样我们把npoi的dll打开来看看,通过看源码和各种f12我们看到了这么一段代码

这里看到用来随机数,而我们知道net的随机数在极短的时间内生成是不可靠的(详见百度或者:

https://docs.microsoft.com/zh-cn/dotnet/api/system.random.-ctor?f1url=https%3A%2F%2Fmsdn.microsoft.com%2Fquery%2Fdev16.query%3FappId%3DDev16IDEF1%26l%3DZH-CN%26k%3Dk(System.Random.%2523ctor);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.0);k(DevLang-csharp)%26rd%3Dtrue&view=netframework-4.8)也就是说生成一样的文件名,然后我们在通过 github里可以看到

早在年初NPOI就对这个问题做了更改就换成guid了,随后我来到了nuget

nuget最新版 是去年12月份发布,并没有包含上面的更改;

所以呢 要么github下载最新版编译要么自己解决,想了想如果换版本的话以前的功能可能会影响到所以,我们就在外面加一把小锁吧!如图

这样呢我们在试试!

很好 不会在出现文件占用问题了;好继续导出!

既然是都先写入缓存文件是不是占用的内存就很小了 来看看

2G多。。。什么情况,还在涨

3G。。。这明显不符合工头的需求了,然后终于它炸了

第一念头是为啥我该怎么办,设置GC的回收模式?手动多GC?还是要把代码给拿下来看看,看看这么大内存哪里没释放文件?冷静、冷静、想想,既然是内存爆了 那么正确流程应该是抓取看看是什么吃的内存得出结果再去改东西,

发现了啥是不是很熟悉的东西? 状态管理、包装类,想到了啥 EF的“模型跟踪”这个功能占用的内存最大了。那就去掉吧 加上这么一句 意思是无跟踪查询 ,修改实例后SaveChanges不对对它生效;

(AsNoTracking 更详情理解介绍请百度在加上msdn:https://docs.microsoft.com/zh-cn/ef/ef6/querying/no-tracking?redirectedfrom=MSDN

现在在继续导出看看:

内存是吃的不大了,

可以看出临时文件还是很大的,这还没导完呢,所以做的时候 尽量要保证下硬盘的空间!

等待。。。

总结:

1.导出大数据用SXSSFWorkbook

2.构建SXSSFWorkbook 时候lock或者自己编译最新版本

3.我们做导出时,ef查询数据后记得加AsNoTracking 关闭绑定跟踪。(以后日常开发中如果只需要查询的也可以这样做)

4.SXSSFWorkbook 导出大数据 临时文件夹所在的硬盘不能太小 因为会生成大于excel本身的缓存文件!

最后导出完毕

用时: