使用Java写入Excel下拉选择框选项过多不显示问题

2023-11-10

1.问题描述

工作中遇到需要使用Java poi读写Excel文件的问题,因为需求中有要求在写文件时创建下拉选择框。按照传统的直接使用List集合保存下拉选择框的选项,再通过poi本身的方法将选择框的选项添加到下拉框中。

一开始编写demo测试时只有几个选项,可以正确的添加下拉框。后来把方法搬到项目中,发现创建的文件中的下拉框的选项数据不能正确的显示。通过对比两个文件,发现唯一的不同点就是下拉框选项的数量存在差异。通过一番查询,发现poi添加下拉框选项的数量被控制在20个以内(官方说法好像是256个字节?记不太清楚了,如果说错了,请大佬批评指正orz)

2.选项数量(<=20)较少的方法

  • 向Excel中写数据,简单样例

    /**
         * 将lines的内容写入excel中
         *
         * @param outputPath excel存放路径
         * @param lines      需要写入execl的文件
         * @throws IOException
         */
        public synchronized void writeInExcel(String outputPath, Collection<String[]> lines) throws IOException {
    
            @SuppressWarnings("resource")
            Workbook workbook = new XSSFWorkbook();
            Sheet sheet = workbook.createSheet();
            // 写入Excel表格开头
            Row firstRow = sheet.createRow(0);
            ArrayList<String> arrayList = new ArrayList<String>();
            String[] excelHeadList = {"a","b","c","d","e"};
            for (int i = 0; i < excelHeadList.length; i++) {
                arrayList.add(excelHeadList[i]);
            }
            String[] arr = new String[arrayList.size()];
            for (int i = 0; i < arrayList.size(); i++) {
                arr[i] = arrayList.get(i);
            }
            writeInRow(firstRow, arr);
    
            if (lines != null && lines.size() > 0) {
                // 写入Excel表格内容
                AtomicInteger i = new AtomicInteger(1);
                lines.forEach(line -> {
                    Row row = sheet.createRow(i.get());
                    writeInRow(row, line);
                    i.set(i.incrementAndGet());
                });
                DataValidationHelper helper = sheet.getDataValidationHelper();
                // 创建审核结果下拉框
                createDropDownBox(sheet, helper, checkResultList, 1, i.get() - 1, arr.length - 6, arr.length - 6);
            }
            // 写入指定的文件
            workbook.write(new FileOutputStream(outputPath));
        }
    
  • 给Excel添加下拉框的方法

    /**
         * 给Excel的添加下拉框
         *
         * @param sheet
         * @param helper
         * @param list     下拉框需要的数据
         * @param firstRow 首行
         * @param lastRow  尾行
         * @param firstCol 首列
         * @param lastCol  尾列
         */
        private void createDropDownBox(Sheet sheet, DataValidationHelper helper, String[] list, int firstRow, int lastRow,
                                       int firstCol, int lastCol) {
            CellRangeAddressList addressList = new CellRangeAddressList(firstRow, lastRow, firstCol, lastCol);
    
            DataValidationConstraint constraint = helper.createExplicitListConstraint(list);
            DataValidation validation = helper.createValidation(constraint, addressList);
            if (validation instanceof XSSFDataValidation) {
                validation.setSuppressDropDownArrow(true);
                validation.setShowErrorBox(true);
            } else {
                validation.setSuppressDropDownArrow(false);
            }
            sheet.addValidationData(validation);
        }
    
  • 把数组的内容写到Excel的行

    /**
         * 将数组中的内容写入excel的行
         *
         * @param row  行
         * @param line 需要写入的数据
         */
        public static void writeInRow(Row row, String[] line) {
            if (line != null) {
                for (int i = 0; i < line.length; i++) {
                    Cell cell = row.createCell(i);
                    cell.setCellValue(line[i]);
                }
            }
        }
    

通过以上三个方法就可以实现向Excel中写入数据,并给指定的列添加下拉框

  • 全部代码

    package com.learning;
    
    import org.apache.poi.hssf.util.CellRangeAddressList;
    import org.apache.poi.ss.usermodel.*;
    import org.apache.poi.xssf.usermodel.XSSFDataValidation;
    import org.apache.poi.xssf.usermodel.XSSFWorkbook;
    
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Collection;
    import java.util.List;
    import java.util.concurrent.atomic.AtomicInteger;
    
    /**
     * @author: alex
     * @date: 2020/8/7 下午5:55
     */
    
    public class Test {
        /**
         * 将lines的内容写入excel中
         *
         * @param outputPath excel存放路径
         * @param lines      需要写入execl的文件
         * @throws IOException
         */
        public synchronized void writeInExcel(String outputPath, Collection<String[]> lines) throws IOException {
    
            @SuppressWarnings("resource")
            Workbook workbook = new XSSFWorkbook();
            Sheet sheet = workbook.createSheet();
            // 写入Excel表格开头
            Row firstRow = sheet.createRow(0);
            ArrayList<String> arrayList = new ArrayList<>();
            // 创建单元格标题数组
            String[] excelHeadList = {"row1","row2","row3","row4","row5"};
            for (int i = 0; i < excelHeadList.length; i++) {
                arrayList.add(excelHeadList[i]);
            }
            String[] arr = new String[arrayList.size()];
            for (int i = 0; i < arrayList.size(); i++) {
                arr[i] = arrayList.get(i);
            }
            writeInRow(firstRow, arr);
    
            String[] selectList = {"option1","option2","option3","option4","option5"};
    
            if (lines != null && lines.size() > 0) {
                // 写入Excel表格内容
                AtomicInteger i = new AtomicInteger(1);
                lines.forEach(line -> {
                    Row row = sheet.createRow(i.get());
                    writeInRow(row, line);
                    i.set(i.incrementAndGet());
                });
                DataValidationHelper helper = sheet.getDataValidationHelper();
                // 创建审核结果下拉框
                createDropDownBox(sheet, helper, selectList, 1, i.get() - 1, arr.length - 6, arr.length - 6);
            }
            // 写入指定的文件
            workbook.write(new FileOutputStream(outputPath));
        }
    
        /**
         * 给Excel的添加下拉框
         *
         * @param sheet
         * @param helper
         * @param list     下拉框需要的数据
         * @param firstRow 首行
         * @param lastRow  尾行
         * @param firstCol 首列
         * @param lastCol  尾列
         */
        private void createDropDownBox(Sheet sheet, DataValidationHelper helper, String[] list, int firstRow, int lastRow,
                                       int firstCol, int lastCol) {
            CellRangeAddressList addressList = new CellRangeAddressList(firstRow, lastRow, firstCol, lastCol);
    
            DataValidationConstraint constraint = helper.createExplicitListConstraint(list);
            DataValidation validation = helper.createValidation(constraint, addressList);
            if (validation instanceof XSSFDataValidation) {
                validation.setSuppressDropDownArrow(true);
                validation.setShowErrorBox(true);
            } else {
                validation.setSuppressDropDownArrow(false);
            }
            sheet.addValidationData(validation);
        }
    
        /**
         * 将数组中的内容写入excel的行
         *
         * @param row  行
         * @param line 需要写入的数据
         */
        public static void writeInRow(Row row, String[] line) {
            if (line != null) {
                for (int i = 0; i < line.length; i++) {
                    Cell cell = row.createCell(i);
                    cell.setCellValue(line[i]);
                }
            }
        }
    
        public static void main(String[] args) {
            System.out.println("hello world!!");
            Test test = new Test();
            List<String[]> list = new ArrayList<>();
            String[] strings = {"aaa","bbb","ccc","ddd","eee"};
            list.add(strings);
            try {
                test.writeInExcel("result/test.xlsx",list);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    

实现效果如下图所示:
实现下拉框

3.下拉框选项的数量超过了20个

上边的方法只适用于下拉框选项的数量在20个以内的情况,如果选项的数量超过了20个,那么需要使用隐藏sheet的方式来实现。即:使用一个隐藏的sheet表来存储下拉框的选项数量,再通过定位引用的方式来获取到选项的值。

只需要在上面的writeInExcel方法中增加下面的代码段嘛,即可实现在Excel中创建一个隐藏的sheet。

// 创建一个隐藏的sheet,存放下拉框选项
Sheet hiddenSheet = workbook.createSheet("hiddenSelect");
//  把下拉框列表数据放进隐藏sheet
Cell cell = null;
for (int i = 0; i < selectList.length; i++) {
   Row row = hiddenSheet.createRow(i);
   cell = row.createCell(0);
   cell.setCellValue(selectList[i]);
}
Name nameCell = workbook.createName();
nameCell.setNameName(hiddenSheet.getSheetName());
nameCell.setRefersToFormula(hiddenSheet.getSheetName() + "!$A$1:$A$" + selectList.length);
workbook.setSheetHidden(workbook.getSheetIndex(hiddenSheet), true);

创建了隐藏的sheet,并进行定位之后,我们还需要对createDropDownBox方法进行修改:

/**
     * 给Excel的添加下拉框
     *
     * @param sheet
     * @param helper
     * @param list     下拉框需要的数据
     * @param firstRow 首行
     * @param lastRow  尾行
     * @param firstCol 首列
     * @param lastCol  尾列
     */
private void createDropDownBox(Sheet sheet, DataValidationHelper helper, String[] list, int firstRow, int lastRow,
                               int firstCol, int lastCol) {
   CellRangeAddressList addressList = new CellRangeAddressList(firstRow, lastRow, firstCol, lastCol);
   DataValidationConstraint constraint = null;
   DataValidation validation = null;
   // 为了适配xls和xlsx不同版本的Excel(即2003和2007版本的)
   if (sheet instanceof XSSFSheet || sheet instanceof SXSSFSheet) {
      constraint = helper.createFormulaListConstraint(hiddenSheet.getSheetName());
      validation = helper.createValidation(constraint, addressList);
   } else {
      constraint = DVConstraint.createFormulaListConstraint(hiddenSheet.getSheetName());
      validation = new HSSFDataValidation(addressList, constraint);
   }
   if (validation instanceof XSSFDataValidation) {
      validation.setSuppressDropDownArrow(true);
      validation.setShowErrorBox(true);
   } else {
      validation.setSuppressDropDownArrow(false);
   }
   sheet.addValidationData(validation);
}

通过以上的方法就可以实现超过20个选项数量的下拉框的创建。
真正用到项目中,还发现了一个问题:在2003版的Exce(即后缀名为:xls)中是可以看见隐藏sheet表的名称的,但是在新版的Office中(即后缀名为:xlsx)中,是看不见隐藏sheet表的。如下图所示:
hideenSelect下拉框选项

我还是太菜了,不知道是什么原因。如果有大佬知道,请指教。

如果有错误欢迎大家指出,有疑问欢迎交流讨论!

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

使用Java写入Excel下拉选择框选项过多不显示问题 的相关文章

  • 比较两个文本文件的最快方法是什么,不将移动的行视为不同

    我有两个文件非常大 每个文件有 50000 行 我需要比较这两个文件并识别更改 然而 问题是如果一条线出现在不同的位置 它不应该显示为不同的 例如 考虑这个文件A txt xxxxx yyyyy zzzzz 文件B txt zzzzz xx
  • 运行具有外部依赖项的 Scala 脚本

    我在 Users joe scala lib 下有以下 jar commons codec 1 4 jar httpclient 4 1 1 jar httpcore 4 1 jar commons logging 1 1 1 jar ht
  • 按第一列排序二维数组,然后按第二列排序

    int arrs 1 100 11 22 1 11 2 12 Arrays sort arrs a b gt a 0 b 0 上面的数组已排序为 1 100 1 11 2 12 11 22 我希望它们按以下方式排序a 0 b 0 首先 如果
  • 使用 AES SecretKey 的 Java KeyStore setEntry()

    我目前正在 Java 中开发一个密钥处理类 特别是使用 KeyStore 我正在尝试使用 AES 实例生成 SecretKey 然后使用 setEntry 方法将其放入 KeyStore 中 我已经包含了代码的相关部分 The KS Obj
  • 如何模拟从抽象类继承的受保护子类方法?

    如何使用 Mockito 或 PowerMock 模拟由子类实现但从抽象超类继承的受保护方法 换句话说 我想在模拟 doSomethingElse 的同时测试 doSomething 方法 抽象超类 public abstract clas
  • 画透明圆,外面填充

    我有一个地图视图 我想在其上画一个圆圈以聚焦于给定区域 但我希望圆圈倒转 也就是说 圆的内部不是被填充 而是透明的 其他所有部分都被填充 请参阅这张图片了解我的意思 http i imgur com zxIMZ png 上半部分显示了我可以
  • Excel 数字缩写格式

    这是我想要完成的任务 Value Display 1 1 11 11 111 111 1111 1 11k 11111 11 11k 111111 111 11k 1111111 1 11M 11111111 11 11M 11111111
  • hibernate锁等待超时超时;

    我正在使用 Hibernate 尝试模拟对数据库中同一行的 2 个并发更新 编辑 我将 em1 getTransaction commit 移至 em1 flush 之后我没有收到任何 StaleObjectException 两个事务已成
  • 输入新行并复制上面单元格中的公式

    我正在尝试创建一个 Excel 宏来执行以下操作 在文档末尾输入新行 复制上面单元格中的公式 到目前为止我有这个 Sub New Delta Go to last cell Range A4 Select Selection End xlD
  • 在 Netbeans 8 上配置 JBoss EAP 的问题

    我已经下载了 JBoss EAP 7 并正在 Netbeans 8 上配置它 我已经到达向导 实例属性 其中要求从选择框中选择 域 当我打开选择框时 它是空的 没有什么可以选择的 因此 完成 按钮也处于非活动状态 这使得无法完成配置 我通过
  • 两个日期之间的小时数在 Excel 中不起作用

    根据要求 我提供了一张简化的屏幕截图来说明该问题 如您所见 我减去了两个日期并将其格式化为 h mm ss 为什么这不能提供两个日期之间经过的总小时数 有一个更好的方法吗 下面有一个很好的答案 但我试图弄清楚为什么按照此屏幕截图中所示的方式
  • Java 8 流 - 合并共享相同 ID 的对象集合

    我有一系列发票 class Invoice int month BigDecimal amount 我想合并这些发票 这样我每个月都会收到一张发票 金额是本月发票金额的总和 例如 invoice 1 month 1 amount 1000
  • Java 中的“Lambdifying”scala 函数

    使用Java和Apache Spark 已用Scala重写 面对旧的API方法 org apache spark rdd JdbcRDD构造函数 其参数为 AbstractFunction1 abstract class AbstractF
  • 以编程方式在java的resources/source文件夹中创建文件?

    我有两个资源文件夹 src 这是我的 java 文件 资源 这是我的资源文件 图像 properties 组织在文件夹 包 中 有没有办法以编程方式在该资源文件夹中添加另一个 properties 文件 我尝试过这样的事情 public s
  • 如何知道抛出了哪个异常

    我正在对我们的代码库进行审查 有很多这样的陈述 try doSomething catch Exception e 但我想要一种方法来知道 doSomething 抛出了哪个异常 在 doSomething 的实现中没有 throw 语句
  • Struts 2 + Sitemesh 3 集成 - FreemarkerDecoratorServlet 中的 NPE

    我将 Struts 2 版本 2 3 14 3 与 Sitemesh 3 版本 3 0 alpha 2 一起使用 并且在某些情况下遇到 NullPointerException 首先 这是我的 web xml 中的 struts2 site
  • Netty:阻止调用以获取连接的服务器通道?

    呼吁ServerBootstrap bind 返回一个Channel但这不是在Connected状态 因此不能用于写入客户端 Netty 文档中的所有示例都显示写入Channel从它的ChannelHandler的事件如channelCon
  • 游戏内的java.awt.Robot?

    我正在尝试使用下面的代码来模拟击键 当我打开记事本时 它工作正常 但当我打开我想使用它的游戏时 它没有执行任何操作 所以按键似乎不起作用 我尝试模拟鼠标移动和点击 这些动作确实有效 有谁知道如何解决这个问题 我发现这个问题 如何在游戏中使用
  • javafx android 中的文本字段和组合框问题

    我在简单的 javafx android 应用程序中遇到问题 问题是我使用 gradle javafxmobile plugin 在 netbeans ide 中构建了非常简单的应用程序 其中包含一些文本字段和组合框 我在 android
  • 带有 Maven Wrapper 的 Java 17 导致无法识别的 VM 选项“MaxPermSize=512m”

    I use OpenJDK 17 https jdk java net 17 使用 Maven Wrapper 3 8 2 从春季初始化 https start spring io Maven项目 JAR打包 Java 17 Spring

随机推荐

  • nfs文件服务器错误码5,使用5.4内核最新代码后作为nfs服务器只能列出共享的文件夹名称,点进去不能显示内容...

    反馈bug 问题模板 提建议请删除 1 关于你要提交的问题 Q 是否搜索了issue 使用 x 选择 没有类似的issue 2 详细叙述 1 具体问题 A 使用5 4内核最新代码后作为nfs服务器只能列出如 mnt sda3的共享的文件夹名
  • 【hortonworks/registry】诡异问题之启动了却无法访问

    1 背景 本地mac启动了registry 但是却无法访问页面 lcc lcc soft registry hortonworks registry 0 9 0 bin registry start lcc lcc
  • osgEarth的Rex引擎原理分析(一二八)rex的引擎和图层投影及其关系

    目标 一二七 中问题214 主要存在三个地方 一是map的type属性 可取两个值geocentric projected 前者用于三维显示 后者用于二维显示 二是map的options属性的srs 可以取spherical mercato
  • 用户复购行为预测--数据挖掘分析案例(天池/python)

    阿里天池新人赛中的一个 记录分享 Repeat Buyers Prediction Challenge the Baseline 天池大赛 阿里云天池 第一次提交 8简单特征 随机森林模型 score 0 5507327 排名 278 第二
  • vue3 父子组件传值 记录

    最近这个组件之间传值用的较多 我这该死的记性 总给忘记写法 特此记录下 第一种 父传子 补充 LeftView vue 是父组件 Video vue 是子组件 第二种 子传父 Video vue 子组件 第一步 引入 import defi
  • PHP Advent 2011:带有CORS的跨域Ajax

    I ve had the honor of writing for this year s PHP Advent blessing you all about Cross Origin Requests with CORS 我很荣幸为今年P
  • nginx中间件漏洞复现

    nginx中间件漏洞复现 nginx介绍 Nginx engine x 是一个高性能的HTTP和反向代理web服务器 同时也提供了IMAP POP3 SMTP服务 Nginx是由伊戈尔 赛索耶夫为俄罗斯访问量第二的Rambler ru站点
  • VMware虚拟机中调用本机摄像头详解

    本机环境 虚拟机 VMware Workstation 16 Player 虚拟机内系统 Centos7 其它也ok的 本机 win10 任何系统都ok 调用本机摄像头 首先wins R输入services msc 打开本地服务列表 确保
  • Java图片透明度调整

    package com image import java awt AlphaComposite import java awt BorderLayout import java awt Graphics import java awt G
  • Java 实现 Base64 加密&解密方法

    1 Base64 加密算法 1 1 标准 Base64 算法 Base64 编码是程序开发中比较常用的一种编码算法 是常用来存储或传输一些二进制数据的方法 也是 MIME 多用途互联网邮件扩展 中的一种编码方法 Base64 可以实现将任何
  • Spring Boot - swagger2 整合

    swagger官网 https swagger io 一 引入依赖
  • 怎么用系统做固定资产管理

    企业如何高效地管理其固定资产已成为了一个不容忽视的问题 传统的资产管理方式往往依赖于人力和纸质记录 这种方式不仅效率低下 而且容易出错 因此 引入一个先进的固定资产管理系统显得尤为重要 本文将探讨如何使用系统进行固定资产管理 并提出一些创新
  • win7无法访问服务器共享文件夹解决办法

    方案 今天的工作本来安排的好好的 本来都已经在开始高效的做事情了 因为服务器要安装一个驱动程序 在安装好了之后结果发现自己的电脑再也没有办法连接到服务器的共享了 真是恼火 造理说我也是可什么设置都没有动过啊 我就只是用下网络的共享服务而已那
  • Eclipse配置

    一 eclipse安装时选择的专门开发java项目的Eclipse IDE for Java Developers 因此没有new Dynamic Web Project 属于JavaEE 选项 方法1 直接安装JavaEE版本eclips
  • 开源ehr系统_国家通过开源EHR节省数百万美元

    开源ehr系统 自从2009年成为 经济和临床健康卫生信息技术 HITECH 法案 的基石以来 电子健康记录 EHR 在美国卫生系统中已无处不在 EHR使医疗保健提供者可以跟踪患者的医疗数据 并与其他授权方共享 VistA是美国退伍军人事务
  • orz项目编译的要点

    Orz 0 4 0 AllInOne iso 的编译指导 其实也没有什么需要指导的 只是想说明 这个过程是很容易的 要有信心 下载到Orz 0 4 0 AllInOne iso之后 按照文档readme hta来操作 因为这是个很老的教材
  • 2008.06.02 读华为前执行副总裁李玉琢的《我与商业领袖的合作与冲突》有感(三)

    理解一下书中提到的几点管理思想 和大家一起分享 1 柳传志的 搭班子 定战略 带队伍 这里需要注意的是搭班子 定战略 带队伍顺序不可乱 为什么这样说 一个组织只有先存在核心 才可能确定明确的战略 不同的核心 定出来的战略就可能不一样 因此是
  • 力扣202.快乐数(java语言HashSet方法,类双指针方法)

    前言 此题被分类到散列表算法题目中 但乍一看此题实在想不到如何去使用散列表 直到看了官方给的答案 题目描述 编写一个算法来判断一个数 n 是不是快乐数 快乐数 定义为 对于一个正整数 每一次将该数替换为它每个位置上的数字的平方和 然后重复这
  • 2021年度

    践行开源共创的精神 FISCO BCOS开源社区致力打造开放多元的开源联盟链生态 目前 社区已汇聚了超70000名社区用户 大家聚集于此碰撞观点 交流技术 围绕FISCO BCOS开发各类实用的应用组件 持续优化项目 并自发输出技术解析 使
  • 使用Java写入Excel下拉选择框选项过多不显示问题

    1 问题描述 工作中遇到需要使用Java poi读写Excel文件的问题 因为需求中有要求在写文件时创建下拉选择框 按照传统的直接使用List集合保存下拉选择框的选项 再通过poi本身的方法将选择框的选项添加到下拉框中 一开始编写demo测