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

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

相关推荐
开开心心就好4 分钟前
多份文档怎么批量打印?支持多种格式
java·服务器·开发语言·pdf·ocr·散列表·启发式算法
Want5955 分钟前
Python炫酷烟花①
开发语言·python
Pniubi40 分钟前
模拟一个充值送token怎么保证幂等?一致性?原子性?
java
企业数字化笔记1 小时前
多租户配额怎么控制?用量口径、并发预留与超额处理的实现方法
java·数据库·spring boot
星夜离尘561 小时前
MATLAB 线性去趋势为何损伤低频正弦:联合最小二乘估计幅相与漂移
开发语言·matlab
巴勒个啦1 小时前
Prompt Engineering 实战:5 个让 AI 生成生产级业务代码的工程模式
java·前端
倚楼听风语2 小时前
Kotlin 协程与 suspend 原理详解
java·算法·kotlin
程序员清风2 小时前
双指针与滑动窗口:高效处理连续区间
开发语言·算法
开开心心就好2 小时前
文件被占用删不掉?解锁工具强制删除
java·运维·服务器·开发语言·前端·pdf·ocr
weixin_460443562 小时前
Java+Linux私有化训考平台:服务、数据库与终端部署结构解析
java·linux·数据库·私有化部署·企业培训考试系统·企业考试系统