JAVA动态生成excel模板;列自定义下拉框赋值

2023-11-18

哈喽,2023大家开工大吉啊!财源滚滚!

业务需求:需要生成excel模板,且对部分列设置下拉框,进行动态赋值,效果如下:

在这里插入图片描述
拿上图举例:针对省这一列,不是填写,而是选择数据,也就是说我们生成excel文件的时候需要把数据填充到下拉框的列中。

大体逻辑就是:java生成excel文件,在生成excel文件的时候将部分列是设置成下拉框,并赋值。

而在 Java 中,操作 excel 目前有两个主流框架,分别是:

apache 的 poi
Apache POI是基于DOM方式进行解析,将文件直接加载内存,速度较快,适合文件数据量不大的应用场景。它分别对不同格式的文件提供不同的文件解析:

    HSSF:  操作Microsoft Excel格式。
    XSSF:  操作Microsoft Excel  OOXML格式。

HSSF主要用于解析.xls格式的Excel文件,而XSSF主要用于解析.xlsx格式的Excel文件

Java Excel
Java Excel是一开放源码项目,通过它Java开发人员可以操作Excel文件(读取,创建,更新等)。

由于其小巧 易用的特点, 逐渐已经取代了 POI-excel的地位。

HSSFWorkbook:是操作Excel2003以前(包括2003)的版本,扩展名是.xls;

XSSFWorkbook:是操作Excel2007的版本,扩展名是.xlsx。

对于不同版本的EXCEL文档要使用不同的工具类,如果使用错了,会提示如下错误信息:

org.apache.poi.openxml4j.exceptions.InvalidOperationExceptionorg.apache.poi.poifs.filesystem.OfficeXmlFileException

java生成excel文件逻辑:
1:创建excel
2:在excel中创建表格
3:在表格中输入列名
4:输入数据

代码如下

	 //导出标头信息
    List<String> headers = Arrays.asList("客户姓名", "客户联系方式", "服务对象", "联系方式", "性别", "出生日期(yyyy-MM-dd)", "身份证号", "关系", "健康状况", "省", "市", "区", "服务地址详情", "一级来源渠道", "二级来源渠道", "首洽日期(yyyy-MM-dd)");
    
   // 创建workbook;可以理解为excel
    HSSFWorkbook hssfWorkbook = new HSSFWorkbook();
    
   //创建sheet:可以理解为在excel中创建表格
    HSSFSheet sheet = hssfWorkbook.createSheet();
    
   // 创建表头,供用户输入:可以理解为为表格输入列名
    initHeaders(hssfWorkbook, sheet, headers);
	
	//对性别做下拉处理;由标头可知性别位于第五列(下标从0开始,也就是4代表性别)
   String sexType = "sex";
    Map<String, String> sexMap = new HashMap<>();
    //key放性别的字段,value逗号拼接性别的所有值
    sexMap.put(sexType, "男,女,未知");
    // 1000表示该列填充1000行
    HSSFDataValidation sexValidation = ExcelUtil.createBox(sexType, sexMap, 1, 1000, 4, 4);
    if (sexValidation != null) {
        sheet.addValidationData(sexValidation);
    }

    String relationType = "relation";
    Map<String, String> relationTypeMap = new HashMap<>();
    relationTypeMap.put(relationType, relationName);
    HSSFDataValidation relationValidation = ExcelUtil.createBox(relationType, relationTypeMap, 1, 1000, 7, 7);
    if (relationValidation != null) {
        sheet.addValidationData(relationValidation);
    }

	//省市区三级联动处理
    SysCity cityParam = new SysCity();
    List<SysCity> araeList = sysCityMapper.selectSysCityList(cityParam);

    //所有省级信息:去除ID为36的请选择信息
    List<SysCity> proList = araeList.stream().filter(model -> "1".equals(model.getType().toString()) && !"36".equals(model.getId().toString())).collect(Collectors.toList());
    
    HSSFSheet mapSheet = hssfWorkbook.createSheet("MAP");
    hssfWorkbook.setSheetHidden(hssfWorkbook.getSheetIndex(mapSheet), false);
    //所有一级
    List<String> mapOneList = new ArrayList<String>();
    //市区关系
    Map<String, List<String>> map = new HashMap<String, List<String>>();


    proList.stream().forEach(model -> {
        mapOneList.add(model.getCityname());
        //获取对应市级名称信息
        List<String> cityNameList = araeList.stream().filter(as -> (as.getPid().toString()).equals(model.getId().toString())).map(ma -> ma.getCityname()).collect(Collectors.toList());
        map.put(model.getCityname(), cityNameList);
        //获取市级信息
        List<SysCity> cityList = araeList.stream().filter(as -> (as.getPid().toString()).equals(model.getId().toString())).collect(Collectors.toList());
        cityList.stream().forEach(city -> {
            //获取对应市级名称信息
            List<String> conturyNameList = araeList.stream().filter(as -> (as.getPid().toString()).equals(city.getId().toString())).map(ma -> ma.getCityname()).collect(Collectors.toList());
            map.put(city.getCityname(), conturyNameList);
        });


    });

    // 3.写入数据 将数据写入sheet中并做好关联关系
    writeData(hssfWorkbook, mapSheet, mapOneList, map);
    // 4.设置数据有效性
    setDataValid(hssfWorkbook, sheet, mapOneList, map, "1", "so");

    /**
     *
     * 渠道来源二级联动处理
     *
     */

    List<BaseSourceChannel> channelList = new BaseSourceChannel();
    //一级线索
    List<String> fatherMap = new ArrayList<String>();
    //二级线索
    Map<String, List<String>> sonMap = new HashMap<String, List<String>>();
    //一级线索
    List<BaseSourceChannel> parentSourceList = channelList.stream().filter(x -> "1".equals(x.getType())).collect(Collectors.toList());

    parentSourceList.stream().forEach(source -> {
        fatherMap.add(source.getSourceName());
        //一级对应的二级线索
        List<String> sonSourceList = channelList.stream().filter(x -> x.getPid().equals(source.getId())).map(y -> y.getSourceName()).collect(Collectors.toList());

        sonMap.put(source.getSourceName(), sonSourceList);

    });
    HSSFSheet sourceSheet = hssfWorkbook.createSheet("sourceMap");
    writeData(hssfWorkbook, sourceSheet, fatherMap, sonMap);
    setDataValid(hssfWorkbook, sheet, fatherMap, sonMap, "2", "source");


    String filename = UUID.randomUUID().toString() + "_测试模板.xlsx";

    String downloadPath = Global.getDownloadPath() + filename;
    File desc = new File(downloadPath);
    if (!desc.getParentFile().exists()) {
        desc.getParentFile().mkdirs();
    }
    FileOutputStream out = null;
    try {
        out = new FileOutputStream(downloadPath);
        hssfWorkbook.write(out);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (out != null) {
            try {
                out.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    return AjaxResult.success(filename);

好了,代码已经提供,有什么不明白的欢迎互相讨论。

createBox 方法如下

   /**
     *  excel导出,有码值的数据使用下拉框展示。
     * @param col             列名
     * @param boxMap          码值集合
     * @param firstRow        插入下拉框开始行号
     * @param lastRow         插入下拉框结束行号
     * @param firstCol        插入下拉框开始列号
     * @param lastCol         插入下拉框结束行号
     * @return
     */
    public static HSSFDataValidation createBox(String col, Map<String, String> boxMap, int firstRow, int lastRow, int firstCol, int lastCol) {
        HSSFDataValidation dataValidation = null;
        //查询码值表
        String cols = "";
        if(null != boxMap.get(col)) {
            cols = boxMap.get(col);
        }
        //设置下拉框
        if(cols.length() > 0 && null != cols) {
            String str[] = cols.split(",");
            //指定行,列为下拉框
            CellRangeAddressList cas = new CellRangeAddressList(firstRow , lastRow , firstCol , lastCol);
            //创建下拉数据列
            DVConstraint dvConstraint = DVConstraint.createExplicitListConstraint(str);
            //将下拉数据放入下拉框
            dataValidation = new HSSFDataValidation(cas, dvConstraint);
        }
        return dataValidation;
    }

生成页面表头方法:initHeaders

/**
 * 生成主页面表头
 *
 * @param wb
 * @param mainSheet
 * @param headers
 */
private void initHeaders(HSSFWorkbook wb, HSSFSheet mainSheet, List<String> headers) {
    //表头样式
    HSSFCellStyle style = wb.createCellStyle();
    style.setAlignment(HorizontalAlignment.CENTER); // 创建一个居中格式
    //字体样式
    HSSFFont fontStyle = wb.createFont();
    fontStyle.setFontName("微软雅黑");
    fontStyle.setFontHeightInPoints((short) 12);
    style.setFont(fontStyle);
    //生成主内容
    HSSFRow rowFirst = mainSheet.createRow(0);//第一个sheet的第一行为标题
    mainSheet.createFreezePane(0, 1, 0, 1); //冻结第一行
    //写标题
    for (int i = 0; i < headers.size(); i++) {
        HSSFCell cell = rowFirst.createCell(i); //获取第一行的每个单元格
        mainSheet.setColumnWidth(i, 4000); //设置每列的列宽
        cell.setCellStyle(style); //加样式
        cell.setCellValue(headers.get(i)); //往单元格里写数据
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JAVA动态生成excel模板;列自定义下拉框赋值 的相关文章

  • 如果测试用例失败,Selenium Web 驱动程序无法关闭 Firefox 实例

    我各位 我正在使用 junit 和 selenium web 驱动程序 2 28 问题是 如果我运行成功的测试用例 Web 驱动器能够关闭 Firefox 实例 但是当测试用例失败时 Selenium Web 驱动器无法关闭 Firefox
  • 如何在 JFace 的 TableViewer 中创建复选框?

    我创建了一个包含两列的 tableViewer 我想将其中一列设为复选框 为此 我创建了一个 CheckBoxCellEditor 但我不知道为什么它不起作用 名为 tableName 的列显示其值正常 色谱柱规格如下 String COL
  • ElasticBeanstalk Java,Spring 活动配置文件

    我正在尝试通过 AWS ElasticBeanstalk 启动 spring boot jar 一切正常 配置文件为 默认 有谁知道如何为 java ElasticBeanstalk 应用程序 不是 tomcat 设置活动配置文件 spri
  • Java程序中的数组奇怪的行为[重复]

    这个问题在这里已经有答案了 我遇到了这个 Java 程序及其以意想不到的方式运行 以下程序计算 int 数组中元素对之间的差异 import java util public class SetTest public static void
  • 解决错误:日志已在具有多个实例的atomikos中使用

    我仅在使用atomikos的实时服务器上遇到问题 在我的本地服务器上它工作得很好 我在服务器上面临的问题是 init 中出错 日志已在使用中 完整的异常堆栈跟踪 java lang RuntimeException Log already
  • CXF Swagger2功能添加安全定义

    我想使用 org apache cxf jaxrs swagger Swagger2Feature 将安全定义添加到我的其余服务中 但是我看不到任何相关方法或任何有关如何执行此操作的资源 下面是我想使用 swagger2feature 生成
  • 使用 ANTLR 为 java 源代码生成抽象语法树

    如何使用 ANTLR 从 java src 代码生成 AST 有什么帮助吗 好的 步骤如下 前往ANTLR站点 http www antlr org 并下载最新版本 下载Java g和JavaTreeParser g文件来自here htt
  • Java 页面爬行和解析之 Crawler4j 与 Jsoup

    我想获取页面的内容并提取其中的特定部分 据我所知 此类任务至少有两种解决方案 爬虫4j https github com yasserg crawler4j and Jsoup http jsoup org 它们都能够检索页面的内容并提取其
  • 序列化对象以进行单元测试

    假设在单元测试中我需要一个对象 其中所有 50 个字段都设置了一些值 我不想手动设置所有这些字段 因为这需要时间而且很烦人 不知何故 我需要获得一个实例 其中所有字段都由一些非空值初始化 我有一个想法 如果我要调试一些代码 在某个时候我会得
  • 检查 Android 手机上的方向

    如何查看Android手机是横屏还是竖屏 当前配置用于确定要检索的资源 可从资源中获取Configuration object getResources getConfiguration orientation 您可以通过查看其值来检查方向
  • 使用 AWS Java SDK 为现有 S3 对象设置 Expires 标头

    我正在更新 Amazon S3 存储桶中的现有对象以设置一些元数据 我想设置 HTTPExpires每个对象的标头以更好地处理 HTTP 1 0 客户端 我们正在使用AWS Java SDK http aws amazon com sdkf
  • Java直接内存:在自定义类中使用sun.misc.Cleaner

    在 Java 中 NIO 直接缓冲区分配的内存通过以下方式释放 sun misc Cleaner实例 一些比对象终结更有效的特殊幻像引用 这种清洁器机制是否仅针对直接缓冲区子类硬编码在 JVM 中 或者是否也可以在自定义组件中使用清洁器 例
  • 应用程序关闭时的倒计时问题

    我制作了一个 CountDownTimer 代码 我希望 CountDownTimer 在完成时重新启动 即使应用程序已关闭 但它仅在应用程序正在运行或重新启动应用程序时重新启动 因此 如果我在倒计时为 00 10 分钟 秒 时关闭应用程序
  • Tomcat 6找不到mysql驱动

    这里有一个类似的问题 但关于类路径 ClassNotFoundException com mysql jdbc Driver https stackoverflow com questions 1585811 classnotfoundex
  • 使用 SAX 进行 XML 解析 |如何处理特殊字符?

    我们有一个 JAVA 应用程序 可以从 SAP 系统中提取数据 解析数据并呈现给用户 使用 SAP JCo 连接器提取数据 最近我们抛出了一个异常 org xml sax SAXParseException 字符引用 是无效的 XML 字符
  • Windows 上的 Nifi 命令

    在我当前的项目中 我一直在Windows操作系统上使用apache nifi 我已经提取了nifi 0 7 0 bin zip文件输入C 现在 当我跑步时 bin run nifi bat as 管理员我在命令行上看到以下消息 但无法运行
  • 查看Jasper报告执行的SQL

    运行 Jasper 报表 其中 SQL 嵌入到报表文件 jrxml 中 时 是否可以看到执行的 SQL 理想情况下 我还想查看替换每个 P 占位符的值 Cheers Don JasperReports 使用 Jakarta Commons
  • 如何测试 spring-security-oauth2 资源服务器安全性?

    随着 Spring Security 4 的发布改进了对测试的支持 http docs spring io spring security site docs 4 0 x reference htmlsingle test我想更新我当前的
  • 休眠以持久保存日期

    有没有办法告诉 Hibernate java util Date 应该持久保存 我需要这个来解决 MySQL 中缺少的毫秒分辨率问题 您能想到这种方法有什么缺点吗 您可以自己创建字段long 或者使用自定义的UserType 实施后User
  • com.jcraft.jsch.JSchException:身份验证失败

    当我从本地磁盘上传文件到远程服务器时 出现这样的异常 com jcraft jsch JSchException Auth fail at org apache tools ant taskdefs optional ssh Scp exe

随机推荐

  • 刷题day65:分割等和子集

    题意描述 给你一个 只包含正整数 的 非空 数组 nums 请你判断是否可以将这个数组分割成两个子集 使得两个子集的元素和相等 思路 使用01背包 背包的体积为sum 2 背包要放入的商品 集合里的元素 重量为 元素的数值 价值也为元素的数
  • 解决qemu虚拟机图形界面卡死问题

    1 基础环境 Virtio gpu双heads 4 9 0内核 xserver1 9 3 modesettings0 5 0驱动 2 问题描述 终端中打开大量文字内容 不停上下滑动 或cat大量内容的文件 操作过程中用户界面卡死 如下 3
  • 吴恩达深度学习笔记——改善深层神经网络:超参数调整,正则化,最优化(Hyperparameter Tuning)

    深度学习笔记导航 前言 传送门 改善深层神经网络 超参数调整 正则化 最优化 Improving Deep Neural Networks Hyperparameter Tuning Regularization and Optimizat
  • 安装或更新 Android Studio

    在开始用 Jetpack Compose 来编写软件之前 我们需要 1 一台可以联网的电脑 2 安装或更新到 最新版的 Android Studio 3 选择创建 Empty Compose Activity 4 保持版本更新 尝试使用最新
  • Retrofit动态代理+注解+反射简析

    1 定义注解 Get注解 用来定义网络请求类型 Target ElementType METHOD Retention RetentionPolicy RUNTIME public interface Get String value Qu
  • sort()函数的用法说明

    sort 排序是一种简单的快速排序 用于对数组的排序 时间复杂度为n log2 n sort 函数必须是在 cpp 的文件中才能运行 头文件为 include
  • jmeter——BeanShell 预处理程序

    jmeter BeanShell 预处理程序 一 BeanShell 预处理程序描述和作用 二 BeanShell 预处理程序的使用 三 BeanShell 预处理程序的注意事项 四 BeanShell 预处理程序的拓展 一 BeanShe
  • 什么是ADT

    Abstract Data Type 抽象数据类型 是指数据结构作为一个软件组件的实现 ADT的接口用一种类型和该类型上的一组操作来定义 每个操作由它的输入和输出定义 ADT并不会指定数据类型如何实现 这些实现细节对于ADT的用户来说是隐藏
  • php 验证密码大、小写英文字母、数字、特殊字符4选3;且长度大于等于8位

    param password string 明文密码 return array 检测密码合法性 大 小写英文字母 数字 特殊字符 4选3 且长度大于等于8位 function check password legal KaTeX parse
  • pandas把索引变成列

    pandas把索引变成列 只需要使用reset index 这样index就会变成一列变量出现在元数据表中 比如原来的数据表是上面这样 使用reset index 就变成这样 具体reset index 还有一些更细的应用 后续随着学习再继
  • 判断电脑是否插入移动磁盘U盘等并显示结果

    VC 检测判断电脑是否插入移动磁盘U盘等并显示结果 判断手机 U盘 存储卡等设备是否插入到电脑接口中 若检测到某设备 则将设备盘符显示于窗口中 项目源代码 部分代码 程序运行截图
  • 数据库运维之数据库备份的多种方法

    数据库备份 数据库为school 素材如下 1 创建student和score表 CREATE TABLE student id INT 10 NOT NULL UNIQUE PRIMARY KEY name VARCHAR 20 NOT
  • 静态路由及默认路由——基本配置

    拓扑图 原理简述 1 静态路由 是指用户或网络管理员手工配置的路由信息 当网络拓扑结构或链路状态发生改变时 需要网络管理员手工配置静态路由信息 相比较动态路由协议 静态路由无需频繁的交换各自的路由表 配置简单 比较适合小型 简单的网络环境
  • el-switch在按钮内加文字内嵌文字

    产品需求 在按钮内内嵌对应操作文字 原生展示效果 升级展示效果 解决方案 按钮
  • %d, %ld, %lld 区别, %s,%c区别

    相信下面几个表达方式 就能说明问题吧 d int ld long lld long long 在32位编译器上 int long 32bit long long 64bit c是单个字符 也就是用 的 s是字符串 用 的
  • 深入理解SSL VPN

    名词解析 SSL Secure Socket Layer 安全套接字层 TLS Transport Layer Security 传输层安全协议 TLS 1 0是IETF Internet Engineering Task Force In
  • docker-6-docker架构和MySQL容器化的优劣

    1 docker架构 1 开发环境 gt 测试环境 gt 生产环境 2 环境和代码一起放在容器中 解决软件跨环境迁移问题 3 Docker是一个开源的应用容器引擎 4 Docker于2013年基于Go语言实现 5 Docker从17 03版
  • vbox 安装linux64,CentOS 5.8 x64安装VirtualBox-5.0虚拟机

    CentOS 5 8 x64安装VirtualBox 5 0虚拟机 根据自己的环境下载相应的安装包 1 下载并安装for el5 virtualbox虚拟机安装包 安装过程如下 缺依赖包 root lvmtest rpm ivh Virtu
  • html中报错:xxx is not a function

    我今天遇到了一个奇怪的问题 在javascript中写好了一个function 而且之前是可以调用的 例如 在onclick事件中调用 可是新增了一部分代码 也用了onclick调用 但是报错了 不能执行 一直说是xxx is not a
  • JAVA动态生成excel模板;列自定义下拉框赋值

    哈喽 2023大家开工大吉啊 财源滚滚 业务需求 需要生成excel模板 且对部分列设置下拉框 进行动态赋值 效果如下 拿上图举例 针对省这一列 不是填写 而是选择数据 也就是说我们生成excel文件的时候需要把数据填充到下拉框的列中 大体