【问题标题】:How to fix ExternalContext call that corrupts xls file to download?如何修复损坏 xls 文件下载的 ExternalContext 调用?
【发布时间】:2017-09-08 13:27:57
【问题描述】:

我有一个使用 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 正确命名法中的链接:http://www.iana.org/assignments/media-types

【问题讨论】:

  • 如果您设置内容类型怎么办?
  • 它以同样的方式损坏......我尝试了几次不同的 ExternalContext 调用,但它总是损坏......建议@Kukeltje?
  • 建议调试响应...大小是多少,是空的吗?如果你下载一个固定的excel怎么办?如果你下载一个固定的 PDF,如果你下载一个固定的图像会怎么样(都是通过同样的结构)。消除事物...缩小原因...设置断点...
  • 那你解决了吗?
  • 我会发布答案

标签: excel jsf jsf-2 download xls


【解决方案1】:

是否知道您无处将 excel 的内容写入响应?所以响应实际上是空的,因此会导致各种奇怪的行为。

你甚至自己写这个:

没有任何字节

你把它放在图像中......

对于 PDF、图像甚至纯文本文件,您也会遇到同样的问题(尽管这不会出错,只是为空)

您甚至会遇到与普通 servlet 相同的问题。因此,您的所有标签(excel、jsf、jsf-2、xls)实际上都与问题无关。缩小范围。

从上下文中获取输出流并将工作簿写入该流应该可以修复它。

OutputStream saida = externalContext.getResponseOutputStream(); 

【讨论】:

    【解决方案2】:

    我是这样解决的

    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
    }
    

    【讨论】:

    • 感谢您接受我的回答和我的调查。不知道下次我是否会努力再次分析问题代码......
    • 感谢您的帮助!
    猜你喜欢
    • 2021-02-18
    • 1970-01-01
    • 1970-01-01
    • 2017-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-01
    • 1970-01-01
    相关资源
    最近更新 更多