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

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

相关推荐
Boilermaker19926 小时前
[Java 并发编程] Synchronized 锁升级
java·开发语言
Cherry的跨界思维6 小时前
28、AI测试环境搭建与全栈工具实战:从本地到云平台的完整指南
java·人工智能·vue3·ai测试·ai全栈·测试全栈·ai测试全栈
MM_MS6 小时前
Halcon变量控制类型、数据类型转换、字符串格式化、元组操作
开发语言·人工智能·深度学习·算法·目标检测·计算机视觉·视觉检测
꧁Q༒ོγ꧂7 小时前
LaTeX 语法入门指南
开发语言·latex
njsgcs7 小时前
ue python二次开发启动教程+ 导入fbx到指定文件夹
开发语言·python·unreal engine·ue
alonewolf_997 小时前
JDK17新特性全面解析:从语法革新到模块化革命
java·开发语言·jvm·jdk
一嘴一个橘子7 小时前
spring-aop 的 基础使用(啥是增强类、切点、切面)- 2
java
sheji34167 小时前
【开题答辩全过程】以 中医药文化科普系统为例,包含答辩的问题和答案
java
古城小栈7 小时前
Rust 迭代器产出的引用层数——分水岭
开发语言·rust
ghie90907 小时前
基于MATLAB的TLBO算法优化实现与改进
开发语言·算法·matlab