我正在使用ApachePOI生成扩展名为. 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();
}
PS我用的是Richfaces4
谢啦
促进从评论到回答:
您应该在写入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();