首页 > 其他 > 详细

使用poi生成复杂多行表头

时间:2015-05-29 17:58:16      阅读:290      评论:0      收藏:0      [点我收藏+]

  最近公司的项目需要添加导出报表的功能,报表都是多行表头,最初是使用事先创建模板然后导出的方式,但是随着报表数量的增加和模板表头的变动,这种导出方案就不合适了。因此尝试使用了poi动态生成复杂多行表头的方式导出。说明一下,表头格式来源是根据页面表格属性生成的,其中页面表格是使用了jqgrid框架。以下是代码实现过程:

  一、js获取表格属性的共用方法:

  1、获取表格的行和列属性;

  2、获取数据行的属性和数据格式,方便动态添加数据行;

  3、获取导出文件名,把菜单名作为导出的excel文件名。

  

/**
 * 下载报表,使用poi,并根据页面报表动态创建表头,不需要事先创建模板
 * @param gridId 页面表格ID
 * @param formId 
 */
function downloadReport(gridId, formId) {
    var downloadReportUrl = "downloadReport";
    var exportHeader = $("#gview_" + gridId).find(‘div.ui-jqgrid-hdiv‘).find(‘table‘).eq(0).find(‘tr‘);
    //获取表头行列属性(为了生成多行表头)
    var mergedRegions = "";
    for(var i = 0;i<exportHeader.length;i++){
        var mergedRegion = "";
        exportHeader.eq(i).find(‘th:visible‘).each(function(){
            if($(this).text() != null && $(this).text() != ‘‘){
                var rowspan = $(this).attr(‘rowspan‘);
                var colspan = $(this).attr(‘colspan‘);
                if(rowspan == null || rowspan == undefined){
                    rowspan = 0;
                }
                if(colspan == null || colspan == undefined){
                    colspan = 0;
                }
                mergedRegion += $(this).text() + "," +rowspan + "," + colspan + ":"
            }
        });
        if(mergedRegion != ""){
            mergedRegion = mergedRegion.substring(0, mergedRegion.length-1);
            mergedRegions += mergedRegion + ";";
        }
    }
    if(mergedRegions != ""){
        mergedRegions = mergedRegions.substring(0, mergedRegions.length-1);
    }
    //获取数据行
    var exportBody = $("#gview_" + gridId).find(‘div.ui-jqgrid-bdiv‘).find(‘table‘).eq(0).find(‘tr‘);
    if(exportBody.length <= 1){
        showAlert("不能导出空报表,请点击查询后再导出!", "信 息");
        return;
    }
    //获取首行数据行(获取name和value,为了导出excel的数据和格式的填充)
    var columnNames = "";
    exportBody.eq(1).find(‘td:visible‘).each(function(){
        var key = $(this).attr(‘aria-describedby‘);
        var value = $(this).text();
        if(key){
            if(key == ""){
                showAlert("报表下载出错,请联系系统管理员!", "信 息");
                return;
            }
            key = key.replace(gridId + ‘_‘,‘‘);
            columnNames += key + "=" + value +"^_^";
        }
    });
    if(columnNames != ""){
        columnNames = columnNames.substring(0, columnNames.length-3);
    }

    //获取表格所在页面的菜单名,为了生成导出报表的文件名
    var fileName = "";
    var labelledby = $("#gview_" + gridId).parents(‘div.ui-tabs-panel‘).attr(‘aria-labelledby‘);
    if(labelledby){
        fileName = $(‘#‘+labelledby).text();
    }
    if(fileName == ""){
        fileName = "报表";
    }
    try {
        $(‘#loading-msk‘).show().find(‘span‘).html(‘正在下载...‘);
        getDownLoadStatu();
        
        //表头信息
        if($("#" + formId).find(‘input[name="excel_mergedRegions"]‘).length == 0){
            $("#" + formId).append(‘<input name="excel_mergedRegions" type="hidden"/>‘);
        }
        $("#" + formId).find("input[name=‘excel_mergedRegions‘]").val(mergedRegions);

        //数据信息
        if($("#" + formId).find(‘input[name="excel_columnNames"]‘).length == 0){
            $("#" + formId).append(‘<input name="excel_columnNames" type="hidden"/>‘);
        }
        $("#" + formId).find("input[name=‘excel_columnNames‘]").val(columnNames);
        
        //报表信息
        if($("#" + formId).find(‘input[name="excel_fileName"]‘).length == 0){
            $("#" + formId).append(‘<input name="excel_fileName" type="hidden"/>‘);
        }
        $("#" + formId).find("input[name=‘excel_fileName‘]").val(fileName);

        
        if($("#" + formId).find(‘input[name="gridParam"]‘).length == 0){
            $("#" + formId).append(‘<input name="gridParam" type="hidden"/>‘);
        }
        
        var $grid    = $(‘#‘ + gridId + ‘‘);
        var postData = $grid.jqGrid("getGridParam", "postData");

        $.extend(postData, {rpt_parameters:$(‘#‘ + formId).serializeJson()});

        $("#" + formId).find("input[name=‘gridParam‘]").val(JSON.stringify(postData));
        $("#" + formId).attr("action", downloadReportUrl).submit();
    } catch(e) {
        $(‘#loading-msk‘).hide();
        showAlert("报表下载出错,请联系系统管理员!", "信 息");
    } finally {
    //    $("#" + formId).attr("action", "#");
        $("#" + formId).find("input[name=‘gridParam‘]").val("");
    }
}


2、后台处理:

 获取表格属性参数

//获取前端传递的表格属性参数
String mergedRegion = p.getParameters().get("excel_mergedRegions");
String columnNames = p.getParameters().get("excel_columnNames");
String fileName = p.getParameters().get("excel_fileName");


动态生成多行表头

/**
     * 根据poi导出excel,并根据页面自动创建表头信息 
     * @param mergedRegion 表头格式信息
     * @param columnNames 字段信息
     * @param fileName 报表名
     * @return
     */
    public static HSSFWorkbook createWorkBook(String mergedRegion, String columnNames, String fileName) {
        // 创建新的Excel 工作簿
        HSSFWorkbook workbook = new HSSFWorkbook();

        // 设置字体
        HSSFFont font = workbook.createFont();
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        font.setFontHeightInPoints((short) 14);

        // 设置样式
        HSSFCellStyle cellStyle = workbook.createCellStyle();
        cellStyle.setFont(font);
        cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        cellStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);

        HSSFCellStyle cellLeftStyle = workbook.createCellStyle();
        cellLeftStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
        cellLeftStyle.setAlignment(HSSFCellStyle.ALIGN_LEFT);

        HSSFCellStyle cellRightStyle = workbook.createCellStyle();
        cellRightStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
        cellRightStyle.setAlignment(HSSFCellStyle.ALIGN_RIGHT);

        HSSFCellStyle cs = workbook.createCellStyle();
        HSSFFont f = workbook.createFont();
        f.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        f.setFontHeightInPoints((short) 10);
        cs.setFont(f);
        cs.setAlignment(CellStyle.ALIGN_CENTER);
        cs.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
        cs.setWrapText(true);

        //获取数据行的列数
        int length = columnNames.split("\\^\\_\\^").length;

        // 第一行
        // 在索引0的位置创建行(最顶端的行)
        HSSFSheet sheet = workbook.createSheet(fileName);
        HSSFRow row = sheet.createRow(0);
        CellRangeAddress cellRangeAddress = new CellRangeAddress(0, 0, 0, length - 1);
        sheet.addMergedRegion(cellRangeAddress);
        // 在索引0的位置创建单元格(左上端)
        HSSFCell cell = row.createCell(0);
        // 定义单元格为字符串类型
        cell.setCellType(HSSFCell.CELL_TYPE_STRING);
        cell.setCellStyle(cellStyle);
        // 在单元格中输入一些内容
        cell.setCellValue(fileName + "报表");

        // 第二行
        row = sheet.createRow(1);
        cellRangeAddress = new CellRangeAddress(1, 1, 0, length - 1);
        sheet.addMergedRegion(cellRangeAddress);
        cell = row.createCell(0);
        cell.setCellStyle(cellRightStyle);
        cell.setCellValue("制表时间:"+ new SimpleDateFormat("yyyy-MM-dd HH:mm").format(new Date()));

        // 处理表头,第三行开始
        String[] mergedRegions = mergedRegion.split(";");
        //创建一个虚拟表头,并使用false标识这个单元格没有被占用
        List<Map<Integer, Boolean>> headerLists = new ArrayList<Map<Integer, Boolean>>();
        for (int i = 0; i <= mergedRegions.length + 1; i++) {
            Map<Integer, Boolean> headerMap = new HashMap<Integer, Boolean>();
            for (int j = 0; j < length; j++) {
                headerMap.put(j, false);
                if (i == 0) {
                    sheet.setColumnWidth(j, (short) (16 * 256));
                }
            }
            headerLists.add(headerMap);
        }
        for (int i = 0; i < mergedRegions.length; i++) {
            String mergedRegionss = mergedRegions[i];
            int x = 2 + i;
            int y = 2 + i;
            int m = 0;
            int n = 0;
            row = sheet.createRow(2 + i);
            row.setHeight((short) (2 * 256));
            String[] _mergedRegionss = mergedRegionss.split(":");
            for (int j = 0; j < _mergedRegionss.length; j++) {
                String mergedRegionsss = _mergedRegionss[j];
                String[] _mergedRegionsss = mergedRegionsss.split(",");
                //获取最小行中未被占用的单元格
                List<Integer> cellNum = new ArrayList<Integer>();
                for (int mm = 0; mm < headerLists.size(); mm++) {
                    Map<Integer, Boolean> headerMap = headerLists.get(mm);
                    for (Integer key : headerLists.get(mm).keySet()) {
                        if (!headerMap.get(key)) {
                            cellNum.add(key);
                        }
                    }
                    if (cellNum.size() > 0) {
                        break;
                    }
                }
                Collections.sort(cellNum);
                m = cellNum.get(0);

                int _y = y + (Integer.parseInt(_mergedRegionsss[1])) - 1;
                if (Integer.parseInt(_mergedRegionsss[1]) == 0) {
                    _y = y;
                }

                n = n + (Integer.parseInt(_mergedRegionsss[2]));
                if (Integer.parseInt(_mergedRegionsss[2]) == 0) {
                    n = m;
                }

                // String cra = x + ", " + _y + ", " + m + ", " + n;
                for (int t = x - 2; t <= _y - 2; t++) {
                    for (int k = m; k <= n; k++) {
                        headerLists.get(t).put(k, true);
                    }
                }
                cellRangeAddress = new CellRangeAddress(x, _y, m, n);
                sheet.addMergedRegion(cellRangeAddress);
                cell = row.createCell(m);
                cell.setCellStyle(cs);
                cell.setCellValue(_mergedRegionsss[0]);
                m = n + 1;
            }
        }
        
        return workbook;
    }


最后就是数据和行格式的填充、导出流的处理。

 

  

使用poi生成复杂多行表头

原文:http://www.cnblogs.com/wh1517/p/4538728.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!