0

我正在使用 Apache POI 生成带有 .docx 扩展名的文档。我在标头响应(HttpServletResponse)中设置了文件名,但是浏览器在我的 URL 末尾保存了一个同名文件,例如:

我的浏览器中的URL是:localhost:8080/MyProject/mypage.jsf,下载的文件的名字是mypage.jsf,忽略头部设置的名字(HttpServletResponse)。如果我编辑 docx 的文件扩展名,内容就可以了。

这是代码:

    private void generateDocument() throws IOException{
      XWPFDocument document = new XWPFDocument();
      //load document here

        FacesContext facesContext = FacesContext.getCurrentInstance();
        HttpServletResponse response = (HttpServletResponse) facesContext
                .getExternalContext().getResponse();

        response.reset();
        response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");

        ServletOutputStream out = response.getOutputStream();
        document.write(out);

        response.setHeader("Content-Disposition",
                "attachment; filename=my_document.docx");
        facesContext.responseComplete();            
}

附言。我正在使用 Richfaces 4

谢谢

4

1 回答 1

0

从评论升级为答案:

在写入 servlet 输出流之前,您应该将 response.setHeader 调用移至。除非您的框架正在进行大量缓冲,否则框架将在您完成将 excel 文件写入流之前很久就发送响应标头。标头必须在数据之前发送,因此一旦您开始发送数据,您就不能再添加新的标头。

(大多数框架都会做一点缓冲,所以在处理简单的文本输出时,即使在写出几行响应之后,您也经常可以偷偷添加一些额外的标题。如果可以避免的话,最好不要依赖它! )

您的代码应更改为:

    FacesContext facesContext = FacesContext.getCurrentInstance();
    HttpServletResponse response = (HttpServletResponse) facesContext
            .getExternalContext().getResponse();

    response.reset();
    response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
    response.setHeader("Content-Disposition",
            "attachment; filename=my_document.docx");

    ServletOutputStream out = response.getOutputStream();
    document.write(out);

    facesContext.responseComplete();          
于 2012-07-27T08:12:57.497 回答