基于POI的Excel下拉框自动搜索,包括数据验证的单列删除

news2025/3/1 20:24:15

目录

目标

例子

1.搜索下拉框页

2.数据源页

3.效果

代码以及注意事项

1.代码

2.注意事项

1.基于Excel的话,相当于加入了一个【数据验证】

2.代码中的一些方法说明


目标

期望在Excel利用代码创建具备自动搜索功能的下拉框

例子

1.搜索下拉框页

2.数据源页

3.效果

代码以及注意事项

1.代码

package yourpackage;

import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.usermodel.*;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDataValidation;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDataValidations;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class YourClass {
    public static void main(String[] args) throws IOException {
        String pathExcel = "D:\\XXXX\\test.xlsx";
        File file = new File(pathExcel);
        FileInputStream fis = new FileInputStream(file);
        XSSFWorkbook book = new XSSFWorkbook(fis);
        XSSFSheet sheetTaget = book.getSheet("目标");
        XSSFSheet sheetEnum = book.getSheet("待搜索数据源");
        //参数说明:
        //1.目标页; 2.目标页第一行表头的列名【自动搜索的数据】;3.数据页的最后一行;4.数据页的数据所在的列序号 5.数据页的sheet名
        resetDropDownPullerMenuListNoRemoveValidationUpdateFormula(sheetTaget,"自动搜索的数据",sheetEnum.getLastRowNum(),
                "A",sheetEnum.getSheetName());
        //写文件
        FileOutputStream fos = new FileOutputStream(file);
        book.write(fos);
        fos.close();
        fis.close();
    }
    public static void resetDropDownPullerMenuListNoRemoveValidationUpdateFormula(XSSFSheet sheet,
                                                                                          String colunmName, int endNum,String indexEnum,String enumSheetName) {
        HashMap<String, Integer> headMap = getHeadMap(sheet);
        Integer indexTarget = headMap.get(colunmName)+1;
        Map<Integer, String> numToABCMap =  parseColumWithReturn();
        String targetIdexABC = numToABCMap.get(indexTarget);
        String sheetName = sheet.getSheetName();

        //找到原来数据验证项目:indexDelete并删除,否则会堆叠,报错
        CTDataValidations dataValidationsCurrent = sheet.getCTWorksheet().getDataValidations();
        int indexDelete = -1;
        if(null!=dataValidationsCurrent){
            List<CTDataValidation> dataValidationList = dataValidationsCurrent.getDataValidationList();
            for(int i=0;i<dataValidationList.size();i++){
                CTDataValidation ctDataValidation = dataValidationList.get(i);
                String region = ctDataValidation.getSqref().toString();
                //targer colunm
                if(region.startsWith(targetIdexABC)){
                    indexDelete = i;
                    break;
                }
//				//change the rest order
//				int oldIndex = CommonUtils.mapStringToNumber(String.valueOf(region.charAt(0)))+1;
//				if(oldIndex>=indexTarget){
//					String Indexnew = numToABCMap.get(oldIndex + 1);
//					String newRegion = region.replace(String.valueOf(region.charAt(0)),Indexnew);
//					ctDataValidation.setSqref(Collections.singletonList(newRegion));
//				}
            }
        }

        if(-1!=indexDelete){
            dataValidationsCurrent.removeDataValidation(indexDelete);
        }

//		sheet.getCTWorksheet().unsetDataValidations();
        //获取当前页并设置验证【下拉框】,CT=current table
        sheet.getCTWorksheet().setDataValidations(dataValidationsCurrent);

        //add new validation
        sheet.disableLocking();
        XSSFDataValidationHelper helper = (XSSFDataValidationHelper) sheet.getDataValidationHelper();
        Integer indexPhysical = headMap.get(colunmName);
        String indexABC = numToABCMap.get(indexPhysical+1);
        String enumCheetolumIndex = indexEnum;
        //设置搜索公式,该步骤等价于在【数据验证】中,选择序列,然后输入公式
        String offsetFormula = "OFFSET("+enumSheetName+"!$"+enumCheetolumIndex+
                "$1,MATCH(\"*\"&"+indexABC+"2&\"*\","+enumSheetName+"!$"+enumCheetolumIndex+":$"+enumCheetolumIndex+",0)-1,0,COUNTIFS("+enumSheetName
                +"!$"+enumCheetolumIndex+":$"+enumCheetolumIndex+",\"*\"&"+indexABC+"2&\"*\")+1,1)";
        XSSFDataValidationConstraint constraint = (XSSFDataValidationConstraint) helper.createFormulaListConstraint(offsetFormula);
        CellRangeAddressList address = new CellRangeAddressList(1, endNum+1,headMap.get(colunmName),headMap.get(colunmName));
        XSSFDataValidation validationNew = (XSSFDataValidation) helper.createValidation(constraint, address);
        validationNew.setSuppressDropDownArrow(true);
        validationNew.setShowErrorBox(false);
        sheet.addValidationData(validationNew);
    }
    public static HashMap<String, Integer> getHeadMap(XSSFSheet sheet) {
        HashMap<String,Integer> headMap=new HashMap<String, Integer>();
        XSSFRow row = sheet.getRow(0);
        for (int i = 0; i < row.getLastCellNum(); i++) {
            String value = parseCell(row.getCell(i));
            if (value.equals("")) {
                continue;
            }
            headMap.put(value, i);
        }
        return headMap;
    }

    //防止CELL为空
    public static String parseCell(XSSFCell cell) {
        if (cell!=null) {
            CellType cellType = cell.getCellType();
            String cellValue="";
            String tmp ="";
            switch (cellType) {
                case STRING:
                    cellValue= cell.getStringCellValue();
                    break;
                case BOOLEAN:
                    cellValue = String.valueOf(cell.getBooleanCellValue());
                    break;
                case BLANK:
                    cellValue="";
                    break;
                case NUMERIC:
                    cellValue = cell.toString();
                    if(cellValue.contains("E") && cellValue.contains(".")){
//                        String[] split = cellValue.split("\\.");
//                        cellValue = split[0];
                        double number = Double.parseDouble(cellValue);
                        // 创建 DecimalFormat 对象,设置格式模式为不使用科学计数法
                        DecimalFormat df = new DecimalFormat("0.##########");
                        // 格式化数字
                        String result = df.format(number);
                        cellValue = result;
                    }else{
                        if(cellValue.endsWith(".0")){
                            cellValue = cellValue.replace(".0", "");
                        }
                    }
                    break;
                case ERROR:
                    break;
                case FORMULA:
                    tmp=cell.toString();
                    if (tmp.contains(",")) {
                        cellValue = tmp.substring(tmp.indexOf(",")+2,tmp.length()-2);
                    }else {
                        cellValue = tmp;
                    }
                    break;
            }
            return cellValue;
        }else {
            return "";
        }
    }

    public static Map<Integer, String> parseColumWithReturn() {
        Map<Integer,String> outmap = new HashMap<Integer,String>();
        String base="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        char[] charArray = base.toCharArray();
        for (int i = 0; i < 50; i++) {
            if (i<26) {
                outmap.put(i+1, String.valueOf(charArray[i]));
            }else {
                outmap.put(i+1, "A"+String.valueOf(charArray[i-26]));
            }
        }
        return outmap;
    }

}

2.注意事项

1.基于Excel的话,相当于加入了一个【数据验证】
=OFFSET(待搜索数据源!$A$1,MATCH("*"&A2&"*",待搜索数据源!$A:$A,0)-1,0,COUNTIFS(待搜索数据源!$A:$A,"*"&A2&"*")+1,1)

2.代码中的一些方法说明

(1)主要功能函数

resetDropDownPullerMenuListNoRemoveValidationUpdateFormula(XSSFSheet sheet,String colunmName, int endNum,String indexEnum,String enumSheetName)

参数说明:

①.目标页;

②.目标页第一行表头的列名【自动搜索的数据】;

③.数据页的最后一行;

④.数据页的数据所在的列序号

⑤.数据页的sheet名

(2)辅助函数

①getHeadMap(XSSFSheet sheet) 获取表头序列,返回一个Map<String,Integer>

②parseCell(XSSFCell cell) 将任何类型的Cell对象转换成字符串类型

③parseColumWithReturn() 返回一个Map,做数字和字母的映射。比如Excel中,1对应A,2对应B,3对应C

(3)该代码还有一些关于数据验证删除的功能,能删除旧的数据有效性。参考阅读方法:

resetDropDownPullerMenuListNoRemoveValidationUpdateFormula中关于indexDelete并删除的内容

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

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

相关文章

Python 数据可视化(一)熟悉Matplotlib

目录 一、安装包 二、先画个折线图 1、修改标签文字和线条粗细 2、内置样式 3、scatter() 绘制散点图 4、scatter() 绘制多个点 5、设置样式 6、保存绘图 数据可视化指的是通过可视化表示来探索和呈现数据集内的规律。 一、安装包 win R 打开终端 安装 Matplotlib&…

考研出分24小时,人类精神状态图鉴

2月24日&#xff0c;上午10点起&#xff0c;各省考研初试成绩陆续公布&#xff0c;考生们或紧张的输入准考证号&#xff0c;或抱团等待“审判”。然而更魔幻的还在后头——下午4点&#xff0c;教育部竟在同一天直接发布了《2025年研考国家分数线》。 不少网友表示&#xff1a;…

神经网络AI原理回顾

长期记忆存储在大模型的参数权重中&#xff0c;不经过推理和编码无法读取&#xff0c;且必须依赖输入的提示&#xff0c;因为大模型不会无缘无故的自言自语&#xff0c;毕竟输入层是它唯一 与外界交互的窗口。 目前个性化大模型的局限就是训练成本过高&#xff0c;除非使用RAG&…

数据库导出

MySQL数据库 使用命令行导出 导出整个数据库&#xff1a;在命令行中输入mysqldump -u用户名 -p密码 数据库名 > 导出文件路径/文件名.sql。例如mysqldump -uroot -p123456 mydb > /home/user/mydb_backup.sql&#xff0c;回车后输入密码即可将名为mydb的数据库导出为SQL…

进程间通信 —— 共享内存

目录 1.共享内存实现通信的原理 2.如何使用共享内存实现通信 共享内存通信接口介绍 shmget shmat shmdt shmctl 使用示例 key和shmid 3.共享内存通信的优缺点 缺点&#xff1a;不提供任何同步机制&#xff0c;可能会造成数据混乱。 优点&#xff1a;共享内存是进程…

本地搭建dify结合ollama+deepseek方法详解

1.安装ollama,安装deepseek-r1:8b模型 2.安装dify社区版 访问Dify GitHub项目地址 git clone https://github.com/langgenius/dify.git cd dify/docker cp .env.example .env docker compose up -d docker compose ps 查重以下实例是否启动成功&#xff1a; 更新Dif…

Linux系统软件管理

systemctl 控制软件启动和关闭 Linux系统很多软件支持使用systemctl命令控制&#xff1a;启动&#xff0c;停止&#xff0c;开启自启。 能被systemctl管理的软件&#xff0c;一般被称为&#xff1a;服务。 语法&#xff1a;systemctl start|stop|status|enable|disable 服务名…

在Linux桌面上创建Idea启动快捷方式

1、在桌面新建idea.desktop vim idea.desktop [Desktop Entry] EncodingUTF-8 NameIntelliJ IDEA CommentIntelliJ IDEA Exec/home/software/idea-2021/bin/idea.sh Icon/home/software/idea-2021/bin/idea.svg Terminalfalse TypeApplication CategoriesApplication;Developm…

从0开始的操作系统手搓教程19:构建我们的内存管理——第二步:内存子系统进化,获取页!

目录 讨论页表的分析和索引的完成 完成一个宽泛的页获取 从指定的内存池中分配若干页 获取准备用来提供给客户端方向的虚拟地址起始位置 根据内存池的选择&#xff0c;完成对物理内存的获取 关联我们的物理内存和虚拟内存 编写尝试 运行的截图 现在&#xff0c;我们将会…

数学软件Matlab下载|支持Win+Mac网盘资源分享

如大家所了解的&#xff0c;Matlab与Maple、Mathematica并称为三大数学软件。Matlab应用广泛&#xff0c;常被用于数据分析、无线通信、深度学习、图像处理与计算机视觉、信号处理、量化金融与风险管理、机器人&#xff0c;控制系统等领域。 Matlab将数值分析、矩阵计算、科学…

FASIONAD:自适应反馈的类人自动驾驶中快速和慢速思维融合系统

24年11月来自清华、早稻田大学、明尼苏达大学、多伦多大学、厦门大学马来西亚分校、电子科大&#xff08;成都&#xff09;、智平方科技和河南润泰数字科技的论文“FASIONAD : FAst and Slow FusION Thinking Systems for Human-Like Autonomous Driving with Adaptive Feedbac…

R语言+AI提示词:贝叶斯广义线性混合效应模型GLMM生物学Meta分析

全文链接&#xff1a;https://tecdat.cn/?p40797 本文旨在帮助0基础或只有简单编程基础的研究学者&#xff0c;通过 AI 的提示词工程&#xff0c;使用 R 语言完成元分析&#xff0c;包括数据处理、模型构建、评估以及结果解读等步骤&#xff08;点击文末“阅读原文”获取完整代…

2020年蓝桥杯Java B组第二场题目+部分个人解析

#A&#xff1a;门牌制作 624 解一&#xff1a; public static void main(String[] args) {int count0;for(int i1;i<2020;i) {int ni;while(n>0) {if(n%102) {count;}n/10;}}System.out.println(count);} 解二&#xff1a; public static void main(String[] args) {…

【Azure 架构师学习笔记】- Azure Databricks (13) -- 搭建Medallion Architecture part 1

本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Databricks】系列。 接上文 【Azure 架构师学习笔记】- Azure Databricks (12) – Medallion Architecture简介 前言 上文已经介绍了关于Medallion的知识&#xff0c;本文开始用ADB 来实现&#xff0c; 但是基于内容较…

2025年2月21日优雅草内测分发站全新升级-测试运营-优雅草内测分发站新用户提供免费100下载点-2月28日正式运营并且提供私有化部署版本

2025年2月21日优雅草内测分发站全新升级-测试运营-优雅草内测分发站新用户提供免费100下载点-2月28日正式运营并且提供私有化部署版本 说明 优雅草内测分发站新用户提供免费100下载点&#xff0c;优雅草分运营站和demo测试站 运营站&#xff1a;www.youyacao.cn 提供免费100…

通过 PromptTemplate 生成干净的 SQL 查询语句并执行SQL查询语句

问题描述 在使用 LangChain 和 Llama 模型生成 SQL 查询时&#xff0c;遇到了 sqlite3.OperationalError 错误。错误信息如下&#xff1a; OperationalError: (sqlite3.OperationalError) near "sql SELECT Name FROM MediaType LIMIT 5; ": syntax error [SQL: …

IP段转CIDR:原理Java实现

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…

[STM32]从零开始的STM32 DEBUG问题讲解及解决办法

一、前言 最近也是重装了一次keil&#xff0c;想着也是重装了&#xff0c;也是去官网下载了一个5.41的最新版&#xff0c;在安装和配置编译器和别的版本keil都没太大的区别&#xff0c;但是在调试时&#xff0c;遇到问题了&#xff0c;在我Debug的System Viewer窗口中没有GPIO&…

MySQL当中的Lock

1. 总览锁的类型 锁的类型&#xff1a; 锁类型 符号/缩写 描述 全局锁 FTWRL 锁定整个数据库&#xff08;FLUSH TABLES WITH READ LOCK&#xff09;&#xff0c;用于全库备份。 表级锁 - 表锁 S/X LOCK TABLES ... READ&#xff08;共享锁&#xff09;或 WRITE&#…

electron-builder打包时github包下载失败【解决办法】

各位朋友们&#xff0c;在使用electron开发时&#xff0c;选择了electron-builder作为编译打包工具时&#xff0c;是否经常遇到无法从github上下载依赖包问题&#xff0c;如下报错&#xff1a; Get "https://github.com/electron/electron/releases/download/v6.1.12/ele…