1

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

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

为什么会发生???

谢谢你。

附上图片。在此处输入图像描述

函数导出的代码是:

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" version="2.5">

<!-- 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>

4

3 回答 3

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 的方法。谢谢!

于 2013-05-16T17:06:29.437 回答
0

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

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

现在创建一个新文件后,在按钮单击后的页面中,您需要在任何输出之前将页面中的内容类型设置为 application excel,并且唯一的输出应该是二进制数据。我不知道丰富的面孔,但在 jsp 中看到人们在 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");    

对于富面孔,请参阅使用 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())

于 2013-05-16T16:17:01.453 回答
0

只做五件事

1.在表单中搜索ajaxSingle="true"ajaxSubmit="true"

2.删除这两个。

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

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

5.form 目标必须是“_blank”或者不要使用它。

于 2016-08-10T12:35:42.220 回答