2011-09-30 126 views
0

我想在我的JSF + Spring Web应用程序中使用iText创建PDF。 当我点击一个按钮时,应该生成pdf。被解雇的方法:无法使用iText和JSF创建PDF

public void createPDF() { 
    log.debug("entered createPDF"); 
    FacesContext context = FacesContext.getCurrentInstance(); 
    HttpServletResponse response = (HttpServletResponse)context.getExternalContext().getResponse(); 
    response.setContentType("application/pdf"); 
    response.setHeader("Content-disposition", "inline=filename=file.pdf"); 
    try { 

     // Get the text that will be added to the PDF 
     String text = "test"; 
     // step 1 
     Document document = new Document(); 
     // step 2 
     ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     PdfWriter.getInstance(document, baos); 
     // step 3 
     document.open(); 
     // step 4 
     document.add(new Paragraph(text)); 
     // step 5 
     document.close(); 

     // setting some response headers 
     response.setHeader("Expires", "0"); 
     response.setHeader("Cache-Control", 
      "must-revalidate, post-check=0, pre-check=0"); 
     response.setHeader("Pragma", "public"); 
     // setting the content type 
     response.setContentType("application/pdf"); 
     // the contentlength 
     response.setContentLength(baos.size()); 
     // write ByteArrayOutputStream to the ServletOutputStream 
     OutputStream os = response.getOutputStream(); 
     baos.writeTo(os); 
     os.flush(); 
     os.close(); 
     log.debug("flushed and closed the outputstream"); 

    } 
    catch(DocumentException e) { 
     log.error("error: "+e); 
    } 
    catch (IOException e) { 
     log.error("error: "+e); 
    } 
    catch (Exception ex) { 
     log.debug("error: " + ex.getMessage()); 
    } 
    context.responseComplete(); 
    log.debug("context.responseComplete()"); 
} 

这是与按钮的页面:

<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<ui:composition xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:s="http://jboss.org/seam/faces" 
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:f="http://java.sun.com/jsf/core" 
    xmlns:h="http://java.sun.com/jsf/html" 
    xmlns:rich="http://richfaces.org/rich" 
    xmlns:a4j="http://richfaces.org/a4j" 
    xmlns:c="http://java.sun.com/jsp/jstl/core" 
    template="/pages/layout/layout.xhtml"> 

<ui:define name="content"> 
     <h:form> 
      <rich:panel style="width: 785px; height: 530px; "> 
<a4j:commandButton value="Afdrukken" execute="@form" 
        action="#{huishoudinkomenAction.print}" style="float:right;" /> 

     </rich:panel> 
    </h:form> 
</ui:define> 

我看到调试消息在日志中,但什么也没有发生在Web应用程序。我没有看到pdf。 我在做什么错?

问候,

德克

编辑: 当我改变了<a4j:commandButton /><h:commandButton />它的工作。

回答

1

当您使用<a4j:commandButton>时,将在您的浏览器上创建一个新的XmlHttpRequest,并且您的serverside方法将通过JS调用。输出PDF将写入输出流,但实际结果将从XmlHttpRequest中读出,并由jsf.ajax.response() javascript函数解释。

由于JSF ajax响应总是以<partial-response>为根的XML,所以基本上是将垃圾邮件发送回JSF ajax处理程序。 (PDF!= XML,<partial-response> root)。很显然,这解析失败,所以看起来“没有任何反应”。

所以你必须使用<h:commandButton/>做一个真正的请求。你也需要做:

response.setHeader("Content-disposition", "attachment; filename=mycool.pdf"); 

服务器端,以便通知其接收到一个新的文件浏览器,并且应该下载它,而不是显示它不是页面的。

这将会产生一个“ajax”调用的最终行为,您可以在其中进行调用,您会收到响应(并保存它),但是您的页面内容会保留在那里。

2

我从来没有用过RichFaces,但有了Primefaces控件,你可以设置属性ajax =“false”。

<p:commandButton id="someid" value="Text for user" action="someConfiguredAction" ajax="false"/> 

<h:commandButton id="someid" value="Text for user" action="someConfiguredAction"/> 
+0

(哎呀,这应该是bogdan.mustiata的答案的补充) –

0

你不能用AJAX下载文件。 Ajax由JavaScript代码触发和处理。但是,JavaScript有明显的安全原因,因此无法强制与JavaScript变量中的任意内容(如ajax请求的响应)进行对话另存为

确保下载按钮激发同步(非Ajax)请求。使用正常的命令按钮或关闭ajax命令按钮中的ajax。