EasyExcel重复多次写入,合并单元格功能详细实现

❤ 作者主页:李奕赫揍小邰的博客

❀ 个人介绍:大家好,我是李奕赫!( ̄▽ ̄)~*

🍊 记得点赞、收藏、评论⭐️⭐️⭐️

📣 认真学习!!!🎉🎉

文章目录

在公司中领导让给查询统计做出一个导出为excel的功能,第一时间想到了easyexcel,为什么?因为他真的很简单,也很容易写,EasyExcel 适用于简单数据的导入导出,因此不是很复杂的导出,都可以考虑使用easyexcel进行实现。但公司的查询统计让我在easyexcel官网中都没有找到合适的样例,因此接下来,我将介绍几种在easyexcel官网中没有记载的使用方式。

EasyExcel

easyexel官网:https://easyexcel.opensource.alibaba.com/

接下来,就默认大家都已经知道easyexcel基本的导出功能了。

如何重复多次将相同的对象写入(写到单个Sheet),并且将列表数据中的某个属性数据排除在外

要导出的页面如下

上述效果需要两个List才能实现,一个是各个业态的数量统计,一个是总数的统计,所以需要将这两个List导入到同一个sheet之中。

java 复制代码
@RequestMapping(value = "/export",method = RequestMethod.GET)
public void exportData(HttpServletResponse response){
    List<ComprehensiveLicenseSummary> summarysheet=comprehensiveLicenseService.getSummarySheet();
    List<ComprehensiveLicenseSummary> summaryTotal = comprehensiveLicenseService.getSummarySheetTotal();
    
    response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    response.setCharacterEncoding("utf-8");
    try {
        String fileName = URLEncoder.encode("汇总表", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        //将列表数据中的某个属性数据排除在外不及进行统计,或者也可以直接在实体类中排除的属性数据上方加上@ExcelIgnore即可
        Set<String> excludeColumnFiledNames = new HashSet<String>();
        excludeColumnFiledNames.add("permitArea");
        ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream(), ComprehensiveLicenseSummary.class).excludeColumnFiledNames(excludeColumnFiledNames).build();
        WriteSheet sheet1 = EasyExcel.writerSheet("汇总表").build();
        excelWriter.write(summarysheet,sheet1);
        excelWriter.write(summaryTotal,sheet1);
        excelWriter.finish();
    }catch (Exception e){
        log.error("汇总表excel文件导出失败:"+e);
    }
}

如何重复多次将不同对象写入到同一个sheet中,且共用一个标题头

效果图同上,但区别是两个List中的对象不同,因此实体类属性不一样的情况下,如何在导出后位置能够匹配上,共用同一个标题头。

java 复制代码
@RequestMapping(value = "/exportFine",method = RequestMethod.GET)
    public void exportFine(HttpServletResponse response){
        List<BusinessDistrict> businessDistricts = summarySheetService.getFineProof();
        List<BusinessCountByDistrict> businessCountByDistricts = summarySheetService.getBusinessCountByDistrictLicense();
        
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        ExcelWriter excelWriter = null;
        try {
            String fileName = URLEncoder.encode("明细表", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            //不同的对象导出到同一个sheet中
            excelWriter = EasyExcel.write(response.getOutputStream()).build();
            WriteSheet sheet1 = EasyExcel.writerSheet("明细表").needHead(Boolean.FALSE).build();
            WriteTable writeTable0 = EasyExcel.writerTable(0).head(BusinessDistrict.class).needHead(Boolean.TRUE).build();
             //这是两个对象,两个标题头的写法.若是需要区分两个对象数据,可以这样尝试。下面再多写两行excelWriter。write()即可
            //WriteTable writeTable1 = EasyExcel.writerTable(1).head(BusinessCountByDistrict.class).needHead(Boolean.TRUE).build();
            excelWriter.write(businessDistricts,sheet1,writeTable0);
            excelWriter.write(businessCountByDistricts,sheet1);
        }catch (Exception e){
            log.error("汇总表excel文件导出失败:"+e);
        }finally {
            if (excelWriter != null) {
                excelWriter.finish();
            }
        }
    }

如何合并单列重复数据

接下来是最复杂的一种,导出数据后合并单列重复数据。,怎么能够将第一列重复数据合并成一个,展示成如下的格式呢?

这次数据仅仅只有一个List,但却需要我们多写一个自定义easyExcel处理器,处理单列数据相同合并单元格。在每个单元格完全创建完之后执行合并的功能。可以在处理器里面规定好要合并哪一列。代码编写如下,注解很多应该可以看懂。

java 复制代码
@RequestMapping(value = "/exportProofByBusiness", method = RequestMethod.GET)
public void exportProofByBusinessHandle(HttpServletResponse response) {
    List<BusinessHandleDetail> licenseList = summarySheetService.getDetailProofByBusiness();
    
    response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    response.setCharacterEncoding("utf-8");
    ExcelWriter excelWriter = null;
    try {
        String fileName = URLEncoder.encode("明细表", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

        // 自定义easyExcel处理器 ,处理单列数据相同合并单元格
        excelWriter = EasyExcel.write(response.getOutputStream(),BusinessHandleDetail.class)
                               .registerWriteHandler(new SimpleExcelMergeUtil()).build();
        WriteSheet sheet = EasyExcel.writerSheet("办理明细表").build();
        excelWriter.write(licenseList,sheet);
    } catch (Exception e) {
        log.error("明细表excel文件导出失败:" + e);
    } finally {
        if (excelWriter != null) {
            excelWriter.finish();
        }
    }
}


//自定义easyExcel处理器,处理单列数据相同合并单元格
public class SimpleExcelMergeUtil implements CellWriteHandler {

    public SimpleExcelMergeUtil() {
    }
    /**
     * 创建每个单元格之前执行
     */
    @Override
    public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {

    }
    /**
     * 创建每个单元格之后执行
     */
    @Override
    public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {

    }
    /**
     * 每个单元格数据内容渲染之后执行
     */
    public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {

    }
    /**
     * 每个单元格完全创建完之后执行
     */
    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
        // 当前行
        int curRowIndex = cell.getRowIndex();
        // 当前列
        int curColIndex = cell.getColumnIndex();

        if (!isHead) {
            if (curRowIndex > 1 && curColIndex == 0) {
                // 从第二行数据行开始,获取当前行第一列数据
                Object curData = cell.getCellTypeEnum() == CellType.STRING ? cell.getStringCellValue() : cell.getNumericCellValue();
                // 获取上一行第一列数据
                Cell preCell = cell.getSheet().getRow(curRowIndex - 1).getCell(curColIndex);
                Object preData = preCell.getCellTypeEnum() == CellType.STRING ? preCell.getStringCellValue() : preCell.getNumericCellValue();
                if (curData.equals(preData)) {
                    Sheet sheet = writeSheetHolder.getSheet();
                    List<CellRangeAddress> mergedRegions = sheet.getMergedRegions();
                    boolean isMerged = false;
                    for (int i = 0; i < mergedRegions.size() && !isMerged; i++) {
                        CellRangeAddress cellRangeAddr = mergedRegions.get(i);
                        // 若上一个单元格已经被合并,则先移出原有的合并单元,再重新添加合并单元
                        if (cellRangeAddr.isInRange(curRowIndex - 1, curColIndex)) {
                            sheet.removeMergedRegion(i);
                            cellRangeAddr.setLastRow(curRowIndex);
                            sheet.addMergedRegion(cellRangeAddr);
                            isMerged = true;
                        }
                    }
                    // 若上一个单元格未被合并,则新增合并单元
                    if (!isMerged) {
                        CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex - 1, curRowIndex, curColIndex, curColIndex);
                        sheet.addMergedRegion(cellRangeAddress);
                    }
                }
            }
        }
    }
}

总结:

上述只是我在实现导出为excel遇到的问题,因为官网没有具体实例,所以我记录了下来,其他正常的导入导出官方文档都有记载,大家可以多看看官方文档

相关推荐
浮游本尊42 分钟前
Java学习第22天 - 云原生与容器化
java
渣哥2 小时前
原来 Java 里线程安全集合有这么多种
java
间彧3 小时前
Spring Boot集成Spring Security完整指南
java
间彧3 小时前
Spring Secutiy基本原理及工作流程
java
Java水解4 小时前
JAVA经典面试题附答案(持续更新版)
java·后端·面试
洛小豆6 小时前
在Java中,Integer.parseInt和Integer.valueOf有什么区别
java·后端·面试
前端小张同学7 小时前
服务器上如何搭建jenkins 服务CI/CD😎😎
java·后端
ytadpole7 小时前
Spring Cloud Gateway:一次不规范 URL 引发的路由转发404问题排查
java·后端
华仔啊7 小时前
基于 RuoYi-Vue 轻松实现单用户登录功能,亲测有效
java·vue.js·后端