Java Apache POI: запись рабочей книги в ServletOutputStream зависает до нажатия кнопки в браузере клиента - PullRequest
2 голосов
/ 24 января 2012

Этот код создает рабочую книгу и отправляет ее в браузер клиента. Это почти нормально, ответ отправляется обратно в браузер, и в браузере открывается приятное всплывающее окно с просьбой сохранить, открыть файл или отменить всю операцию. Классический.

Дело в том, что, если я отлаживаю этот код, иногда и только в IE , Java-машина застрянет на линии wb.write (out); (но у меня все еще есть файл Excel, отправленный клиенту, я могу загрузить его, и все в порядке).

Проблема в том, что я хотел поместить некоторый код после этой строки, поэтому иногда он не выполняется.

Любая подсказка?

public static void export(List<ExportSheetData> exportSheetsData, String fileName) throws IOException {

    FacesContext context = FacesContext.getCurrentInstance();
    HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext()
            .getResponse();
    response.setContentType("application/vnd.ms-excel");
    String headerResponse = "attachment;filename=";
    headerResponse = headerResponse.concat(fileName);
    response.addHeader("Content-disposition", headerResponse);
    ServletOutputStream out = response.getOutputStream();

    Workbook wb = new XSSFWorkbook();
    for (ExportSheetData exportSheetData : exportSheetsData) {
        Sheet sheet = wb.createSheet(exportSheetData.getTitle());
                    // creating workbook here...
    }

    wb.write(out); // JVM sometimes get stucked here
    out.flush();
    out.close();
    context.responseComplete();

}

1 Ответ

3 голосов
/ 24 января 2012

JVM останавливается здесь, потому что ничего не читает из потока на другой стороне.Следующая строка будет выполнена после загрузки всего файла.Firefox, Opera и Chrome начинают загрузку, прежде чем нажать «Сохранить».При нажатии «отмена» - файл удаляется.IE ожидает загрузки для вашего клика.

Однажды у меня была похожая проблема, и я создал другой поток, который записывал в поток, в то время как этот поток занимался чем-то другим.

Вы также можете попробоватьобернуть поток вывода в BufferedOutputStream.Должно работать, если файл достаточно мал и помещается в буфер.

...