在这里,我们要使用一个POI插件。使用里面定义的类和方法就可以操作excel文件了。
如下:
HSSFWorkbook wb = new HSSFWorkbook(); //建立工作薄
HSSFSheet sheet = wb.createSheet("sheet1");//建立一张表sheet
HSSFRow row = sheet.createRow(0);//建立第一行
//我们要在第一行中建立几个单元格
//第一格
HSSFCell cell = row.createCell((short) 0);
cell.setEncoding(HSSFCell.ENCODING_UTF_16);//中文编码
cell.setCellValue("序号");//设置值
----------------------------
--------------------------------
List<User> list = this.findAll();//这里查询数据库操作,并将查询到的结果送至List对象中
//以下的功能是实现将List中的内容放置到单元格中
for (int i = 0; i < list.size(); ++i)
{
User user = list.get(i);
row = sheet.createRow(i + 1);
cell = row.createCell((short) 0);
cell.setEncoding(HSSFCell.ENCODING_UTF_16);
cell.setCellValue(i + 1);
cell = row.createCell((short) 1);
cell.setEncoding(HSSFCell.ENCODING_UTF_16);
cell.setCellValue(user.getFirstname());
-------------------------------------
---------------------------------------
}
//然后我们将内容放置到内存中,也即放置到字节输出流中对象中
ByteArrayOutputStream os = new ByteArrayOutputStream();
wb.write(os);//将将wb写至os中,这里还要捕获异常
byte[] content = os.toByteArray();//得到字节
InputStream is = new ByteArrayInputStream(content);//字节写入内存
这样就生成了一个流入流对象is了,然后可以返回出去
还有一种方法,就是生成一个文件,然后用一个线程延时一段时间,再将其删除掉,为防止没有及有删除临时文件而使其成为永久文件,我们还可以做一个servlet,在其init()函数中实现删除指定上当下该类型的所有文件.以下为实现方式.
String fileName = RandomStringUtils.randomAlphanumeric(10);//利用apache内部提拱的包类,生成一个10位的随机的文件名
fileName = new StringBuffer(fileName).append(".xls").toString();//加上扩展名
final File file = new File(fileName);//因为要在内部类实现之,只有要申明为final型
try
{
OutputStream os = new FileOutputStream(file);//文件输出流
wb.write(os);//写入至该对象中
os.close();//关闭
}
catch (Exception e)
{
e.printStackTrace();//处理异常
}
InputStream is = null;/申明输入流
try
{
is = new FileInputStream(file);//初始化文件输入流
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
//使用一个线程来捕捉,每过一段时间(15s),将该文件删除掉.
new Thread(new Runnable()
{
public void run()
{
try
{
Thread.sleep(15000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
file.delete();//删除临时文件
}
}).start();//启动线程
//如果有时我们在关闭服务器的时候,如果没有即时删除掉该临时文件,于是就会出现成为永久性文件
这样我们就要使用一个servlet类来处理这种情况,我们只要init()函数中进行删除操作即可,然后在web.xml中对应的
<servlet></servlet>中加入<servlet-name>DeleteFilesServlet</servlet-name>
<servlet-class>com.test.servlet.DeleteFilesServlet</servlet-class>
<load-on-startup>8</load-on-startup>
即可,我们又不关注该servlet什么时候运行,也即先后顺序,只在能启动这类即可,还有就是我们并不需要客户端访问这个servlet类,
所以不需要使用<servlet-mapping></servlet-mapping>
下面我们来讲讲这个服务器servlet类。
在init()函数中加入如下代码:
File file = new File(".");//表示当前目录。也可以使用 System.getProperty("user.dir");
//下面设置文件过滤器,对该目录下所有的文件进行过滤.
File[] subFiles = file.listFiles(new FileFilter()
{
public boolean accept(File pathname)
{
if(pathname.getName().endsWith("xls"))
//如果后缀名为xls的文件筛选出来
{
return true; //返回成功
}
return false;
}
}
);
//然后进行删除
for(File f : subFiles)//这里的for语句并不是传统意义上的那个for(;;)。
{
f.delete();//删除操作
}
}
最后我要讲的是我们返回出去的那个is(inputStream)对象,是如何被Action使用的呢?
首先我们在struts.xml中的<package></package>中加入
<action name="generateExcel" class="generateExcelAction">
<result name="success" type="stream">
<param name="contentType">application/vnd.ms-excel</param>
<param name="contentDisposition">filename="AllUsers.xls"</param>
<param name="inputName">downloadFile</param>
</result>
</action>
//这里第一个参数 result下,type为stream表示二进制格式
contentType表示下载的文件,为xls后缀名
contentDisposition中的filename指示文件名
inputName表示action中类可以使用getDownloadFile()开得到该is(inputStream)对象了.
即要getDownloadFile()只需加入
return this.service.getInputStream();即可
这样在jsp前端的一个超链接,只需提拱<s:a herf="action.do">下载</a>这个action就慢我们之前定义的generateExcelAction
这样就可以实现一个下载文件的功能了。
《待续》。。。。。。