Wednesday, April 8, 2015

Data Export as CSV Format in Liferay

In general we will export data into different formats in our applications and one of format is CSV (Comma-separated values). CSV is similar to Micro Soft XLS.

In Liferay Portlet Development we may get requirement to export data as different formats. This article is explaining how to export data as CSV in Liferay Portlet Development.

Assume in Liferay we have many users in portal and we will export all users details as CSV formatted file.

Steps:
  • We get all users from Portal using UserLocalServiceUtil
  • We prepare each record and its columns as CSV format like each record as new line and each column separated by comma delimiter.
  • Finally we will export this data as CSV file.

The following is sample code


public static String[] columnNames = { "UserId", "FirstName", "LastName","EmailAddress", "Screen Name" };
public static final String CSV_SEPARATOR = ",";

protected void exportCSVData(ResourceRequest resourceRequest,
ResourceResponse resourceResponse) throws Exception {
StringBundler sb = new StringBundler();
for (String columnName : columnNames) {
sb.append(getCSVFormattedValue(columnName));
sb.append(CSV_SEPARATOR);
}
sb.setIndex(sb.index() - 1);
sb.append(CharPool.NEW_LINE);
List<User> usersList = UserLocalServiceUtil.getUsers(0,
UserLocalServiceUtil.getUsersCount());
for (User user : usersList) {
sb.append(
getCSVFormattedValue(String.valueOf(user.getUserId())));
sb.append(CSV_SEPARATOR);
sb.append(
getCSVFormattedValue(String.valueOf(user.getFirstName())));
sb.append(CSV_SEPARATOR);
sb.append(
getCSVFormattedValue(String.valueOf(user.getLastName())));
sb.append(CSV_SEPARATOR);
sb.append(getCSVFormattedValue(String.valueOf(user
.getEmailAddress())));
sb.append(CSV_SEPARATOR);
sb.append(
getCSVFormattedValue(String.valueOf(user.getScreenName())));
sb.append(CSV_SEPARATOR);
sb.setIndex(sb.index() - 1);
sb.append(CharPool.NEW_LINE);
}

String fileName = "portalUsers.csv";
byte[] bytes = sb.toString().getBytes();
String contentType = ContentTypes.APPLICATION_TEXT;
PortletResponseUtil.sendFile(resourceRequest, resourceResponse,
fileName, bytes, contentType);
}

protected String getCSVFormattedValue(String value) {
StringBundler sb = new StringBundler(3);
sb.append(CharPool.QUOTE);
sb.append(StringUtil.replace(value, CharPool.QUOTE,
StringPool.DOUBLE_QUOTE));
sb.append(CharPool.QUOTE);
return sb.toString();
}


While export data as files we will use following Method so that it will export as desired file format


String contentType = ContentTypes.APPLICATION_TEXT;
PortletResponseUtil.sendFile(resourceRequest, resourceResponse,
fileName, bytes, contentType);


In the above code we retrieved the data from database and perepared as CSV.
Assume we have HTML table in the page now we will export this HTML tables as CSV file.

Steps:
  • We take all HTML table data and send it to Portlet action class
  • We use jsoup Java HTML Parser to manipulate and access data from HTML table.
  • We prepare each row and its columns as CSV format like each row as new line and each cell separated by comma delimiter.
  • Finally we will export this data as CSV file.

Example Code


protected void exportHTMLCSVData(ResourceRequest resourceRequest,
ResourceResponse resourceResponse) throws Exception {
String tableHTML = ParamUtil.getString(resourceRequest,"tableHTMLDataInput");
StringBundler sb = new StringBundler();
Document doc = Jsoup.parseBodyFragment(tableHTML);
Elements cells = doc.getElementsByTag("th");
for (Element cell : cells) {
sb.append(getCSVFormattedValue(String.valueOf(cell.text())));
sb.append(CSV_SEPARATOR);
}
sb.setIndex(sb.index() - 1);
sb.append(CharPool.NEW_LINE);
Elements rows = doc.getElementsByTag("tr");
for (Element row : rows) {
Elements tdcells = row.getElementsByTag("td");
for (Element cell : tdcells) {
sb.append(getCSVFormattedValue(String.valueOf(cell.text())));
sb.append(CSV_SEPARATOR);
}
sb.setIndex(sb.index() - 1);
sb.append(CharPool.NEW_LINE);
}
String fileName = "portalUsers.csv";
byte[] bytes = sb.toString().getBytes();
String contentType = ContentTypes.APPLICATION_TEXT;
PortletResponseUtil.sendFile(resourceRequest, resourceResponse,
fileName, bytes, contentType);
}
protected String getCSVFormattedValue(String value) {
StringBundler sb = new StringBundler(3);
sb.append(CharPool.QUOTE);
sb.append(StringUtil.replace(value, CharPool.QUOTE,
StringPool.DOUBLE_QUOTE));
sb.append(CharPool.QUOTE);
return sb.toString();
}


Note:

When we work with jsoup Java HTML Parser then we need to add jsoup-1.8.1.jar in plugin Portlet lib directory.

Download LiferayCSVDataExport-portlet


Portlet View Page



Data Exported as CSV file


Complete Portlet Example

View JSP Page (/html/liferaycsvdataexport/view.jsp)


<%@page import="com.liferay.portal.kernel.util.ParamUtil"%>
<%@page import="com.liferay.portal.kernel.util.Constants"%>
<%@page import="com.liferay.portal.service.UserLocalServiceUtil"%>
<%@page import="com.liferay.portal.model.User"%>
<%@page import="java.util.List"%>
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<%@ taglib uri="http://liferay.com/tld/portlet" prefix="liferay-portlet" %>
<%@ taglib uri="http://liferay.com/tld/aui" prefix="aui" %>
<portlet:defineObjects />
<h2>Data Export as CSV in Liferay Portlet</h2>
<%
List<User> usersList=UserLocalServiceUtil.getUsers(0,
UserLocalServiceUtil.getUsersCount());
String portletResource = ParamUtil.getString(request, "portletResource");
%>
<portlet:resourceURL  var="exportCSVURL">
<portlet:param name="<%= Constants.CMD %>" value="exportCSV"/>
</portlet:resourceURL>
<portlet:resourceURL  var="exportHTMLCSVURL">
<portlet:param name="<%= Constants.CMD %>" value="exportHTMLCSV"/>
</portlet:resourceURL>
<style>
#exportlinks th{
padding: 5px 20px 5px 20px;
}

</style>
<table border="0" id="exportlinks">
<tr>
<th><a href="<%=exportCSVURL%>">Export Data as CSV</a></th>
<th><a id="<portlet:namespace/>exportHTMLCSV" href="#">Export HTML Table as CSV</a></th>
</tr>
</table>
<br/>
<div id="<portlet:namespace/>usersData">
<table border="1" >
<tr>
<th>UserID</th>
<th>First Name</th>
<th>Last Name</th>
<th>Email Address</th>
<th>Screen Name</th>
</tr>
<%for(User user:usersList) {%>
<tr>
<td><%=user.getUserId()%></td>
<td><%=user.getFirstName() %></td>
<td><%=user.getLastName() %></td>
<td><%=user.getEmailAddress()%></td>
<td><%=user.getScreenName()%></td>
</tr>
<%} %>
</table>
</div>
<form action="<%=exportHTMLCSVURL%>" name="userDataForm"  method="POST">
<input  type="text" name="<portlet:namespace/>tableHTMLDataInput" id="<portlet:namespace/>tableHTMLDataInput" value="DASFASF"/>
</form>
<aui:script>
AUI().use('aui-base', function(A){
A.one("#<portlet:namespace/>exportHTMLCSV").on('click',function(){
var tableHtml=A.one('#<portlet:namespace/>usersData').getHTML();
A.one('#<portlet:namespace/>tableHTMLDataInput').set('value', tableHtml)
document.userDataForm.submit();
});
});
</aui:script>


Portlet Action Class (LiferayCSVDataExport.java)

package com.meera.liferay.csvexport;

import java.util.List;

import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.portlet.PortletResponseUtil;
import com.liferay.portal.kernel.util.CharPool;
import com.liferay.portal.kernel.util.Constants;
import com.liferay.portal.kernel.util.ContentTypes;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.kernel.util.StringBundler;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.WebKeys;
import com.liferay.portal.model.User;
import com.liferay.portal.service.UserLocalServiceUtil;
import com.liferay.portal.theme.ThemeDisplay;
import com.liferay.util.bridges.mvc.MVCPortlet;
public class LiferayCSVDataExport extends MVCPortlet {
public static String[] columnNames = { "UserId", "FirstName", "LastName",
"EmailAddress", "Screen Name" };
public static final String CSV_SEPARATOR = ",";

@Override
public void serveResource(ResourceRequest resourceRequest,
ResourceResponse resourceResponse) {

String cmd = ParamUtil.getString(resourceRequest, Constants.CMD);
//System.out.println("cmd"+cmd);

try {
if (cmd.equals("exportCSV")) {
exportCSVData(resourceRequest, resourceResponse);
}else if(cmd.equals("exportHTMLCSV")){
exportHTMLCSVData(resourceRequest, resourceResponse);
}
} catch (Exception e) {
_log.error(e, e);
}
}
protected void exportHTMLCSVData(ResourceRequest resourceRequest,
ResourceResponse resourceResponse) throws Exception {
String tableHTML = ParamUtil.getString(resourceRequest,"tableHTMLDataInput");
//System.out.println("tableHTMLDataInput"+tableHTML);
StringBundler sb = new StringBundler();
Document doc = Jsoup.parseBodyFragment(tableHTML);
Elements cells = doc.getElementsByTag("th");
// System.out.println("cells"+cells.size());
for (Element cell : cells) {
sb.append(getCSVFormattedValue(String.valueOf(cell.text())));
sb.append(CSV_SEPARATOR);
}
sb.setIndex(sb.index() - 1);
sb.append(CharPool.NEW_LINE);
Elements rows = doc.getElementsByTag("tr");
for (Element row : rows) {
Elements tdcells = row.getElementsByTag("td");
for (Element cell : tdcells) {
sb.append(getCSVFormattedValue(String.valueOf(cell.text())));
sb.append(CSV_SEPARATOR);
}
sb.setIndex(sb.index() - 1);
sb.append(CharPool.NEW_LINE);
}
String fileName = "portalUsers.csv";
byte[] bytes = sb.toString().getBytes();
String contentType = ContentTypes.APPLICATION_TEXT;
PortletResponseUtil.sendFile(resourceRequest, resourceResponse,
fileName, bytes, contentType);
}
protected void exportCSVData(ResourceRequest resourceRequest,
ResourceResponse resourceResponse) throws Exception {
StringBundler sb = new StringBundler();
for (String columnName : columnNames) {
sb.append(getCSVFormattedValue(columnName));
sb.append(CSV_SEPARATOR);
}
sb.setIndex(sb.index() - 1);
sb.append(CharPool.NEW_LINE);
List<User> usersList = UserLocalServiceUtil.getUsers(0,
UserLocalServiceUtil.getUsersCount());
for (User user : usersList) {
sb.append(getCSVFormattedValue(String.valueOf(user.getUserId())));
sb.append(CSV_SEPARATOR);
sb.append(getCSVFormattedValue(String.valueOf(user.getFirstName())));
sb.append(CSV_SEPARATOR);
sb.append(getCSVFormattedValue(String.valueOf(user.getLastName())));
sb.append(CSV_SEPARATOR);
sb.append(getCSVFormattedValue(String.valueOf(user
.getEmailAddress())));
sb.append(CSV_SEPARATOR);
sb.append(getCSVFormattedValue(String.valueOf(user.getScreenName())));
sb.append(CSV_SEPARATOR);
sb.setIndex(sb.index() - 1);
sb.append(CharPool.NEW_LINE);
}

String fileName = "portalUsers.csv";
byte[] bytes = sb.toString().getBytes();
String contentType = ContentTypes.APPLICATION_TEXT;
PortletResponseUtil.sendFile(resourceRequest, resourceResponse,
fileName, bytes, contentType);
}

protected String getCSVFormattedValue(String value) {
StringBundler sb = new StringBundler(3);
sb.append(CharPool.QUOTE);
sb.append(StringUtil.replace(value, CharPool.QUOTE,
StringPool.DOUBLE_QUOTE));
sb.append(CharPool.QUOTE);
return sb.toString();
}

private static Log _log = LogFactoryUtil.getLog(LiferayCSVDataExport.class);
}



Tuesday, April 7, 2015

Liferay Site/Organization Virtual Hosting

Generally in Liferay administration we create sites and organizations and each site and organization have unique URL to access these sites/organizations. Generally we will have friendly URL to access these sites/organizations in Liferay.

Each site/organization has its own friendly URL and it consist pattern like /web and site/organization name. When we see /web in the URL then we can consider that is Site/Organization in Liferay.

Site Example

Site Name:
LiferaySavvy
Site Friendly URL
/web/liferaysavvy
Complete URL Pattern
Host Name+ Site Friendly URL
Complete URL
http://localhost:8080 /web/liferaysavvy

Organization Example

Site Name:
LiferaySavvyORG
Site Friendly URL
/web/liferaysavvy
Complete URL Pattern
Host Name+ Organization Friendly URL
Complete URL
http://localhost:8080 /web/liferaysavvyorg

Generally in real time we won’t use friendly URL to access site/organization we will use unique domain name and that will be pointing to Liferay site/organization.to achieve this we will use Liferay virtual host configuration.

Liferay Virtual Host is way of accessing site/organization with real world domain names. In Production we use apache web server, domain vendor control panel configurations and finally we use Liferay virtual host configuration.

In development environment to replicate same kind of configuration in our local system we will follow some sequence of steps.

Assume we wanted to access our Liferay site/organization with URL like www.liferaysavvy.com  in our local system.

Steps:
  • Create Site/Organization
  • Configure Site URL with desired domain name www.sitename.com
  • In host file map 127.0.0.1 with your domain name

Liferay Site Virtual Hosting

Create Site

Access Liferay portal and login as Liferay Administration.

Go Control Panel from Admin Docbar.


Control panel we can see site section there click on sites link



Now in the sites page we can see Add button click on Add and select Blank Site



Once we click on Blank site we can see site creation form and it will ask basic details related to site like name and description. Please fill all details and click on save button then site will be created.



After successful site creation then it will navigate to site settings page there we can see many option related to site settings


In site setting page Right site section we can see Site URL link click on site URL then we can have provision to specify our site URL and this is the place we need to provide our desired domain name/site host name.
We have two kinds of pages in Liferay Site Public pages and Private pages. Public pages is can be accessed by all the site users but private pages can be accessed by only the user who is created  it means site admin and site owner can access.

We can provide two distinct Virtual Hosts (URL/Domain Name) for each set of pages. For accessing public pages we can give one Virtual Host (URL/Domain Name) and for private pages we can give other Virtual Host (URL/Domain Name).

When we click on Site URL link then we can have provision to give public pages Virtual Host and Private pages Virtual Host.

We need to provide valid URL/Host Name in Virtual Host input fields then click on save button. Now Our Site can be accessed by given site URL.



 As we know that at time of site creation we have chosen black site so that it does not have any pages.
Liferay site should have at least one page to access with URL now we need to create one site page for our newly created site (LiferaySavvy)

Now in the site Options page Left Site Section you can find Pages menu tab there you can see site pages link. Click on that so that we can create pages for site.


Now select public pages and under this we can create new page by clicking one Add Page option .when we click on Add Page it will open popup there  it will ask required page details. Once we fill detail then click on adds page button in the popup then page will be crated under site public pages section.



New page (home) will be created in the public pages section



Mapping Virtual Host Name with local system IP

This is final step in Liferay Site Virtual Host and here we need to map given Site URL with our Local System IP address (127.0.0.1)

Generally our local system IP is 127.0.0.1 and we need to map IP with Site URL in the system host file.

In every system OS we have host file there we will configure host names related to our local system. Based on Operating System we can find host file in different locations. Generally it will be under etc directory (etc/host)

For windows this file location as follows

C:\Windows\System32\drivers\etc


Now open host file in editor and map your Site URL with 127.0.0.1 in the new line in file and finally save the file then mapping will be completed.

127.0.0.1     www.liferaysavvy.com


Now open your desire browser, in the address bar ping your given Site URL then it will open your Liferay site.



Note:

In Development environment we are using only Application servers so we need to append Port number for Site URL when we access from browser.

If Site is already created then we need to access site setting page then follow the above steps to complete Liferay site virtual hosting.

Go to list of sites and select your desired site then click on Actions menu there we can find Site Administration.


Once we click on site administration then we can see configuration in Left side Menu when we click on that we can find site settings. In the Site Setting right side section you can see site URL there you need to enter your desired site URL name. Rest of the steps same as above.




Same way we can also configure virtual host for site private pages. You also follow same steps for Liferay Organizations to configure virtual host.

Recent Posts

Recent Posts Widget

Popular Posts