【EasyExcel】导出excel冻结表头和冻结指定列并支持筛选器

本文介绍了如何利用easyExcel库在导出Excel时,通过自定义`SheetWriteHandler`来实现表头冻结和指定区域的自动筛选功能,包括重写接口方法和提供示例代码实现。
摘要由CSDN通过智能技术生成

需求背景:

        导出excel的同时冻结表头和前两列基础信息,方便导出后用户查看信息。

一、技术选型:

        easyExcel的自定义写策略处理:SheetWriteHandler

二、方案设计:(基于实现 SheetWriteHandler 接口)

        1、重写afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder)方法

        2、通过 writeSheetHolder.getSheet() 获取 sheet,通过 sheet.createFreezePane() 方法设置导出excel指定冻结行和列,通过 sheet.setAutoFilter() 给指定导出的excel单元格设置自动筛选器.

三、代码实现:

3.1:pom.xml
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.3.2</version>
</dependency>
3.2: API
 @ApiOperation(value = "导出")
 @GetMapping(value = "/export")
 public void exportExcel(HttpServletResponse response,@RequestBody TestParam param) {
        service.export(response, param);
 }
3.3:工具类 IEasyExcelServicey
import com.alibaba.excel.write.handler.WriteHandler;

import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * @author c
 */
public interface IEasyExcelService {
    /**
     * 导出excel方法
     *
     * @param exportData 需要导出的数据
     * @param response   response
     * @param tClass     导出excel的字段实体类
     * @param fileName   文件名字
     * @param sheetName  sheet名字
     */
    <T> void exportExcel(List<T> exportData, HttpServletResponse response, Class<T> tClass, String fileName, String sheetName);
    /**
     * 导出excel方法 (携带自定义策略)
     * @param exportData 需要导出的数据
     * @param response HttpServletResponse
     * @param tClass 导出excel的字段实体类
     * @param fileName 文件名字
     * @param sheetName sheet名字
     * @param writeHandler 自定义策略(可扩展多个)
     * @param <T> T
     */
    <T> void exportExcelWithHandler(List<T> exportData, HttpServletResponse response, Class<T> tClass, String fileName, String sheetName, WriteHandler writeHandler);
}

 工具类:EasyExcelServiceImpl

@Slf4j
public class EasyExcelServiceImpl implements IEasyExcelService {

    /**
     * 本地转:response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileNameEncoder + ".xlsx");
     * @param exportData 需要导出的数据
     * @param response   response
     * @param tClass     导出excel的字段实体类
     * @param fileName   文件名字
     * @param sheetName  sheet名字
     * @param <T> T
     */
    @Override
    public <T> void exportExcel(List<T> exportData, HttpServletResponse response, Class<T> tClass, String fileName, String sheetName){
        try{
            // 使用swagger 会导致各种问题,直接用浏览器或者用postman
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            // fileName encoder
            String fileNameEncoder = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileNameEncoder + ".xlsx");
            response.setHeader("Access-Control-Expose-Headers", "Content-disposition");
            // write to excel
            EasyExcelFactory.write(response.getOutputStream(), tClass)
                    .autoCloseStream(Boolean.FALSE)
                    .sheet(sheetName)
                    .doWrite(exportData);
        }catch (Exception e){
            log.error("EasyExcelServiceImpl->exportExcel error, message is :{}", e.getMessage());
        }
    }

    @Override
    public <T> void exportExcelWithHandler(List<T> exportData, HttpServletResponse response, Class<T> tClass, String fileName, String sheetName, WriteHandler writeHandler){
        try{
            // 使用swagger 会导致各种问题,直接用浏览器或者用postman
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            // fileName encoder
            String fileNameEncoder = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileNameEncoder + ".xlsx");
            response.setHeader("Access-Control-Expose-Headers", "Content-disposition");
            // write to excel
            EasyExcelFactory.write(response.getOutputStream(), tClass)
                    .autoCloseStream(Boolean.FALSE)
                    // 自定义策略(支持扩展多个)
                    .registerWriteHandler(writeHandler)
                    .sheet(sheetName)
                    .doWrite(exportData);
        }catch (Exception e){
            log.error("EasyExcelServiceImpl->exportExcel error, message is :{}", e.getMessage());
        }
    }


}
3.4: 自定义Handle:(自定义设置导出excel设置冻结列和列以及是否自动加筛选器)
/**
 * easyExcel:export handle
 * freeze row and col with set auto filter range
 * @author c
 * @date: 2024-1-5 13:44:26
 */
public class FreezeRowColHandler implements SheetWriteHandler {

    private final FreezeRowColOptions options;

    public FreezeRowColHandler(FreezeRowColOptions options) {
        this.options = options;
    }

    @Override
    public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
        Sheet sheet = writeSheetHolder.getSheet();
        sheet.createFreezePane(options.getColSplit(), options.getRowSplit(), options.getLeftmostColumn(), options.getTopRow());
        if (null != options.getAutoFilterRange()) {
            sheet.setAutoFilter(CellRangeAddress.valueOf(options.getAutoFilterRange()));
        }
    }

}
参数:FreezeRowColOptions
@Data
@AllArgsConstructor
@NoArgsConstructor
public class FreezeRowColOptions {
    /**
     * Horizontal position of split
     */
    private Integer colSplit;
    /**
     * Vertical position of split
     */
    private Integer rowSplit;
    /**
     * Left column visible in right pane
     */
    private Integer leftmostColumn;
    /**
     * Top row visible in bottom pane
     */
    private Integer topRow;
    /**
     * auto filter range
     */
    private String autoFilterRange;
}
参数解释和示例:
四个参数分别代表:
colSplit:表示要冻结的列数;
rowSplit:表示要冻结的行数;
leftmostColumn:表示被固定列右边第一列的列号;
topRow:表示被固定行下边第一列的行号;

举例:
CreateFreezePane(0,1,0,1):冻结第一行,冻结行下侧第一行的左边框显示“2”
CreateFreezePane(1,0,1,0):冻结第一列,冻结列右侧的第一列为B列
CreateFreezePane(2,0,5,0):冻结左侧两列,冻结列右侧的第一列为F列

可以自定义 FreezeRowColConstant 方便维护,如下

/**
 * handle constant:export FreezeRowColConstant
 * freeze row and col with set auto filter range constant
 * @author c
 * @date: 2024-1-5 14:22:21
 */
public class FreezeRowColConstant {
    /**
     * TEST_ONE  export
     */
    public static final FreezeRowColOptions TEST_ONE = new FreezeRowColOptions(2, 2, 0, 0, "A2:BH2");
    /**
     * TEST_TWO  export
     */
    public static final FreezeRowColOptions TEST_TWO = new FreezeRowColOptions(2, 2, 0, 0, "A2:AC2");
    /**
     * TEST_THREE  export
     */
    public static final FreezeRowColOptions TEST_THREE = new FreezeRowColOptions(2, 2, 0, 0, "A2:T2");
}

ITestExportService:(这里可以根据自己的业务进行自定义,本文定义这个是因为在同一个业务里面有几个类似的导出可以共用这个导出接口)

public interface ITestExportService {
    /**
     * export data
     * @param response HttpServletResponse
     * @param param export common param
     * @throws BaseException ex
     */
    default void exportData(HttpServletResponse response, TestParam param) {}
}

下面给出其中一个导出的实现方法:

@Service
@Slf4j
public class TestOneServiceImpl implements ITestExportService {

    private static final String FILE_NAME_TEST = "测试";
    private final IEasyExcelService easyExcelService;
  
    public TestOneServiceImpl (IEasyExcelService easyExcelService) {
        this.easyExcelService = easyExcelService; 
    }

    @Override
    public void exportData(HttpServletResponse response, TestParam param) {
        // 这里是根据查询参数param获取需要导出的数据
        // get data
        List<DemoExcelData> data = this.ExportData(param);
        // export:调用 exportExcelWithHandler 导出
        easyExcelService.exportExcelWithHandler(data, response, DemoExcelData.class, FILE_NAME_TEST, FILE_NAME_TEST,
                new FreezeRowColHandler(FreezeRowColConstant.TEST_ONE));
    }
}

实现效果:(都加上了自动筛选器 )

下面是示例,在TestOneServiceImpl 方法中调用exportExcelWithHandler方法的时候实际用的是FreezeRowColConstant.TEST_ONE,其中 FreezeRowColConstant.TEST_ONE 设置的是 new FreezeRowColOptions(2, 2, 0, 0, "A2:BH2"),其含义是:

        第一个参数:表示冻结前两行

        第二个参数:表示冻结前两列 

        "A2:BH2":表示单元格"A2:BH2"区间设置添加自动筛选器

表头固定效果:

 前两列固定效果:

相关文章推荐:

【EasyExcel】导出excel并支持自定义设置数据行背景颜色等_easyexcel rrg背景-CSDN博客

                                👍如果对你有帮助,给博主一个免费的点赞以示鼓励
                                                欢迎各位🔎点赞👍评论收藏⭐️

  • 26
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
EasyExcel 支持导出合并行和表头Excel,可以通过设置 `@HeadRowHeight`、`@HeadColumnWidth`、`@ContentRowHeight` 和 `@ContentColumnWidth` 注解来控制表头和内容的行高和宽。同时,可以通过设置 `@ExcelProperty` 注解的 `colspan` 和 `rowspan` 属性来合并行和。 以下是一个例子,导出一个合并了表头Excel: ```java @ExcelIgnoreUnannotated public class ExportData { @ExcelProperty(index = 0, value = "姓名", rowspan = 2, colspan = 2) @HeadRowHeight(30) @HeadColumnWidth(15) private String name; @ExcelProperty(index = 2, value = "性别", rowspan = 2) @HeadRowHeight(30) @HeadColumnWidth(15) private String gender; @ExcelProperty(index = 3, value = "联系方式", colspan = 2) @HeadRowHeight(30) @HeadColumnWidth(20) private String contact; @ExcelProperty(index = 4, value = "电话") @HeadRowHeight(30) @HeadColumnWidth(15) private String phone; @ExcelProperty(index = 5, value = "邮箱") @HeadRowHeight(30) @HeadColumnWidth(20) private String email; // 其他属性... // getter/setter 方法... } ``` 在这个例子中,我们使用 `@HeadRowHeight` 和 `@HeadColumnWidth` 注解设置表头的行高和宽,使用 `@ContentRowHeight` 和 `@ContentColumnWidth` 注解设置内容的行高和宽。同时,我们使用 `@ExcelProperty` 注解的 `colspan` 和 `rowspan` 属性来合并行和。注意,需要将 `@ExcelIgnoreUnannotated` 注解添加到类上,以忽略未注解的属性。 然后,我们可以使用 EasyExcel 的 `ExcelWriter` 和 `Sheet` 类来写入数据。以下是一个示例代码: ```java public class ExcelExportUtil { public static void exportExcel(List<ExportData> dataList, String fileName, HttpServletResponse response) throws IOException { // 设置响应头 response.setContentType("application/vnd.ms-excel"); response.setCharacterEncoding("utf-8"); response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); // 创建 ExcelWriter ServletOutputStream outputStream = response.getOutputStream(); ExcelWriter excelWriter = new ExcelWriter(outputStream, ExcelTypeEnum.XLSX); // 创建 Sheet Sheet sheet = new Sheet(1, 0, ExportData.class); sheet.setTableStyle(createTableStyle()); // 写入数据 excelWriter.write(dataList, sheet); // 关闭 ExcelWriter excelWriter.finish(); } private static TableStyle createTableStyle() { TableStyle tableStyle = new TableStyle(); tableStyle.setTableContentBackGroundColor(IndexedColors.WHITE); tableStyle.setTableContentFontName("宋体"); tableStyle.setTableContentFontSize(12); tableStyle.setTableHeadBackGroundColor(IndexedColors.GREY_25_PERCENT); tableStyle.setTableHeadFontName("宋体"); tableStyle.setTableHeadFontSize(14); tableStyle.setTableHeadFontBold(true); tableStyle.setTableHeadFontColor(IndexedColors.WHITE); return tableStyle; } } ``` 在这个例子中,我们使用 `ExcelWriter` 和 `Sheet` 类来写入数据,使用 `createTableStyle()` 方法创建表格样式。注意,需要设置表格样式,否则导出Excel 可能会出现样式问题。 最后,在需要导出 Excel 的方法中调用 `ExcelExportUtil.exportExcel()` 方法即可。例如: ```java public class ExportController { @GetMapping("/export") public void export(HttpServletResponse response) throws IOException { List<ExportData> dataList = // 查询数据... ExcelExportUtil.exportExcel(dataList, "export", response); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿七度

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值