Java 如何从HSSFWorkbook对象获取输入流

Java 如何从HSSFWorkbook对象获取输入流,java,apache-poi,Java,Apache Poi,我希望我的web应用程序用户下载一些数据作为Excel文件 我有下一个函数在响应对象中发送输入流 public static void sendFile(InputStream is, HttpServletResponse response) throws IOException { BufferedInputStream in = null; try { int count; byte[] buffer = ne

我希望我的web应用程序用户下载一些数据作为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 
}

我想我明白你想做什么(不过,也许我没做到)

你其实不需要那么多的代码-查看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后不会尝试对其进行处理。如果尝试,您将得到一个异常抛出,告诉您输出流已经关闭。

您的问题是您正在混合输出流和输入流。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数据存储在某个地方,然后将其转换为输入流。通过将其写入ByteArrayInputStream,然后使用ByteArrayInputStream读取这些字节,很容易做到这一点,但我不推荐这样做。作为一个通用管道实现,您现有的方法会更有用,您可以将数据从InputStream管道传输到和OutputStream,但在编写POI对象时不需要它。

您可以从对象创建InputStream

public InputStream generateApplicationsExcel() {
    HSSFWorkbook wb = new HSSFWorkbook();
    // Populate a InputStream from the excel object
    return new ByteArrayInputStream(excelFile.getBytes());
}

我的解决方案是首先将HSSF工作簿传输到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());

+1例如。但如何获得HSSF工作簿的文件大小?我想添加一个头
Content Length
@MyTitle我想如果你想设置一个Content Length头,你需要先将流写入ByteArrayOutputStream,然后获取它的长度,然后将它写入HTTP响应。