// 清空response response.reset(); // 设置response的Header response.addHeader("Content-Disposition", "attachment;filename=Shit.xls"); OutputStream out = new BufferedOutputStream(response.getOutputStream()); response.setContentType("application/octet-stream"); HSSFWorkbook workbook = new HSSFWorkbook(); HSSFSheet sheet = workbook.createSheet("sheet"); ......//填充数据到sheet中 workbook.write(out); out.flush(); out.close();但是代码不在Action中的话,我们不能够在Struts框架中对文件的上传下载进行一些控制,所以需要把这段代码放置到Action中去。于是我遇到了这个问题:在Struts中下载文件的办法是提供一个stream类型的返回结果,并且需要在Action中提供一个返回结果为InputStream类型的get方法,于是Struts会自动调用这个get方法来读取源文件,如果服务器已经存有现成的文件,那么这二个InputStream很好满足,只要一个FileInputStream就OK了,但是像POI生成的Excel这种情况该怎么办呢?使用InputStream必须要提供给他一个现成的数据源,但POI并没有真正生成一个文件存放在服务器上,而是提供一个workbook.write(out)的方法将数据流写入到out中。
最早我考虑的办法是先将Excel写入到一个临时文件,然后读取读取这个文件提供FileInputStream输入流,最后再把这个文件删除,可是这种做法太过曲折,不优雅。彷徨之际,两个Java类帮了我的大忙,它们就是:ByteArrayInputStream和ByteArrayOutputStream。于是我先将workbook写入到ByteArrayOutputStream中,然后用ByteArrayInputStream读取这个ByteArrayOutputStream中的数据,因为ByteArrayInputStream是InputStream的派生类,所以最后可以提供给Struts一个InputStream,问题就这样解决了!主要的代码如下:
ByteArrayOutputStream baos = new ByteArrayOutputStream(); workbook.write(baos); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); return bais;