首页 > 编程语言 >java EasyExcel 导出不同dto到多sheet,同时有动态字段,分页写入方案,解决存在oom的问题

java EasyExcel 导出不同dto到多sheet,同时有动态字段,分页写入方案,解决存在oom的问题

时间:2024-04-30 17:25:45浏览次数:17  
标签:dto isNotNull oom EasyExcel treeMap param field key 动态

思路 

1 将一次查询数据改成分页查询,比如一次2000条,

2 将每次查询的数据按业务分组计算每类业务 动态列追加的最大次数

treeMap    追加列  2    在excel列表头则是追加2列,名称自定义,我这边是补数字,示例 追加列1,追加列2 
我的业务是按数据库存放的图片来确定最大追加列,需要将图片字段按 |||拆分 。然后将内容分别填充到追加列1,追加列2 等
    /**
     * 计算  图片值分割后的最大次数
     * @param dto
     * @param treeMap  key 列头中文名,  value  追加的最大次数
     * @param key   列头的key
     * @param filedName  对象 字段
     */
    private void getMaxCountImageField(Object dto, TreeMap<String, Integer> treeMap, String key, String filedName) {
        try {

            Object pictures = ReflectUtil.getFieldValue(dto, filedName);
            if (ObjUtil.isNotNull(pictures)) {
                String[] split = pictures.toString().split("\\|\\|\\|");
                //取最大值
                treeMap.put(key, Math.max(treeMap.getOrDefault(key, 0), split.length));
            }
        } catch (Exception e) {
            // 添加适当的日志记录
            log.error("计算动态列最大出现次数异常:", e);
        }
    }

  

 

 

3将分页数据暂时暂存redis ,key要唯一哦,  最好是  业务key+毫秒数+分页页码  示例: type1: 毫秒数:1    type2:毫秒数:1 

4 循环完毕,计算每个sheet的列表头如何确定

扫描dto的注解 如@Excel  @ExcelProperty  或者自定义注解,需要注意的是,该注解一定是固定列,最好有序

按上计算动态列追加次数,继续计算 sheet的列表头。代码如下:

 

    /**
     * 获取导出sheet里的所有列头   固定+动态
     *
     * @param c    模板类
     * @param initTreeMap 动态列头集合 有序
     * @param workPlanType   工单类型
     * @return //返回  编号,姓名,。。   处理前1,处理前2.。。处理后1.。。。。等动态列头
     */
    private List<List<String>>  getFaultCellHeads(Class c, Map<Integer,TreeMap<String,Integer>> initTreeMap,Integer workPlanType) {
        //固定列
        List<List<String>> excelAnnotations = ExcelFileNameUtils.getExcelAnnotations(c);


        //固定列 +动态列    适用其他工单
        for (Map.Entry<String, Integer> entry : treeMap.entrySet()) {
            String name = entry.getKey();
            Integer count = entry.getValue();
            //初始化1    ,map  value次数等于0 的时候,不追加
            int init = 1;
            //可以改成stream写法
            while (init <= count) {
                String prefix = name + init;
                List<String> list=new ArrayList<>();
                list.add(prefix);
                excelAnnotations.add(list);
                init++;
            }
        }
        //返回  编号,姓名,。。   处理前1,处理前2.。。处理后1.。。。。等动态列头
        return excelAnnotations;
    }

开始写入数据到excel  ,分分页循环,挨个类型去获取缓存数据写入

 

需要初始化多个sheet

 获取头

 动态填充数据

 填充方法

/**
     * excel 行数据写入,  即 表头  固定列+动态列
     *
     * 本方法支持 
     * @param dataVoList   数据
     * @param treeMap  动态列
     * @param <T>
     * @return
     */
    public <T> List<List<Object>> getCommonDataExcelList(List<T> dataVoList, TreeMap<String, Integer> treeMap) {
        List<List<Object>> dataLists = new ArrayList<>();
        for (T dataVo : dataVoList) {
            // 第一行导出数据,按序赋值
            List<Object> objects = new ArrayList<>();
            // 赋值
            Field[] declaredFields = dataVo.getClass().getDeclaredFields();
            Field beforePictureField = null;
            Field afterPictureField = null;
            Field picturesField = null;
            // 处理固定列数据,代码属性不要错位写,有序声明
            for (Field field : declaredFields) {
                Excel excel = field.getAnnotation(Excel.class);
                if (excel != null) {
                    // 铺开列,获取属性的值,属性格式化还未处理 TODO
                    field.setAccessible(true);
                    Object value = null;
                    try {
                        value = field.get(dataVo);
                    } catch (Exception e) {
                        // 出取值异常,写入空
                    }
                    objects.add(value);
                }
                if ("beforePicture".equals(field.getName())) {
                    beforePictureField = field;
                    field.setAccessible(true);
                }
                if ("afterPicture".equals(field.getName())) {
                    afterPictureField = field;
                    field.setAccessible(true);
                }
                if ("pictures".equals(field.getName())) {
                    picturesField = field;
                    field.setAccessible(true);
                }
            }
            try {
                //处理前动态列
                if (ObjUtil.isNotNull(beforePictureField)) {
                    Object beforePicture = beforePictureField.get(dataVo);
                    if (ObjUtil.isNotNull(beforePicture)) {
                        Integer integer = treeMap.get(ExcelDynamicHeadConstants.BEFORE_PROCESSING);
                        spreadImageColumns(beforePicture.toString(), integer, objects);
                    }
                }
                //处理后动态列
                if (ObjUtil.isNotNull(afterPictureField)) {
                    Object afterPicture = afterPictureField.get(dataVo);
                    if (ObjUtil.isNotNull(afterPicture)) {
                        Integer integer = treeMap.get(ExcelDynamicHeadConstants.AFTER_PROCESSING);
                        spreadImageColumns(afterPicture.toString(), integer, objects);
                    }
                }
                //处理图片动态列
                if (ObjUtil.isNotNull(picturesField)) {
                    Object pictures = picturesField.get(dataVo);
                    if (ObjUtil.isNotNull(pictures)) {
                        Integer integer = treeMap.get(ExcelDynamicHeadConstants.IMAGE_PROCESSING);
                        spreadImageColumns(pictures.toString(), integer, objects);
                    }
                }
            } catch (Exception e) {
                log.error("写入excel行数据,包含动态头报错:", e);
            }
            dataLists.add(objects);
        }
        return dataLists;
    }

 

注意需要处理无任务数据需要写个空白页

 

最后

excelWriter.finish();

 

以上是核心逻辑代码,有不懂可以留言

 

标签:dto,isNotNull,oom,EasyExcel,treeMap,param,field,key,动态
From: https://www.cnblogs.com/woshuaile/p/18168390

相关文章

  • 使用 EasyExcel 进行数据解析
    一、添加pom.xml导入相关依赖<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.12</version></dependency><depende......
  • boom lab分析
    单步调试:(gdb)bt#10x0000000000401347instrings_not_equal()#20x0000000000400eeeinphase_1()#30x0000000000400e3finmain(argc=<optimizedout>,argv=<optimizedout>)atbomb.c:74这里的执行流程为:/*Hmm...Sixphasesmustbemoresecur......
  • echarts折线图使用dataZoom,切换数据时渲染异常,出现竖线bug
     今天做项目遇到一个省份过多时,要加滚动条的需求。但是切换数据的时候,出现上图所出现的问题。经查资料,发现可以设置一个属性来解决这个问题。    filterMode:'empty' dataZoom:{     show:this.xiaonengXData.length>12?true:false,//为true滚动条......
  • Poi-tl和EasyExcel以及Apache-Poi的版本冲突问题
    有新需求需要导出word文档;于是选择了Poi-tl,项目中已经使用了EasyExcel做相关Excel的导入与导出;当加入poi-tl做导出word时各种报错...踩过的坑就不展示了....下面是CV可用的,直接复制即可<properties> <poi-tl.version>1.12.0</poi-tl.version> <poi.version>5.2.2</poi.v......
  • easyExcel
    一、导入1、单个sheet页写法一(使用监听器)://导入接口@GetMappingpublicvoidreadExcel(@RequestParam("file")MultipartFilefile)throwsIOException{InputStreaminputStream=file.getInputStream();EasyExcel.read(inputStream)......
  • Kernel panic - not syncing: Out of memory: system-wide panic_on_oom is enabled
    内存不足,导致Java 进程被杀掉。 [1534.300650]Kernelpanic-notsyncing:Outofmemory:system-widepanic_on_oomisenabled[1534.301803]CPU:5PID:2930Comm:javaKdump:loadedTainted:GO5.10.0-60.18.0.50.r1083_58.hce2.x86_64#1[153......
  • nestjs 中管道的使用-验证DTO
    1.安装管道nestgpirole意思是安装一个role模块的管道2.在controller中使用管道 管道的作用:1.数据的转换2.DTO规则验证 一般使用全局配置管道 区别:自己写:需要一个个的带入 ......
  • EasyExcel 自定义宽高
    packagecom.cloud.module.management.common.handler;importcn.hutool.core.util.ObjectUtil;importcom.alibaba.excel.enums.CellDataTypeEnum;importcom.alibaba.excel.metadata.Head;importcom.alibaba.excel.metadata.data.CellData;importcom.alibaba.excel.......
  • Heirloom Painting
    先考虑无解的情况,来看样例三,很容易发现是因为\(k\)太大了,所以每次都会修改之前已经改好的。于是我们猜想,如果任意一段连续的数的长度都小于\(k\),那么就无解,证明比较容易,反证就好了,如果存在一个解,那么这个解的最后一步操作,一定是连续的\(k\)个格子,而且这\(k\)个格子的颜色一定要一......
  • Adobe Lightroom Classic v13.2 (macOS, Windows) - 桌面照片编辑
    AdobeLightroomClassicv13.2(macOS,Windows)-桌面照片编辑Acrobat、AfterEffects、Animate、Audition、Bridge、CharacterAnimator、Dimension、Dreamweaver、Illustrator、InCopy、InDesign、LightroomClassic、MediaEncoder、Photoshop、PremierePro、AdobeXD......