Java 如何从 HSSFWorkbook 对象获取输入流
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/378883/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I get an Input Stream from HSSFWorkbook Object
提问by Sergio del Amo
I want my web application users to download some data as an Excel file.
我希望我的 Web 应用程序用户将一些数据下载为 Excel 文件。
I have the next function to send an Input Stream in the response object.
我有下一个函数来在响应对象中发送一个输入流。
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(); }
}
}
}
I would like to transform my HSSFWorkbook Object to an input stream and pass it to the previous method.
我想将我的 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
http://poi.apache.org/apidocs/org/apache/poi/hssf/usermodel/HSSFWorkbook.html
采纳答案by u7867
The problem with your question is that you are mixing OutputStreams and InputStreams. An InputStream is something you read from and an OutputStream is something you write to.
您的问题的问题在于您正在混合 OutputStreams 和 InputStreams。InputStream 是您从中读取的内容,OutputStream 是您写入的内容。
This is how I write a POI object to the output stream.
这就是我将 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
}
}
If you wanted to re-use your existing code you'd have to store the POI data somewhere then turn THAT into an input stream. That'd be easily done by writing it to a ByteArrayOutputStream, then reading those bytes using a ByteArrayInputStream, but I wouldn't recommend it. Your existing method would be more useful as a generic Pipe implementation, where you can pipe the data from an InputStream to and OutputStream, but you don't need it for writing POI objects.
如果您想重新使用现有代码,则必须将 POI 数据存储在某处,然后将其转换为输入流。通过将其写入 ByteArrayOutputStream,然后使用 ByteArrayInputStream 读取这些字节,这很容易完成,但我不推荐它。您现有的方法作为通用 Pipe 实现会更有用,您可以在其中将数据从 InputStream 传送到 OutputStream,但不需要它来编写 POI 对象。
回答by lucas
I think I understand what you're trying to do (maybe I am undershooting, though)
我想我明白你想要做什么(不过,也许我没有达到目标)
you don't really need that much code - check out the write method -
你真的不需要那么多代码 - 查看 write 方法 -
HSSFWorkbook wb = new HSSFWorkBook();
//populate
ServletOutputStream out = response.getOutputStream();
try {
wb.write(out);
out.flush();
}
catch (IOException ioe) {
//whatever
}
out.close();
As far as I remember when I worked w/ POI that's what I did. If you're inside a web framework you may have to finaggle it so that the framework doesn't try to do something with the that ServletOutputStream after you've closed it. If it tries, you'll get an exception throwing telling you that the output stream is closed already.
据我记得,当我和 POI 一起工作时,我就是这么做的。如果您在 Web 框架内,则可能必须对其进行调整,以便框架在您关闭该 ServletOutputStream 后不会尝试对其执行任何操作。如果它尝试,您将收到一个异常抛出,告诉您输出流已经关闭。
回答by Xiong xiao Luo
you can create a InputStream from a object.
您可以从对象创建 InputStream 。
public InputStream generateApplicationsExcel() {
HSSFWorkbook wb = new HSSFWorkbook();
// Populate a InputStream from the excel object
return new ByteArrayInputStream(excelFile.getBytes());
}
回答by Laurent
My solution is to transfer the HSSFWorkbook to ByteArrayOutputStream first, and then create an InputStream from ByteArrayOutputStream :
我的解决方案是先将 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());