Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JSF从另一个页面导出excel数据_Jsf_Jsf 2_Primefaces - Fatal编程技术网

JSF从另一个页面导出excel数据

JSF从另一个页面导出excel数据,jsf,jsf-2,primefaces,Jsf,Jsf 2,Primefaces,我是jsf新手,我正在建立一个基本的报告工具sql queries,它在主页上显示报告列表。我想在主页中放置一个excel导出命令按钮,导出用户选择的报告,或者将用户驱动到另一个执行页面,以便在数据表中显示所选报告的结果。我怎样才能做到这一点?当然,带有查询结果的datatable仅在执行页面中可见,并在查询执行期间动态创建。这部分工作正常。我疯了吗?提前感谢您的建议。如果您想将数据导出到Excel,您需要使用第三方库。有像和这样的免费的。此外,还有商业图书馆,如。如果要选择开源库,请检查以下问

我是jsf新手,我正在建立一个基本的报告工具sql queries,它在主页上显示报告列表。我想在主页中放置一个excel导出命令按钮,导出用户选择的报告,或者将用户驱动到另一个执行页面,以便在数据表中显示所选报告的结果。我怎样才能做到这一点?当然,带有查询结果的datatable仅在执行页面中可见,并在查询执行期间动态创建。这部分工作正常。我疯了吗?提前感谢您的建议。

如果您想将数据导出到Excel,您需要使用第三方库。有像和这样的免费的。此外,还有商业图书馆,如。如果要选择开源库,请检查以下问题:

将数据导出到Excel时,必须创建Excel文件并为客户端下载内容。您可以通过@BalusC JSF expert检查如何使用


还有一条建议,当您下载文件时,不要将ajax功能添加到命令链接/按钮。

您可以在代码下使用此代码块,以常规方式提供excel导出。您可以发送任何列表和文件名

公开课的优异成绩{

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);
}

}

我正在使用primefaces 3.2和dataexporter组件,但如果有助于解决问题,我愿意使用其他组件!感谢@luiggi的回答,我意识到了这一点,我的问题更多地与架构问题有关:从与实际显示数据的页面不同的页面调用excel下载。昨天我找到了一个解决方法,我在第一页中放置了一个未呈现的数据表,并根据需要填充它以供excel下载。我不确定这是否是最干净的方法,但在运行查询时,可以使用datatable生成报告。在报告中使用相同的数据而无需再次请求,您可以构建Excel文件并下载它。您可以通过请求传递数据。我想你的问题可能是关于定义托管bean的范围。如果我错了,请纠正我Hi@luiggi,很抱歉回答晚了,不完全是这样,我的主要问题是excel按钮位于第一页,datatable位于另一页,执行页仅用于显示数据,而主页显示报告列表,因此,用户可以下载excel版本的报表,甚至不显示查询结果。因此,我的解决方案是将会话bean作为sql引擎,将视图bean放在报表列表的主页中,并在同一页面中放置一个假的未呈现数据表,以获取用于excel下载的数据。你认为这是一种干净的方式吗?因为对我来说听起来很奇怪,谢谢你的帮助time@jsfviky71如果我是对的,您可以有一个业务类,而不必是一个托管bean,用于检索报表,可能有一个业务类用于包含不同参数的报表类型。然后调用getDataForReportA方法来获取报告数据并构建excel文件,或者根据用户的选择向用户显示数据。这样,生成报告的逻辑是灵活的、可维护的,并且与表示层分离。