我希望我的网络应用程序用户将一些数据下载为Excel文件。
我有下一个函数在响应对象中发送输入流。
public static void sendFile(InputStream is, HttpServletResponse response) throws IOException {
BufferedInputStream in = null;
try {
int count;
byte[] buffer = new byte[BUFFER_SIZE];
in = new BufferedInputStream(is);
ServletOutputStream out = response.getOutputStream();
while(-1 != (count = in.read(buffer)))
out.write(buffer, 0, count);
out.flush();
} catch (IOException ioe) {
System.err.println("IOException in Download::sendFile");
ioe.printStackTrace();
} finally {
if (in != null) {
try { in.close();
} catch (IOException ioe) { ioe.printStackTrace(); }
}
}
}
我想将我的HSSFWorkbook对象转换为输入流并将其传递给前一个方法。
public InputStream generateApplicationsExcel() {
HSSFWorkbook wb = new HSSFWorkbook();
// Populate the excel object
return null; // TODO. return the wb as InputStream
}
http://poi.apache.org/apidocs/org/apache/poi/hssf/usermodel/HSSFWorkbook.html
答案 0 :(得分:10)
您的问题是您正在混合OutputStreams和InputStreams。 InputStream是您读取的内容,OutputStream是您写入的内容。
这是我将POI对象写入输出流的方式。
// this part is important to let the browser know what you're sending
response.setContentType("application/vnd.ms-excel");
// the next two lines make the report a downloadable file;
// leave this out if you want IE to show the file in the browser window
String fileName = "Blah_Report.xls";
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
// get the workbook from wherever
HSSFWorkbook wb = getWorkbook();
OutputStream out = response.getOutputStream();
try {
wb.write(out);
}
catch (IOException ioe) {
// if this happens there is probably no way to report the error to the user
if (!response.isCommited()) {
response.setContentType("text/html");
// show response text now
}
}
如果您想重新使用现有代码,则必须将POI数据存储在某处,然后将其转换为输入流。这可以通过将其写入ByteArrayOutputStream,然后使用ByteArrayInputStream读取这些字节来轻松完成,但我不推荐它。您现有的方法作为通用管道实现会更有用,您可以将数据从InputStream传递到OutputStream,但是您不需要它来编写POI对象。
答案 1 :(得分:2)
我的解决方案是先将HSSFWorkbook传输到ByteArrayOutputStream,然后从ByteArrayOutputStream创建一个InputStream:
HSSFWorkbook wb = ...
// Fill an empty output stream
ByteArrayOutputStream baos = new ByteArrayOutputStream();
wb.write(baos);
// Close the document
wb.close();
// Create the input stream (do not forget to close the inputStream after use)
InputStream is = new ByteArrayInputStream(baos.toByteArray());
答案 2 :(得分:1)
您可以从对象创建一个InputStream。
public InputStream generateApplicationsExcel() {
HSSFWorkbook wb = new HSSFWorkbook();
// Populate a InputStream from the excel object
return new ByteArrayInputStream(excelFile.getBytes());
}
答案 3 :(得分:0)
我想我明白你要做的事情(也许我正在低估)
你真的不需要那么多代码 - 请查看write方法 -
HSSFWorkbook wb = new HSSFWorkBook();
//populate
ServletOutputStream out = response.getOutputStream();
try {
wb.write(out);
out.flush();
}
catch (IOException ioe) {
//whatever
}
out.close();
据我记得当我和POI一起工作时,我就是这么做的。如果你在一个Web框架内,你可能需要对其进行处理,以便框架在关闭它之后不会尝试对该ServletOutputStream执行某些操作。如果它尝试,你将得到一个异常抛出告诉你输出流已经关闭。