使用easyexcel实现单元格样式设置和下拉框设置

news2025/3/15 8:50:08

1.单元格样式设置

1.1实体类

public class DemoData {

    @ExcelProperty("PK")
    private String name;

    @ExcelProperty("年龄")
    private int age;

    // 必须提供无参构造方法
    public DemoData() {}

    public DemoData(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
// 省略 getter/setter
}

1.2启动类

public class ExcelExporter {
    public static void main(String[] args) {
        String fileName = "D:\\idea代码\\demo1\\src\\main\\resources\\example3.xlsx";

        List<com.example.demo1.com.liyingjie.mapper.ExcelExporter.DemoData> dataList = new ArrayList<>();
        dataList.add(new com.example.demo1.com.liyingjie.mapper.ExcelExporter.DemoData("姓名", 20));
        dataList.add(new com.example.demo1.com.liyingjie.mapper.ExcelExporter.DemoData("姓名", 30));
        EasyExcel.write(fileName, DemoData.class)
                .registerWriteHandler(new HeaderBackgroundColorHandler())
                .sheet("Sheet1")
                .doWrite(dataList);
    }
}

1.3自定义拦截器

public class HeaderBackgroundColorHandler implements CellWriteHandler {

    private  Set<String> targetHeaders;  // 目标表头集合
    private  String targetHeader1="PK";
    private  String targetHeader2="主";
    
    @Override
    public void afterCellDispose(CellWriteHandlerContext context) {
        boolean isHead = context.getHead() != null && context.getHead();
        // 处理表头行
        if (isHead) {
            String headerValue = context.getFirstCellData().getStringValue();
            if (headerValue.trim().contains(targetHeader1) || headerValue.trim().contains(targetHeader2)) {
                // 获取或创建样式
                WriteCellStyle writeCellStyle = context.getFirstCellData().getOrCreateStyle();
                // 设置背景色
                writeCellStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
                writeCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
                // 设置字体样式
                WriteFont writeFont = new WriteFont();
                writeFont.setBold(true);  // 加粗
                writeFont.setColor(IndexedColors.BLACK.getIndex());  // 字体颜色
                writeCellStyle.setWriteFont(writeFont);
            }
        }

    }

}

2 下拉框设置

2.1实体类

public class Employee {
    @ExcelProperty("姓名")
    private String name;
    // 姓名
    @ExcelProperty("部门")
    private String department; // 部门
    @ExcelProperty("职位")
    private String position; // 职位

    // 无参构造函数
    public Employee() {
    }

    // 全参构造函数
    public Employee(String name, String department, String position) {
        this.name = name;
        this.department = department;
        this.position = position;
    }

    // Getter和Setter方法
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDepartment() {
        return department;
    }

    public void setDepartment(String department) {
        this.department = department;
    }

    public String getPosition() {
        return position;
    }

    public void setPosition(String position) {
        this.position = position;
    }

    // toString方法
    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", department='" + department + '\'' +
                ", position='" + position + '\'' +
                '}';
    }
}
public class Department {
    @ExcelProperty(value = "部门")
 private String departmentName; // 部门名称

    @ExcelProperty(value = "职位")
    private String position; // 职位

    // 无参构造函数
    public Department() {
    }

    // 全参构造函数
    public Department(String departmentName, String position) {
        this.departmentName = departmentName;
        this.position = position;
    }

    // Getter和Setter方法
    public String getDepartmentName() {
        return departmentName;
    }

    public void setDepartmentName(String departmentName) {
        this.departmentName = departmentName;
    }

    public String getPosition() {
        return position;
    }

    public void setPosition(String position) {
        this.position = position;
    }

    // toString方法
    @Override
    public String toString() {
        return "Department{" +
                "departmentName='" + departmentName + '\'' +
                ", position='" + position + '\'' +
                '}';
    }
}

2.2自定义拦截器

public class DynamicDropDownHandler implements SheetWriteHandler {
    // 字典数据格式: Map<表头名称, Map<Key, Value>> 
    private final Map<String, Map<Integer, String>> dictDataMap;
    // 新增:传入的表头数据
    private final List<List<String>> listHead;

    public DynamicDropDownHandler(Map<String, Map<Integer, String>> dictDataMap, List<List<String>> listHead) {
        this.dictDataMap = dictDataMap;
        this.listHead = listHead;
    }

    @Override
    public void afterSheetCreate(SheetWriteHandlerContext context) {
        Sheet sheet = context.getWriteSheetHolder().getSheet();
        DataValidationHelper helper = sheet.getDataValidationHelper();

        // 1. 直接使用传入的表头数据,跳过映射逻辑
        Map<String, Integer> headerMap = new HashMap<>();
        for (int i = 0; i < listHead.size(); i++) {
            List<String> headers = listHead.get(i);
            if (!headers.isEmpty()) {
                headerMap.put(headers.get(0), i); // 取每个 List<String> 的第一个元素作为表头名称
            }
        }

        // 2. 遍历字典数据,设置下拉框
        for (Map.Entry<String, Map<Integer, String>> entry : dictDataMap.entrySet()) {
            String headerName = entry.getKey();
            Map<?, ?> optionsMap = entry.getValue();

            // 如果当前 Sheet 存在该表头,则设置下拉框
            if (headerMap.containsKey(headerName)) {
                // 提取下拉选项(假设使用 Map 的 Value 作为选项)
                List<String> options = new ArrayList<>();
                for (Object value : optionsMap.values()) {
                    options.add(value.toString());
                }

                // 设置下拉框
                setDropDownForColumn(sheet, helper, headerMap.get(headerName), options);
            } else {
                System.out.println("未找到匹配的表头: " + headerName);
            }
        }
    }

    /**
     * 为指定列设置下拉框
     */
    private void setDropDownForColumn(Sheet sheet,
                                 DataValidationHelper helper,
                                 int columnIndex,
                                 List<String> options) {
        if (options.isEmpty()) return;

        // 设置应用范围(从第二行开始,默认设置100行)
        int lastRow = 100; // 默认设置100行
        CellRangeAddressList range = new CellRangeAddressList(1, lastRow, columnIndex, columnIndex);

        // 创建数据验证约束
        DataValidationConstraint constraint = helper.createExplicitListConstraint(
            options.toArray(new String[0])
        );

        // 创建并应用验证
        DataValidation validation = helper.createValidation(constraint, range);
        validation.setSuppressDropDownArrow(true);
        sheet.addValidationData(validation);
    }
}

2.3启动类

public class Main {
    public static void main(String[] args) {

        // 定义字典数据格式: Map<表头名称, Map<Key, Value>>
        Map<String, Map<Integer, String>> dictData = new LinkedHashMap<>();

// 部门下拉选项(Key 可忽略)
        Map<Integer, String> departmentOptions = new HashMap<>();
        departmentOptions.put(1, "技术部");
        departmentOptions.put(2, "市场部");
        departmentOptions.put(3, "财务部");
        dictData.put("部门", departmentOptions);

// 职位下拉选项
        Map<Integer, String> positionOptions = new HashMap<>();
        positionOptions.put(1, "开发工程师");
        positionOptions.put(2, "销售经理");
        positionOptions.put(3, "会计");
        dictData.put("职位", positionOptions);

        Employee employee1 = new Employee("张三", "技术部", "开发工程师");
        Employee employee2 = new Employee("李四", "市场部", "销售经理");
        ArrayList<Employee> list = new ArrayList<>();
        list.add(employee1);
        list.add(employee2);

        ArrayList<Department> list1 = new ArrayList<>();
        Department department = new Department("技术部", "技术经理");
        Department department1=  new Department("技术部", "技术经理");
        list1.add(department);
        list1.add(department1);

        List<List<String>> listHead = new ArrayList<>();

listHead.add(new ArrayList<String>() {{
    add("姓名");
}});
listHead.add(new ArrayList<String>() {{
    add("部门");
}});
listHead.add(new ArrayList<String>() {{
    add("职位");
}});


        // 写入 Excel
        String fileName = "D:\\idea代码\\demo1\\src\\main\\resources\\output24.xlsx";
        ExcelWriter build = EasyExcel.write(fileName)
               .build();// 注册处理器
       WriteSheet dic = EasyExcel.writerSheet("字典项页").head(Department.class).build();
       build.write(list1, dic);

        WriteSheet data = EasyExcel.writerSheet("数据页").head(listHead)
                .registerWriteHandler(new DynamicDropDownHandler(dictData,listHead)).build();// 写入数据

        build.write(list, data);
        build.finish();

    }
}

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

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

相关文章

TCP 三次握手四次挥手过程详解

注&#xff1a;本文为 “TCP 的三次握手与四次挥手” 相关文章合辑。 英文引文&#xff0c;机翻未校。 中文引文&#xff0c;未整理去重。 英文引文第二篇&#xff0c;实为国内《稀土掘金技术社区》文章&#xff0c;没检索到原文&#xff0c;此处 “出口转内销” 。 如有内…

程序编译生成的文件

目录 .i 文件 .s 文件 .o文件 总结 在 C 编程中&#xff0c;.i、.s和 .o 文件是编译过程中生成的不同阶段的文件&#xff0c;它们代表不同的含义&#xff1a; .i 文件 全称 &#xff1a;预处理后的文件&#xff08;Intermediate File&#xff09;。 含义&#xff1a;.i文件…

C++类的基础题(4)

练习1&#xff1a;&#xff08;简单&#xff09; 基于如下程序&#xff0c;按要求修改和完善。 #include <iostream> using namespace std; class Student {public: Student(int n,float s):num(n),score(s){} void change(int n,float s) {numn;scores;} void displ…

MindGYM:一个用于增强视觉-语言模型推理能力的合成数据集框架,通过生成自挑战问题来提升模型的多跳推理能力。

2025-03-13&#xff0c;由中山大学和阿里巴巴集团的研究团队提出了MindGYM框架&#xff0c;通过合成自挑战问题来增强视觉-语言模型&#xff08;VLMs&#xff09;的推理能力。MindGYM框架通过生成多跳推理问题和结构化课程训练&#xff0c;显著提升了模型在推理深度和广度上的表…

WPS 搭配 Zotero 插件使用

安装Zotero后&#xff0c;Word自动引入了插件&#xff0c;但WPS却没有&#xff0c;做为WPS的重度用户&#xff0c;这是不行的。 解决方案&#xff1a; 1.找到 Zotero.dotm 一般在安装目录下&#xff0c; 2.然后复制到WPS的startup下 我的目录是&#xff1a;C:\Users\lianq…

汽车NVH诊断案例 | 纯电车急加速过大弯底盘异响

引言 失去发动机的掩蔽效应后&#xff0c;新能源电车的NVH问题&#xff0c;成为了困扰维修技师新难点。风噪、胎噪、电机高频啸叫等问题更容易车主识别&#xff0c;根源却难以被有效分辨。如何更精准且高效地识别电车NVH问题根源&#xff1f;今天分享的这个案例&#xff0c;内…

万字长文详解嵌入式电机软件开发

第一章&#xff1a;嵌入式电机概述 1.1 电机类型&#xff1a;选对 “主角” 有多重要&#xff1f; 在嵌入式电机控制系统里&#xff0c;电机就如同故事中的主角&#xff0c;选对了方能使整个剧情顺利推进。不同应用场景对精度、速度、功率以及成本的需求各异&#xff0c;因而了…

电机控制常见面试问题(十二)

文章目录 一.电机锁相环1.理解锁相环2.电机控制中的锁相环应用3.数字锁相环&#xff08;DPLL&#xff09; vs 模拟锁相环&#xff08;APLL&#xff09;4.锁相环设计的关键技术挑战5.总结 二、磁链观测1.什么是磁链&#xff1f;2.为什么要观测磁链&#xff1f;3.怎么观测磁链&am…

卡尔曼滤波算法从理论到实践:在STM32中的嵌入式实现

摘要&#xff1a;卡尔曼滤波&#xff08;Kalman Filter&#xff09;是传感器数据融合领域的经典算法&#xff0c;在姿态解算、导航定位等嵌入式场景中广泛应用。本文将从公式推导、代码实现、参数调试三个维度深入解析卡尔曼滤波&#xff0c;并给出基于STM32硬件的完整工程案例…

韦伯望远镜的拉格朗日点计算推导过程,包含MATLAB和python运动轨迹仿真代码

研究过程 起源与提出&#xff1a;1687 年牛顿提出 “三体问题”&#xff0c;旨在研究三个可视为质点的天体在相互之间万有引力作用下的运动规律&#xff0c;但因运动方程过于复杂&#xff0c;难以得到完全解。欧拉的贡献1&#xff1a;1767 年&#xff0c;瑞士数学家莱昂哈德・…

STM32 RS232通信开发全解析 | 零基础入门STM32第五十九步

主题内容教学目的/扩展视频RS232串口电路原理&#xff0c;跳线设置&#xff0c;驱动程序。与超级终端通信。了解电路原理和RS232协议。 师从洋桃电子&#xff0c;杜洋老师 &#x1f4d1;文章目录 一、RS232通信系统架构二、RS232核心原理与硬件设计2.1 电气特性对比2.2 典型电路…

C# net deepseek RAG AI开发 全流程 介绍

deepseek本地部署教程及net开发对接 步骤详解&#xff1a;安装教程及net开发对接全流程介绍 DeepSeekRAG 中的 RAG&#xff0c;全称是 Retrieval-Augmented Generation&#xff08;检索增强生成&#xff09;&#xff0c;是一种结合外部知识库检索与大模型生成能力的技术架构。其…

建筑管理(2): 施工承包模式,工程监理,质量监督

文章目录 一. 施工承包模式1. 施工总承包模式1.1 施工总承包的特点1.2 施工总承包模式中的承包方 2. 平行承包模式3. 联合体与合作体承包模式 二. 工程监理1. 强制实行监理的工程范围1.1 国家重点建设工程1.2 大中型公用事业工程(重点)1.3 成片开发建设的住宅小区工程1.4 必须实…

最节省服务器,手搓电子证书查询系统

用户预算150元&#xff0c;想要一个最简单证书查询系统。前台能查询证书、后台管理员能登录能修改密码&#xff0c;证书能够手动输入修改删除、批量导入导出删除数据、查询搜索。能够兼容苹果、安卓、PC三端浏览器&#xff0c;最后帮忙部署到云服务器上。 用户预算不多&#xf…

STM32F407 IIC通信

1、IIC 介绍 IIC(Inter-Integrated Circuit)总线是一种由数据线 SDA 和时钟线 SCL 构成的两线式串行总线,可发送和接收数据,常用于 MPU/MCU 与外部设备连接通信、数据传输。每个连接到总线的设备都有一个独立的地址,主机可以通过该地址来访问不同设备。因为 IIC 协议比较简单…

jupyter无法转换为PDF,HTMLnbconvert failed: Pandoc wasn‘t found.

无法转为PDF 手动下载工具 https://github.com/jgm/pandoc/releases/tag/3.6.3 似乎跟我想的不大一样&#xff0c;还有新的报错 https://nbconvert.readthedocs.io/en/latest/install.html#installing-tex 不知道下的啥玩意儿 sudo apt-get install texlive-xetex texlive-fon…

使用 Excel 实现绩效看板的自动化

引言 在日常工作中&#xff0c;团队的绩效监控和管理是确保项目顺利进行的重要环节。然而&#xff0c;面临着以下问题&#xff1a; ​数据分散&#xff1a;系统中的数据难以汇总&#xff0c;缺乏一个宏观的团队执行情况视图。​看板缺失&#xff1a;系统本身可能无法提供合适…

vue3怎么和大模型交互?

引言 平时我们都是用的在线的AI工具&#xff0c;直接输入问题&#xff0c;然后AI回答我们&#xff0c;那么怎么把AI接入项目中呢&#xff1f; 这个问题问得好。 方案一&#xff1a;引入第三方已封装好的UI库方案二&#xff1a;自己写 对于方案一&#xff0c;市面上已有一些…

【网络编程】HTTP网络编程

13.1 HTTP 简介 HTTP(Hyper Text Transfer Protocol,超文本传输协议)是用于从万维网(WWW:World Wide Web) 服务器(简称Web 服务器)传输超文本到本地浏览器的传送协议&#xff0c;基于TCP/IP 通信协 议来传递数据 (HTML 文件、图片文件、查询结果等)。 13.2 HTTP 的工作原理 …

【Qt】QWidget属性介绍

&#x1f3e0;个人主页&#xff1a;Yui_ &#x1f351;操作环境&#xff1a;Qt Creator &#x1f680;所属专栏&#xff1a;Qt 文章目录 前言1. enabled属性2.geometry属性2.1 改变控件位置2.2 女神表白程序2.3 知识补充——window frame 3. windowsTitle属性4. windowIcon属性…