EasyExcel导出模板实现下拉选(解决下拉超过50个限制)

2023-11-05


先来看看最终实现效果,如果效果是你想要的,再看看实现逻辑。

在这里插入图片描述



EasyExcel本身是支持设置下拉校验的,但有个问题,一旦下拉数据超过50个左右的时候就无法正常展示,当然,现在这个问题得到了解决。


来看整体的项目目录

在这里插入图片描述

如果你之前使用过EasyExcel那上面主流程代码你将会很熟悉,下拉选相较于之前的导出只是多注册了一个 Handler。


一、主流程代码

@RestController
@RequestMapping("/one")
public class OneController {

    // 测试数据构建
    private static List<String> countryList = Arrays.asList("中国","美国","俄罗斯","德国","日本");
    private static List<String> cityList = Arrays.asList("深圳","广州","上海","北京","纽约","莫斯科","东京");
    private static Map<String, List> dropDownData = new HashMap<>(2);
    private static List<SheetOneVO> cityEntityList = new ArrayList<>(cityList.size());
    static {
        dropDownData.put("country", countryList);
        dropDownData.put("city", cityList);

        for (String item : cityList) {
            cityEntityList.add(new SheetOneVO(item));
        }
    }



    @GetMapping("/kk-one")
    public void one(HttpServletResponse response) throws Exception {

        // 通用内容设置
        String fileName = URLEncoder.encode("templateOne.xlsx",CharEncoding.UTF_8);
        response.setContentType("application/octet-stream");
        response.setCharacterEncoding(CharEncoding.UTF_8);
        response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + fileName);

        // 构建模板数据
        ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();
        WriteSheet writeSheet = EasyExcel
                .writerSheet(0, "one")
                .registerWriteHandler(new XdxCellWriteHandler(dropDownData))
                .head(TemplateOneVO.class)
                .build();

        WriteSheet citySheet = EasyExcel
                .writerSheet(1, "city")
                .head(SheetOneVO.class)
                .needHead(false)
                .build();

        excelWriter.write(Arrays.asList(new TemplateOneVO("张三","美国", "胡佛")), writeSheet)
                .write(cityEntityList, citySheet).
                finish();
    }
}

二、处理器代码


  1. 这个handler重写了单元格拦截器,在遍历表头的时候,设置下拉选。
  2. 正常是超过50个下拉才会出问题,这里懒得造那么多数据所以设置了一个LIMIT,超过它就会换成联动sheet方式,从而就解决了个数限制的问题。
public class XdxCellWriteHandler implements CellWriteHandler {

    /**
     * 超过 LIMIT 的大小就使用 sheet关联下拉,否则直接设置下拉
     */
    private static final Integer LIMIT = 6;

    private Map<String, List> dropDownData;

    public XdxCellWriteHandler(Map<String, List> dropDownData) {
        this.dropDownData = dropDownData;
    }

    /**
     * 设置下拉框数据
     * @param writeSheetHolder
     * @param key 当前列名
     * @param rowIndex 行号
     * @param columnIndex 列号
     */
    private void setSelectDataList(WriteSheetHolder writeSheetHolder, String key, int rowIndex, int columnIndex) {
        if (dropDownData.get(key) == null) {
            return;
        }

        Sheet sheet = writeSheetHolder.getSheet();
        DataValidationHelper helper = sheet.getDataValidationHelper();

        // 设置下拉列表的行: 首行,末行,首列,末列
        CellRangeAddressList rangeList = new CellRangeAddressList(rowIndex, 50000, columnIndex, columnIndex);
        // 设置下拉列表的值
        DataValidationConstraint constraint;
        if (dropDownData.get(key).size() < LIMIT) {
            // 直接设置下拉选
            constraint = helper.createExplicitListConstraint((String[]) dropDownData.get(key).toArray(new String[0]));
        } else {
            // 联动到另外一个 sheet
            constraint = helper.createFormulaListConstraint(key+ "!$A$1:$A$" + dropDownData.get(key).size());
        }

        // 设置约束
        DataValidation validation = helper.createValidation(constraint, rangeList);
        // 阻止输入非下拉选项的值
        validation.setErrorStyle(DataValidation.ErrorStyle.STOP);
        validation.setShowErrorBox(true);
        validation.setSuppressDropDownArrow(true);
        validation.createErrorBox("提示", "请输入下拉选项中的内容");
        sheet.addValidationData(validation);
    }

    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
                                 List<WriteCellData<?>> cellDataList, Cell cell, Head head,
                                 Integer relativeRowIndex, Boolean isHead) {
                                 
        // 设置隐藏 sheet
        WriteSheet writeSheet = writeSheetHolder.getWriteSheet();
        if (writeSheet.getSheetNo() > 0) {
            Workbook workbook = writeSheetHolder.getParentWriteWorkbookHolder().getWorkbook();
            workbook.setSheetHidden(writeSheet.getSheetNo(), true);
            return;
        }                         
                                 
        if (!isHead) {
            //设置value下拉框
            setSelectDataList(writeSheetHolder, head.getFieldName(), cell.getRowIndex(), cell.getColumnIndex());
        }
    }
}

三、两个VO


TemplateOneVO

@Data
@AllArgsConstructor
public class TemplateOneVO {

    @ExcelProperty("姓名")
    private String name;

    @ExcelProperty("国家")
    private String country;

    @ExcelProperty("城市")
    private String city;
}

SheetOneVO

@Data
@AllArgsConstructor
public class SheetOneVO {

    private String key;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

EasyExcel导出模板实现下拉选(解决下拉超过50个限制) 的相关文章

随机推荐

  • 华为OD机试 Python 【单词加密】

    题目 给你一句英文 里面有很多单词 单词间用空格隔开 我们要对这句子做点的变化 加密规则 如果单词里有元音 a e i o u 大小写都算 就把元音变成 如果一个单词完全没有元音 那就让这个单词的第一个和最后一个字母交换位置 输入 一句英文
  • SKB几个复制函数的区别

    1 skb clone Skb clone 函数只是复制sk buff结构 并不复制skb的数据缓冲区 Clone后的sk buff结构与原始的sk buff指向同一数据缓冲区 原始的和clone后的skb描述符的cloned值都会被置1
  • 前端基础之滚动显示

    marquee滚动标签 注 该标签已经过时 被w3c弃用 使用样例
  • 设计模式(一)- 模板方法模式

    模板方法模式 文章目录 模板方法模式 1 模板方法模式 1 介绍 2 应用实例 代码 1 父类抽象模板 统一方法定为final 2 子类去实现不同的方法 3 其他子类实现不同的方法 4 结果展示 1 模板方法模式 在模板模式 Templat
  • 微信小程序 功能页导航 functional-page-navigator 组件

    完整微信小程序 Java后端 技术贴目录清单页面 必看 仅在插件中有效 用于跳转到插件功能页 属性 类型 默认值 必填 说明 最低版本 version string release 否 跳转到的小程序版本 线上版本必须设置为 release
  • linux安装idea并创建快捷方式

    一 安装 1 下载 在linux自带的火狐浏览器打开下载更方便 下载 IntelliJ IDEA JetBrains 功能强大 符合人体工程学的 Java IDE 选择Linux 这里以下载社区版为例 我下载的版本是2022 2 3 文件名
  • 了解应用层

    应用层 1 概述 2 应用程序组织方式 2 1 C S方式 2 1 P2P方式 3 动态主机配置协议DHCP 3 1 DHCP工作流程 4 域名系统DNS 4 1 域名结构 4 2 域名分类 4 3 域名服务器 4 3 1 分类 4 4 D
  • Python-爬虫(Scrapy爬虫框架,爬取豆瓣读书和评分)

    文章目录 1 Scrapy注意点 2 Scrapy爬取豆瓣读书和评分 代码部分 数据定义items py 爬虫部分spiders book py 数据存储部分pipelines py 启动爬虫执行cmd命令 start py 1 Scrap
  • QT设计电子时钟类

    1 界面效果 2 类的声明 wedgit h class Widget public QWidget Q OBJECT public Widget QWidget parent nullptr 默认构造函数 Widget 默认析构函数 vo
  • 磁共振检查头部能检测出什么_头部核磁共振可以检查什么?

    很多人会疑惑为什么要做头部核磁共振 做CT不好吗 这是因为脑CT具有一定的局限性 有时候脑CT是不能诊断出脑部异常情况的 头部核磁共振检査较CT更为敏感 具有多方向切层 多参数成像的特点 能更精确的现实病变位置 范围大小及组织学特性 是发现
  • 【Java】利用SpringBoot搭建WebService服务接口

    前言 在项目开发过程中经常会碰到对接医疗软件系统的时候对方要求提供WebService形式的接口 本篇文章记载了个人对接项目过程中整合并搭建的WebService形式的接口 希望对您能够有所帮助 一 在pom xml文件中导入WebServ
  • 期权、期货及其他衍生产品 第一章读书笔记

    期权 期货及其他衍生产品 第一章读书笔记 介绍 什么是衍生产品 衍生产品的特点 有哪些交易所场所 交易所市场 一些著名的交易所市场 场外市场 我国的场外市场 远期合约 远期合约可以用来对冲外汇风险 远期合约的收益 远期价格和即期价格 期货合
  • lua学习笔记—table

    1 什么是table table是lua的一种数据结构 可以用来创建数组或映射 lua中的table使用的是关联型数组 关联数组的key值可以是除过nil之外任意类型的值 table的大小是不固定的 可以自己进行扩容 2 如何构造table
  • iOS autorelease 示例研究

    iOS autorelease是Objective C中的一个自动内存管理机制 它通过在对象创建时将其添加到自动释放池中 在池被释放时自动释放对象 从而减少手动内存管理的工作量 本文将介绍如何使用autorelease机制来管理内存 aut
  • 跨部门的高效沟通与协作

    在企业管理当中 沟通是一个非常重要的技能 它运用我们管理当中每一个细节 首先要做好沟通和协作 我们需要有一个很好的思维模式 这个就像盖房子一样 它是地基 是一个房子的地基部分 没有一个正确的思维模式 那我们其后的技巧都不会有一个很好的效果
  • 大数据框架总结

    hdfs 1 写数据流程 2 HDFS读数据流程1 3 HDFS副本节点选择 4 HDFS nn 2nn 镜像文件以及编辑日志的工作机制 注意此类机制都是先更新编辑日志 再更新内存文件block元数据 checkpoint触发默认条件是一小
  • 谈谈虚幻引擎4的Global Illumination

    本届GDC 2013 Epic再次展示了UE4的最新demo 效果惊艳毋庸置疑 不过今天我们只谈UE4的光照利器 SVOGI SVOGI全称Sparse Voxel Octree Global Illumination 由Epic的Andr
  • DES的加密与解密(C语言实现)——大三密码学实验

    目录 DES的描述 Feistel体制 密钥扩展函数 F函数 总流程 代码 get函数的构建 yihuo函数的构建 fuck函数的构建 left move函数的构建 exchange函数的构建 erzhuanshi函数的构建 shizhua
  • 利用Vulnhub复现漏洞 - GoAhead 远程命令执行漏洞(CVE-2017-17562)

    GoAhead 远程命令执行漏洞 CVE 2017 17562 Vulnhub官方复现教程 漏洞原理 复现漏洞 启动环境 漏洞复现 动态链接库源码 编译so文件 发送payload Vulnhub官方复现教程 https vulhub or
  • EasyExcel导出模板实现下拉选(解决下拉超过50个限制)

    学习地址 https d9bp4nr5ye feishu cn wiki O3obweIbgi2Rk1ksXJncpClTnAf B站视频 https www bilibili com video BV1H34y1T7Lm 先来看看最终实现