IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> Java实现导出excel对重复数据进行单元格合并 -> 正文阅读

[开发测试]Java实现导出excel对重复数据进行单元格合并

Java 导出excel重复数据动态合并单元

前言:记录下第一次做动态导出excel表格,重复数据合并行。这个难就难在不知道从数据库查出来的数据那些是重复的哪些是不重复的,全部都是动态合并,并不能进行表格写死合并,要根据实际数据来合并。我这个项目是利用poi实现的。注意:我的表格导出功能是有前端配合的,没用swagger和postman导出过。以下就分享纯后端的导出合并单元格逻辑处理,前端自理。

没有合并重复数据之前的excel

在这里插入图片描述

合并重复数据之后的excel

在这里插入图片描述

实现代码

需要用到的maven依赖

		<!-- excel工具 -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
        </dependency>

在实体类需要导出的字段上加上poi里的@Excel,此处我只是挑了两个字段举例

	@ApiModelProperty(value = "规模")
    @Excel(name = "规模")
    private String reservoirScale;

    @ApiModelProperty(value = "地区")
    @Excel(name = "地区")
    private String reservoirRegion;

步骤一:service层的数据处理实现业务,先查询出来需要导出的数据,最后的数据导出来也就是图一的样子,这一步很简单就是controller调service调dao调mapper查出数据库的数据然后返回一个List<对象>集合

//先查询出来需要导出的数据
public List<SchedulingExportVo> exportScheduling(SelectSchedulingBo schedulingBo){
        //校验
        if (schedulingBo != null) {
            //获取需要被导出的数据
            List<SchedulingExportVo> schedulingExportVos = inspectionSchedulingMapper.exportScheduling(schedulingBo);
            //获取字典表数据
            List<SysDictData> data = dictTypeService.selectDictDataByType("reservoir_scale");
            //键值对存入
            Map<String, String> map = data.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
            //遍历
            for (int i = 0; i < schedulingExportVos.size(); i++) {
                schedulingExportVos.get(i).setReservoirScale(map.get(schedulingExportVos.get(i).getReservoirScale()));
            }
            return schedulingExportVos;
        }
        return new ArrayList<>();
    }

步骤二:service层的数据处理实现业务。另外在写一个单元格合并的方法,对查询出来的数据进行和合并单元格操作,注意:exportReceipt方法里面的list,就是步骤一查出来的list集合数据,利用poi加二维数组实现

//把需要导出的数据进行合并单元格的处理  List<SchedulingExportVo> list:步骤一查出来的数据
public XSSFWorkbook exportReceipt(List<SchedulingExportVo> list) {
        // 定义时间格式
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        // 标题
        String[] tableTitle = {"名称", "规模", "地区", "标题", "日期", "责任领导", "排班人员", "巡查人员", "巡查项目", "备注"};
        // 定义表格列数
        Integer colTol = tableTitle.length;
        // 定义行数 数据条数 + 主题(1) + 标题(1) = 2 + 数据条数
        Integer rowTol = (list != null ? list.size() : 0) + 1;
        // 定义 容器装载数据  二维数组
        String[][] receiptTwoArr = new String[rowTol][colTol];
        // 循环行
        for (int i = 0; i < receiptTwoArr.length; i++) {
            // 循环列
            for (int y = 0; y < receiptTwoArr[i].length; y++) {
                // 标题
                if (i == 0) {
                    receiptTwoArr[i][y] = tableTitle[y];
                    continue;
                }
                SchedulingExportVo schedulingExportVo = list.get(i - 1);
                switch (y) {
                    case 0:
                        // 名称
                        receiptTwoArr[i][y] = StrUtil.isNotBlank(schedulingExportVo.getReservoirName()) ? schedulingExportVo.getReservoirName() : "";
                        break;
                    case 1:
                        // 规模
                        receiptTwoArr[i][y] = StrUtil.isNotBlank(schedulingExportVo.getReservoirScale()) ? schedulingExportVo.getReservoirScale() : "";
                        break;
                    case 2:
                        // 地区
                        receiptTwoArr[i][y] = StrUtil.isNotBlank(schedulingExportVo.getReservoirRegion()) ? schedulingExportVo.getReservoirRegion() : "";
                        break;
                    case 3:
                        // 标题
                        receiptTwoArr[i][y] = StrUtil.isNotBlank(schedulingExportVo.getTitle()) ? schedulingExportVo.getTitle() : "";
                        break;
                    case 4:
                        // 开始日期
                        if (DateUtil.format(schedulingExportVo.getStartDate(), "yyyy-MM-dd").equals(DateUtil.format(schedulingExportVo.getEndDate(), "yyyy-MM-dd"))) {
                            receiptTwoArr[i][y] = simpleDateFormat.format(schedulingExportVo.getStartDate());
                        } else {
                            receiptTwoArr[i][y] = simpleDateFormat.format(schedulingExportVo.getStartDate()) + " ~ " + simpleDateFormat.format(schedulingExportVo.getEndDate());
                        }
                        break;
                    case 5:
                        // 领导
                        receiptTwoArr[i][y] = schedulingExportVo.getPersonLiable() != null ? schedulingExportVo.getPersonLiable() : "";
                        break;
                    case 6:
                        // 排班人员
                        receiptTwoArr[i][y] = schedulingExportVo.getSchedulingPerson() != null ? schedulingExportVo.getSchedulingPerson() : "";
                        break;
                    case 7:
                        // 巡查人员
                        receiptTwoArr[i][y] = StrUtil.isNotBlank(schedulingExportVo.getNickName()) ? schedulingExportVo.getNickName() : "";
                        break;
                    case 8:
                        // 巡查项目
                        receiptTwoArr[i][y] = StrUtil.isNotBlank(schedulingExportVo.getInspectPositionNames()) ? schedulingExportVo.getInspectPositionNames() : "";
                        break;
                    case 9:
                        // 备注
                        receiptTwoArr[i][y] = StrUtil.isNotBlank(schedulingExportVo.getRemark()) ? schedulingExportVo.getRemark() : "";
                        break;
                }
            }
        }

        XSSFWorkbook wb = new XSSFWorkbook();
        XSSFCellStyle style = wb.createCellStyle();
        XSSFCellStyle style2 = wb.createCellStyle();
        //创建HSSFSheet对象
        XSSFSheet sheet = wb.createSheet("excel表格的标题名字");
        XSSFFont font = wb.createFont();

        //================ 设置表格里面的主题样式 start =============
        //HSSFColor.VIOLET.index //字体颜色
        //font.setColor(new HSSFColor().getIndex());
        //字体大小
        font.setFontHeightInPoints((short) 12);
        //把字体应用到当前的样式
        style.setFont(font);
        style2.setFont(font);
        // 垂直
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        style2.setVerticalAlignment(VerticalAlignment.CENTER);
        //水平居中
        style.setAlignment(HorizontalAlignment.CENTER);
        style2.setAlignment(HorizontalAlignment.LEFT);
        CellStyle cellStyle = wb.createCellStyle();
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        cellStyle.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex());
        cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        Font headerFont = wb.createFont();
        headerFont.setFontName("Arial");
        headerFont.setFontHeightInPoints((short) 10);
        headerFont.setBold(true);
        headerFont.setColor(IndexedColors.WHITE.getIndex());
        cellStyle.setFont(headerFont);
        //================ 设置主题样式 end =============

        //创建HSSFRow对象
        XSSFRow xssfRow = null;
        XSSFCell xssfCell = null;
        // 循环行
        for (int i = 0; i < receiptTwoArr.length; i++) {
            xssfRow = sheet.createRow(i);
            // 设置主题
            if (i == 0) {
                //高度
                xssfRow.setHeight((short) 700);
            }
            // 标题
            if (i == 1) {
                //高度
                xssfRow.setHeight((short) 600);
            }
            //高度
            xssfRow.setHeight((short) 500);
            // 循环列
            for (int y = 0; y < receiptTwoArr[i].length; y++) {
                xssfCell = xssfRow.createCell(y);
                xssfCell.setCellValue(receiptTwoArr[i][y]);
                if (i == 0) {
                    if (Arrays.asList(new Integer[]{2, 7, 8}).contains(y)) {
                        sheet.setColumnWidth(y, 34 * 256);
                    } else if (Arrays.asList(new Integer[]{3, 4, 9}).contains(y)) {
                        sheet.setColumnWidth(y, 24 * 256);
                    } else {
                        sheet.setColumnWidth(y, 17 * 256);
                    }
                    xssfCell.setCellStyle(cellStyle);
                    continue;
                }
                if (Arrays.asList(new Integer[]{2, 3, 7, 8, 9}).contains(y)) {
                    // 自适应宽度
                    xssfCell.setCellStyle(style2);
                    continue;
                }
                xssfCell.setCellStyle(style);
            }
        }
        //开始数据合并   合并行
        List<Long> collect = list.stream().map(o -> o.getId()).distinct().collect(Collectors.toList());
        List<Integer> collect1 = collect.stream().map(o -> list.stream().filter(q -> q.getId().longValue() == o.longValue()).collect(Collectors.toList()).size()).collect(Collectors.toList());
        for (int index = 0; index < collect1.size(); index++) {
            int sum = collect1.stream().limit(index).mapToInt(o -> (int) o).sum();
            int count = collect1.get(index) > 1 ? collect1.get(index) : 0;
            if (count == 0) {
                continue;
            }
            sheet.addMergedRegion(new CellRangeAddress(sum + 1, sum + count, 0, 0));
            sheet.addMergedRegion(new CellRangeAddress(sum + 1, sum + count, 1, 1));
            sheet.addMergedRegion(new CellRangeAddress(sum + 1, sum + count, 2, 2));
            sheet.addMergedRegion(new CellRangeAddress(sum + 1, sum + count, 3, 3));
            sheet.addMergedRegion(new CellRangeAddress(sum + 1, sum + count, 4, 4));
            sheet.addMergedRegion(new CellRangeAddress(sum + 1, sum + count, 5, 5));
            sheet.addMergedRegion(new CellRangeAddress(sum + 1, sum + count, 6, 6));
            sheet.addMergedRegion(new CellRangeAddress(sum + 1, sum + count, 9, 9));
        }
        return wb;
    }

步骤三:controller层调用service

	@GetMapping("/export")
    @ApiOperation(value = "列表导出")
    @ResponseBody
    public AjaxResult exportScheduling(SelectSchedulingBo schedulingBo) {
        if (schedulingBo.getDeptId() == null) {
            schedulingBo.setDeptId(SecurityUtils.getLoginUser().getUser().getDeptId());
        }
        OutputStream out = null;
        XSSFWorkbook wb = null;
        try {
            List<SchedulingExportVo> list = inspectionSchedulingExportService.exportScheduling(schedulingBo);
            wb = inspectionSchedulingExportService.exportReceipt(list);
            ExcelUtil<SchedulingExportVo> util = new ExcelUtil<SchedulingExportVo>(SchedulingExportVo.class);
            String filename = util.encodingFilename("巡检排班");
            out = new FileOutputStream(util.getAbsoluteFile(filename));
            wb.write(out);
            return AjaxResult.success(filename);
        } catch (Exception e) {
            e.printStackTrace();
            throw new CustomException("导出Excel失败,请联系网站管理员!");
        } finally {
            if (wb != null) {
                try {
                    wb.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                    }
            }
        }
    }

至于service调dao调mapper去数据库查数据我就不放出来了,这个我想各位既然是都能被安排写导出合并单元的程序员了,只要看上面service的业务实现应该就可以了。

最后配合前端点击导出按钮就能实现单元格合并咯。还在等什么,奥里给起来!!!

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2021-12-15 18:35:34  更:2021-12-15 18:36:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/18 7:50:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码