9 Replies Latest reply on Nov 20, 2007 5:46 AM by Pete Muir

    PDF - is there a way?

    Tim Evers Master

      Hi all,

      I'm experiencing a little difficulty in getting SEAM's PDF functionality to work.

      I can get what I want if I put all my variables into a SESSION scope. But as soon as I want to try use a CONVERSATION scope the PDF has no data in it.

      Now I'm assuming that this is because of the way that PDF's are handled. So, I guess my question is, What is the work around?

      I have a page where users search for records based on some criteria. My aim is to have a button on the page which will generate a PDF document with these results in them and display them in an iframe or equivalent below, allowing them to get a print friendly version of the records.

      Currently I'm experiencing considerable difficulty in passing data to the xhtml page where my pdf is defined.

      here is some of the more necessary code

      Don't worry too much about the reference to GekkoReport it is just a bunch of getters and setters at the moment.

      package gekko.web.actionbean.enquiry;
      
      import static org.jboss.seam.ScopeType.CONVERSATION;
      import static org.jboss.seam.ScopeType.PAGE;
      import static org.jboss.seam.ScopeType.SESSION;
      import gekko.domain.calculator.ltlr.UvAveraging;
      import gekko.domain.reference.ltl.SubcategoryCode;
      import gekko.web.actionbean.search.CatSubcatDateSearch;
      import gekko.web.services.GekkoReport;
      
      import java.util.HashMap;
      import java.util.List;
      
      import org.jboss.seam.annotations.Begin;
      import org.jboss.seam.annotations.In;
      import org.jboss.seam.annotations.Name;
      import org.jboss.seam.annotations.Out;
      import org.jboss.seam.annotations.Scope;
      import org.jboss.seam.annotations.datamodel.DataModel;
      import org.jboss.seam.annotations.datamodel.DataModelSelection;
      
      
      @Name("averagingEnquiry")
      @Scope(PAGE)
      public class AveragingEnquiry {
      
       @Out(required=false, scope=SESSION, value="gekkoPDFReport")
       @In(create=true, value="gekkoReport")
       private GekkoReport gekkoPDFReport;
      
       @Out(required=false, scope=SESSION, value="searchResults")
       private List<UvAveraging> searchResults;
      
       @In(value="#{catSubcatDateSearch}", create=true, scope=CONVERSATION)
       private CatSubcatDateSearch searchBean; //NOPMD
      
       @DataModel(value="averagingEnquiry_uvAveragings")
       private List<UvAveraging> uvAveragingList;
      
       @DataModelSelection(value="averagingEnquiry_uvAveragings")
       @Out(required=false, scope=CONVERSATION, value="averagingEnquiry_uvAveraging")
       private UvAveraging uvAveraging;
      
       @Out(required=false, scope=CONVERSATION, value="selectedSubcategory")
       private SubcategoryCode selectedSubcategory;
      
       private boolean showReport = false;
      
       ....getters and setters...
      
       @Begin(join=true)
       public String editUvAveraging() {
       selectedSubcategory = uvAveraging.getSubcategory();
       return "createEditAveraging";
       }
      
       @Begin(join=true)
       public String createUvAveraging() {
       uvAveraging = new UvAveraging();
       selectedSubcategory = new SubcategoryCode();
       return "createEditAveraging";
       }
      
       public boolean getShowReport() {
       return showReport;
       }
      
       @Begin(join=true)
       public void displayReport() {
       HashMap<String, String> criteria = new HashMap<String, String>();
       criteria.put("Category", searchBean.getCatSubcatEnquiry().getCategoryCode().getName());
      
       //TODO: do criteria a better way
      
       gekkoPDFReport.setCriteria(criteria);
       searchResults = uvAveragingList;
      
       showReport = true;
       }
      
       public void hideReport() {
       showReport = false;
       }
      
      }
      


      The search page
      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      <html xmlns="http://www.w3.org/1999/xhtml"
       xmlns:ui="http://java.sun.com/jsf/facelets"
       xmlns:h="http://java.sun.com/jsf/html"
       xmlns:f="http://java.sun.com/jsf/core"
       xmlns:rich="http://richfaces.org/rich"
       xmlns:a4j="https://ajax4jsf.dev.java.net/ajax"
       xmlns:s="http://jboss.com/products/seam/taglib"
       xmlns:gekko="http://gekkoTagLibs.com"
       xmlns:c="http://java.sun.com/jstl/core">
      
       <ui:composition template="/web/templates/gekkoTemplate.xhtml">
       <ui:define name="title">Average Years Enquiry</ui:define>
       <ui:define name="titlebar">Average Years Enquiry</ui:define>
       <ui:define name="content">
       <ui:decorate template="/web/compositions/search/catSubcatDateSearch.xhtml">
       <ui:define name="cScSearchCommand">
       <h:commandButton id="averagingCScSearchCommand"
       value="Search"
       action="#{averagingEnquiry.getUvAveragings}">
       <gekko:defaultAction/>
       </h:commandButton>
       </ui:define>
       </ui:decorate>
      
       <h:form id="results" styleClass="resultsForm">
       <rich:panel header="Averagings">
       <rich:dataTable id="averagingTable"
       value="#{averagingEnquiry_uvAveragings}"
       var="uvAveraging"
       style="width:100%;"
       rows="20">
       <f:facet name="header">
       <rich:columnGroup>
       <rich:column>
       <rich:spacer width="2px;"/>
       </rich:column>
       <rich:column>
       <h:outputText value="Num Years"/>
       </rich:column>
       <rich:column>
       <h:outputText value="Effective Date"/>
       </rich:column>
       <rich:column>
       <h:outputText value="Expiry Date"/>
       </rich:column>
       <rich:column>
       <h:outputText value="Comment"/>
       </rich:column>
       </rich:columnGroup>
       </f:facet>
      
       <rich:column>
       <h:commandLink value="Edit" action="#{averagingEnquiry.editUvAveraging}"/>
       </rich:column>
       <rich:column>
       <h:outputText value="#{uvAveraging.years}"/>
       </rich:column>
       <rich:column>
       <h:outputText value="#{uvAveraging.effective}"/>
       </rich:column>
       <rich:column>
       <h:outputText value="#{uvAveraging.expiry}"/>
       </rich:column>
       <rich:column>
       <h:outputText value="#{uvAveraging.comment}"/>
       <rich:spacer rendered="#{empty uvAveraging.comment}"/>
       </rich:column>
      
       <f:facet name="footer">
       <rich:columnGroup>
       <rich:column colspan="5">
       <rich:datascroller align="left" for="averagingTable" renderIfSinglePage="false"/>
       </rich:column>
       </rich:columnGroup>
       </f:facet>
      
       </rich:dataTable>
      
       <a4j:commandButton id="reportButton" value="Report" reRender="pdfReportForm" action="#{averagingEnquiry.displayReport}"/>
       <h:commandButton id="newButton" action="#{averagingEnquiry.createUvAveraging}" value="New"/>
       </rich:panel>
       </h:form>
       <a4j:log/>
       </ui:define>
      
      
       <ui:define name="pdfReport">
       <h:form id="pdfReportForm">
       <rich:panel header="Report" rendered="#{averagingEnquiry.showReport}">
       <f:facet name="header">
       <h:outputText value="Report"/>
       <a4j:commandLink action="#{averagingEnquiry.hideReport}"
       value="Hide Report"
       reRender="pdfReportForm"/>
       </f:facet>
       <iframe frameborder="0" width="98%" height="600" src="/gekko-tje/web/reports/averageYearsReport.jsf" />
       </rich:panel>
       </h:form>
       </ui:define>
       </ui:composition>
      </html>
      


      And finally the pdf xhtml file
      <p:document xmlns:ui="http://java.sun.com/jsf/facelets"
       xmlns:p="http://jboss.com/products/seam/pdf"
       xmlns:s="http://jboss.com/products/seam/taglib"
       xmlns:f="http://java.sun.com/jsf/core"
       pageSize="A4">
      
       <f:facet name="header">
       <p:font size="12">
       <p:footer borderWidthTop="1" borderColorTop="Gray" borderWidthBottom="0" alignment="center">
       <p:pageNumber/>
       </p:footer>
       </p:font>
       </f:facet>
      
       <p:font size="18">
       <p:paragraph>Average Years</p:paragraph>
       </p:font>
      
       <p:table columns="2" headerRows="1">
       <p:cell colspan="2">
       <p:font size="14">
       <p:paragraph>Search Criteria</p:paragraph>
       </p:font>
       </p:cell>
      
       <ui:repeat value="#{gekkoReport.criteria.keySet}" var="key">
       <p:cell>#{key}</p:cell>
       <p:cell>#{gekkoReport.criteria.get(key)}</p:cell>
       </ui:repeat>
       </p:table>
      
       <p:table columns="4" headerRows="1">
      
       <ui:repeat value="#{gekkoReport.columns}" var="column">
       <p:font size="14">
       <p:cell>#{column}</p:cell>
       </p:font>
       </ui:repeat>
      
       <ui:repeat value="#{searchResults}" var="uvAveraging">
       <p:cell>#{uvAveraging.years}</p:cell>
       <p:cell>#{uvAveraging.effective}</p:cell>
       <p:cell>#{uvAveraging.expiry}</p:cell>
       <p:cell>#{empty uvAveraging.comment}</p:cell>
       </ui:repeat>
       </p:table>
      
      </p:document>
      




      That code is the best implementation I've had so far in that I at least get results on my page but...... I don't want to be putting all this data into my SESSION scope.

      I'll keep looking for some decent examples and reading doco but... any ideas would be great. :)

      Thanks




        • 1. Re: PDF - is there a way?
          Joshua Jackson Master

          Try changing your enquiry scope into EVENT

          • 2. Re: PDF - is there a way?
            Damian Harvey Master

            If your Bean is CONVERSATION scoped does your pdf xhtml page join that conversation? (eg. <begin-conversation join="true"/>)

            Cheers,

            Damian.

            • 3. Re: PDF - is there a way?
              Norman Richards Master

              The rendered PDF is stored in the conversation.


              Can you verify that accessing the PDF directly does or doesn't work? (you might need to stub out your data)

              • 4. Re: PDF - is there a way?
                Tim Evers Master

                OK,

                I have tried everything at CONVERSATION scope but the PDF document will never be able to find the variable. I've tried the BEAN, and all the OUT variables on CONVERSATION but that does not seem to change the outcome.

                As I stated in my original post the only way I get any data is if I outject to SESSION scope.

                @thejavafreak
                I can't see how changing the scope to EVENT would help as EVENT scope is even shorter then conversation, but I'll give it a go.

                @norman.richards
                The PDF works fine if I take out all reference to my outjected values.
                And I believe you that the PDF is stored in the conversation as I see the conversation ID in the url to the pdf, but for some reason whatever the process is for generating the pdf the conversation variables are not available. I'll keep playing around and stepping through the code..... problem is I'm not entirely sure where it all goes wrong so....it's taking me a long time to make progress.

                I believe this is probably a good case for doing some more in depth examples of using the seam pdf functionality, as it is the itext example does not work out of the box if I run the ant targets I still can't run the app in tomcat so not sure what's going on there. It just hangs forever on the index page. I don't get any errors or anything.

                • 5. Re: PDF - is there a way?
                  Tim Evers Master

                  Well, to make matters even more confusing it seems as though this has absolutely nothing to do with the pdf at all.

                  I created another straight xhtml file that uses the variable and put it in the iframe and NOTHING!

                  The variable

                  @DataModelSelection(value="averagingEnquiry_uvAveragings")
                  @Out(required=false, scope=CONVERSATION, value="averagingEnquiry_uvAveraging")
                  private UvAveraging uvAveraging;
                  


                  is not available at all.

                  There is something really strange going on here with conversation management. Somehow my conversations are ending without me specifically telling seam to do so. I am thoroughly confused right now and I am starting to wonder if doing a simple conversation like this is this hard what am I looking at when I start developing the larger application in a few weeks time *sigh*.

                  I'm assuming I have done something really stupid....but right now I just can't seem to find it! I get no errors, I get no messages.....just nothing.

                  Well, I'm almost to point of losing my hair!!! LOL

                  thanks for all the help tho guys.... it is appreciated.

                  • 6. Re: PDF - is there a way?
                    Tim Evers Master

                    Baby steps.....

                    Ok, I'm now almost 100% certain that the cause of all my problems lies in the use of the iframe.

                    It appears that conversations do not span over iframes.... now from all my reading and the way I understand conversations this should not be the case!

                    Am I right in assuming this? And if so, does anyone have any idea why my conversation is non-existent when inside the iframe?

                    I think I'm going to have bad dreams about this all night tonight :P

                    • 7. Re: PDF - is there a way?
                      Tim Evers Master

                      Ok, it is most certainly the IFrame that is the cause of pretty much all my grief.

                      I do not know of anyway of ensuring that the src attribute of the iframe will indeed join my current conversation... infact I don't even know where to begin in trying to do that.

                      I have succeeded in using a s:link tag to open my content in a new window and this is working! So for now I'm going to leave it at that unless someone can tell me how to get iframes working.... maybe we need a s:iframe component to allow for conversation propagation?

                      I would like to use iframes and I *know* that for the next phase of the application it will most likely be a must....although we may not use seam to generate the pdfs....we'll see.


                      s:iframe..... how hard would that be to implement?

                      • 8. Re: PDF - is there a way?
                        Tim Evers Master

                        Actually forget what i said about it working with s:link....it's not. *sigh*


                        I'm at a loss now :(

                        • 9. Re: PDF - is there a way?
                          Pete Muir Master

                          Conversations aren't propagated into iframes, no.