Как я могу получить входной поток из объекта HSSFWorkbook

StackOverflow https://stackoverflow.com/questions/378883

  •  22-08-2019
  •  | 
  •  

Вопрос

Я хочу, чтобы пользователи моего веб-приложения загружали некоторые данные в виде файла Excel.

У меня есть следующая функция для отправки входного потока в объекте response.

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

Это было полезно?

Решение

Проблема с вашим вопросом заключается в том, что вы смешиваете OutputStreams и InputStreams.Входной поток - это то, из чего вы читаете, а Выходной поток - это то, в что вы записываете.

Вот как я записываю объект 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 и в OutputStream, но вам это не нужно для записи объектов POI.

Другие советы

вы можете создать входной поток из объекта.

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

Я думаю, я понимаю, что вы пытаетесь сделать (хотя, возможно, я недоговариваю)

на самом деле вам не нужно так много кода - ознакомьтесь с методом write -

HSSFWorkbook wb = new HSSFWorkBook();
//populate

ServletOutputStream out = response.getOutputStream();
try {
   wb.write(out);
   out.flush();
}       
catch (IOException ioe) { 
   //whatever
}
out.close();

Насколько я помню, когда я работал без POI, именно этим я и занимался.Если вы находитесь внутри веб-фреймворка, вам, возможно, придется настроить его так, чтобы фреймворк не пытался что-то сделать с этим ServletOutputStream после того, как вы его закроете.Если он попытается, вы получите выдачу исключения, сообщающего вам, что выходной поток уже закрыт.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top