如何在Struts的Action中直接使用POI生成Excel并下载

        前段时间需要做一个导出Excel的功能,用的POI,以前我的做法是模仿前人的代码,在Servlet中生成需要导出的Excel,然后调用workbook.write(out)将生成的Excel文件流写入到OutputStream out中去,其中out是由response.getOutputStream()得到的,当然一般我们都会OutputStream out = new BufferedOutputStream(response.getOutputStream())来提高效率,这样就可以生成对客户端的下载响应,主要代码如下:
		// 清空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;

猜你喜欢

转载自mossad.iteye.com/blog/1562255