记录使用jxls和poi制作向右扩展且合并单元格的表格

需要制作一个报表

成品样式

记录使用jxls和poi制作向右扩展且合并单元格的表格_第1张图片

 如图所见,这个报表需要可以配置显示信息,并一直向右向下拓展,且需要合并所需的单元格

第一步 制作模板

记录使用jxls和poi制作向右扩展且合并单元格的表格_第2张图片

 模板最终射击成这个样子,两个表中间的距离,由上表的循环极限行数决定,在a1和a13处使用批注jx:area(lastCell="I6") 之类的命令来圈定区域

然后是其他地区的循环,可见行6和行18是向下循环的,而b2:e6、f2:i6、b14:e18、f14:i18区域是向右循环增加的,向右循环需要在批注注明,例如b2处批注为:

jx:each(items="zzz"var="qj"lastCell="E6"direction="RIGHT")
jx:each(items="qj.yearList"var="year"lastCell="E6"direction="RIGHT")

b6处批注为: jx:each(items="year.list"var="l"lastCell="E6")

现在每个表分为三个list进行循环,而主要地区的list中仍有其他list进行循环

第二步 在后台获取填充用的list,这步就随便了

第三部 合并单元格.

jxls有合并单元格的功能 :合并单元格说明

这个功能可以通过提供批注来进行合并单元格操作,例如

jx:mergeCells(cols="year.mergeCell>0?year.mergeCell*4:4"lastCell="E2")之类的,但是不太好用,因为lastCell="E2"的原因,就会停止合并单元格,使得每个循环出的块状区域不能合并,想了半天还是用poi解决.
         
    JxlsHelper.getInstance().processTemplate(is, outputStream, context);
// 生成输出流后将其转换为字节数组
    byte[] content = outputStream.toByteArray();
//将字节数组转为poi工作表,并获取该页
    XSSFWorkbook wbook =  new XSSFWorkbook(new ByteArrayInputStream(content));
    Sheet sheet = wbook.getSheet("xxx");
// 获取待合并数据
    Row xxx= sheet.getRow(1); // 第一行
    Row yyy= sheet.getRow(2); //第二行
    String name= "";
    int startNum = 0; // 开始合并单元格的列的位置
    int endNum = 0; // 结束合并单元格列的位置
    int rowNum = 1 ;// 合并起始和结束的行数
for(int ii = 1 ; ii < xxx.getLastCellNum() ; ii += 4) {
                if (yyy.getCell(ii).toString().equals("")){
                    // 如果进入隔壁区域则退出循环
                    if (endNum > 0){
                        //如果大于0 则存在合并位置 进行合并
                        CellRangeAddress region = new CellRangeAddress(rowNum,rowNum,startNum,endNum+3);
                        sheet.addMergedRegion(region);
                        xxx.getCell(startNum).setCellValue(name);
                    }
                    break;
                }
                // 1. 获取单元格内容
                if (name.equals("")){
                    name= xxx.getCell(ii).toString();
                    startNum = ii;
                }else{
                    // 2. 如果相同则进行合并 如果不同则更新对比
                    if (xxx.getCell(ii).toString().equals(name)){
                        // 相同则记录单元格位置
                        endNum = ii;
                    }else{
                        // 如果不同 且存在合并区域 则进行更新
                        if (endNum > 0){
                            //如果大于0 则存在合并位置 进行合并
                            CellRangeAddress region = new CellRangeAddress(rowNum,rowNum,startNum,endNum+3);
                            sheet.addMergedRegion(region);
                            xxx.getCell(startNum).setCellValue(name);
                        }else{
                            //如果大于0 则存在合并位置 进行合并
                            CellRangeAddress region = new CellRangeAddress(rowNum,rowNum,startNum,startNum+3);
                            sheet.addMergedRegion(region);
                            xxx.getCell(startNum).setCellValue(name);
                        }
                        //更新单元格起始位置
                        name= xxx.getCell(ii).toString();
                        startNum = ii;
                        endNum = 0;
                    }
                }
            }

总之大概就这样, 其他地方类似

然后合并标题单元格

// 合并标题单元格并更新
            CellStyle cellStyle = sheet.getRow(0).getCell(0).getCellStyle(); //获取单元格样式
            int titleEndNum = zzz.getLastCellNum()-1;
            Row row12 = sheet.getRow(12);
            Row row0 = sheet.getRow(0);
 // 更新标题单元格样式
            for (int ii = 7 ; ii< titleEndNum+1; ii++ ){
                if ( sheet.getRow(0).getCell(ii) != null){
                    sheet.getRow(0).getCell(ii).setCellStyle(cellStyle);
                    sheet.getRow(12).getCell(ii).setCellStyle(cellStyle);
                }else{
                    sheet.getRow(0).createCell(ii);
                    sheet.getRow(12).createCell(ii);
                    sheet.getRow(0).getCell(ii).setCellStyle(cellStyle);
                    sheet.getRow(12).getCell(ii).setCellStyle(cellStyle);
                }
               
            }
   //表1标题
            String title = sheet.getRow(0).getCell(0).toString();
            CellRangeAddress region = new CellRangeAddress(0,0,0,titleEndNum);
            
            sheet.addMergedRegion(region);
            sheet.getRow(0).getCell(0).setCellValue(title);

你可能感兴趣的:(java)