1 1 1 1 认识认识认识认识 NPOI
NPOI
NPOI
NPOI
本章将介绍 NPOI 的一些基本信息,包括以下几个部分
•
•
•
•
•
•
什么是 NPOI
版权说明
相关资源
团队介绍
未来展望
各 Assembly 的作用
1.1 什么是什么是什么是什么是 NPOI
1.1
NPOI
NPOINPOI
1.1 1.1
NPOI,顾名思义,就是 POI 的.NET 版本。那 POI 又是什么呢?POI 是一套用 Java 写成
的库,能够帮助开发者在没有安装微软 Office 的情况下读写 Office 97-2003 的文件,支持
的文件格式包括 xls, doc, ppt 等。在本文发布时,POI 的最新版本是 3.5 beta 6。
NPOI 1.x 是基于 POI 3.x 版本开发的,与 poi 3.2 对应的版本是 NPOI 1.2,目前最新发布
的版本是 1.2.1,在该版本中仅支持读写 Excel 文件和 Drawing 格式,其他文件格式将在以
后的版本中得到支持。
1.2 版权说明
1.2
版权说明
版权说明版权说明
1.2 1.2
NPOI 采用的是 Apache 2.0 许可证(poi 也是采用这个许可证),这意味着它可以被用
于任何商业或非商业项目,你不用担心因为使用它而必须开放你自己的源代码,所以它对于
很多从事业务系统开发的公司来说绝对是很不错的选择。
当然作为一个开源许可证,肯定也是有一些义务的,例如如果你在系统中使用 NPOI,
你必须保留 NPOI 中的所有声明信息。对于源代码的任何修改,必须做出明确的标识。
完整的 apache 2.0 许可证请见 http://www.phpx.com/man/Apache-2/license.html
1.3 相关资源
1.3
相关资源
相关资源相关资源
1.3 1.3
官方网站:http://npoi.codeplex.com/
POIFS Browser 1.2 下载地址:
http://npoi.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=24305
QQ 交流群: 78142590
1.4 团队介绍
1.4
团队介绍
团队介绍团队介绍
1.4 1.4
Tony Qu 来自于中国上海,是这个项目的发起人和开发人员,时区是 GMT+8,2008 年 9
月开始了 NPOI 的开发,负责 NPOI 所有底层库的开发、测试和 bug 修复。个人 blog 地址为
http://tonyqus.cnblogs.com/
Hüseyin Tüfekçilerli 来自于土耳其的伊斯坦布尔,也是这个项目的开发人员,时区
是 GMT+2,2008 年 11 月参与了 NPOI 的开发,主要负责 POIFS Browser 1.0 的开发工作。个
人 blog 地址为 http://huseyint.com/
aTao.Xiang,来自中国,2009 年 8 月开始参与该项目,主要参与了 NPOI 1.2 中文版的
撰写工作和推广工作。个人 blog 地址为 http://www.cnblogs.com/atao/
1.5 回顾与展望
1.5
回顾与展望
1.5 1.5
回顾与展望
回顾与展望
目前 POI 版本中的 HWPF(用于 Word 的读写库)还不是很稳定,并非正式发布版本,且
负责 HWPF 的关键开发人员已经离开,所以 NPOI 可能考虑自己重新开发 HWPF。另外,目前
微软正在开发 Open XML Format SDK,NPOI 可能会放弃对 ooxml 的支持,当然这取决于用户
的需求和 Open XML Format SDK 的稳定性和速度。从目前而言,NPOI 有几大优势:
第一,完全基于.NET 2.0,而非.NET 3.0/3.5。
第二,读写速度快(有个国外的兄弟回复说,他原来用 ExcelPackage 生成用了 4-5 个
小时,现在只需要 4-5 分钟)
第三,稳定性好(相对于用 Office OIA 而言,毕竟那东西是基于 Automation 做的,在
Server 上跑个 Automation 的东西,想想都觉得可怕),跑过了将近 1000 个测试用例(来
自于 POI 的 testcase 目录)
第四,API 简单易用,当然这得感谢 POI 的设计师们
第五,完美支持 Excel 2003 格式(据说 myxls 无法正确读取 xls 模板,但 NPOI 可以),
以后也许是所有 Office 2003 格式
希望 NPOI 把这些优势继续发扬下去,这样 NPOI 才会更有竞争力。
1.61.61.61.6 Assembly
Assembly 的作用的作用的作用的作用
Assembly
Assembly
NPOI 目前有好几个 assembly,每个的作用各有不同,开发人员可以按需加载相应的
assembly。在这里大概罗列一下:
NPOI.Util: 基础辅助库
NPOI.POIFS: OLE2 格式读写库
NPOI.DDF: Microsoft Drawing 格式读写库
NPOI.SS: Excel 公式计算库
NPOI.HPSF: OLE2 的 Summary Information 和 Document Summary Information 属性
读写库
NPOI.HSSF : Excel BIFF 格式读写库
2.1 创建基本内容
2.1
创建基本内容
2.1 2.1
创建基本内容
创建基本内容
Workbook 和和和和 Sheet
2.1.1 创建创建创建创建 Workbook
2.1.1
Sheet
Sheet
Workbook
2.1.1
2.1.1
Workbook
Sheet
创建 Workbook 说白了就是创建一个 Excel 文件,当然在 NPOI 中更准确的表示是在内存
中创建一个 Workbook 对象流。
本节作为第 2 章的开篇章节,将做较为详细的讲解,以帮助 NPOI 的学习者更好的理解
NPOI 的组成和使用。
NPOI.HSSF 是专门负责 Excel BIFF 格式的命名空间,供开发者使用的对象主要位于
NPOI.HSSF.UserModel 和 NPOI.HSSF.Util 命名空间下,下面我们要讲到的 Workbook 的创建
用的就是 NPOI.HSSF.UserModel.HSSFWorkbook 类,这个类负责创建.xls 文档。
在开始创建 Workbook 之前,我们先要在项目中引用一些必要的 NPOI assembly,如下
所示:
NPOI.dll
NPOI.POIFS.dll
NPOI.HSSF.dll
NPOI.Util.dll
要创建一个新的 xls 文件其实很简单,只要我们初始化一个新的 HSSFWorkbook 实例就
行了,如下所示:
using NPOI.HSSF.UserModel;
using
NPOI.HSSF.UserModel;
NPOI.HSSF.UserModel;
using
using
NPOI.HSSF.UserModel;
............
HSSFWorkbook hssfworkbook = newnewnewnew HSSFWorkbook();
HSSFWorkbook hssfworkbook =
HSSFWorkbook();
HSSFWorkbook();
HSSFWorkbook hssfworkbook =
HSSFWorkbook hssfworkbook =
HSSFWorkbook();
是不是很方便啊,没有任何参数或设置,但这么创建有一些限制,这样创建出来的
Workbook 在 Excel 中打开是会报错的,因为 Excel 规定一个 Workbook 必须至少带 1 个 Sheet,
这也是为什么在 Excel 界面中,新建一个 Workbook 默认都会新建 3 个 Sheet。所以必须加
入下面的创建 Sheet 的代码才能保证生成的文件正常:
HSSFSheet sheet = hssfworkbook.CreateSheet("new sheet"
HSSFSheet sheet = hssfworkbook.CreateSheet(
"new sheet"););););
"new sheet"
HSSFSheet sheet = hssfworkbook.CreateSheet(
HSSFSheet sheet = hssfworkbook.CreateSheet(
"new sheet"
如果要创建标准的 Excel 文件,即拥有 3 个 Sheet,可以用下面的代码:
hssfworkbook.CreateSheet("Sheet1"
hssfworkbook.CreateSheet(
"Sheet1"););););
"Sheet1"
hssfworkbook.CreateSheet(
hssfworkbook.CreateSheet(
"Sheet1"
hssfworkbook.CreateSheet("Sheet2"
hssfworkbook.CreateSheet(
"Sheet2"););););
"Sheet2"
hssfworkbook.CreateSheet(
hssfworkbook.CreateSheet(
"Sheet2"
ssfworkbook.CreateSheet("Sheet3"
hhhhssfworkbook.CreateSheet(
"Sheet3"););););
"Sheet3"
ssfworkbook.CreateSheet(
ssfworkbook.CreateSheet(
"Sheet3"
最后就是把这个 HSSFWorkbook 实例写入文件了,代码也很简单,如下所示:
@"test.xls", FileMode.Create);
FileStream(@"test.xls"
FileStream file = newnewnewnew FileStream(
FileStream file =
, FileMode.Create);
, FileMode.Create);
@"test.xls"
FileStream(
FileStream file =
FileStream file =
FileStream(
@"test.xls"
, FileMode.Create);
hssfworkbook.Write(file);
hssfworkbook.Write(file);
hssfworkbook.Write(file);
hssfworkbook.Write(file);
file.Close();
file.Close();
file.Close();
file.Close();
这里假设文件名是 test.xls,,在创建完 FileStream 之后,直接调用 HSSFWorkbook
类的 Write 方法就可以了。
最后你可以打开 test.xls 文件确认一下,是不是有 3 个空的 Sheet。
相关范例请见 NPOI 1.2 正式版中的 CreateEmptyExcelFile 项目。
DocumentSummaryInformation 和和和和 SummaryInformation
2.1.2 创建创建创建创建 DocumentSummaryInformation
2.1.2
SummaryInformation
SummaryInformation
DocumentSummaryInformation
2.1.2
2.1.2
DocumentSummaryInformation
SummaryInformation
前一节中我们讲解了如何创建一个新的 Workbook,但在此过程中大家也许会发现一个
细节,这些文件没有包括 DocummentSummaryInformation 和 SummaryInformation 头。如果
你还不是很清楚我在说什么,可以看 POIFS Browser 打开 test.xls 文件后的截图:
你会发现只有 Workbook 目录,其他什么都没有,但事实上一个正常的 xls 文件,比如
说 Excel 生成的 xls 文件是类似下面的结构:
是不是多出来 DocumentSummaryInformation 和 SummaryInformation 两个头?很多人可
能对 DocumentSummaryInformation 和 SummaryInformation 很陌生,可能第一次听说这玩意,
没事,这很正常,因为普通用户很少会去使用这些东西,但它们其实比想象中有用。
请看上图中的信息,如作者、标题、标记、备注、主题等信息,其实这些信息都是存储
在 DocummentSummaryInformation 和 SummaryInformation 里面的,这么一说我想大家应该
明白了吧,这些信息是为了快速提取文件信息准备。在 Windows XP 中,也有对应的查看和
修改界面,只是没有 Vista 这么方便,如下所示:
这恐怕也是很多人对于这些信息漠不关心的原因吧,因为没有人愿意通过 右击文件->
属性 这样复杂的操作去查看一些摘要信息。
提示提示提示提示
DocummentSummaryInformation 和 SummaryInformation 并不是 Office 文件的专利,只
要是 OLE2 格式,都可以拥有这两个头信息,主要目的就是为了在没有完整读取文件数据的
情况下获得文件的摘要信息,同时也可用作桌面搜素的依据。要了解
DocummentSummaryInformation 的全部属性请见
http://msdn.microsoft.com/en-us/library/aa380374(VS.85).aspx;要了解
SummaryInformation 的全部属性请见
http://msdn.microsoft.com/en-us/library/aa369794(VS.85).aspx。
好了,说到这里,我想大家对于接下来我们要创建的内容有了初步的认识,下面我们就
马上动手创建。
首先引用以下这些命名空间:
using NPOI.HSSF.UserModel;
using
NPOI.HSSF.UserModel;
NPOI.HSSF.UserModel;
using
using
NPOI.HSSF.UserModel;
using NPOI.HPSF;
using
NPOI.HPSF;
NPOI.HPSF;
using
using
NPOI.HPSF;
using NPOI.POIFS.FileSystem;
using
NPOI.POIFS.FileSystem;
NPOI.POIFS.FileSystem;
using
using
NPOI.POIFS.FileSystem;
其中与 DocummentSummaryInformation 和 SummaryInformation 密切相关的是 HPSF 命名
空间。
首先创建 Workbook
HSSFWorkbook hssfworkbook = newnewnewnew HSSFWorkbook();
HSSFWorkbook hssfworkbook =
HSSFWorkbook();
HSSFWorkbook();
HSSFWorkbook hssfworkbook =
HSSFWorkbook hssfworkbook =
HSSFWorkbook();
然后创建 DocumentSummaryInformation
DocumentSummaryInformation dsi =
DocumentSummaryInformation dsi =
DocumentSummaryInformation dsi =
DocumentSummaryInformation dsi =
PropertySetFactory.CreateDocumentSummaryInformation();
PropertySetFactory.CreateDocumentSummaryInformation();
PropertySetFactory.CreateDocumentSummaryInformation();
PropertySetFactory.CreateDocumentSummaryInformation();
dsi.Company = """"NPOI Team"
dsi.Company =
NPOI Team";;;;
NPOI Team"
dsi.Company =
dsi.Company =
NPOI Team"
再创建 SummaryInformation
SummaryInformation si = PropertySetFactory.CreateSummaryInformation();
SummaryInformation si = PropertySetFactory.CreateSummaryInformation();
SummaryInformation si = PropertySetFactory.CreateSummaryInformation();
SummaryInformation si = PropertySetFactory.CreateSummaryInformation();
si.Subject = "NPOI SDK Example"
si.Subject =
"NPOI SDK Example";;;;
"NPOI SDK Example"
si.Subject =
si.Subject =
"NPOI SDK Example"
因为是范例,这里仅各设置了一个属性,其他都没有设置。
现在我们把创建好的对象赋给 Workbook,这样才能保证这些信息被写入文件。
hssfworkbook.DocumentSummaryInformation = dsi;
hssfworkbook.DocumentSummaryInformation = dsi;
hssfworkbook.DocumentSummaryInformation = dsi;
hssfworkbook.DocumentSummaryInformation = dsi;
hssfworkbook.SummaryInformation = si;
hssfw
orkbook.SummaryInformation = si;
orkbook.SummaryInformation = si;
hssfw
hssfw
orkbook.SummaryInformation = si;
最后和 2.1.1 节一样,我们把 Workbook 通过 FileStream 写入文件。
相关范例请见 NPOI 1.2 正式版中的 CreatePOIFSFileWithProperties
2.1.3 创建单元格
2.1.3
创建单元格
创建单元格
2.1.3
2.1.3
创建单元格
用过 Excel 的人都知道,单元格是 Excel 最有意义的东西,我们做任何操作恐怕都要和
单元格打交道。在 Excel 中我们要添加一个单元格只需要点击任何一个单元格,然后输入内
容就是了,但是 Excel 底层其实没有这么简单,不同的单元格是有不同的类型的,比如说数
值单元格是用 NumberRecord 表示,文本单元格是用 LabelSSTRecord 表示,空单元格是用
BlankRecord 表示。这也就意味着,在设置单元格时,你必须告诉 NPOI 你需要创建哪种类
型的单元格。
要创建单元格首先要创建单元格所在的行,比如,下面的代码创建了第 0 行:
heet1 = hssfworkbook.CreateSheet("Sheet1"
HSSFSheet sheet1 = hssfworkbook.CreateSheet(
HSSFSheet s
"Sheet1"););););
"Sheet1"
heet1 = hssfworkbook.CreateSheet(
HSSFSheet s
HSSFSheet s
heet1 = hssfworkbook.CreateSheet(
"Sheet1"
HSSFRow row1=sheet1.CreateRow(0);
HSSFRow row1=sheet1.CreateRow(0);
HSSFRow row1=sheet1.CreateRow(0);
HSSFRow row1=sheet1.CreateRow(0);
行建好了,就可以建单元格了,比如创建 A1 位置的单元格:
row1.CreateCell(0).SetCellValue(1);
row1.CreateCell(0).SetCellValue(1);
row1.CreateCell(0).SetCellValue(1);
row1.CreateCell(0).SetCellValue(1);
这里要说明一下,SetCellValue 有好几种重载,你可以设置单元格为 bool、double、
DateTime、string 和 HSSFRichTextString 类型。其中对于 string 类型的重载调用的就是
HSSFRichTextString 类型的重载,所以是一样的,HSSFRichTextString 可用于有字体或者
Unicode 的文本。
如果你觉得每一行要声明一个 HSSFRow 很麻烦,可以用下面的方式:
sheet1.CreateRow(0).CreateCell(0).SetCellValue("This is a Sample"
sheet1.CreateRow(0).CreateCell(0).SetCellValue(
"This is a Sample"););););
"This is a Sample"
sheet1.CreateRow(0).CreateCell(0).SetCellValue(
sheet1.CreateRow(0).CreateCell(0).SetCellValue(
"This is a Sample"
这么用有个前提,那就是第 0 行还没创建过,否则得这么用:
sheet1.GetRow(0).CreateCell(0).SetCellValue("This is a Sample"
sheet1.GetRow(0).CreateCell(0).SetCellValue(
"This is a Sample"););););
"This is a Sample"
sheet1.GetRow(0).CreateCell(0).SetCellValue(
sheet1.GetRow(0).CreateCell(0).SetCellValue(
"This is a Sample"
注意:这里的行在 Excel 里是从 1 开始的,但是 NPOI 内部是从 0 开始的;列在 Excel
里面是用字母表示的,而 NPOI 中也是用从 0 开始的数字表示的,所以要注意转换。
如果你要获得某一个已经创建的单元格对象,可以用下面的代码:
sheet1.GetRow(row_index).GetCell(column_index);
sheet1.GetRow(row_index).GetCell(column_index);
sheet1.GetRow(row_index).GetCell(column_index);
sheet1.GetRow(row_index).GetCell(column_index);
本节仅讲解最基本的单元格创建,有关单元格格式设置、样式等高级话题请见:2.2 节
单元格相关操作。
相关范例请见 NPOI 1.2 正式版中的 SetCellValuesInXls 项目。
2.1.4 创建批注
2.1.4
创建批注
创建批注创建批注
2.1.4
2.1.4
很多人不怎么用 Excel 中的批注,所以我特地截了张图,让大家知道本节我们要创建的
到底是什么东西。
在过去,我们恐怕没有办法实现这一功能,因为无论是 cvs 法、html 法、oledb 法都没
有提供这样的接口,当然 Office PIA 法可以做到,但是性能实在太差,而且稳定性不好,
经常莫名其妙 crash(这是某某兄弟给我的反馈,我引用了下,呵呵)。在以后的教程中,
你将看到更多在过去无法通过传统方法实现的东西,好戏才刚刚开始。
批注主要有三个属性需要设置,一个是批注的位置和大小、一个是批注的文本、还有一
个是批注的作者。
批注的位置和大小,在 Excel 中是与单元格密切相关的,NPOI 中通过 HSSFClientAnchor
的实例来表示,它的构造函数比较复杂,有 8 个参数,它们分别是
参数
说明
dx1
dy1
dx2
dy2
第 1 个单元格中 x 轴的偏移量
第 1 个单元格中 y 轴的偏移量
第 2 个单元格中 x 轴的偏移量
第 2 个单元格中 y 轴的偏移量