当前位置: 首页 > news >正文

apache poi 实现下拉框联动校验

apache poi 提供了 DataValidation​ 接口 让我们可以轻松实现 Excel 下拉框数据局校验。但是下拉框联动校验是无法直接通过 DataValidation ​实现,所以我们可以通过其他方式间接实现。

步骤如下:

  1. 创建一个隐藏 sheet
 private static void createHiddenSheet(List<String> provinceList, Map<String, String[]> regionMap, Workbook workbook) {String hiddenSheetName = "region";Sheet hiddenSheet = workbook.createSheet(hiddenSheetName);// 这里也可以设置 hidden 为 false 这样可以直接看到 sheet 内容workbook.setSheetHidden(workbook.getSheetIndex(hiddenSheet), true);}
  1. 将数据放入隐藏 sheet
        int rowNum = 0;// 第一行存放省数据Row row = hiddenSheet.createRow(rowNum);for (int i = 0; i < provinceList.size(); i++) {Cell cell = row.createCell(i);cell.setCellValue(provinceList.get(i));}rowNum++;for (String key : regionMap.keySet()) {String[] dataArray = regionMap.get(key);// 循环创建行,每行存放一个数组row = hiddenSheet.createRow(rowNum);// key 放在每行第一个,value 放在每行的后面Cell keyCell = row.createCell(0);keyCell.setCellValue(key);for (int i = 0, length = dataArray.length; i < length; i++) {Cell cell = row.createCell(i + 1);cell.setCellValue(dataArray[i]);}Name name = workbook.createName();// 将key 设置为下拉框的keyname.setNameName(key);String formula = hiddenSheetName + "!$B$" + (rowNum + 1) + ":$" + (convertNumberToLetter(dataArray.length + 1)) + "$" + (rowNum + 1);name.setRefersToFormula(formula);// 可以将formula 放在最后一列Cell formulaCell = row.createCell(dataArray.length + 1);formulaCell.setCellValue(formula);rowNum++;}
  1. 在主 sheet 中使用 formula 来使用隐藏 sheet 的数据
    DataValidationHelper helper = mainSheet.getDataValidationHelper();// 设置省份下拉框CellRangeAddressList provRangeAddressList = new CellRangeAddressList(1, 1000, 0, 0);// formula 为  region!$A$1:$E$1DataValidationConstraint dvConstraint = helper.createFormulaListConstraint("region!$A$1:$" + (convertNumberToLetter(provinceList.size())) + "$1");DataValidation provinceDataValidation = helper.createValidation(dvConstraint, provRangeAddressList);provinceDataValidation.setSuppressDropDownArrow(true);mainSheet.addValidationData(provinceDataValidation);
  1. 设置联动下拉框 DataValidation
 // 设置市下拉框  firstCol lastCol 根据实际情况设置CellRangeAddressList cityRange = new CellRangeAddressList(1, 1000, 1, 1);DataValidationConstraint cityConstraint = helper.createFormulaListConstraint("INDIRECT(A2)");DataValidation cityValidation = helper.createValidation(cityConstraint, cityRange);mainSheet.addValidationData(cityValidation);// 设置县下拉框 firstCol lastCol 根据实际情况设置CellRangeAddressList districtRange = new CellRangeAddressList(1, 1000, 2, 2);DataValidation districtValidation = helper.createValidation(helper.createFormulaListConstraint("INDIRECT(B2)"), districtRange);mainSheet.addValidationData(districtValidation);
  1. 完整代码如下:
package com.shang;import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;import java.io.FileOutputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/**
* @author: shangwei
* @date: 2024/11/3 13:01
*/
public class ExcelUtil {public static void createExcel(String path, List<String> provinceList, Map<String, String[]> regionMap) {try {Workbook workbook = new XSSFWorkbook();createHiddenSheet(provinceList, regionMap, workbook);Sheet mainSheet = workbook.createSheet("mainSheet");// 主sheet 第一行数据String[] titles = {"省", "市", "县"};int rowNum = 0;Row row = mainSheet.createRow(rowNum);for (int i = 0; i < titles.length; i++) {Cell cell = row.createCell(i);cell.setCellValue(titles[i]);}DataValidationHelper helper = mainSheet.getDataValidationHelper();// 设置省份下拉框CellRangeAddressList provRangeAddressList = new CellRangeAddressList(1, 1000, 0, 0);// formula 为  region!$A$1:$E$1DataValidationConstraint dvConstraint = helper.createFormulaListConstraint("region!$A$1:$" + (convertNumberToLetter(provinceList.size())) + "$1");DataValidation provinceDataValidation = helper.createValidation(dvConstraint, provRangeAddressList);provinceDataValidation.setSuppressDropDownArrow(true);mainSheet.addValidationData(provinceDataValidation);// 设置市下拉框  firstCol lastCol 根据实际情况设置CellRangeAddressList cityRange = new CellRangeAddressList(1, 1000, 1, 1);DataValidationConstraint cityConstraint = helper.createFormulaListConstraint("INDIRECT(A2)");DataValidation cityValidation = helper.createValidation(cityConstraint, cityRange);mainSheet.addValidationData(cityValidation);// 设置县下拉框 firstCol lastCol 根据实际情况设置CellRangeAddressList districtRange = new CellRangeAddressList(1, 1000, 2, 2);DataValidation districtValidation = helper.createValidation(helper.createFormulaListConstraint("INDIRECT(B2)"), districtRange);mainSheet.addValidationData(districtValidation);FileOutputStream fileOutputStream = new FileOutputStream(path);workbook.write(fileOutputStream);} catch (Exception e) {e.printStackTrace();}}private static void createHiddenSheet(List<String> provinceList, Map<String, String[]> regionMap, Workbook workbook) {String hiddenSheetName = "region";Sheet hiddenSheet = workbook.createSheet(hiddenSheetName);int rowNum = 0;// 第一行存放省数据Row row = hiddenSheet.createRow(rowNum);for (int i = 0; i < provinceList.size(); i++) {Cell cell = row.createCell(i);cell.setCellValue(provinceList.get(i));}rowNum++;for (String key : regionMap.keySet()) {String[] dataArray = regionMap.get(key);// 循环创建行,每行存放一个数组row = hiddenSheet.createRow(rowNum);// key 放在每行第一个,value 放在每行的后面Cell keyCell = row.createCell(0);keyCell.setCellValue(key);for (int i = 0, length = dataArray.length; i < length; i++) {Cell cell = row.createCell(i + 1);cell.setCellValue(dataArray[i]);}Name name = workbook.createName();// 将key 设置为下拉框的keyname.setNameName(key);String formula = hiddenSheetName + "!$B$" + (rowNum + 1) + ":$" + (convertNumberToLetter(dataArray.length + 1)) + "$" + (rowNum + 1);name.setRefersToFormula(formula);// 可以将formula 放在最后一列Cell formulaCell = row.createCell(dataArray.length + 1);formulaCell.setCellValue(formula);rowNum++;}// 这里也可以设置 hidden 为 false 这样可以直接看到 sheet 内容workbook.setSheetHidden(workbook.getSheetIndex(hiddenSheet), true);}/*** 将数字 1 到 26 转换为对应的字母 A 到 Z。** @param number 要转换的数字,范围是 1 到 26。* @return 对应的字母。*/public static String convertNumberToLetter(int number) {if (number < 1 || number > 26) {throw new IllegalArgumentException("Number must be between 1 and 26");}return String.valueOf((char) ('A' + number - 1));}public static void main(String[] args) {Map<String, String[]> regionMap = new HashMap<>();List<String> provinceList = Arrays.asList("湖北省", "湖南省", "广东省", "江苏省", "浙江省");regionMap.put("湖北省", new String[]{"武汉市", "黄石市", "十堰市", "宜昌市", "襄樊市", "鄂州市", "荆门市", "孝感市", "荆州市", "黄冈市", "咸宁市", "随州市"});regionMap.put("湖南省", new String[]{"长沙市", "株洲市", "湘潭市", "衡阳市", "邵阳市", "岳阳市", "常德市", "张家界市", "益阳市", "郴州市", "永州市", "怀化市"});regionMap.put("广东省", new String[]{"广州市", "韶关市", "深圳市", "珠海市", "汕头市", "佛山市", "江门市", "湛江市", "茂名市", "肇庆市", "惠州市", "梅州市", "汕尾市", "河源市", "阳江市", "清远市"});regionMap.put("江苏省", new String[]{"南京市", "无锡市", "徐州市", "常州市", "苏州市", "南通市", "连云港市", "淮安市", "盐城市", "扬州市", "镇江市", "泰州市", "宿迁市"});regionMap.put("浙江省", new String[]{"杭州市", "宁波市", "温州市", "嘉兴市", "湖州市", "绍兴市", "金华市", "衢州市", "舟山市", "台州市", "丽水市"});regionMap.put("武汉市", new String[]{"江岸镇", "江汉镇", "江夏镇", "硚口镇", "武昌镇", "江夏镇"});regionMap.put("黄石市", new String[]{"黄石港镇", "西塞山镇", "下陆镇", "大冶镇", "大冶镇"});String path = "/Users/shangwei/Desktop/example" + System.currentTimeMillis() + ".xlsx";createExcel(path, provinceList, regionMap);}}

相关 Maven 依赖

<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.3</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.11.0</version></dependency>

运行截图:

​​运行截图

相关文章:

apache poi 实现下拉框联动校验

apache poi 提供了 DataValidation​ 接口 让我们可以轻松实现 Excel 下拉框数据局校验。但是下拉框联动校验是无法直接通过 DataValidation ​实现&#xff0c;所以我们可以通过其他方式间接实现。 ‍ 步骤如下&#xff1a; 创建一个隐藏 sheet private static void create…...

【canal 中间件】canal 实时监听 binlog

文章目录 一、安装 MySQL1.1 启动 mysql 服务器1.2 开启 Binlog 写入功能1.2.1创建 binlog 配置文件1.2.2 修改配置文件权限1.2.3 挂载配置文件1.2.4 检测 binlog 配置是否成功 1.3 创建账户并授权 二、安装 canal2.1 安装 canal-admin(可选)2.1.1 启动 canal-admin 容器2.1.2 …...

JVM垃圾收集算法、对应收集器和选择建议

如果说垃圾收集算法是内存回收的方法论&#xff0c;那么垃圾收集器就是内存回收的具体实现。 到目前为止还没有最好的垃圾收集器出现&#xff0c;也没万能的垃圾收集器。实际使用中&#xff0c;根据具体应用场景选择合适的垃圾收集器。 1、垃圾收集算法 垃圾收集算法可以从高…...

如何在算家云搭建Aatrox-Bert-VITS2(音频生成)

一、模型介绍 ‌ Aatrox - Bert -VITS2 模型是一种基于深度学习的语音合成系统&#xff0c;结合了 BERT 的预训练能力和 VITS2 的微调技术&#xff0c;旨在实现高质量的个性化语音合成。 二、模型搭建流程 1. 创建容器实例 进入算家云的“应用社区”&#xff0c;点击搜索找到…...

ceph灾备之cephfs snapshot mirror和rsync对比

背景 最近要做ceph集群之间的灾备功能&#xff0c;主要讨论文件存储&#xff0c;因为ceph集群容量越来越大&#xff0c;接入的业务也越来越多&#xff0c;一旦出现故障&#xff0c;恢复时间都是小时级(根据经验每年都会出现几次这种事故)&#xff0c;对于核心业务无法接受&…...

【工具分享】Plutocrypt勒索病毒解密工具

前言 Plutocrypt勒索软件首次出现在2021年&#xff0c;作为CryptoJoker勒索软件的变种。该恶意软件通过钓鱼邮件和恶意链接传播&#xff0c;主要针对个人和小型企业用户。Plutocrypt使用了.NET框架开发&#xff0c;并依赖AES-256和RSA-4096的加密算法来加密受害者的文件。与Cr…...

IDEA启动提示Downloading pre-built shared indexes

Download pre-built shared indexes Reduce the indexing time and CPU load with pre-built JDK shared indexes 翻译&#xff1a; 下载预构建的共享索引 使用预构建的JDK共享索引减少索引时间和CPU负载. 使用预构建的JDK共享索引可以显著减少索引构建时间和CPU负载&#xf…...

[HCTF 2018]WarmUp 1--详细解析

打开靶机&#xff0c;进入界面&#xff1a; 信息搜集 当前界面没有任何有用信息。 想到查看页面源代码。右键–查看页面源代码 看到hint&#xff1a;<!--source.php--> 进入/source.php页面&#xff0c;看到页面源代码&#xff1a; <?phphighlight_file(__FILE_…...

软考教材重点内容 信息安全工程师 第1章 网络信息安全概述

第 1 章 网络信息安全概述 1.1.1 网络信息安全相关概念 狭义上的网络信息安全特指网络信息系统的各组成要素符合安全属性的要求&#xff0c;即机密性、完整性、可用性、抗抵赖性、可控性。 广义上的网络信息安全是涉及国家安全、城市安全、经济安全、社会安全、生产安全、人身安…...

TOSHIBA 74VHC00FT COMS汽车、工业企业的选择

74VHC00FT 是一种四路双输入 NAND 门&#xff0c;属于 CMOS 系列数字集成电路。它采用东芝先进的硅栅 C2MOS 技术设计&#xff0c;能够实现类似于双极性肖特基 TTL 逻辑电路的高速运行&#xff0c;同时保持 CMOS 器件的低功耗。这种独特的结合使其非常适合需要高性能和低功耗的…...

【Android】使用productFlavors构建多个变体

项目需求 在一个设备上安装两个一样的程序app 需求解决 我们知道每一个app都有一个包名的&#xff0c;如果一个app在Android设备上安装之后&#xff0c;再安装这个app的话会进行覆盖安装&#xff0c;因为他们两个的包名是一样的&#xff0c;默认是一个app。 但是我们现在需…...

ubuntu 22.04 防火墙 ufw

Ubuntu&#xff08;22.04&#xff09;云主机SSH安全加固 https://blog.csdn.net/qq_44846097/article/details/141098092 ubuntu22.04防火墙策略 https://blog.csdn.net/sunyuhua_keyboard/article/details/139493464 Ubuntu 22.04 防火墙设置和开放端口命令 https://blog.c…...

MySQL压缩版安装详细图解

1.下载 mysql压缩包版本和msi版的安装方法不一样&#xff0c;下面的是压缩包版本的安装详细图解&#xff1a; 总地址下载地址&#xff1a;MySQL :: Download MySQL Community Server MySQL :: Download MySQL Community Server (Archived Versions) 压缩版下载MySQL :: Dow…...

elementui中的新增弹窗在新增数据成功后再新增 发现数据无法清除解决方法

elementui中的新增弹窗在新增数据成功后再新增 发现数据无法清除解决方法 试过网上其他方法&#xff0c;发现表单清空数据还是有问题&#xff0c;索性用下面方法解决: // 给弹框里面添加 v-ifvisible测试无问题&#xff0c;暂时先这样解决&#xff0c;如果有其他方法&#x…...

软件开发项目管理:实现目标的实用指南

由于软件项目多数是复杂且难以预测的&#xff0c;对软件开发生命周期的深入了解、合适的框架以及强大的工作管理平台是必不可少的。项目管理系统在软件开发中通常以监督为首要任务&#xff0c;但优秀的项目计划、管理框架和软件工具可以使整个团队受益。 软件开发项目管理的主要…...

Jenkins面试整理-如何在 Jenkins 中进行并行构建?

在 Jenkins 中,并行构建 是通过并行执行多个任务来提高构建效率的常见方法。并行构建特别适用于需要执行多个独立步骤的工作流,如并行测试、构建不同平台上的软件或并行执行多个阶段。Jenkins 提供了两种方式来配置并行构建:Declarative Pipeline 和 Scripted Pipeline。下面…...

DPDK(F-Stack) 实现UDP通信

因刚开始学习DPDK&#xff0c;在学习过程中了解到需使用用户态协议栈&#xff0c;在网上找到F-Stack的相关介绍&#xff0c;但是缺乏DPDK的相关知识&#xff0c;导致使用F-Stack 时UDP数据无法收到 一文了解dpdk rte_ring无锁队列F-Stack实现UDP服务端、客户端&#xff0c;并进…...

基于ExtendSim的库存与订购实验

说明&#xff1a; 库存和订购实验室是一个单部件模拟模型&#xff0c;旨在测试从组件需求站点到组件分发站点的订购策略&#xff0c;以及 在组件分销现场的生产区域内。最佳解决方案允许为需求站点提供高服务级别&#xff0c;同时最大限度地降低总库存水平。 该模型演示了分层模…...

操作系统个人八股文总结

1.进程和线程的区别 进程和线程的定义 进程&#xff1a; 进程是一个运行中的程序实例&#xff0c;是资源分配的基本单位。每个进程都有自己的地址空间、数据、堆栈以及其他辅助数据。线程&#xff1a; 线程是进程中的一个执行单元&#xff0c;是CPU调度的基本单位。一个进程可…...

scala set训练

Set实训内容&#xff1a; 1.创建一个可变Set&#xff0c;用于存储图书馆中的书籍信息&#xff08;假设书籍信息用字符串表示&#xff09;&#xff0c;初始化为包含几本你喜欢的书籍 2.添加两本新的书籍到图书馆集合中&#xff0c;使用操作符 3.删除一本图书馆集合中的书籍&…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…...

XCTF-web-easyupload

试了试php&#xff0c;php7&#xff0c;pht&#xff0c;phtml等&#xff0c;都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接&#xff0c;得到flag...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间&#xff0c; 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点&#xff0c;不需要开启数据库闪回。…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

人机融合智能 | “人智交互”跨学科新领域

本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...