I am new to jsf and I am setting up a basic reporting tool (sql queries) which shows a list of reports in the home page. I want to put an excel export commandbutton in the home page and export the report selected by the user or drive the user to a different execution page to show results in a datatable for the selected report. How can I achieve that? datatable with query results, of course, is visible only in the execution page and is dynamically created during query execution (this part works fine). Am I going crazy for nothing? Thanks in advance for any suggestion.
Asked
Active
Viewed 2,091 times
1
-
I am using primefaces 3.2 and dataexporter component, but willing to use other components if it helps to solve the issue! thanks – jsfviky Apr 28 '12 at 14:57
2 Answers
0
If you want to export data to Excel you need to use a third party library. There are free ones like JExcelApi and Apache POI. Also, there are commercial libraries like Aspose. If you're going to choose an open source library check this question: Choosing an excel java api.
When you export data to Excel, you must create the Excel file and download the content for the client. You can check how to download a file using JSF by @BalusC (JSF expert).
One more advice, when you're downloading a file don't add ajax functionality to the command link/button.

Community
- 1
- 1

Luiggi Mendoza
- 85,076
- 16
- 154
- 332
-
Thanks for the answer @luiggi, I was aware of that, my issue is more related to an architectural problem: invoking excel download from a page different from the one where data is actually displayed. Yesterday I found a workaround, I place a not rendered data table in the first page and I populate it as needed for excel download. I am not sure this is the cleanest way to proceed, but works. – jsfviky Apr 29 '12 at 18:58
-
@jsfviky71 When you run a query you build the report using a datatable. Using the same data for your report without making another request, you can build the Excel file and download it. You can pass the data by request. IMHO maybe your problem was about defining the scope of your managed beans. Correct me if I'm wrong – Luiggi Mendoza Apr 29 '12 at 19:13
-
Hi @luiggi and sorry for the late answer, not exactly, my main problem was having the excel button in the first page and the datatable in another page, the execution page is only for data show purposes whereas the home page shows a report list, so the user is able to download an excel version of the report without even showing the results of the query. – jsfviky May 03 '12 at 20:55
-
So my "solution" was to put a session bean as sql engine, a view bean in home page for report list, and a fake (not rendered) datatable in the same page to grab the data for excel download. In your opinion is this a clean way to proceed? Because to me sounds weird, thanks for your time – jsfviky May 03 '12 at 20:56
-
@jsfviky71 If I'm right you can have a Business Class (not a managed bean necessarily) that retrieves the report (maybe 1 Business Class for report type including different parameters). Then you call a method `getDataForReportA()` to get the report data and build your excel file or to shown data to the user depending what he/she chooses. In that way, the logic to generate the report is flexible, maintainable and separated from the presentation layer. – Luiggi Mendoza May 04 '12 at 02:22
-
So I should write my own custom component, because the primefaces one has a target attribute pointing to a datatable obj, thats the reason I had to build a fake one in home page. Thanks – jsfviky May 04 '12 at 19:31
0
You can use under code this code block provide excel export as genericly way. You can send any List and send any fileName
public class ExcelUtils {
public static <T> void writeToExcel(String fileName, List<T> data) {
FacesContext context = FacesContext.getCurrentInstance();
HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xls");
response.setHeader("Pragma", "no-cache");
OutputStream fos = null;
try {
fos = response.getOutputStream();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
XSSFWorkbook workbook = null;
try {
// File file = new File(fileName);
workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet();
List<String> fieldNames = getFieldNamesForClass(data.get(0).getClass());
int rowCount = 0;
int columnCount = 0;
Row row = sheet.createRow(rowCount++);
for (String fieldName : fieldNames) {
if (!fieldName.equals("serialVersionUID")) {
Cell cell = row.createCell(columnCount++);
cell.setCellValue(fieldName);
}
}
Class<? extends Object> classz = data.get(0).getClass();
for (T t : data) {
row = sheet.createRow(rowCount++);
columnCount = 0;
for (String fieldName : fieldNames) {
if (!fieldName.equals("serialVersionUID")) {
Cell cell = row.createCell(columnCount);
Method method = null;
try {
method = classz.getMethod("get" + capitalize(fieldName));
} catch (NoSuchMethodException nme) {
method = classz.getMethod("get" + fieldName);
}
Object value = method.invoke(t, (Object[]) null);
if (value != null) {
if (value instanceof String) {
cell.setCellValue((String) value);
} else if (value instanceof Long) {
cell.setCellValue((Long) value);
} else if (value instanceof Integer) {
cell.setCellValue((Integer) value);
} else if (value instanceof Double) {
cell.setCellValue((Double) value);
}
}
columnCount++;
}
}
}
workbook.write(fos);
fos.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (fos != null) {
fos.close();
context.responseComplete();
context.renderResponse();
}
} catch (IOException e) {
}
try {
if (workbook != null) {
workbook.close();
}
} catch (IOException e) {
}
}
}
// retrieve field names from a POJO class
private static List<String> getFieldNamesForClass(Class<?> clazz) throws Exception {
List<String> fieldNames = new ArrayList<String>();
Field[] fields = clazz.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
fieldNames.add(fields[i].getName());
}
return fieldNames;
}
// capitalize the first letter of the field name for retriving value of the
// field later
private static String capitalize(String s) {
if (s.length() == 0)
return s;
return s.substring(0, 1).toUpperCase() + s.substring(1);
}
}

Yasin
- 123
- 1
- 12