easyexcel 2.2.6版本导出excel模板时,标题带下拉框及其下拉值过多不显示问题

需求背景:有一个需求要做下拉框的值有100多条,同时这个excel是一个多sheet的导入模板
直接用easyexcel 导出,会出现下拉框的值过多,导致生成出来的excel模板无法正常展示下拉功能

 

使用的easyexcel版本:<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.2.6</version>
</dependency>
自定义处理器package com.manager.utils;import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddressList;
import java.util.Map;/*** 解决使用 easyExcel导出模板,下拉框数据超长,导出模板后,下拉框数据不展示问题* @author yjj* @date 2025/02/18 10:16**/
public class EasyExcelCellWriteHandler implements SheetWriteHandler {public static final String SHEET_NAME = "下拉框隐藏表hidden";/*** 设置阈值,避免生成的导入模板下拉值获取不到*/private static final Integer LIMIT_NUMBER = 50;private Map<Integer, String[]> map = null;public EasyExcelCellWriteHandler(Map<Integer, String[]> map) {this.map = map;}@Overridepublic void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {}@Overridepublic void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {// 这里可以对cell进行任何操作Sheet sheet = writeSheetHolder.getSheet();DataValidationHelper helper = sheet.getDataValidationHelper();Class<?> headClass = writeSheetHolder.getClazz();// k 为存在下拉数据集的单元格下表 v为下拉数据集map.forEach((k, v) -> {System.out.println("Key = " + k + ", Value = " + v);// 设置下拉单元格的首行 末行 首列 末列CellRangeAddressList rangeList = new CellRangeAddressList(EasyExcelUtils.headRowNumber(headClass), 65536,k,k);// 如果下拉值总数大于50,则使用一个新sheet存储,避免生成的导入模板下拉值获取不到if (v.length > LIMIT_NUMBER) {//定义sheet的名称//1.创建一个隐藏的sheet 名称为 hidden + kString sheetName = SHEET_NAME +sheet.getSheetName() + k;Workbook workbook = writeWorkbookHolder.getWorkbook();Sheet hiddenSheet = workbook.createSheet(sheetName);for (int i = 0, length = v.length; i < length; i++) {// 开始的行数i,列数khiddenSheet.createRow(i).createCell(k).setCellValue(v[i]);}Name category1Name = workbook.createName();category1Name.setNameName(sheetName);String excelLine = getExcelLine(k);// =hidden!$H:$1:$H$50  sheet为hidden的 H1列开始H50行数据获取下拉数组String refers = "=" + sheetName + "!$" + excelLine + "$1:$" + excelLine + "$" + (v.length + 1);// 将刚才设置的sheet引用到你的下拉列表中DataValidationConstraint constraint = helper.createFormulaListConstraint(refers);DataValidation dataValidation = helper.createValidation(constraint, rangeList);writeSheetHolder.getSheet().addValidationData(dataValidation);// 设置存储下拉列值得sheet为隐藏int hiddenIndex = workbook.getSheetIndex(sheetName);if (!workbook.isSheetHidden(hiddenIndex)) {workbook.setSheetHidden(hiddenIndex, true);}}// 下拉列表约束数据DataValidationConstraint constraint = helper.createExplicitListConstraint(v);// 设置约束DataValidation validation = helper.createValidation(constraint, rangeList);// 阻止输入非下拉选项的值validation.setErrorStyle(DataValidation.ErrorStyle.STOP);validation.setShowErrorBox(true);validation.setSuppressDropDownArrow(true);validation.createErrorBox("提示", "此值与单元格定义格式不一致");// validation.createPromptBox("填写说明:","填写内容只能为下拉数据集中的单位,其他单位将会导致无法入仓");sheet.addValidationData(validation);});}/*** 返回excel列标A-Z-AA-ZZ** @param num 列数* @return java.lang.String*/private 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;}}
导出工具类/*** 支持超长下拉框展示* 下载导入模板 - 支持多sheet*/public static void writeTemplateBoxTooLong(HttpServletResponse response, ExcelModel excelModel) {ExcelWriter excelWriter = null;try {excelWriter = EasyExcel.write(outputStream(excelModel.getFileName(), response)).registerConverter(new DateConverter()).useDefaultStyle(false).build();List<ExcelModel.Sheet<?>> sheets = excelModel.getSheets();for (int i = 0; i < sheets.size(); i++) {ExcelModel.Sheet<?> sheet = sheets.get(i);WriteSheet writeSheet;if (ExtraOption.class.isAssignableFrom(sheet.getHeadClass())) {writeSheet = EasyExcel.writerSheet(i, sheet.getSheetName()).registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).registerWriteHandler(HorizontalCellStyleStrategyFactory.optStyleStrategy()).head(sheet.getHeadClass()).sheetName(sheet.getSheetName()).build();} else {Map<Integer, String[]> map = buildExcelDropDownSetField(sheet.getHeadClass());writeSheet = EasyExcel.writerSheet(i, sheet.getSheetName()).registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).registerWriteHandler(new EasyExcelCellWriteHandler(map)).registerWriteHandler(new ImportTempleRowWriteHandler()).registerWriteHandler(new ImportTempleCellWriteHandler()).head(sheet.getHeadClass()).sheetName(sheet.getSheetName()).relativeHeadRowIndex(RELATIVE_HEAD_ROW_INDEX).includeColumnFiledNames(sheet.getIncludeFiledNames()).build();}excelWriter.write(sheet.getData(), writeSheet);}} catch (Exception e) {Throwable cause = Throwables.getRootCause(e);log.error("下载模板失败:{}", cause.getMessage(), cause);throw new ServiceException("下载模板失败:{0}", cause.getMessage());} finally {if (excelWriter != null) {excelWriter.finish();}}}
 /*** 批量导入 - 支持多sheet*/@SuppressWarnings("rawtypes")public static Map<Class<?>, List<?>> readMultiSheet(MultipartFile file, Class<?>... classes) {Map<Class<?>, List<?>> resultMap = Maps.newHashMapWithExpectedSize(classes.length + 1);try {checkExcelFile(file);ByteArrayInputStream inputStream = deleteHiddenSheets(file);ExcelReader excelReader = EasyExcel.read(inputStream).build();for (int i = 0; i < classes.length; i++) {Class clazz = classes[i];SimpleAnalysisEventListener listener = SimpleAnalysisEventListener.factory(true);ReadSheet readSheet = EasyExcel.readSheet(i).head(clazz).registerReadListener(listener).headRowNumber(headRowNumber(clazz)).build();excelReader.read(readSheet);resultMap.put(clazz, listener.getResults());}if (resultMap.values().stream().allMatch(CollectionUtils::isEmpty)) {throw new ServiceException("请至少录入一条数据");}} catch (Exception e) {Throwable cause = Throwables.getRootCause(e);log.error("解析异常:{}", cause.getMessage(), cause);throw new ServiceException("解析异常:{0}", cause.getMessage());}return resultMap;}//删除导出模板时生成的隐藏sheet,避免导入时读取带隐藏sheet报错public static ByteArrayInputStream deleteHiddenSheets(MultipartFile file){try (InputStream inputStream = file.getInputStream();ByteArrayOutputStream outputStream = new ByteArrayOutputStream();){Workbook workbook = new XSSFWorkbook(inputStream);for (int i = 0; i < workbook.getNumberOfSheets(); i++) {Sheet sheet = workbook.getSheetAt(i);if (sheet.getSheetName().contains(EasyExcelCellWriteHandler.SHEET_NAME)) {workbook.removeSheetAt(i);i--;  // 因为删除了一个sheet,索引需要调整}}workbook.write(outputStream);workbook.close();return new ByteArrayInputStream(outputStream.toByteArray());} catch (IOException e) {log.error("解析excel失败!",e);throw new ServiceException("解析失败!");}}

原生poi参考这位大佬:解决POI的SXSSFSheet 创建excel下拉框,下拉框内容过多时不显示的问题_java poi 下拉框数据7万行,隐藏sheet方法也看不不全-CSDN博客

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

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

相关文章

基于WebRTC与AI大模型接入EasyRTC:打造轻量级、高实时、强互动的嵌入式音视频解决方案

随着物联网和嵌入式技术的快速发展&#xff0c;嵌入式设备对实时音视频通信的需求日益增长。然而&#xff0c;传统的音视频解决方案往往存在体积庞大、实时性差、互动体验不佳等问题&#xff0c;难以满足嵌入式设备的资源限制和应用场景需求。 针对以上痛点&#xff0c;本文将介…

AI工作流+专业知识库+系统API的全流程任务自动化

我有点悲观&#xff0c;甚至很沮丧&#xff0c;因为AI留给普通人的机会不多了&#xff0c;这既是人类之间权力的斗争&#xff0c;也是硅基生命和碳基生命的斗争。AI自动化是无法避免的趋势&#xff0c;如果人类不能平权&#xff0c;那就只能跪下接受审判。 通过整合AI工作流、专…

Lua | 每日一练 (3)

&#x1f4a2;欢迎来到张胤尘的技术站 &#x1f4a5;技术如江河&#xff0c;汇聚众志成。代码似星辰&#xff0c;照亮行征程。开源精神长&#xff0c;传承永不忘。携手共前行&#xff0c;未来更辉煌&#x1f4a5; 文章目录 Lua | 每日一练 (3)题目参考答案减少查找次数预分配表…

二叉树(中等题)

1、先序&#xff0c;中序遍历确定二叉树 105 方法一、 前提 ① 必须不能有重复元素② 只有先序&#xff0b;中序和后序&#xff0b;中序才能实现唯一树 思考要点&#xff1a; 不要想着用for循环&#xff0c;递归一定更好解决输入是vector&#xff0c;递归就得考虑传入索…

服务器通过 ollama 运行deepseek r1

1、服务器环境简介 56核 CPU64G 内存无显卡已安装 Ollama 2、下载模型与配置 正常可以通过 ollama pull 或 ollama run 命令直接下载&#xff0c;但通常会遇到连接超时、找不到网址等总理。因此&#xff0c;可以使用国内的模型站进行下载&#xff0c;在这里使用魔塔查找模型…

java项目排查线上问题1111

1.磁盘容量不足&#xff1a; 应用抛出的异常信息&#xff1a;java.io.IOException: 磁盘空间不足 1.1 指令获取磁盘状态&#xff1a;df -h 1.2 获取目录下文件夹大小&#xff1a;du -sh * 1.3 获取目录下文件夹大小&#xff1a;ls -lh 可以找到最大的文件&#xff0c;如日…

js中 ES6 新特性详解

ES6&#xff08;ECMAScript 2015&#xff09;是 JavaScript 的一次重大更新&#xff0c;引入了许多新的特性&#xff0c;使 JavaScript 代码更加简洁、可读和高效。以下是 ES6 的主要新特性及其原理 1. let 和 const 关键字 原理解析 1.1 作用域 var 关键字的作用域&#xf…

深入理解设计模式之解释器模式

深入理解设计模式之解释器模式 在软件开发的复杂世界中,我们常常会遇到需要处理特定领域语言的情况。比如在开发一个计算器程序时,需要解析和计算数学表达式;在实现正则表达式功能时,要解析用户输入的正则表达式来匹配文本。这些场景都涉及到对特定语言的解释和执行,而解…

巧妙实现右键菜单功能,提升用户操作体验

在动态交互式图库中&#xff0c;右键菜单是一项能够显著提升用户操作便捷性的功能。它的设计既要响应用户点击位置&#xff0c;又需确保菜单功能与数据操作紧密结合&#xff0c;比如删除图片操作。以下将通过一段实际代码实现&#xff0c;展示从思路到实现的详细过程。 实现右键…

​​​​​​​​​​​​​​如何使用函数指针来调用函数

在C和C编程中&#xff0c;函数指针是一种特殊类型的指针&#xff0c;它指向一个函数而不是一个变量。使用函数指针可以动态地调用不同的函数&#xff0c;这在实现回调函数、事件处理、策略模式等场景中非常有用。 以下是如何定义和使用函数指针来调用函数的步骤&#xff1a; 定…

KEGG条形图绘制

原始数据 setwd("C:\\Users\\HUAWEI\\Desktop\\proteomic_WGCNA\\bacteria\\Eggnog\\KEGGhun") library(ggplot2) library(cols4all) dt <- read.csv("bacteria_KEGG.csv")dt$KEGG_Term <- factor(dt$KEGG_Term, levels rev(dt$KEGG_Term))#基础富集…

My Metronome for Mac v1.4.2 我的节拍器 支持M、Intel芯片

应用介绍 My Metronome 是一款适用于 macOS 的专业节拍器应用程序&#xff0c;旨在帮助音乐家、作曲家、学生和任何需要精确节奏控制的人进行练习。无论是进行乐器练习、音乐创作还是演出排练&#xff0c;My Metronome 都能为用户提供精准的节拍支持和灵活的功能&#xff0c;确…

宇树科技13家核心零部件供应商梳理!

2025年2月6日&#xff0c;摩根士丹利&#xff08;Morgan Stanley&#xff09;发布最新人形机器人研报&#xff1a;Humanoid 100: Mapping the Humanoid Robot Value Chain&#xff08;人形机器人100&#xff1a;全球人形机器人产业链梳理&#xff09;。 Humanoid 100清单清单中…

Part 3 第十二章 单元测试 Unit Testing

概述 第十二章围绕单元测试展开&#xff0c;阐述了单元测试的实践与重要性&#xff0c;通过对比其他测试类型&#xff0c;突出其特点&#xff0c;还介绍了单元测试的最佳实践、避免的反模式以及与测试替身相关的内容&#xff0c;为编写高质量单元测试提供指导。 章节概要 1…

【Vite SVG 图标方案:vite-plugin-svg-icons 指南】

&#x1f31f; Vite SVG 图标方案&#xff1a;vite-plugin-svg-icons 指南 &#x1f4dc; 背景与痛点 &#x1f30d; 前端图标演进史 1.0 &#x1f5bc;️ 图片图标 → 2.0 &#x1f3ad; 字体图标 → 3.0 &#x1f3a8; SVG 图标传统方案存在三大痛点&#xff1a; 字体图标…

go flag参数 类似Java main 的args

两部分内容 go run test1.go aa -name 123 1. 解析&#xff1a;aa -name 123 2. 解析&#xff1a;name 123 代码 package mainimport ("log""os" )func main() {log.Println("main ...")if len(os.Args) > 0 {for index, arg : ra…

酒店旅游API:数据交互的隐形桥梁——以携程API为例

一、API&#xff1a;酒店 和第三方服务无缝连接。 核心价值&#xff1a; 实时数据互通&#xff1a;房态、价格、库存秒级同步。业务流程自动化&#xff1a;预订、支付、确认全程无需人工干预。生态扩展&#xff1a;开发者可基于API构建定制化工具&#xff08;如比价插件、智能…

深入理解 JSP 与 Servlet:原理、交互及实战应用

一、引言 在 Java Web 开发领域,JSP(JavaServer Pages)和 Servlet 是两个至关重要的技术,它们共同构成了动态网页开发的基础。Servlet 作为服务器端的 Java 程序,负责处理客户端请求并生成响应;而 JSP 则是一种简化的 Servlet 开发方式,允许开发者在 HTML 页面中嵌入 J…

【JavaScript】《JavaScript高级程序设计 (第4版) 》笔记-Chapter20-JavaScript API

二十、JavaScript API JavaScript API 随着 Web 浏览器能力的增加&#xff0c;其复杂性也在迅速增加。从很多方面看&#xff0c;现代 Web 浏览器已经成为构建于诸多规范之上、集不同 API 于一身的“瑞士军刀”。浏览器规范的生态在某种程度上是混乱而无序的。一些规范如 HTML5&…

AI芯片的关键特征

AI芯片是专门为人工智能应用设计的芯片&#xff0c;以下是其应具备的关键特征&#xff1a; 强大的并行计算能力&#xff1a;AI任务如深度学习中的神经网络训练和推理&#xff0c;涉及大量矩阵运算和并行数据处理。AI芯片需有众多计算单元&#xff08;如GPU的大量流处理器、ASIC…