JAVA 使用POI实现单元格行合并生成

预期效果

maven引用

xml 复制代码
 <dependency>
     <groupId>org.apache.poi</groupId>
     <artifactId>poi-ooxml</artifactId>
     <version>5.2.2</version>
 </dependency>

Java代码实现

功能实现

java 复制代码
    private boolean callExcel(List<MColumnValueVo> mColumnValueVos,String name){
        SXSSFWorkbook workbook = new SXSSFWorkbook(100);
        Sheet sheet = workbook.createSheet("明细信息");

        //设置单元格居中
        CellStyle cellStyle = workbook.createCellStyle();
        //设置边框样式
        cellStyle.setAlignment(HorizontalAlignment.CENTER);//左右居中
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 上下居中
        String[] headers1 = {"号码","名称"};//2个
        String[] mxHeaders = {"行号","行性质"};//2个
        String[] headers2 = {"合计金额","状态"};//2个

        Row headerRow = sheet.createRow(0); // 创建表头行,索引为0
        for (int i = 0; i < headers1.length; i++) {//headers1表格合并并赋值
            Cell cell = headerRow.createCell(i);//创建列
            cell.setCellStyle(cellStyle);//设置表格样式
            cell.setCellValue(headers1[i]);//表格赋值内容
            sheet.addMergedRegion(new CellRangeAddress(0, 1, i, i));//表格的合并,先填内容在合并且合并保留内容为合并的第一行内容
        }

        int firstCol = headers1.length+mxHeaders.length; // 从第一行开始填充数据
        int hlt = firstCol+headers2.length;// 合计列
        // 自动调整列宽(可选)
        for (int colNum = 0; colNum < hlt; colNum++) {
            sheet.setColumnWidth(colNum, 256 * 25);
        }
        //发票明细表格合并并赋值
        Row two = sheet.getRow(1);
        if (two == null) {
            two = sheet.createRow(1);
        }
        sheet.addMergedRegion(new CellRangeAddress(0, 0, headers1.length, firstCol-1));
        Cell mergedCell = headerRow.createCell(headers1.length); // 合并后的单元格左上角
        mergedCell.setCellStyle(cellStyle);
        mergedCell.setCellValue("明细");

        for (int i = 0; i < mxHeaders.length; i++) {//明细表头赋值
            Cell cell = two.createCell(i + headers1.length);
            cell.setCellStyle(cellStyle);
            cell.setCellValue(mxHeaders[i]);
        }

        for (int i = 0; i < headers2.length; i++) {
            Cell cell = headerRow.createCell(i + firstCol);
            cell.setCellStyle(cellStyle);
            cell.setCellValue(headers2[i]);
            sheet.addMergedRegion(new CellRangeAddress(0, 1, firstCol+i, firstCol+i));
        }


        // 填充数据
        int lastRowIndex = 2; //记录最后行位置
        for (MColumnValueVo vo : mColumnValueVos) {
            // 创建行
            Row row = sheet.createRow(lastRowIndex);
            if(vo.getMxQueryOuts()!=null){//添加发票明细
                for (int i = 0; i < vo.getMxQueryOuts().size(); i++) {
                    MMColumnValueVo mxVo = vo.getMxQueryOuts().get(i);
                    Row row1 = sheet.getRow(lastRowIndex + i);
                    if(row1 == null) {
                        row1 = sheet.createRow(lastRowIndex + i);
                    }
                    for (int j = 0; j < headers2.length; j++) {
                        Cell cell = row1.createCell(headers1.length + j);
                        cell.setCellStyle(cellStyle);
                        cell.setCellValue(getValueFromMMVo(mxVo, j));
                    }
                }
            }
            for (int i = 0; i < headers1.length; i++) {
                Cell cell = row.createCell(i);
                cell.setCellStyle(cellStyle);
                cell.setCellValue(getValueFromMxVo1(vo, i));
                if(vo.getMxQueryOuts()!=null && vo.getMxQueryOuts().size()>1){
                    sheet.addMergedRegion(new CellRangeAddress(lastRowIndex, lastRowIndex+vo.getMxQueryOuts().size()-1, i, i));
                }
            }

            for (int i = 0; i < headers2.length; i++) {
                Cell cell = row.createCell(i + firstCol);
                cell.setCellStyle(cellStyle);
                cell.setCellValue(getValueFromMxVo2(vo, i));
                if(vo.getMxQueryOuts()!=null && vo.getMxQueryOuts().size()>1){
                    sheet.addMergedRegion(new CellRangeAddress(lastRowIndex, lastRowIndex+vo.getMxQueryOuts().size()-1, firstCol+i, firstCol+i));
                }
            }
            if(vo.getMxQueryOuts()==null){
                lastRowIndex++;
            }else {
                lastRowIndex += vo.getMxQueryOuts().size();
            }
            logger.info("lastRowIndex:{}",lastRowIndex);
        }
        // 写入到文件 name:绝对路径并带excel文件名称及后缀
        try (FileOutputStream out = new FileOutputStream(name)) {
            workbook.write(out);
        } catch (IOException e) {
            logger.error("生成明细信息excel表格异常",e);
            return false;
        } finally {
            // 关闭workbook,释放资源
            workbook.dispose();
        }
        return true;
    }

返回内容

java 复制代码
private String getValueFromMxVo1(MMColumnValueVo vo, int colNumMx) {
    switch (colNumMx) {
        case 0: return vo.getLineNo() != null ? vo.getLineNo().toString() : "";
        case 1: return vo.getLineNature();
        default: return "";
    }
}

注: 返回内容都可以按照该种方式

相关推荐
锦***林22 分钟前
用 Python 写一个自动化办公小助手
开发语言·python·自动化
陈小桔44 分钟前
idea中重新加载所有maven项目失败,但maven compile成功
java·maven
小学鸡!1 小时前
Spring Boot实现日志链路追踪
java·spring boot·后端
xiaogg36781 小时前
阿里云k8s1.33部署yaml和dockerfile配置文件
java·linux·kubernetes
逆光的July1 小时前
Hikari连接池
java
微风粼粼1 小时前
eclipse 导入javaweb项目,以及配置教程(傻瓜式教学)
java·ide·eclipse
番茄Salad1 小时前
Spring Boot临时解决循环依赖注入问题
java·spring boot·spring cloud
立志成为大牛的小牛2 小时前
数据结构——二十六、邻接表(王道408)
开发语言·数据结构·c++·学习·程序人生
天若有情6732 小时前
Spring MVC文件上传与下载全面详解:从原理到实战
java·spring·mvc·springmvc·javaee·multipart
祈祷苍天赐我java之术2 小时前
Redis 数据类型与使用场景
java·开发语言·前端·redis·分布式·spring·bootstrap