0

我在我的 Bean 中生成了一个 exportList:

    public void exportExcel() throws WriteException {
    try {
        FacesContext context = FacesContext.getCurrentInstance();
        HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();
        response.setContentType("application/vnd.ms-excel");
        response.setHeader("Content-Disposition", "attachment; filename=\"hours.xls\";");
        OutputStream out = response.getOutputStream();

        WorkbookSettings ws = new WorkbookSettings();
        ws.setLocale(new Locale("de", "DE"));
        WritableWorkbook workbook = Workbook.createWorkbook(out, ws);
        WritableSheet sheet = workbook.createSheet("Sheet1", 0);
        sheet.addCell(new Label(0, 0, "ID", bold));
        int row = 1;
        for (Hour hour : this.listHours) {
            sheet.addCell(new Label(0, row, String.valueOf(hour.getId())));
            row++;
        }

        SheetFormatter.setOptimalColumnWidth(sheet);
        workbook.write();
        workbook.close();
        response.flushBuffer();
        context.responseComplete();
        context.addMessage(null, new FacesMessage("Liste Exportiert"));
    }
    catch (Exception e) {
    }
}

在我的页面中,我调用 p:commandButton 中的方法

    <p:commandButton  value="#{msg.export}" update="growl"
                    immediate="true" action="#{hoursView.exportExcel()}" />

我的页面不会打开 excel 列表...如果添加属性 ajax="false" 它可以工作,但更新将不会执行...

有关信息,如果这会产生一些差异,我的 Bean 是 SessionScoped

4

1 回答 1

2

您的第一个错误是您尝试使用 ajax 下载文件。那是不可能的。Ajax 由 JavaScript 代码执行,由于安全原因,该代码无法强制“另存为”对话和/或将检索到的响应写入本地磁盘文件系统。否则,这将为各种令人讨厌的安全漏洞可能性打开大门。

所以,使用ajax="false"是绝对必要的。

您的第二个错误是您试图将不同的响应混合成一个响应。那是不可能的。您只能返回文件下载或 ajax 更新,不能同时返回。要检索两个不同的响应,您基本上需要让客户端发送两个不同的请求。您可以按如下方式处理:

  1. 让客户端向支持 bean 发送一个 ajax 请求。
  2. 让服务器创建 Excel 文件并将其保存在服务器的临时存储系统中,并生成一个唯一的 URL,以便 servlet 可以访问它。
  3. 让服务器发送一个包含消息和 URL 的 ajax 响应。
  4. 让客户端显示消息并在 URL 上调用新的 GET 请求。您可以使用window.location=url;让 JavaScript 在 URL 上调用新的 GET 请求。
于 2012-08-24T11:39:52.257 回答