NPOI简介

作者:Tony Qu

========================================

[更新] NPOI 1.2.4 新教程地址:http://tonyqus.sinaapp.com

========================================

NPOI 微博: http://weibo.com/npoi

NPOI QQ交流群: 

群1:189925337

群2:124527967

群3: 116053476

 

更新

2009.3.24  把npoi 1.2 alpha的链接换成NPOI 1.2 beta

2009.11.18  把npoi 1.2 beta的链接换成NPOI 1.2.1; 增加NPOI教程链接

2009.12.1 增加QQ群

===================================================

本文将通过问答的方式帮助你了解NPOI。

 

什么是NPOI?

NPOI,顾名思义,就是POI的.NET版本。那POI又是什么呢?POI是一套用Java写成的库,能够帮助开发者在没有安装微软Office的情况下读写Office 97-2003的文件,支持的文件格式包括xls, doc, ppt等。目前POI的稳定版本中仅支持Excel文件格式xls,其他的都属于不稳定版本(放在poi的scrachpad目录中)。NPOI是构建在POI 3.x版本之上的,本月发布的NPOI 1.2是对应于POI 3.2 final的,所以它支持Excel文件读写,但由于人手和精力原因,还没有实现读写Word, PowerPoint, Visio的文件格式。

 

NPOI的官方网站是啥?

npoi.codeplex.com

 

为什么用NPOI?

因为它能够帮助你生成真正的Office文件格式,比如说Excel文件格式。我曾经看到好几个园友发过有关如何生成Excel报表的帖子,大家确实花了很多心思,具体的帖子如下:

生成Excel高级报表(用的是Office PIA库)

http://www.cnblogs.com/xiaobier/archive/2008/10/13/1310399.html

Datagrid数据导出到excel文件的三种方法

http://www.cnblogs.com/xieduo/articles/606202.html

其中提到了的2种方法分别是:cvs法、html法

.net 操作 EXCEL

http://www.cnblogs.com/jhobo/archive/2009/02/17/1392423.html

其中提到了Office PIA法、OLEDB法、OPENXML法

 

特别是其中的cvs法和html法值得提一下,这得感谢Microsoft Office对于格式的强大兼容性,貌似国产某某Office软件就无法正常显示基于html的xls文件。

好了,回到我们的问题上,为什么要用NPOI呢?

第一点,你不需要在服务器上安装微软的Office,可以避免版权问题。

第二点,使用起来比Office PIA的API更加方便,更人性化。

第三点,你不用去花大力气维护NPOI,NPOI Team会不断更新、改善NPOI,绝对省成本。

第四点,很多事情是html和cvs法做不到的,比如说公式计算[Cell C1]=A1+B1*A2、单元格高级样式(如文本旋转、对齐、宽度)等,其中公式计算可以适当减轻服务器端的计算压力

第五点,你很难保证你的客户机器上都安装了Office 2007或Office Compatiblity Pack for Office 2003,出于向前兼容的考虑,还是生成Office 97-2003格式比较可靠

 

当然有人要说了,那我用myXls等同类产品可不可以?当然可以,纯属个人喜好,这就好比你愿意用NHibernate还是NBear,完全可以自由选择。

 

NPOI由哪些东西组成?

NPOI目前主要由以下部分组成

NPOI.POIFS OLE2 Document File System Library
NPOI.DDF Microsoft Office Drawing format Library
NPOI.HPSF OLE2 Propertyset library (包括SummaryInformation和DocumentSummaryInformation)
NPOI.HSSF Microsoft Excel BIFF library
NPOI.SS Formula Evaluation library
NPOI.Util 基础类库,提供了很多实用功能,可用于其他读写文件格式项目的开发

 

NPOI目前的版本如何?包括哪些功能?

目前NPOI的最新版是NPOI 1.2.1,其中包括了以下功能:

a. 读写OLE2文档

b. 读写DocummentSummaryInformation和SummaryInformation

c. 基于LittleEndian的字节读写

d. 读写Excel BIFF格式

e. 识别并读写Excel BIFF中的常见Record,如RowRecord, StyleRecord, ExtendedFormatRecord

f. 支持设置单元格的高、宽、样式等

g. 支持调用部分Excel内建函数,比如说sum, countif以及计算符号

h. 支持在生成的Xls内嵌入打印设置,比如说横向/纵向打印、缩放、使用的纸张等

i. ……  (功能太多,无法一一例举,大家自己研究吧)

下载地址:http://npoi.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=19351

 

在开发中哪些地方可以使用NPOI

a. 生成Excel报表

b. Excel中的文本提取(主要用于搜索引擎)

c. 批量生成Excel文件

d. 基于Excel文件模板生成新的Excel

e. 研究Excel BIFF文件格式及OLE2文件格式

 

NPOI的最终目标是什么?

a. 能够读写几乎所有的Office 97-2003文件格式,至少能够支持Word, PowerPoint, Excel, Visio的格式,其他的会根据实际需求而定。

b. 作为教学Office文件格式的“活”教材,也可作为研究生阶段研究数据结构的教材。

即使是目前的1.2版本也很不完善,支持的Excel功能还很有限,没有搞过NPOI的研发,包括我在内的很多人很难想象微软这样一个Excel软件的开发量,其中除了我们常用的基本功能以外,还有很多内置函数的实现、对行进行分组、行的锁定、表单的保护等。说实话有些功能我也是第一次听说,是在开发中一边看Excel界面一边实现的(呵呵,是不是很土)。由于Office 2007为了兼容Office 97-2003,在其基础上增加了很多新的Record,所以要生成真正意义上的全新的Excel BIFF很难(话说微软的开发速度贼快)。

在NPOI以后的版本中还会支持Pivot表和图表(Chart),其实你在poi的svn中已经可以看到最新的pivot和chart的代码了,只是还在开发中,没有发布正式版本,估计今年中旬会发一个新的版本。

 

我也想研究Office文件格式,有没有相关的文档和工具可供参考?

首先是文件格式的说明文档,你可以去微软的官方网站下载:http://www.microsoft.com/interop/docs/officebinaryformats.mspx

接着是,我和Huseyin共同开发了POIFS Browser,目前的版本是1.2,已经能够识别Excel BIFF了。

你可以去http://npoi.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=23409下载。

 

我可以参加NPOI开发组吗?

当然可以,我非常欢迎大家加入NPOI Team,因为目前狂缺人手,很多事情要做,比如说实现读写Word格式的库,即HWPF;还需要有人帮忙一起写文档、写范例、写教程。目前团队中只有2个人,我和Huseyin(土耳其人),最近Huseyin也很忙,没时间维护NPOI,所以我很需要你的加入。大家有兴趣可以到http://npoi.codeplex.com/Thread/View.aspx?ThreadId=36157回帖,或者直接发邮件给我(具体邮件地址见我blog的左边栏)。

 

NPOI有教程吗?

有,该教程是为NPOI 1.2写的,详细目录请见http://www.cnblogs.com/tonyqus/archive/2009/04/12/1434209.html

 

NPOI Team下一步准备干嘛?

上一个问题中提到事情真的很多,下面罗列一下:

a. 使Excel读写库(HSSF)更加稳定

b. 开发HSSF对Pivot Table和Chart的支持

c. 开发Word读写库(HWPF)、PowerPoint读写库(HSLF)

d. 把HSSF的注释补全,把java的注释转成.NET的,便于用NDoc生成文档和智能感知

e. 写NPOI 1.2的范例(目前只有10个左右,目标是>50个,类似于微软的SDK,这样方便大家学习和理解)

f.  写NPOI 1.2的教程

posted @ 2009-03-16 07:49 Tony Qu 阅读(19237) 评论(45) 编辑 收藏

 回复 引用 查看   
#1楼2009-03-16 08:28 | 菌哥      
不错
 回复 引用 查看   
#2楼2009-03-16 08:33 | Haozes      
mark
 回复 引用 查看   
#3楼2009-03-16 08:47 | 张蒙蒙      
不错,我正好在用apach的poi,想着想着.net版本的也就来了
 回复 引用 查看   
#4楼2009-03-16 09:00 | Carlos Zhao      
先收藏,待会再慢慢看.
 回复 引用 查看   
#5楼2009-03-16 09:09 | 生鱼片      
前一阵子也做了些处理Excel报表的,有时间看看楼主的这个
 回复 引用 查看   
#6楼2009-03-16 09:13 | Allie      
没怎么用过这东西!关注下 mark!
 回复 引用 查看   
#7楼2009-03-16 09:27 | 双鱼座      
明明M$的东西,非得从Java来。感觉你在打M$的脸啊!不过这脸打得好。
其实M$一开始就应该提供Inproc server而不是automation直接访问office文件。

 回复 引用 查看   
#8楼2009-03-16 09:56 | Sunshushou      
期待早点出完整版,打算用它来做搜索引擎提取office文档内容
 回复 引用 查看   
#9楼2009-03-16 11:41 | 李春雷      
Mark
 回复 引用 查看   
#10楼2009-03-16 20:57 | wsky      

 回复 引用 查看   
#11楼2009-03-23 08:54 | tan_Cool      
收藏起来,不断关注
 回复 引用 查看   
#12楼2009-04-01 10:04 | 鱼蛋      
等可以写word了再用
 回复 引用 查看   
#13楼2009-05-05 23:01 | FredChen      
tonyqus你好,我用npoi生成excel 数据。但是,怎么最多只能生成3个sheet表的?当超过3个的时候会提示:
Sheet index (3) Is out of range (0..2)

这是bug吗?还是哪里限制了。请赐教!

 回复 引用 查看   
#14楼[楼主]2009-05-07 06:48 | Tony Qu      
我刚才做了个实验,可以生成第4个sheet,你确定调用了4次CreateSheet吗?会不会少了一次?
 回复 引用 查看   
#15楼2009-05-21 15:50 | FredChen      
谢谢Tony的解答.
之前主要遇到了项目需要用到导出excel报表。所以尝试一下npoi。当时我是通过先读取excel模板到FileStream里,再根据FileStream创建HSSFWorkbook的。出现那个问题是因为我要在一个HSSFWorkbook里根据数据的多少创建几个sheet,每个sheet的结构是跟模板的结构一样的。当时是判断如果要创建多个sheet的话就第一个sheet=GetSheetAt(0),其它的sheet就用clone的方式。然后命名也是根据顺序命名的。
问题就出在原来创建HSSFWorkbook时,它就会默认帮我创建了3个空白的sheet。所以后面的判断就出错了。。
不过后来这个方案还是没有成功。因为通过模板创建excel的话,客户就不可以选择要显示的字段数据了。而不通过模板的话,又得手动为每张报表写生成模表头表尾的方法,很麻烦,特别是对于多行表头的报表,感觉很羊水疼。而且,每个格子的判断,填充数据,好像效率也蛮慢的。。
后来想用rdlc,或是水晶报表那种,但是还是感觉不太顺手。现在还没解决问题。不知道Tony 有没有做过报表的项目,对于一些复杂的报表你们的解决方案是什么样的?我是一个新手,如能点拨一二,感激不尽。。
再次感谢。

 回复 引用 查看   
#16楼[楼主]2009-08-13 07:56 | Tony Qu      
我觉得你这个问题技术没法解决,还是个态度问题,软件开发要么让客户不爽,要么程序员自己不爽。既然你要动态生成,肯定是要在内存中动态生成的,即使是水晶报表,你也要写很多判断语句,如果是动态列还要想办法动态生成rdlc,那个恐怕比用NPOI更加麻烦。

总之你有2中选择:要么告诉客户动态列很麻烦,做不了;要么自己忍忍,把逻辑写在代码里,做是肯定能做出来的。

 回复 引用 查看   
#17楼2009-08-18 14:49 | lemonhall      
功能REQUEST

既然是NPOI,能否做一些和.NET平台,特别是ASP.NET平台相关的函数。

比如像EXCELPACKAGE中的一个PATCH,可以直接将DATATABLE输出给EXCEL。

其实我觉得最有用的是GRIDVIEW输出到EXCEL,大家以前都是用得HTML或者CSV方法。

如果能把GRIDVIEW的结果输出到真正的XLS内存缓存中,然后程序员就可以在内存里,增加【条件格式】啊,总计啊什么的。

GRIDVIEW本身也有GROUP的能力,这样输出的时候把GROUP信息也带入进EXCEL。

这样大量的简单表就不再需要REPORTING SERVICE了~~~

 回复 引用 查看   
#18楼2009-08-18 14:54 | lemonhall      
Adapted from rob_dot_net's patch (1042) to add in the following functionality via overloads:

Can force all data to be treated as strings (critical for cases where an employeeId or similar data is used that can begin with 0)

Can dynamically select which columns to use from DataTable and optionally set header row label (instead of default of DataTable's column name)

Can set the style Id to be used for the header row

Default still works as before (although name changed to be more descriptive):
worksheet.LoadFromDataTable(dt);

Example overload:
worksheet.LoadFromDataTable(dt, new string[] { "PersonId", "PersonName", "Department" });

Assuming your DataTable had more fields like Telephone, Email, etc, only the three fields specified above would be output to the Excel file.

Again working witht he above if you wanted the header columns labeled you could do:

KeyValuePair<string, string>[] columns = new KeyValuePair<string, string>[3];
columns[0] = new KeyValuePair<string, string>("PersonId", "Badge Number");
columns[1] = new KeyValuePair<string, string>("PersonName", "Employee Name");
columns[2] = new KeyValuePair<string, string>("Department", "Department");
worksheet.LoadFromDataTable(dt, columns);

 回复 引用 查看   
#19楼2009-08-18 14:56 | lemonhall      
当然也可以自己实现一个NPOI版本的:

worksheet.LoadFromDataTable(dt);

但是限于水平问题,非常无奈~~

 回复 引用 查看   
#20楼2009-08-18 15:11 | lemonhall      
最后再给一个建议,就是写完了GRIDVIEW简单到处的函数后,大约的函数形式大致是:

gv1.ExportTodownload("filename");

再到CODEPROJECT上用英文发一篇帖子,一定会火~~~,和GOOGLE搜索gridview excel的那片matt的帖子再做个链接。

非常非常复杂的动态报表,还是用报表服务器的好。

 回复 引用 查看   
#21楼2009-09-18 12:03 | High      
能生成图形吗?如圆饼
 回复 引用 查看   
#22楼[楼主]2009-09-19 09:49 | Tony Qu      
@High
Excel Graph目前不支持,但是基本的图形是可以画的。

 回复 引用 查看   
#23楼2009-12-21 16:21 | 银河      
好东东,顶一下。
有时间慢慢看。

 回复 引用 查看   
#24楼2010-01-25 17:15 | 阿水      
加油加油
 回复 引用 查看   
#25楼2010-01-26 21:14 | skyaspnet      
非常支持!
 回复 引用 查看   
#26楼2010-05-19 17:39 | cxmskd      
如何将生成的EXCEL文件设为只读文件?
 回复 引用 查看   
#27楼2010-09-13 16:10 | 李玉来      
mark

 回复 引用 查看   
#28楼2011-01-07 20:34 | lhuser      
mark
 回复 引用 查看   
#29楼2011-03-23 14:47 | 阿水      
有个问题想问一下,NPOI可以调用EXCEL定义好的宏吗?
比如用NPOI导出数据到EXCEL文件,然后调用EXCEL中定义的宏进行后续处理,可以吗?谢谢!

 回复 引用 查看   
#30楼2011-03-24 17:40 | net1234      
FileStream file = new FileStream(fd.FileName, FileMode.Open);
HSSFWorkbook hssfworkbook = new HSSFWorkbook(file);

出现“NPOI.HSSF.Record.RecordFactory”的类型初始值设定项引发异常。
请问如何解决,谢谢

 回复 引用 查看   
#31楼[楼主]2011-04-02 08:41 | Tony Qu      
引用阿水:
有个问题想问一下,NPOI可以调用EXCEL定义好的宏吗?
比如用NPOI导出数据到EXCEL文件,然后调用EXCEL中定义的宏进行后续处理,可以吗?谢谢!

不支持,宏调用是Excel自身带的引擎做的,而非文件格式相关,更何况宏中经常会牵扯到Excel内部对象,如果放在NPOI中调用,肯定会出问题,所以无法支持。但NPOI支持单元格的公式计算

 回复 引用 查看   
#32楼2011-05-03 19:52 | Brian Zhang      
有word读写的功能吗?迫切需要word读写功能!
 回复 引用 查看   
#33楼[楼主]2011-07-19 06:37 | Tony Qu      
Word刚开始支持,但暂不放在正式release中,因为问题很多
 回复 引用 查看   
#34楼2011-07-26 21:08 | cejay      
能问你的问题吗?
excel分页里面的SetRowBreak 不管用 是为什么

 回复 引用 查看   
#35楼2011-08-04 16:54 | 迷死万千母牛      
有个问题,找了很多帖子,也看了官方的例子,但是还是没找到,所以特意来这里问一下,NPOI是否支持角标,如果支持,该如何设置?谢谢。
 回复 引用 查看   
#36楼2011-08-07 17:47 | 樊勇      
关注你了!楼主!
最近在找工作,很辛苦!
我是明年的毕业生,请问你可以帮忙推荐一下吗?

 回复 引用 查看   
#37楼2011-08-25 12:25 | 海南.胡勇      
好文。
 回复 引用 查看   
#38楼2011-08-26 14:44 | summerxll      
导出的数据很多的时候,最后导致内存溢出。这样的问题怎么处理呀~?

我需要导出50W条数据。5W条数据一个sheet,预期的结果是一个Excel文件,里面有10个sheet。 大概在20~30W之间会出现内存溢出的错误。

 回复 引用 查看   
#39楼2011-09-05 14:57 | likely      
什么时候可以支持office 2007呀
 回复 引用 查看   
#40楼2011-09-28 16:24 | 樊勇      
早听说这个东西了,就是没用过。
 回复 引用 查看   
#41楼2011-12-09 16:29 | 悄无声息      
我也没用过这东西,不过用office excel导入数据时,出现了这样的错:
Invalid header magic number.,真的没法解决

 回复 引用 查看   
#42楼2011-12-09 16:29 | 悄无声息      
不知哪位高人指点一下
 回复 引用 查看   
#43楼2012-01-04 17:36 | Rookier      
NPOI是针对excel的吗?能处理word,ppt吗?网上没有找到相关教程。。求指导。
 回复 引用 查看   
#44楼2012-01-20 10:32 | aquilahkj      
感谢楼主的工作,最近把NPOI用在mono中,但mono不支持"UTF-16LE"的编码名称方式获取,建议楼主把编码的获取方式由"UTF-16LE"直接改为unicode,两者应该是一样的,我源码重编解决.
 回复 引用 查看   
#45楼2012-02-07 17:59 | Gabriel Zhang      
引用aquilahkj:感谢楼主的工作,最近把NPOI用在mono中,但mono不支持"UTF-16LE"的编码名称方式获取,建议楼主把编码的获取方式由"UTF-16LE"直接改为unicode,两者应该是一样的,我源码重编解决.

我在mono里面试过导入导出excel啊,好像没什么问题的