Export from Displaytag inside a Portlet

The Problem:
When using Displaytag inside a Prortlet, the export functionality will not work because the portlet has no way to produce other than it’s portlet content for display (see http://jira.codehaus.org/browse/DISPL-344).
Since Displaytag export functionality produces downloadable content that the portlet container will interpret as a portlet render result, you will see the Displaytag output as HTML-rubbish.

The Solution:
When we came over this problem, a promising solution seemed to be the one described in this post:  http://www.jroller.com/hakan/entry/liferay_portal_4_1_2,  but nobody was able to get it running.
Based on the concept in this post I came up with the following simple idea: If the problem is, that the output is produced by something inside the portlet, than the solution is to produce the export result outside of the portlet. And it works.

It works like this:

  1. Disable the standard Displaytag export functionality
  2. Create a copy of your page and place it somewhere outside the portlet
  3. Add manually links to the copied page, providing the parameters required by Displaytag

Let’s look at this in detail on a concrete example:

I have a page containing the Displaytag

/WEB-INF
   /view
      /cercaaree.jsp(original)

and create a copy of this under

/export
  /cercaaree.jsp (copy)

Essential is that /export is not inside WEB-INF, besides that, it could be placed anywhere.

Now I add manually the required export links below the display-tag in the original file, csv and excel in this case:

...
</display:table>
<div class="exportlinks">Export:
    <a href="<%=currentPagePath%>?d-16544-e=1&d-49243-e=1&6578706f7274=1">
              <span class="export csv"> CSV </span>
    </a>
    |
    <a href="<%=currentPagePath%>?d-16544-e=2&d-49243-e=2&6578706f7274=1">
        <span class="export excel"> Excel </span>
    </a>
</div>

Where currentPagePath is defined to point to the copy of the page, in this case.:

<%
   String currentPagePath =  "http://" + request.getServerName() + ":"
       + request.getServerPort()
       + request.getContextPath()
       + "/export/cercaaree.jsp";
%>

Note that  the constructed absolute path “/export”  is not below “/WEB-INF”.

You must include all the displaytag parameters as shown, the number given to in the d-16544-e parameter determines the result type (1=CSV, 2=EXCEL …).

The copied cercaaree.jsp lays outside our Struts2 web application, so there will be no Struts2 support. That’s fine for the export, but we need a way to access the data to export. We do this through the HttpSession which is easily accessible from Struts2 and plain jsp.

The original jsp gets the the data to display from the session:

<%
  List areeProduttive = (List) PortletActionContext.getRequest().getPortletSession().getAttribute("areeProduttive");
  request.setAttribute("areaList", areeProduttive);
%>
<display:table name="areaList" pagesize="8" id="area" export="false">
...

In the copy, this fails since we are outside the portlet code and there are no Portlet Resources available. What we can do instead is to look in the standard HTTPSession of the jsp page for the data (“areaList”). The Session is the same as the one underlying the portlet functionality, but the portlet data is ‘encoded’. In Liferay Portal, the key will be something like:

javax.portlet.p.AreeIndustrialiPortlet_WAR_conextname_LAYOUT_11901?areeProduttuve

I access this simply searching the session data:

<%
// reload the data from the session
List<AreaProduttiva>  areeProduttive = null;
Enumeration names =  session.getAttributeNames();
while (names.hasMoreElements()) {
   String name = (String) names.nextElement();
  if (name.contains("areeProduttive")) {
    areeProduttive = (List<AreaProduttiva>) request.getSession().getAttribute(name);
    break;
  }
}
request.setAttribute("areaList", areeProduttive);
%>

This is, how we access the data for export. Note that this works with Liferay, but I have not tested how other portals encode portlet session data.

The copied page will produce the desired export output without doing any rendering. Having to copy the page might be a drawback, but it has also the nice side effect that you can change the columns included in the export.

2 Comments

  1. Hi,

    I am facing the problem to export data from Displaytag inside a portlet. Will you provide source exaple for your implementation.

    If same page copied outside WEB-INF, how data will be exported to that page?

    Reply
  2. Chakravarthy,
    I posted all relevant pieces of code in the article. To get the data into the page outside WEB-INF, look at the paragraph starting with “The copied cercaaree.jsp lays outside our Struts2 web application, so there will be no Struts2 support. That’s fine for the export, but we need a way to access the data to export.”
    Cheers,
    Dominik

    Reply

Submit a Comment

Your email address will not be published. Required fields are marked *