6

I would like to export the contents of a <rich:dataTable> or <rich:extendedDataTable> to excel.

  • I have see that PrimeFaces has the "exporter feature" http://www.primefaces.org/showcase/ui/exporter.jsf

  • I would like to be able to do something similar to this only with out using PrimeFaces, but with richFaces (version 3.3.3)...(I would like to migrate to RichFaces 4 at some point in the future but am stuck with 3.3.3 for now)

  • I have read that it is possible to build your own using http://poi.apache.org/ but I do not know where to start on implementing something like this...

Any thoughts about how best to preform the desired export and examples would be much appreciated!

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Curt
  • 2,944
  • 6
  • 29
  • 34

2 Answers2

10

Using POI in JSF isn't really different from using POI in plain Java. Just have a collection of items representing each record. You must already have it as you're using a datatable which also takes such a collection. You just have to iterate over exactly the same collection to create an excel sheet in POI.

Here's a kickoff example, where items is a List<Item> which you're also using in the datatable:

Workbook workbook = new HSSFWorkbook();
Sheet sheet = workbook.createSheet("sheet title");
int rowIndex = 0;

for (Item item : items) {
    Row row = sheet.createRow(rowIndex++);
    int columnIndex = 0;

    row.createCell(columnIndex++).setCellValue(item.getId());
    row.createCell(columnIndex++).setCellValue(item.getName());
    row.createCell(columnIndex++).setCellValue(item.getValue());
    // ...
}

workbook.write(someOutputStream); // Write the Excel result to some output.

In order to offer this as a download to the JSF response, you need to provide the ExternalContext#getResponseOutputStream() as someOutputStream. You also need to set the response content type (so that the browser knows what application to associate with it) and the response content disposition (so that it's opened as an attachment and that it has a valid filename).

FacesContext context = FacesContext.getCurrentInstance();
ExternalContext externalContext = context.getExternalContext();
externalContext.responseReset(); 
externalContext.setResponseContentType("application/vnd.ms-excel");
externalContext.setResponseHeader("Content-Disposition", "attachment;filename=export.xls");
workbook.write(externalContext.getResponseOutputStream());
context.responseComplete(); // Prevent JSF from performing navigation.

In the end, FacesContext#responseComplete() must be invoked to prevent JSF from performing the default navigation task (which would only corrupt the Excel file by appending some HTML output of the navigated page to the end).

Note that the above JSF example assumes JSF 2.x. If you're actually using JSF 1.x, which lacks several convenience ExternalContext delegate methods, then you'd need to grab the raw HttpServletResponse by ExternalContext#getResponse() and perform the actions on it. See also How to provide a file download from a JSF backing bean?

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • 3
    Just to add some info to this answer, in RichFaces 3.3 you should use an `` to handle this operation. The provided code will force a download and you can't download any file with an ajax request. Assuming this code is on `Bean#toExcel()`, you should have this JSF code in your page: `` or similar, depending on the needs. – Luiggi Mendoza Nov 02 '12 at 17:08
  • Indeed, file downloads can't be handled by JS/Ajax. You can also just use ``. This disclaimer is also mentioned in the last linked question http://stackoverflow.com/questions/9391838/how-to-stream-a-file-download-in-a-jsf-backing-bean/9394237#9394237 – BalusC Nov 02 '12 at 17:09
  • Thank you for this as always you are very helpful! This seems to be a much better approach then what I was attempting before..., I do have one question, where you initialize 'Workbook' like 'Workbook workbook = new HSSFWorkbook();' I seem to be having a hard time, it looks like HSSFWorkbook isnt in the poi-3.8 jar that I downloaded... I was wondering if maybe you knew? – Curt Nov 02 '12 at 17:43
  • It is in there. All the POI related imports you need for the particular code snippet are `import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook;` – BalusC Nov 02 '12 at 17:44
  • I keep getting 'Type mismatch: cannot convert from HSSFWorkbook to Workbook' – Curt Nov 02 '12 at 17:48
  • You have either the wrong import of `Workbook`, or a duplicate older versioned POI library elsewhere in classpath. The class `Workbook` is also provided by JExcelAPI (POI has it as an interface). Perhaps you've it also in the classpath by some experiment? Anyway doublecheck the imports and compare them with the ones shown in my previous comment. – BalusC Nov 02 '12 at 17:49
-2

I needed also this functionality so I took the primefaces dataExporter component and modified it to use it with Richfaces. I also added the capability to export collapsibleSubTable insides tables. Primefaces and Richfaces are opensource, feel free to improve it. Package containing sources and examples: bundle

jerem
  • 1