如何将rich:dataTable导出为Excel

6
我想将 <rich:dataTable><rich:extendedDataTable> 的内容导出到 Excel。我已经看到 PrimeFaces 有“导出器功能”http://www.primefaces.org/showcase/ui/exporter.jsf,但我想使用 RichFaces(版本为3.3.3)来完成类似的操作(虽然我以后想升级到 RichFaces 4,但现在只能使用 3.3.3)。我了解到可以使用http://poi.apache.org/ 来构建自己的导出器,但我不知道如何开始实现这样的功能...如果您有任何关于如何最好地执行所需的导出和示例的想法,将不胜感激!
2个回答

10

在JSF中使用POI与在普通Java中使用POI并没有太大区别。只需拥有代表每个记录的项目集合,您已经拥有它,因为您正在使用还接收这种集合的datatable。您只需对完全相同的集合进行迭代,以在POI中创建Excel工作表。

以下是一个快速演示示例,其中items是一个List<Item>,您还将在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.
为了将此内容作为JSF响应的下载提供,您需要将ExternalContext#getResponseOutputStream()提供为someOutputStream。您还需要设置响应内容类型(以便浏览器知道与之关联的应用程序)和响应内容设置(以便其作为附件打开并具有有效的文件名)。
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.
最后,必须调用FacesContext#responseComplete()以防止JSF执行默认的导航任务(该任务只会将一些HTML输出附加到导航页面的末尾,从而破坏Excel文件)。请注意,上述JSF示例假定使用JSF 2.x。如果你实际上使用的是JSF 1.x,并且缺少几个便利的ExternalContext委托方法,则需要通过ExternalContext#getResponse()获取原始的HttpServletResponse并在其上执行操作。另请参见How to provide a file download from a JSF backing bean?

3
仅在此回答中添加一些信息,如果您使用的是RichFaces 3.3,您应该使用<a4j:htmlCommandLink>来处理此操作。提供的代码将强制下载文件,您无法使用ajax请求下载任何文件。假设此代码在Bean#toExcel()上,您应该在页面中拥有此JSF代码:<a4j:htmlCommandLink action="#{bean.toExcel}" target="_blank" value="To Excel" /> 或类似的内容,具体取决于需求。 - Luiggi Mendoza
事实上,JS/Ajax 无法处理文件下载。您也可以使用 <h:commandLink>。该免责声明也在最后一个链接的问题中提到:https://dev59.com/XGox5IYBdhLWcg3wKBN9#9394237 - BalusC
谢谢您一如既往的帮助!这似乎是比我之前尝试的方法更好的方法...,我有一个问题,在您初始化“Workbook”像“Workbook workbook = new HSSFWorkbook()”时,我似乎遇到了困难,看起来HSSFWorkbook不在我下载的poi-3.8 jar包中...我想知道您是否知道? - Curt
这些都在里面。你需要的与POI相关的导入语句如下: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
我一直收到“类型不匹配:无法将HSSFWorkbook转换为Workbook”的错误。 - Curt
你可能导入了错误的 Workbook,或者在类路径中有一个旧版本的 POI 库的重复。Workbook 类也由 JExcelAPI 提供(POI 将其作为接口)。也许你在某些实验中也将其放在了类路径中?无论如何,请仔细检查导入并将其与我之前评论中显示的导入进行比较。 - BalusC

-2
我也需要这个功能,所以我使用了Primefaces的dataExporter组件,并修改它以与Richfaces一起使用。我还添加了在表格内导出折叠子表格的功能。 Primefaces和Richfaces都是开源的,欢迎您进行改进。 包含源代码和示例的软件包: bundle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接