Liferay diaries: Serving resources from a portlet with Spring
So there comes the day when you finally have to serve an image, pdf or excel report generated by a portlet or, more elegantly, by a Spring controller backing a portlet. At a first take this may seem impossible since the markup produced by a portlet is embedded in the markup (i.e. HTML) of all the other portlets running on that page and then decorated by the portal's theme which makes it pretty much impossible to generate a standalone XML or even a binary file like an image from a database or a PDF report.
The elements of the solution is provided in this post [1] which needs to be adapted a little bit for our Spring setup.
1. Requesting the resource
The HTML must request the resource (here: an Excel report over an account balance) by using the portlet:resourceURL
tag:
<portlet:resourceURL id="searchBalanceExcel" var="searchBalanceExcelURL"/> <a href="<%=searchBalanceExcelURL%>">Download Report</a>
2. Serving the resource
Our controller needs to provide a handling method annotated with @ResourceMapping
:
@ResourceMapping("searchBalanceExcel") public ModelAndView findDeliveries(BalanceQuery query,BindingResult result,ResourceRequest request, ResourceResponse response, ModelMap modelMap) throws Exception{ ModelAndView mav = new ModelAndView("balanceReportExcel"); if (!result.hasErrors()) { query.setCredentials(getLoggedInCustomerCredentials()); List<Balance> rs = customersService.findBalance(query); modelMap.put("result", rs); } response.setContentType("application/vnd.ms-excel"); response.setCharacterEncoding("UTF-8"); modelMap.put("balanceQuery", query); return mav; }
In this case the Excel is rendered by a JSP (trivia: MS Excel actually can parse a specially formatted HTML as an Excel file), but the response
object offers an OutputStream
which can be written binary data to.
Resources
[1] Portlet 2.0 AJAX serveResource portlet:resourceURL does not work in 5.0.1
http://www.liferay.com/community/forums/-/message_boards/message/937530