NPOI锦囊:如何用NPOI生成可下载的Excel
作者:Tony Qu
NPOI官方教程:http://tonyqus.sinaapp.com |
请给国产开源项目NPOI投上一票,谢谢,投票请猛击这里。记得别投错了~是NPOI,投错了打小屁屁,呵呵。
这其实是个老话题,但近期问的人实在有点多,所以我决定写篇文章帮助大家巩固基础知识。
下载Xls的主要问题是如何让浏览器知道你下载的是xls文件而不是一个网页,因为通常你下载时访问的都是一个网页地址,如download.aspx。
这个问题可以通过设置ContentType来解决,如下所示
1
2
3
4
|
Response.ContentType =
"application/vnd.ms-excel"
;
Response.AddHeader(
"Content-Disposition"
,
string
.Format(
"attachment;filename={0}"
,filename));
Response.Clear();
|
这里我们把ContentType设置为ms-excel,请注意这里仅支持Excel 2003文件格式,Excel 2007的格式是另外一种ContentType,不能混用。这里的Header主要是为了让浏览器知道应该保存为哪个文件名。
下载的时候,你会看到Firefox以下窗口弹出,由于我们刚才设置了类型,所以Firefox才会知道这个文件是Excel2003 文件,其实浏览器没有这么聪明,做不到自动检测文件格式。然后文件名是我们在Header中指定的名字,这里是test.xls。
接下来,我们要做的是把二进制流写入Response里面。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
HSSFWorkbook hssfworkbook;
MemoryStream GetExcelStream()
{
//Write the stream data of workbook to the root directory
MemoryStream file =
new
MemoryStream();
hssfworkbook.Write(file);
return
file;
}
using
(MemoryStream file =
new
MemoryStream())
{
hssfworkbook.Write(file);
GetExcelStream().WriteTo(Response.OutputStream);
}
|
这里是把HSSFWorkbook的数据写入MemoryStream,然后通过MemoryStream的WriteTo最后写入Response。请注意,这种写法有个非常大的好处就是省内存,可能有些人没有看出名堂,不就是Stream嘛,和省内存有什么关系,其实还有一种不好的写法,如下:
1
2
|
Response.BinaryWrite(GetExcelStream().GetBuffer());
这种写法呢,唯一的区别在于中间会生成一个
byte
[]临时变量数据,这个数据是取决于你的xls的大小的,文件越大数组越大,占用的内存就越多。
|
1
|
这里呢,牵扯到一个面试题叫Stream和
byte
[]有何区别,为什么?既然是面试题,我就不说答案了,大家当回家作业,不过么我上面基本已经说了一半了,肯定Stream比
byte
[]好,至于怎么好法你们就自己琢磨吧。
|
1
|
|
1
|
另外,有网友提供了ASP.NET MVC 3的下载代码,一并在这里列出
|
1
2
3
4
5
6
7
8
9
|
public
ActionResult Test()
{
//Excel功能
HSSFWorkbook hssfworkbook =
new
HSSFWorkbook();
//新建一个xls文件
ISheet sheet = hssfworkbook.CreateSheet(“newsheet”);
//创建一个sheet
MemoryStream filestream =
new
MemoryStream();
//内存文件流(应该可以写成普通的文件流)
hssfworkbook.Write(filestream);
//把文件读到内存流里面
return
new
FileContentResult(filestream.GetBuffer(), “application/vnd.ms-excel”);
}
|
但这FileContentResult貌似不支持Stream,只能先用byte[]了,有人如果有更好的方法,请在评论中列出,谢谢。