JAVA导出Excel通用工具——第二篇:使用EasyExcel导出excel的多种情况的例子介绍

news2025/1/15 20:40:39

JAVA导出Excel通用工具——第二篇:使用EasyExcel导出excel的多种情况的例子介绍

  • 1. 前言
  • 2. 依赖
  • 3. 导出简单例子
    • 3.1 ① 基础入门例子
      • 3.1.1 核心代码
      • 3.1.2 效果展示
    • 3.2 ② 注解的简单使用
      • 3.2.1 @ExcelIgnore
      • 3.2.2 @ExcelProperty
        • 3.2.2.1 一般效果(表头合并等)
        • 3.2.2.2 其他特殊情况(枚举映射等)
          • 1. 枚举使用1
          • 2. 枚举使用2
          • 3. 其他
      • 3.2.3 数据格式转换
        • 3.2.3.1 @NumberFormat
        • 3.2.3.2 @DateTimeFormat
      • 3.2.4 @
  • 4. 重复写入 和 使用table写入
    • 4.1 重复多次写入
    • 4.2 不同对象写到同一sheet页内(table写入)
  • 5. 合并单元格
    • 5.1 表头合并
    • 5.2 内容合并
      • 5.2.1 非动态合并
      • 5.2.2 动态合并(自定义单元格合并策略)
        • 5.2.2.1 核心代码
        • 5.2.2.2 处理数据
        • 5.2.2.3 测试看效果
  • 6. 自定义拦截器
    • 6.1 自定义拦截器->单元格合并策略
    • 6.2 自定义拦截器->数据单元格增加下拉框
      • 6.2.1 只针对单列设置下拉数据
      • 6.2.2 支持可多列设置下拉数据
    • 6.3 自定义拦截器->设置表头支持筛选
  • 7. 表格样式
  • 8. 结束

1. 前言

  • 本文构造数据代码都可以参考上篇POI文章,上篇使用POI导出的请看下面文章:
    JAVA导出Excel通用工具类——仅此一篇足以让你精通(详细介绍POI 和 EasyExcel导出excel的多种情况,包括筛选、合并单元格等复杂情况——保姆级别,不能再详细了,代码拿来即用.

2. 依赖

  • 如下:
    在这里插入图片描述

            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>easyexcel</artifactId>
                <version>3.1.5</version>
            </dependency>
    

3. 导出简单例子

3.1 ① 基础入门例子

3.1.1 核心代码

  1. 实体:EasyCatEntity.java
    package com.liu.susu.excel.easyexcel.example.export.data;
    
    import com.alibaba.excel.annotation.ExcelIgnore;
    import com.alibaba.excel.annotation.ExcelProperty;
    import com.liu.susu.excel.common.enums.CatKindEnum;
    import com.liu.susu.excel.common.enums.SexEnum;
    import lombok.Data;
    import lombok.experimental.Accessors;
    
    /**
     * description
     *
     * @author susu
     **/
    @Data
    @Accessors(chain = true)
    public class EasyCatEntity {
    
        @ExcelProperty(value = "姓名")
        private String name;
    
        @ExcelProperty(value = "性别")
        @ExcelIgnore //忽略这个字段的导出
        private SexEnum sex;
    
        @ExcelIgnore //忽略这个字段的导出
        private CatKindEnum kind;
    
        @ExcelProperty(value = "年龄")
        private String age;
    
        @ExcelProperty(value = "颜色")
        private String colour;
    
        @ExcelProperty(value = "猫猫的两个好朋友")
        private String friendOne;
    
        @ExcelProperty(value = "猫猫的两个好朋友")//如果表头单元格一样,自动合并
        private String friendTwo;
    
        @ExcelProperty(value = "猫猫头标志")
        private String headFlag;
    
        @ExcelProperty(value = "猫猫价格")
        private Double price;
    
    }
    
  2. 造数:MakeEasyCatData.java
    在这里插入图片描述
  3. 导出测试类 EasyTestExportA.java
    在这里插入图片描述
    package com.liu.susu.excel.easyexcel.example.export.example1;
    
    import com.alibaba.excel.EasyExcel;
    import com.alibaba.excel.ExcelWriter;
    import com.alibaba.excel.write.metadata.WriteSheet;
    import com.liu.susu.excel.easyexcel.example.export.data.EasyCatEntity;
    import com.liu.susu.excel.easyexcel.example.export.data.MakeEasyCatData;
    
    import java.util.List;
    
    /**
     * description  基础入门写法
     *
     * @author susu
     **/
    public class EasyTestExportA {
    
        public static void main(String[] args) {
    
            /**
             * 注意:
             *  下面的三种写法:在数据量不大的情况下可以使用(5000以内,具体也要看实际情况),数据量大参照 重复多次写入
             */
            List<EasyCatEntity> catList = MakeEasyCatData.getCats();//获取测试数据
            String fileName = "C:\\Users\\Administrator\\Desktop\\easyexcel导出\\excel_A1.xlsx";
            // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
            // 如果这里想使用03 则 传入 excelType 参数即可
            /写法 1/
            EasyExcel.write(fileName, EasyCatEntity.class)
                    .sheet("模板")
                    .doWrite(() -> {
                        return catList;
                    });
    
            /写法 2/
            fileName = "C:\\Users\\Administrator\\Desktop\\easyexcel导出\\excel_A2.xlsx";
            EasyExcel.write(fileName, EasyCatEntity.class).sheet("模板").doWrite(catList);
    
            /写法 3/
            fileName = "C:\\Users\\Administrator\\Desktop\\easyexcel导出\\excel_A3.xlsx";
            try (ExcelWriter excelWriter = EasyExcel.write(fileName, EasyCatEntity.class).build()) {
                WriteSheet writeSheet = EasyExcel.writerSheet("模板").build();
                excelWriter.write(catList, writeSheet);
            }
    
        }
    
    }
    
    

3.1.2 效果展示

  • 效果如图:
    在这里插入图片描述
    在这里插入图片描述

3.2 ② 注解的简单使用

3.2.1 @ExcelIgnore

  1. 忽略某个字段的导出:属性上加上此注解即可,上面有用到不说了
  2. 单独

3.2.2 @ExcelProperty

3.2.2.1 一般效果(表头合并等)

  1. 实现横向合并
    @ExcelProperty(value = "猫猫的两个好朋友") 注解中的value值一样即可横向合并
    在这里插入图片描述
  2. 复杂表头的横向合并
    @ExcelProperty({"猫猫的两个好朋友", "朋友1"})
    
    在这里插入图片描述
    效果如下:
    在这里插入图片描述
  3. 其他

3.2.2.2 其他特殊情况(枚举映射等)

1. 枚举使用1
  • 使用枚举的时候,如果不进行转换会报错,错误如下:
    在这里插入图片描述

    Exception in thread "main" com.alibaba.excel.exception.ExcelWriteDataConvertException: Can not find 'Converter' support class CatKindEnum.
    	at com.alibaba.excel.write.executor.AbstractExcelWriteExecutor.doConvert(AbstractExcelWriteExecutor.java:323)
    	at com.alibaba.excel.write.executor.AbstractExcelWriteExecutor.convert(AbstractExcelWriteExecutor.java:277)
    	at com.alibaba.excel.write.executor.AbstractExcelWriteExecutor.converterAndSet(AbstractExcelWriteExecutor.java:58)
    	at com.alibaba.excel.write.executor.ExcelWriteAddExecutor.addJavaObjectToExcel(ExcelWriteAddExecutor.java:174)
    	at com.alibaba.excel.write.executor.ExcelWriteAddExecutor.addOneRowOfDataToExcel(ExcelWriteAddExecutor.java:82)
    	at com.alibaba.excel.write.executor.ExcelWriteAddExecutor.add(ExcelWriteAddExecutor.java:58)
    	at com.alibaba.excel.write.ExcelBuilderImpl.addContent(ExcelBuilderImpl.java:59)
    	at com.alibaba.excel.ExcelWriter.write(ExcelWriter.java:70)
    	at com.alibaba.excel.ExcelWriter.write(ExcelWriter.java:47)
    	at com.alibaba.excel.write.builder.ExcelWriterSheetBuilder.doWrite(ExcelWriterSheetBuilder.java:62)
    	at com.alibaba.excel.write.builder.ExcelWriterSheetBuilder.doWrite(ExcelWriterSheetBuilder.java:79)
    	at com.liu.susu.excel.easyexcel.example.export.example1.EasyTestExportA.main(EasyTestExportA.java:31)
    
  • 怎么解决呢?

    • 先看我的枚举
      在这里插入图片描述
    • 再看@ExcelProperty注解要求,可以怎么处理
      在这里插入图片描述
      所以,写个实现 Converter 接口的转换类,泛型用 Ienum 即可解决问题,往下看吧
  • 解决问题:

    • 首先先写一个转换类,因为我弄的导出,在导出时发现了问题,所以只重写了关于导出的方法,如下:
      在这里插入图片描述
      在这里插入图片描述
      package com.liu.susu.excel.easyexcel.common;
      
      import com.alibaba.excel.converters.Converter;
      import com.alibaba.excel.converters.WriteConverterContext;
      import com.alibaba.excel.metadata.data.WriteCellData;
      import com.baomidou.mybatisplus.annotation.IEnum;
      
      /**
       * description
       *
       * @author susu
       **/
      public class MyEnumConverter implements Converter<IEnum> {
      
          @Override
          public WriteCellData<?> convertToExcelData(WriteConverterContext<IEnum> context) throws Exception {
      //        return null;
              return new WriteCellData(context.getValue().toString());//导出的时候重写改方法
          }
      }
      
    • 注解上使用,如下
      @ExcelProperty(value = "种类",converter = MyEnumConverter.class)
      
      在这里插入图片描述
  • 效果:
    在这里插入图片描述

2. 枚举使用2
  • 如果按照上面的转换类写成 implements Converter<IEnum> 这样,还会有个问题,什么问题呢?
    对于部分没有实现IEnum接口的枚举,依然不能会报上面的错误,所以直接改成 implements Converter<Enum> 即可,这样所有枚举都解决了,如下:
    在这里插入图片描述
3. 其他

3.2.3 数据格式转换

3.2.3.1 @NumberFormat

  • 实现占比数字格式化:
    @NumberFormat("#.##%")
    
    在这里插入图片描述

3.2.3.2 @DateTimeFormat

  • 日期格式设置,使用如下:
    @DateTimeFormat("yyyy年MM月dd日HH时mm分ss秒")
    

3.2.4 @

4. 重复写入 和 使用table写入

4.1 重复多次写入

  • 先看官网提供的重复写入的三种情况,如果你有需求再看下面《4.2 不同对象写到同一sheet页内》
    • 先看效果:
      在这里插入图片描述
      看到了吧,就是同一对象数据重复写入到同一个sheet内,很简单,直接看实现代码
    • 代码如下:
      /**
       * description  同一数据重复多次写到同一个sheet页
       *
       * @author susu
       **/
      public class EasyTestExportB1 {
      
          public static void main(String[] args) {
      
              List<EasyCatEntity> catList = MakeEasyCatData.getCats();//获取测试数据
              String fileName = "C:\\Users\\Administrator\\Desktop\\easyexcel导出\\excel_B1.xlsx";
              String sheetName = "模板";
      
              try (ExcelWriter excelWriter = EasyExcel.write(fileName, EasyCatEntity.class).build()) {
                  // 这里注意 如果同一个sheet只要创建一次
                  WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).build();
                  // 去调用写入,这里我调用了五次,实际使用时根据数据库分页的总的页数来
                  for (int i = 0; i < 5; i++) {
                      excelWriter.write(catList, writeSheet);
                  }
              }
          }
      }
      
      
  • 那有没有提供别的多次写入方法呢?写入到多个sheet?
    有,看看官网提供的这3个例子吧:
    在这里插入图片描述
    在这里插入图片描述
    这几个需要的话,自己去官网拿例子吧

4.2 不同对象写到同一sheet页内(table写入)

  • 上面的三个例子都没有提到这种情况,当然你也可以用上面的例子实现,但是会导致第二个table没有表头了,所以要想实现下面的效果,参考官网提供的另一种实现方式:使用table去写入
  • 先看效果
    在这里插入图片描述
  • 核心代码如下
    package com.liu.susu.excel.easyexcel.example.export.example2;
    
    import com.alibaba.excel.EasyExcel;
    import com.alibaba.excel.ExcelWriter;
    import com.alibaba.excel.write.metadata.WriteSheet;
    import com.alibaba.excel.write.metadata.WriteTable;
    import com.liu.susu.excel.easyexcel.example.export.data.EasyCatEntity;
    import com.liu.susu.excel.easyexcel.example.export.data.EasyDogEntity;
    import com.liu.susu.excel.easyexcel.example.export.data.MakeEasyCatData;
    import com.liu.susu.excel.easyexcel.example.export.data.MakeEasyDogData;
    
    import java.util.List;
    
    /**
     * description  不同对象写到同一sheet页内(同一个sheet页导出两个不同业务的table数据)
     *
     * @author susu
     **/
    public class EasyTestExportB2 {
    
        public static void main(String[] args) {
    
    
            List<EasyCatEntity> catList = MakeEasyCatData.getCats();//小猫数据
            List<EasyDogEntity> dogList = MakeEasyDogData.getDogs();//小狗数据
    
            String fileName = "C:\\Users\\Administrator\\Desktop\\easyexcel导出\\excel_B4.xlsx";
            String sheetName = "模板";
    
            try {
                ExcelWriter excelWriter = null;
                try {
                    excelWriter = EasyExcel.write(fileName).build();
                    WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).build();
    
                    // 第一个对象,这里指定需要表头
                    WriteTable writeTableCat = EasyExcel.writerTable(0).head(EasyCatEntity.class).needHead(Boolean.TRUE).build();
    
                    // 第二个对象 读取对象的excel实体类中的标题
                    WriteTable writeTableDog = EasyExcel.writerTable(1).head(EasyDogEntity.class).needHead(Boolean.TRUE).build();
    
                    // 第一次写入:cat数据
                    excelWriter.write(catList, writeSheet, writeTableCat);
                    // 第二次写入:dog数据,在第一次后面写入数据(上面设置了表头就会含表头)
                    excelWriter.write(dogList, writeSheet, writeTableDog);
    
                } finally {
                    // 记得finally 会帮忙关闭流
                    if (excelWriter != null) {
                        excelWriter.finish();
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    }
    
    
  • 官网例子如下:
    在这里插入图片描述

5. 合并单元格

5.1 表头合并

  • 请参考上面的《3.2.2.1 一般效果》,有说到表头合并,以及复杂表头合并

5.2 内容合并

5.2.1 非动态合并

  1. 类注解:@OnceAbsoluteMerge,使用方法和效果,如下:
    @OnceAbsoluteMerge(firstRowIndex = 2, lastRowIndex = 3, firstColumnIndex = 1, lastColumnIndex = 2)
    
    在这里插入图片描述
    在这里插入图片描述
  2. 属性注解:@ContentLoopMerge
    @ContentLoopMerge(eachRow = 2)//每两行一合并
    
    在这里插入图片描述
  3. 使用easyexcel自带的单元格合并策略:
    • 使用方法如下:
      在这里插入图片描述
    • 官网的合并策略:
      在这里插入图片描述
      自己可以点进去看看,这种方式的合并与上面注解实现的效果差不多,因为这个 eachRow 参数是定死的,不能动态地根据单元格的内容相同去合并,要想实现自己想要的效果,还需自定义一个合并策略,往下看……

5.2.2 动态合并(自定义单元格合并策略)

5.2.2.1 核心代码

  • 核心代码如下:
    在这里插入图片描述
    在这里插入图片描述
  • 上代码 MergerCellStrategy.java
    package com.liu.susu.excel.easyexcel.common.merge;
    
    import com.alibaba.excel.write.handler.RowWriteHandler;
    import com.alibaba.excel.write.handler.context.RowWriteHandlerContext;
    import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
    import org.apache.poi.ss.usermodel.Row;
    import org.apache.poi.ss.usermodel.Sheet;
    import org.apache.poi.ss.util.CellRangeAddress;
    
    /**
     * description 单元格合并策略
     *
     * @author susu
     **/
    public class MergerCellStrategy implements RowWriteHandler {
    
    
        private final int[] columnIndex;
    
        public MergerCellStrategy(int[] columnIndex) {
            this.columnIndex = columnIndex;
        }
    
        @Override
        public void afterRowDispose(RowWriteHandlerContext context) {
            dealVerticalMerger(context);
        }
    
        public void dealVerticalMerger(RowWriteHandlerContext context) {
            /**
             * 1. 先获取当前行号,根据当前行号 获取上一行中此列的内容
             * 2. 对比上一行的内容与此行内容是否一致
             * 3. 最后拿到要合并的起始行、结束行、起始实列 和 结束列(其中其实列和结束列就是本列)
             */
            Integer currentRowIndex = context.getRowIndex();
            if (columnIndex == null) {
                return;
            }
            if (currentRowIndex == 0) {
                return;
            }
            WriteSheetHolder writeSheetHolder = context.getWriteSheetHolder();
            Sheet sheet = writeSheetHolder.getSheet();
            Row currentRow = context.getRow();
            for (int colIndex : columnIndex) {
                String currentCellValue = currentRow.getCell(colIndex).getStringCellValue();
                String upCellValue = sheet.getRow(currentRowIndex - 1).getCell(colIndex).getStringCellValue();
                if (currentCellValue.equals(upCellValue)) {
                    CellRangeAddress cellRangeAddress = new CellRangeAddress(currentRowIndex - 1, currentRowIndex, colIndex, colIndex);
                    sheet.addMergedRegionUnsafe(cellRangeAddress);
                }
            }
    
        }
    
    }
    
    

5.2.2.2 处理数据

  • 为了观察效果,先给数据进行排序一下:
    在这里插入图片描述
            //按种类排序
            Collections.sort(dogList, new Comparator<EasyDogEntity>(){
                @Override
                public int compare(EasyDogEntity o1, EasyDogEntity o2) {
                    return o1.getKind().compareTo(o2.getKind());
                }
            });
    

5.2.2.3 测试看效果

  1. 测试代码:
    在这里插入图片描述
    package com.liu.susu.excel.easyexcel.example.export.example3;
    
    import com.alibaba.excel.EasyExcel;
    import com.liu.susu.excel.easyexcel.common.merge.MergerCellStrategy;
    import com.liu.susu.excel.easyexcel.example.export.data.EasyDogEntity;
    import com.liu.susu.excel.easyexcel.example.export.data.MakeEasyDogData;
    
    import java.util.List;
    
    /**
     * description  测试-自定义单元格合并策略
     *
     * @author susu
     **/
    public class EasyTestExportC2 {
    
        public static void main(String[] args) {
    
            List<EasyDogEntity> dogList = MakeEasyDogData.getDogs();//小狗数据
            String fileName = "C:\\Users\\Administrator\\Desktop\\easyexcel导出\\excel_C2.xlsx";
            String sheetName = "模板";
    
            // 使用自定义的单元格合并策略
            int[] columnIndex = {2};
            MergerCellStrategy mergerCellStrategy = new MergerCellStrategy(columnIndex);
    
            EasyExcel.write(fileName, EasyDogEntity.class)
                    .registerWriteHandler(mergerCellStrategy)
                    .sheet(sheetName).doWrite(dogList);
        }
    
    }
    
    
  2. 测试效果:
    在这里插入图片描述

6. 自定义拦截器

6.1 自定义拦截器->单元格合并策略

  • 这个就是我们上面提到过的自定义单元格合并策略来动态实现纵向单元格的合并,忘记的可以往上翻,看上面《5.2.2 动态合并(自定义单元格合并策略)》

6.2 自定义拦截器->数据单元格增加下拉框

6.2.1 只针对单列设置下拉数据

  • 核心代码如下:
    • 自定义拦截器SelectSheetWriteHandler.java
      package com.liu.susu.excel.easyexcel.common.handle.select;
      
      import com.alibaba.excel.write.handler.SheetWriteHandler;
      import com.alibaba.excel.write.handler.context.SheetWriteHandlerContext;
      import lombok.extern.slf4j.Slf4j;
      import org.apache.poi.ss.usermodel.DataValidation;
      import org.apache.poi.ss.usermodel.DataValidationConstraint;
      import org.apache.poi.ss.usermodel.DataValidationHelper;
      import org.apache.poi.ss.util.CellRangeAddressList;
      
      /**
       * description 自定义拦截器-数据单元格新增下拉框
       *
       * @author susu
       **/
      @Slf4j
      public class SelectSheetWriteHandler implements SheetWriteHandler {
      
          private final int firstRow;
          private final int lastRow;
          private final int colIndex;
          private final String[] selectData;
      
          public SelectSheetWriteHandler(int firstRow, int lastRow, int colIndex,String[] selectData) {
              this.firstRow = firstRow;
              this.lastRow = lastRow;
              this.colIndex = colIndex;
              this.selectData = selectData;
          }
      
          @Override
          public void afterSheetCreate(SheetWriteHandlerContext context) {
              CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(firstRow, lastRow, colIndex, colIndex);
              DataValidationHelper helper = context.getWriteSheetHolder().getSheet().getDataValidationHelper();
              DataValidationConstraint constraint = helper.createExplicitListConstraint(selectData);
              DataValidation dataValidation = helper.createValidation(constraint, cellRangeAddressList);
              context.getWriteSheetHolder().getSheet().addValidationData(dataValidation);
          }
      
      }
      
      
    • 测试代码
      在这里插入图片描述
  • 测试效果如下:
    在这里插入图片描述

6.2.2 支持可多列设置下拉数据

  • 在上面的基础上简单优化一下,实现可支持多列下拉:
  • 修改后的代码也是很简单的,如下:
    在这里插入图片描述
    package com.liu.susu.excel.easyexcel.common.handle.select;
    
    import com.alibaba.excel.write.handler.SheetWriteHandler;
    import com.alibaba.excel.write.handler.context.SheetWriteHandlerContext;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.poi.ss.usermodel.DataValidation;
    import org.apache.poi.ss.usermodel.DataValidationConstraint;
    import org.apache.poi.ss.usermodel.DataValidationHelper;
    import org.apache.poi.ss.util.CellRangeAddress;
    import org.apache.poi.ss.util.CellRangeAddressList;
    
    import java.util.Map;
    
    /**
     * description 自定义拦截器-数据单元格新增下拉框
     *
     * @author susu
     **/
    @Slf4j
    public class SelectSheetWriteHandler2 implements SheetWriteHandler {
    
        private final int firstRow;
        private final int lastRow;
        private final Map<Integer,String[]> selectDataMap;
    
        public SelectSheetWriteHandler2(int firstRow, int lastRow, Map<Integer,String[]> selectDataMap) {
            this.firstRow = firstRow;
            this.lastRow = lastRow;
            this.selectDataMap = selectDataMap;
        }
    
        @Override
        public void afterSheetCreate(SheetWriteHandlerContext context) {
            if (selectDataMap!=null && !selectDataMap.isEmpty()){
                DataValidationHelper helper = context.getWriteSheetHolder().getSheet().getDataValidationHelper();
                selectDataMap.forEach((colIndex,selectData)->{
                    CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(firstRow, lastRow, colIndex, colIndex);
                    DataValidationConstraint constraint = helper.createExplicitListConstraint(selectData);
                    DataValidation dataValidation = helper.createValidation(constraint, cellRangeAddressList);
                    context.getWriteSheetHolder().getSheet().addValidationData(dataValidation);
                });
            }
        }
    
    }
    
    
  • 测试太简单了,简单给个图看看就行,如下:
    在这里插入图片描述

6.3 自定义拦截器->设置表头支持筛选

  • 效果如下:
    在这里插入图片描述
    在这里插入图片描述
  • 核心代码如下:
    • 拦截器代码:
      package com.liu.susu.excel.easyexcel.common.handle.filter;
      
      import com.alibaba.excel.write.handler.SheetWriteHandler;
      import com.alibaba.excel.write.handler.context.SheetWriteHandlerContext;
      import lombok.extern.slf4j.Slf4j;
      import org.apache.poi.ss.usermodel.*;
      import org.apache.poi.ss.util.CellRangeAddress;
      
      /**
       * description 自定义拦截器-设置表头筛选的属性
       *
       * @author susu
       **/
      @Slf4j
      public class AutoFilterSheetWriteHandler implements SheetWriteHandler {
      
          private int firstRow = 0;
          private int lastRow = 0;
          private boolean headAutoFilterFlag;
          private int[] filterColumnsIndex;
          private int firstCol;
          private int lastCol;
      
          public AutoFilterSheetWriteHandler(boolean headAutoFilterFlag, int[] filterColumnsIndex) {
              this.headAutoFilterFlag = headAutoFilterFlag;
              this.filterColumnsIndex = filterColumnsIndex;
          }
      
          public AutoFilterSheetWriteHandler(boolean headAutoFilterFlag, int firstCol, int lastCol) {
              this.headAutoFilterFlag = headAutoFilterFlag;
              this.firstCol = firstCol;
              this.lastCol = lastCol;
          }
      
          @Override
          public void afterSheetCreate(SheetWriteHandlerContext context) {
              dealAutoFilter(context);
          }
      
          public void dealAutoFilter(SheetWriteHandlerContext context) {
              if (!headAutoFilterFlag) {
                  return;
              }
              Sheet sheet = context.getWriteSheetHolder().getSheet();
              //需要设置表头筛选
              if (filterColumnsIndex == null) {
                  if (!(firstCol >= 0 && lastCol >= firstCol)) {
                      firstCol = 0;
                      //int headColNum = context.getWriteWorkbookHolder().getHead().size();
                      int headColNum = 10;//默认给个  这个要么默认 要么不用,不满足直接return 要么用RowWriteHandler
                      lastCol = headColNum - 1;
                  }
                  CellRangeAddress rangeAddress = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
                  sheet.setAutoFilter(rangeAddress);
              } else {
                  //这个不行,不能指定列,先放着吧
                  for (int columnsIndex : filterColumnsIndex) {
                      CellRangeAddress rangeAddress = new CellRangeAddress(firstRow, lastRow, columnsIndex, columnsIndex);
                      sheet.setAutoFilter(rangeAddress);
                  }
              }
          }
      
      }
      
      
    • 测试代码
      在这里插入图片描述

7. 表格样式

  • 样式先放这吧,后续再说

8. 结束

  • 就介绍这么多吧,毕竟大多都能在官网上找到例子,实在没有的也能比葫芦画瓢自己写一个,都是能实现你的需求的,还有关于项目源码可以看上面前言去上篇POI文章里

  • 最后,附上官网地址,多去官网走走,少走弯路。

    官网地址:https://easyexcel.opensource.alibaba.com/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/162512.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL高级【InnoDB引擎】

1&#xff1a;InnoDB引擎1.1&#xff1a;逻辑存储引擎 InnoDB的逻辑存储结构如下图所示: 1). 表空间 表空间是InnoDB存储引擎逻辑结构的最高层&#xff0c; 如果用户启用了参数 innodb_file_per_table(在 8.0版本中默认开启) &#xff0c;则每张表都会有一个表空间&#xff08…

【iOS】—— 初识block

block 文章目录block什么是block&#xff1f;block语法Block变量截获自动变量值__block说明符截获的自动变量block的三种存储类型NSGlobalBlockNSStackBlockNSMallocBlockblock的父类block循环引用未完待续什么是block&#xff1f; Blocks是带有自动变量&#xff08;局部变量&…

React--》初识React框架及其基本使用

目录 React React的安装与使用 JSX语法及使用 模块与组件 React开发者工具的安装 面向组件编程 React React是一个用于构建用户界面的JavaScript库。用户界面:HTML页面(前端)。React主要用来写HTML页面&#xff0c;或构建Web应用。 如果从 MVC的角度来看&#xff0c;…

第一天总结之后端登录功能的实现

第一天总结之后端登录功能的实现 一、 前端页面 从图片 很明显知道 两个intput输入框 一个输入username 一个输入password 从前端的页面代码 可以找到form表单 根据form表单的action属性了解到 点击登录跳转到 controller 层的 LoginServlet 二、controller 层 创建一个 Log…

2023年跨境电商新趋势,新手小白还有出路吗?

跨境电商一直位于我国对外开放的最前沿&#xff0c;当下已经成为我国进出口贸易的关键组成部分之一&#xff0c;是外贸企业顺利开展进出口业务的重要保障&#xff0c;更是拥有庞大发展潜力以及活力的贸易新业态。在经济全球化趋势下&#xff0c;充分发挥出跨境电商的战略新通道…

Java 包的使用详解

文章目录1. 概念2. 导入包中的类2.1 使用类的全路径2.2 导入包2.3 静态导入包3. 自定义包4. 包的访问权限控制5. 常用的包Java编程基础教程系列1. 概念 在开发过程中&#xff0c;会定义很多的类&#xff0c;随着类的定义越来越多&#xff0c;难免会出现类名重复的情况&#xf…

mac 安装redis

文章目录mac 安装redis使用Homebrew安装Redis1.搜索redis版本2.使用Homebrew安装命令3.查看是否安装完成4.启动redis服务5.查看redis服务进程6.redis-cli连接redis服务7.检测 redis 服务是否启动8.修改密码mac 安装redis 使用Homebrew安装Redis 首先这里需要安装homebrew 1.搜…

【Kubernetes 企业项目实战】03、基于 Alertmanager 发送报警到多个接收方(上)

目录 一、配置 Alertmanager 发送报警到 qq 邮箱 1.1 设置 163 邮箱 1.2 创建 alertmanager 配置文件 1.3 创建 prometheus 告警规则配置文件 1.4 安装 prometheus 和 alertmanager 1.5 部署 alertmanager 的 service 1.6 浏览器访问 Prometheus 和 alertmanager 二、配…

ELK日志(2)

elasticsearch群集状态颜色&#xff1a;灰色&#xff1a;未连接绿色&#xff1a;数据完整态黄色&#xff1a;副本不完整红色&#xff1a;数据分片不完整紫色&#xff1a;数据分片复制过程群集主机角色&#xff1a;主节点master&#xff1a;负责管理调度工作节点&#xff1a; 负…

从IPv6的普及看中国未来网络的发展

最近看了一篇《邬贺铨&#xff1a;IPv6或是未来主流网络》的文章,谈到了未来网络的发展问题。IPv6也许是未来主流网络的发展方向。那么什么是IPv6呢,不妨来看下关于他的另一篇文章《邬贺铨&#xff1a;IPv6是IPv6规模部署第三阶段重要抓手》。 他谈到&#xff0c;IPv6是下一代互…

单绞机张力开环控制(绞臂行星差速机构算法)

PLC的开环和闭环张力控制算法,可以参看下面的文章链接: PLC张力控制(开环闭环算法分析)_plc张力控制程序_RXXW_Dor的博客-CSDN博客里工业控制张力控制无处不在,也衍生出很多张力控制专用控制器,磁粉制动器等,本篇博客主要讨论PLC的张力控制相关应用和算法,关于绕线机的…

动态内存管理(1)

TIPS 1. 2. malloc, free, calloc, realloc 这些的基本前提都是在内存堆区 内存堆区不能与内存栈区两者混淆乱套 动态内存管理存在的原因 1. 为什么要有动态内存管理&#xff1f;其实我们之前学过比如说对内存的管理&#xff0c;比方说我申请一块内存空间&#xff1a; 1.…

任意方向边界框——day64 读论文:基于自适应目标定位特征卷积神经网络的高分辨率遥感影像多面向目标检测

Multi-Oriented Object Detection in High-Resolution Remote Sensing Imagery Based on Convolutional Neural Networks with Adaptive Object Orientation Features 基于自适应目标定位特征卷积神经网络的高分辨率遥感影像多面向目标检测1. Introduction2. Materials and Met…

jQuery ajax中dataFilter的用法

参考资料 jquery的ajax的dataFilter参数的使用 ⏹用于处理 XMLHttpRequest 原始响应数据的函数 运行在success函数之前, 对Ajax请求返回的原始数据进行预处理 可以对返回的json数据中的null属性进行过滤可以对返回的json数据添加一些自定义的属性 如果不返回原始数据,返回其他…

零代码连接邮箱腾讯云企业网盘,附件管理超轻松

在日常工作中&#xff0c;想必大家每天都会收到各种各样的工作邮件&#xff0c;并且很多重要的文件材料也是通过邮件附件的形式来传输的&#xff0c;那么如何一站式管理这些文件&#xff0c;对于提高办公效率就至关重要了。关于邮件附件管理&#xff0c;相信大家也都碰到过这样…

全面了解文件上传漏洞, 通关upload-labs靶场

靶场简介 upload-labs是一个专门用于学习文件上传漏洞攻击和防御的靶场。它提供了一系列模拟文件上传漏洞的实验环境&#xff0c;用于帮助用户了解文件上传漏洞的原理和防御技术。 这个靶场包括了常见的文件上传漏洞类型&#xff0c;如文件名欺骗、文件类型欺骗、文件上传功能…

1582_C代码实现的快速、可移植MD5信息摘要算法

全部学习汇总&#xff1a; GreyZhang/c_units: A small piece of code which can be reuse anywhere, I call it a unit. This is a collection of unit in C language! Ok, yes, it would be my toolbox. (github.com) 工作之中&#xff0c;同事用到了MD5信息摘要算法&#x…

面试加分题--socket是否是并发安全的?

今天和大家聊一个有点儿东西的面试题&#xff1a;socket是否是并发安全的&#xff1f; 为了帮助大家理解&#xff0c;我们先假设一个场景。 就拿游戏架构来说&#xff0c;我们想象中的游戏架构是下面这样的。 想象中的游戏架构 也就是用户客户端直接连接游戏核心逻辑服务器&…

解决⾃动驾驶中计算机视觉的⽬标检测问题

来源&#xff1a;投稿 作者&#xff1a;cairuyi01 编辑&#xff1a;学姐 最近读了《Object detection with location-aware deformable convolution and backward attention filtering》&#xff0c;这是⼀篇2019年刊登在CVPR上的CV论⽂。与解决普适性的CV任务不同&#xff0c…

SpringMVC如何优化Ajax技术

SpringMVC如何优化Ajax技术&#xff1f; AJAX Asynchronous JavaScript and XML&#xff08;异步的 JavaScript 和 XML&#xff09;。 AJAX 是一种在无需重新加载整个网页的情况下&#xff0c;能够更新部分网页的技术。 Ajax 不是一种新的编程语言&#xff0c;而是一种用于创…