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

需要制作一个报表

成品样式

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

第一步 制作模板

 模板最终射击成这个样子,两个表中间的距离,由上表的循环极限行数决定,在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);

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以回答您关于jxls合并单元的问题。jxls是一个基于Java的开源Excel操作工具,可以通过Excel模板来实现数据的导出和导入等功能。下面是一个简单的jxls合并单元示例: 1. 创建Excel模板 在Excel模板中,需要使用jxls提供的标记语言来标记出需要合并单元。例如,下面是一个包含合并单元的模板示例: ``` <html xmlns:jxl="http://jxls.sf.net/1.0/mini"> <body> <table> <tr> <td jxl:merge="0,1,0,2">姓名</td> <td>年龄</td> <td>性别</td> </tr> <tr> <td></td> <td></td> <td></td> </tr> <jxl:each items="users" var="user"> <tr> <td>${user.name}</td> <td>${user.age}</td> <td>${user.gender}</td> </tr> </jxl:each> </table> </body> </html> ``` 在上面的模板中,我们使用jxl:merge标记来标记需要合并单元,其中0,1,0,2表示需要合并从第0行到第1行、从第0列到第2列的单元。 2. 编写导出代码 在Java代码中,可以使用jxls提供的API来进行导出操作。例如: ``` // 加载Excel模板 InputStream is = new FileInputStream("template.xls"); Workbook workbook = WorkbookFactory.create(is); // 创建Excel上下文对象 Map<String, Object> context = new HashMap<>(); context.put("users", getUserList()); // 执行模板引擎,生成Excel文件 JxlsHelper.getInstance().processTemplate(context, workbook.getSheetAt(0)); // 保存Excel文件 OutputStream os = new FileOutputStream("output.xls"); workbook.write(os); os.close(); ``` 在上面的代码中,我们首先加载Excel模板,然后创建Excel上下文对象,并将需要合并单元的数据添加到上下文中。最后,使用JxlsHelper的processTemplate方法执行模板引擎,生成Excel文件,并保存到本地。 3. 导出Excel文件 运行上面的代码后,会在项目根目录下生成一个名为output.xls的Excel文件,其中包含了我们导出的数据和合并单元。 以上就是一个简单的jxls合并单元示例,希望能对您有所帮助。如果您有其他问题,可以继续咨询我。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值