EasyExcel下拉列表长度过长不显示【已修复】

EasyExcel下拉列表长度过长不显示【已修复】

背景

在使用easyexcel进行报表生成的时候,有需求要把字典数据塞到单元格中,easyexcel提供了一个直接生成下拉列表的方法,但是实际使用过程中,字典长度过长时,会导致下拉列表无数据的问题

环境

组件 版本
jdk 1.8
x-easypdf 2.10.0

最新插入下拉数据方法

先创建一个隐藏的字典sheet,在对应列中插入字典数据,在原sheet里根据列序号找到字典sheet中对应的字典数据,作为下拉列表

java 复制代码
    /**
     * 处理下拉数据
     * @param sheet
     * @param cell
     */
    private void handleDropDown(Sheet sheet, Cell cell) {
        String hiddenName = "hidden";
        Workbook workbook = sheet.getWorkbook();
        Sheet hidden = workbook.getSheet(hiddenName);
        if(ObjectUtils.isEmpty(hidden)) {
            hidden = workbook.createSheet(hiddenName);
        }
        // 设置隐藏
        workbook.setSheetHidden(workbook.getSheetIndex(hidden), true);
        DataValidationHelper helper = sheet.getDataValidationHelper();
        Map<String, Map<String, String>> rowColMap = new HashMap<>();
        Map<String, String> colReferMap = new HashMap<>();
        if(ObjectUtils.isEmpty(needPickData)) {
            return;
        }
        for (Integer k : needPickData.keySet()) {
            List<Object> v = needPickData.get(k);
            if(CollectionUtils.isEmpty(v)) {
                continue;
            }
            String excelLine = getExcelLine(k);
            List<Object> lists = v.stream().filter(ObjectUtils::isNotEmpty).distinct().collect(Collectors.toList());
            colReferMap.put(k.toString(), "=" + hiddenName + "!$" + excelLine +
                    "$1:$" + excelLine + "$" + (lists.size()));
            if(CollectionUtils.isEmpty(lists)) {
                continue;
            }
            for (int i = 0; i < lists.size(); i++) {
                Map<String, String> colMap = rowColMap.containsKey(Integer.toString(i))?rowColMap.get(Integer.toString(i)):new HashMap<>();
                String value = lists.get(i).toString();
                colMap.put(k.toString(), value);
                rowColMap.put(Integer.toString(i), colMap);
            }
        }
        if(rowColMap.size()>0) {
            for (String rowNum : rowColMap.keySet().stream().sorted(Comparator.comparing(Integer::parseInt)).collect(Collectors.toList())) {
                Row row = hidden.createRow(Integer.parseInt(rowNum));
                if (rowColMap.get(rowNum).size() == 0) {
                    continue;
                }
                for (String colNum : rowColMap.get(rowNum).keySet().stream().sorted(Comparator.comparing(Integer::parseInt)).collect(Collectors.toList())) {
                    row.createCell(Integer.parseInt(colNum)).setCellValue(rowColMap.get(rowNum).get(colNum));
                }
            }
        }
        if(colReferMap.size()>0) {
            for (String colNum : colReferMap.keySet().stream().sorted(Comparator.comparing(Integer::parseInt)).collect(Collectors.toList())) {
                // 设置下拉列表的行: 首行,末行,首列,末列
                CellRangeAddressList addressList = new CellRangeAddressList(cell.getRowIndex(), 10000, Integer.parseInt(colNum), Integer.parseInt(colNum));
                DataValidationConstraint constraint = helper.createFormulaListConstraint(colReferMap.get(colNum));
                DataValidation dataValidation = helper.createValidation(constraint, addressList);
                sheet.addValidationData(dataValidation);
            }
        }
    }

    /**
     *  返回excel列标A-Z-AA-ZZ
     * @param num 列数
     * @return java.lang.String
     */
    public String getExcelLine ( int num){
        String line = "";
        int first = num / 26;
        int second = num % 26;
        if (first > 0) {
            line = (char) ('A' + first - 1) + "";
        }
        line += (char) ('A' + second) + "";
        return line;
    }

旧版插入下拉数据方法

缺陷:字典长度过长时,无法插入下拉列表

java 复制代码
    /**
     * 处理下拉数据
     * @param sheet
     * @param cell
     */
    @Deprecated
    private void handleDropDownOld(Sheet sheet, Cell cell) {
        DataValidationHelper helper = sheet.getDataValidationHelper();
        needPickData.forEach((k, v) -> {
            // 设置下拉列表的行: 首行,末行,首列,末列
            CellRangeAddressList rangeList = new CellRangeAddressList(cell.getRowIndex(), 100000, k, k);

            // 设置下拉列表的值
            if (CollectionUtils.isNotEmpty(v)){
                List<Object> lists = v.stream().filter(ObjectUtils::isNotEmpty).distinct().collect(Collectors.toList());
                if(CollectionUtils.isNotEmpty(lists)) {
                    String[] values = new String[lists.size()];
                    for (int i = 0; i < lists.size(); i++) {
                        values[i] = lists.get(i).toString();
                    }
                    DataValidationConstraint constraint = helper.createExplicitListConstraint(values);
                    // 设置约束
                    DataValidation validation = helper.createValidation(constraint, rangeList);
                    // 阻止输入非下拉选项的值
                    validation.setErrorStyle(DataValidation.ErrorStyle.STOP);
                    validation.setShowErrorBox(true);
                    validation.setSuppressDropDownArrow(true);
                    validation.createErrorBox("提示", "请输入下拉选项中的内容");
                    sheet.addValidationData(validation);
                }
            }
        });
    }
相关推荐
学长毕设8 小时前
基于springboot科创竞赛信息平台-附源码
java·spring boot·后端
聪明的笨猪猪9 小时前
Java 工程案例:AI 生成 @Async 异步线程池踩坑
java·经验分享·面试·ai编程
学长毕设9 小时前
基于SpringBoot公务员考试交流平台-附源码
java·spring boot·后端
SL_staff11 小时前
私有化低代码:面向强监管行业的可控数字化实践
java·低代码
饮水桶_T12 小时前
JAVA IO流笔记
开发语言·数据结构·算法
三翼鸟数字化技术团队12 小时前
高性能存储引擎RocksDB:原理与Java生态实践
java
SL_staff12 小时前
JVS-APS有限产能建模的七个刚性支点:面向产线真实约束的技术实现解析
java·开源·全栈
特立独行的猫A12 小时前
少 3 个环节、少 1 次 ABI、少 3500 行代码:cj-tauri 与 Ionic/Capacitor 的鸿蒙桥接机制对比
java·后端·python
学长毕设12 小时前
基于SpringBoot的高校后勤报修管理系统-附源码
java·spring boot·后端
特立独行的猫A13 小时前
cj-tauri vs Rust/Tauri 同款播放器实测:编译 21 秒 vs 11 分钟,磁盘 12 MB vs 1.2 GB
java·后端·python