如何修复损坏要下载的 xls 文件的 ExternalContext 调用?
How to fix ExternalContext call that corrupts xls file to download?
我有一个使用 jett 生成报告并为用户显示文件下载对话框的方法:
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
externalContext.responseReset();
externalContext.setResponseContentType("application/vnd.ms-excel");
externalContext.setResponseHeader("Content-Disposition", "attachment; filename=\"" + "precificacao.xls" + "\"");
//map beans omitted
FileOutputStream saida = null;
try {
saida = new FileOutputStream(getClass().getResource("/.").getPath() + "/precificacao.xls");
} catch (IOException e) {
System.err.println(getClass().getResource("/.").getPath() + "/precificacao.xls" + ": " + e.getMessage());
}
InputStream entrada = null;
try {
entrada = new BufferedInputStream(new FileInputStream(getClass().getResource("/template.xls").getFile()));
ExcelTransformer transformer = new ExcelTransformer();
Workbook workbook = transformer.transform(entrada, beans);
workbook.write(saida);
saida.flush();
saida.close();
facesContext.responseComplete();
} //catch ommitted
下载的文件已经损坏,为文本文档,没有任何字节:
print
在此下载对话框例程之前,xls 是正常生成的,所以我认为是 setResponseContentType 出错了,尽管我在 xls 的正确命名法中看到了 link:http://www.iana.org/assignments/media-types
您是知道您没有将excel的内容写入响应吗?所以响应实际上是空的,因此会导致各种奇怪的行为。
你甚至自己写这个:
without any byte
你在图像中有它...
对于 PDF、图像甚至纯文本文件,您可能会遇到同样的问题(尽管不会给出错误,只是为空)
您甚至会在使用普通 servlet 时遇到同样的问题。因此,实际上您的所有标签(excel、jsf、jsf-2、xls)都与问题无关。缩小范围。
从上下文获取输出流并将工作簿写入该流应该可以解决这个问题。
OutputStream saida = externalContext.getResponseOutputStream();
我是这样解决的
public void createRelatorioFichaTecnica(Produto produto) throws IOException {
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
externalContext.responseReset();
externalContext.setResponseContentType("application/vnd.ms-excel");
externalContext.setResponseHeader("Content-Disposition", "attachment; filename=\"" + "precificacao.xls" + "\"");
//map beans omitted
OutputStream saida = externalContext.getResponseOutputStream();
try{
InputStream entrada = new BufferedInputStream(new FileInputStream(getClass().getResource("/template.xls").getFile()));
ExcelTransformer transformer = new ExcelTransformer();
Workbook workbook = transformer.transform(entrada, beans);
workbook.write(saida);
saida.flush();
saida.close();
facesContext.responseComplete();
}
//catch omitted
}
我有一个使用 jett 生成报告并为用户显示文件下载对话框的方法:
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
externalContext.responseReset();
externalContext.setResponseContentType("application/vnd.ms-excel");
externalContext.setResponseHeader("Content-Disposition", "attachment; filename=\"" + "precificacao.xls" + "\"");
//map beans omitted
FileOutputStream saida = null;
try {
saida = new FileOutputStream(getClass().getResource("/.").getPath() + "/precificacao.xls");
} catch (IOException e) {
System.err.println(getClass().getResource("/.").getPath() + "/precificacao.xls" + ": " + e.getMessage());
}
InputStream entrada = null;
try {
entrada = new BufferedInputStream(new FileInputStream(getClass().getResource("/template.xls").getFile()));
ExcelTransformer transformer = new ExcelTransformer();
Workbook workbook = transformer.transform(entrada, beans);
workbook.write(saida);
saida.flush();
saida.close();
facesContext.responseComplete();
} //catch ommitted
下载的文件已经损坏,为文本文档,没有任何字节: print
在此下载对话框例程之前,xls 是正常生成的,所以我认为是 setResponseContentType 出错了,尽管我在 xls 的正确命名法中看到了 link:http://www.iana.org/assignments/media-types
您是知道您没有将excel的内容写入响应吗?所以响应实际上是空的,因此会导致各种奇怪的行为。
你甚至自己写这个:
without any byte
你在图像中有它...
对于 PDF、图像甚至纯文本文件,您可能会遇到同样的问题(尽管不会给出错误,只是为空)
您甚至会在使用普通 servlet 时遇到同样的问题。因此,实际上您的所有标签(excel、jsf、jsf-2、xls)都与问题无关。缩小范围。
从上下文获取输出流并将工作簿写入该流应该可以解决这个问题。
OutputStream saida = externalContext.getResponseOutputStream();
我是这样解决的
public void createRelatorioFichaTecnica(Produto produto) throws IOException {
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
externalContext.responseReset();
externalContext.setResponseContentType("application/vnd.ms-excel");
externalContext.setResponseHeader("Content-Disposition", "attachment; filename=\"" + "precificacao.xls" + "\"");
//map beans omitted
OutputStream saida = externalContext.getResponseOutputStream();
try{
InputStream entrada = new BufferedInputStream(new FileInputStream(getClass().getResource("/template.xls").getFile()));
ExcelTransformer transformer = new ExcelTransformer();
Workbook workbook = transformer.transform(entrada, beans);
workbook.write(saida);
saida.flush();
saida.close();
facesContext.responseComplete();
}
//catch omitted
}