当我从Java下载Excel文件时不显示“另存为”窗口,但文件已正确保存

时间:2013-05-16 16:05:37

标签: java richfaces seam

当我点击我的应用程序的“导出文件”选项时,我想向用户显示“另存为”Windows,该文件是我使用Apache POI创建的excel 2007。该文件已正确保存在文件夹“D:\ jboss-6.1.0.Final \ bin”中,但不要显示“另存为”窗口,它会重定向到带有奇怪符号和字符的页面

最奇怪的是我有其他按钮可以在我的应用程序的其他页面下载excel文件,并且与POI相同的代码y也会正常显示“另存为”。

为什么会这样?

谢谢。

我附上了一张图片。enter image description here

功能导出的代码是:

public void exportarTabla(){

    XSSFWorkbook workbook = new XSSFWorkbook(); 
    XSSFSheet sheet = workbook.createSheet("Hoja 1");           
    XSSFRow row;
    XSSFCell cell;

    for (int i = 0; i < getLstEtiquetasCol().size(); i++) {
        row = sheet.createRow(i+3);
        for (int j = 0; j < getLstEtiquetasCol().get(i).size(); j++) {
            cell = row.createCell(j+3+getLstEtiquetasFil().get(0).size());
            cell.setCellValue(getLstEtiquetasCol().get(i).get(j).getValor().getEtiqueta());                 
        }
    }


    for (int i = 0; i < getLstEtiquetasFil().size(); i++) {
        row = sheet.createRow( i+3+getLstEtiquetasCol().size());
        for (int j = 0; j < getLstEtiquetasFil().get(i).size(); j++) {
            cell = row.createCell(j+3);
            cell.setCellValue(getLstEtiquetasFil().get(i).get(j).getValor().getEtiqueta()); 
        }
    }


    for (int i = 0; i < getTableContact().size(); i++) {
        row = sheet.getRow(  i+3+getLstEtiquetasCol().size());
        for (int j = 0; j < getTableContact().get(i).size(); j++) {
            cell = row.createCell(j+3+getLstEtiquetasFil().get(0).size());
            cell.setCellValue(Double.parseDouble(getTableContact().get(i).get(j).getEtiqueta()));                   
        }
    }


    try {

        this.archivo_salida = "D:/jboss-6.1.0.Final/bin/output2.xlsx";
        FileOutputStream fileOut = new FileOutputStream(new File(archivo_salida));
        workbook.write(fileOut);

        if(fileOut != null){
            try{ 
                File ficheroXLS = new File(archivo_salida);
                FacesContext ctx = FacesContext.getCurrentInstance();
                FileInputStream fis = new FileInputStream(ficheroXLS);
                byte[] bytes = new byte[1000];
                int read = 0;

                if (!ctx.getResponseComplete()) {
                   String fileName = ficheroXLS.getName();
                   String contentType = "application/vnd.ms-excel";
                   //String contentType = "application/pdf";
                   HttpServletResponse response =(HttpServletResponse) ctx.getExternalContext().getResponse();
                   response.setContentType(contentType);
                   response.setHeader("Content-Disposition","attachment;filename=\"" + fileName + "\"");
                   ServletOutputStream out = response.getOutputStream();

                   while ((read = fis.read(bytes)) != -1) {
                        out.write(bytes, 0, read);
                   }

                   out.flush();
                   out.close();
                   System.out.println("\nDescargado\n");
                   ctx.responseComplete();                     
                }       
            }catch(IOException e){ 
                e.printStackTrace(); 
            }  finally {
                 try {
                     if (fileOut != null) {
                         fileOut.close();
                     }            
                 } catch (IOException ex) {
                      ex.printStackTrace();
                 }
            }
        }

    } catch (IOException e) {
        e.printStackTrace();
    } 
}

WEB.xml

<?xml version="1.0" ?>

http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd”     版本= “2.5” &GT;

<!-- RichFaces -->

<context-param>
    <param-name>org.richfaces.SKIN</param-name>
    <param-value>blueSky</param-value>
</context-param>

<!-- Suppress spurious stylesheets -->

<context-param>
    <param-name>org.richfaces.CONTROL_SKINNING</param-name>
    <param-value>disable</param-value>
</context-param>

<context-param>
    <param-name>org.richfaces.CONTROL_SKINNING_CLASSES</param-name>
    <param-value>disable</param-value>
</context-param>

<!-- Change load strategy to DEFAULT to disable sending scripts/styles as 
    packs -->

<context-param>
    <param-name>org.richfaces.LoadStyleStrategy</param-name>
    <param-value>ALL</param-value>
</context-param>

<context-param>
    <param-name>org.richfaces.LoadScriptStrategy</param-name>
    <param-value>ALL</param-value>
</context-param>

<!-- Seam -->

<listener>
    <listener-class>org.jboss.seam.servlet.SeamListener</listener-class>
</listener>

<filter>
    <filter-name>Seam Filter</filter-name>
    <filter-class>org.jboss.seam.servlet.SeamFilter</filter-class>

    <init-param>
        <param-name>maxRequestSize</param-name>
        <param-value>1000000</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>Seam Filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<servlet>
    <servlet-name>Seam Resource Servlet</servlet-name>
    <servlet-class>org.jboss.seam.servlet.SeamResourceServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>Seam Resource Servlet</servlet-name>
    <url-pattern>/seam/resource/*</url-pattern>
</servlet-mapping>

<!-- Facelets development mode (disable in production) -->

<context-param>
    <param-name>facelets.DEVELOPMENT</param-name>
    <param-value>@debug@</param-value>
</context-param>

<!-- JSF -->

<context-param>
    <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
    <param-value>.xhtml</param-value>
</context-param>

<servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.seam</url-pattern>
</servlet-mapping>

<security-constraint>
    <display-name>Restrict raw XHTML Documents</display-name>
    <web-resource-collection>
        <web-resource-name>XHTML</web-resource-name>
        <url-pattern>*.xhtml</url-pattern>
    </web-resource-collection>
    <auth-constraint />
</security-constraint>

<persistence-unit-ref>
    <persistence-unit-ref-name>demoencuesta06/pu</persistence-unit-ref-name>
    <persistence-unit-name>demoencuesta06</persistence-unit-name>
</persistence-unit-ref>

3 个答案:

答案 0 :(得分:1)

感谢他们的回复,我发现了问题,它是在带有ajax的按钮中的.xhtml文件中。那是:

<a4j:commandButton id="btnexportar" onclick="this.disabled=true" oncomplete="this.disabled=false; alert('La Exportacion de Datos ha finalizado')" 
                            action="#{dndBean.exportarTabla}"
                            value="Exportar Datos">
</a4j:commandButton>

我改为:

<h:commandButton id="generarinforme" action="#{dndBean.exportarTabla}"                              
                                value="Exportar Datos">
</h:commandButton>

奇怪的角色不再出现了。现在我必须搜索使用onclick和oncomplete的方法。谢谢!

答案 1 :(得分:0)

首先:除非您只有一个人访问此报告,否则您确实知道使用像您这样的固定路径意味着如果同时有两个请求 - 结果未知 - 很可能一个人无法获得文件或将看到对方的数据。在某些情况下,文件可能已损坏。

您需要在服务器上使用随机名称保存数据(您可以使用java.io.File.createTempFile(String“3-char-min”,                   字符串“.xls”,                   文件directoryOnServer)

现在创建一个新文件后,在按钮单击后的页面中,您需要在页面中将内容类型设置为应用程序excel,然后输出任何内容,唯一的输出应该是二进制数据。我不知道丰富的面孔,但在jsps中,人们看到人们在jsp标签之间的标题中插入新行。

实施例

<%@ page import="sel2in.prjx.conf.*, sel2in.urlShorten.data.*, sel2in.prjx.common.*"%>
<%  
///this is bad : new line after %>
        response.setHeader("pragma","No-cache");

正确的方式

 <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <% response.setContentType("application/vnd.ms-excel"); %><%@ page import="sel2in.prjx.conf.*, sel2in.urlShorten.data.*, sel2in.prjx.common.*"%><%    
///this is okay : No new line after %>
        response.setHeader("pragma","No-cache");    

对于富人,请参阅File download using RichFaces

(以下从那里复制)

<h:commandLink value="Download" action="#{appController.downloadFile}" 
rendered="#{!file.directory}">
 <f:param name="file" value="#{file.absoluteFilename}" />
</h:commandLink>

关于设置内容类型,如果您手头有扩展名的文件名,可以使用ServletContext#getMimeType()根据web.xml(服务器的默认名称或webapp的名称)解析它。

ServletContext servletContext = (ServletContext) externalContext.getContext();
String contentType = servletContext.getMimeType(file.getName());

if (contentType == null) {
    contentType = "application/octet-stream";
}

response.setContentType(contentType);
// ...

(注意这是针对JSF 1.x的,因为JSF 2.x也可以使用ExternalContext#getMimeType())

答案 2 :(得分:0)

只做五件事

1.在表格中搜索 ajaxSingle =&#34; true&#34; ajaxSubmit =&#34; true&#34;

2.删除这两个。

3.使用 h:commondLink 从服务器或本地目录下载文件。

4.确保内容类型与文件格式匹配。

5.表格目标必须&#34; _blank&#34; 或不使用它。