Java Apache POI:将工作簿写入 ServletOutputStream 挂起,直到在客户端浏览器中单击按钮

发布于 2024-12-28 12:49:57 字数 1247 浏览 2 评论 0原文

此代码创建一个工作簿并将其发送到客户端浏览器。几乎没问题,响应被发送回浏览器,浏览器中会打开一个漂亮的弹出窗口,要求保存、打开文件或取消整个操作。经典的。

问题是,如果我调试这段代码,有时,并且仅在 IE 中,java 机器将卡在 wb.write(out); 行上。 em>(但我仍然有我的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();

}

This code creates a workbook and send it to client browser. It's almost fine, response is sent back to browser and a nice popup opens up in browser asking to save, open file, or cancel the whole operation. Classic.

The thing is, if I debug this code, sometimes, and only in IE, java machine will get stucked on line wb.write(out); (but I still have my excel file sent to client, I can download it and it's ok).

Problem is I wanted to put some code after this line, so sometimes it's not executed.

Any clue ?

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();

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

末骤雨初歇 2025-01-04 12:49:57

JVM 在此停止,因为没有从另一端的流中读取任何内容。下载整个文件后将执行下一行。 Firefox、Opera 和 Chrome 在您单击“保存”之前开始下载。当您单击“取消”时,文件将被删除。 IE 等待您点击下载。

我曾经遇到过类似的问题,我创建了另一个线程,该线程正在写入流,而该线程正在做其他事情。

您还可以尝试将输出流包装到 BufferedOutputStream 中。如果文件足够小并且适合缓冲区,它应该可以工作。

JVM stops here because nothing reads from the stream on the other side. Next line will be executed after whole file is downloaded. Firefox, Opera and Chrome starts download before you click "save". When you click "cancel" - the file is deleted. IE waits with download for your click.

I had similiar problem once and I've created another Thread that was writing to a stream while this thread wa doing something else.

You can also try to wrap output stream into a BufferedOutputStream. It should work if the file is small enough and fits into a buffer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文