cn.hutool.poi.excel 实现excel导出效果 首行高度,行样式,颜色,合并单元格,例子样式

需求

接了需求,下载excel模版,本来看着还是简单的,然后实现起来一把泪,首先是使用poi,我查了好久,才实现,然后是我用easyexcel又实现了一遍,用了一个周多才实现。
在这里插入图片描述
这是需求,第一行是一个多行文本,红色,第二行一个合并单元格题目,第三行是一个多单元格标题,第四行是一个例子,红色。

实现

@Operation(summary = "人员维护模版下载", description = "人员维护模版下载")
    @PostMapping("persondowntemplate")
    public void personDownTemplate(HttpServletResponse response) {
        ExcelWriter writer = ExcelUtil.getWriter(true);
		//主标题
        String note = "1.前四行数据,系统不读取,不需要删除\n" +
                "2.约束区县,请输入约束的部门或者区县或者地市\n" +
                "3.约束岗位族的值列表,请参考第二个Sheet2,多个岗位族,请使用英文逗号隔开\n" +
                "4.日期格式:yyyy-mm-dd\n" +
                "5.下拉数据的值,不允许输入下拉值以外的数据";

        // 创建总标题行
        List<String> totalHeader1 = Lists.newArrayList();
        totalHeader1.add(note);
        writer.writeHeadRow(totalHeader1); // 写入总标题行,使用默认样式
        short headerRowHeight = 80 * 20; // 设置行高为30磅
        Sheet sheet = writer.getSheet();
        //因为是多行所以要自己控制行高
        sheet.getRow(0).setHeight(headerRowHeight);

        // 创建样式,建立每一行的样式
        CellStyle cellStyle1 = createRedRightAlignedCellStyle(writer.getWorkbook());
        Row row1 = sheet.getRow(0);
        Cell cell = row1.getCell(0);
        cell.setCellStyle(cellStyle1);

        // 创建总标题行
        List<String> totalHeader = Lists.newArrayList();
        totalHeader.add("人员契约化管理导入");
        writer.writeHeadRow(totalHeader); // 写入总标题行

        // 创建样式
        CellStyle cellStyle2 = createRedRightAlignedCellStyle2(writer.getWorkbook());
        Row row2 = sheet.getRow(1);
        Cell cell1 = row2.getCell(0);
        cell1.setCellStyle(cellStyle2);

        List<String> header = Lists.newArrayList();
        header.add("组织名称");
        header.add("* 员工编号");
        header.add("加入本企业途径");
        header.add("是否启用约束区县");
        header.add("约束区县");
        header.add("约束区县开始日期");
        header.add("约束区县结束日期");
        header.add("是否启用约束岗位族");
        header.add("约束岗位族");
        header.add("约束岗位族开始日期");
        header.add("约束岗位族结束日期");

        int mergeRowIndex = 0; // 总标题所在行索引
        int mergeColumnStartIndex = 0; // 起始列索引
        int mergeColumnEndIndex = header.size() - 1; // 结束列索引
		//其实上面的这些索引没啥用,下面几行是合并某几行的单元格
        CellRangeAddress cellRangeAddress = new CellRangeAddress(mergeRowIndex, mergeRowIndex, mergeColumnStartIndex, mergeColumnEndIndex);
        sheet.addMergedRegion(cellRangeAddress);

        CellRangeAddress cellRangeAddress1 = new CellRangeAddress(1, 1, mergeColumnStartIndex, mergeColumnEndIndex);
        sheet.addMergedRegion(cellRangeAddress1);

        writer.writeHeadRow(header); // 写入头部标题
		//建立新的sheet
        writer.renameSheet(0, "人员维护");
        StyleSet styleSet = writer.getStyleSet();
        //实话说这一块是直接抄的别的,你说有用处吧,可能也有,你说没用吧,可能也没有
        for (int i = 0; i < 11; i++) {
            CellStyle cellStyle = writer.createColumnStyle(i);
            DataFormat format = writer.getWorkbook().createDataFormat();
            cellStyle.setDataFormat(format.getFormat("@"));
            writer.setStyleSet(styleSet);
        }
		//实话说这一块好像是也没生效
        for (int i = 0; i < header.size(); i++) {
            int headerLength = header.get(i).length(); // 获取列名长度
            int cellWidth = headerLength * 500; // 将字符长度转换为列宽单位

            // 如果内容比默认宽度要宽,则使用内容宽度;否则使用默认宽度
            int defaultWidth = 24 * 256; // 默认宽度
            int columnWidth = Math.max(cellWidth, defaultWidth);

            sheet.setColumnWidth(i, columnWidth); // 设置列宽
        }
        //这是列表下面的示例行
        List<Map<String, Object>> dataList = new ArrayList<>();
        Map<String, Object> dataRow = new HashMap <>();
        dataRow.put("组织名称", "请参考hr标准组织名称");
        dataRow.put("* 员工编号", "0000001");
        dataRow.put("加入本企业途径", "社会招聘");
        dataRow.put("是否启用约束区县", "是");
        dataRow.put("约束区县", "泰安市分公司管理层");
        dataRow.put("约束区县开始日期", "2024-04-11");
        dataRow.put("约束区县结束日期", "2024-06-11");
        dataRow.put("是否启用约束岗位族", "是");
        dataRow.put("约束岗位族", "基层组织建设与党员教育管理");
        dataRow.put("约束岗位族开始日期", "2024-04-11");
        dataRow.put("约束岗位族结束日期", "2024-06-11");
        dataList.add(dataRow);
        writer.write(dataList, false);
        for (int i = 0; i < header.size(); i++) {
            // 创建样式
            CellStyle cellStyle4 = createRedRightAlignedCellStyle3(writer.getWorkbook());
            Row row4 = sheet.getRow(3);
            Cell cell4 = row4.getCell(i);
            cell4.setCellStyle(cellStyle4);

            // 创建样式
            CellStyle cellStyle5 = createRedRightAlignedCellStyle5(writer.getWorkbook());
            Row row5 = sheet.getRow(2);
            Cell cell5 = row5.getCell(i);
            cell5.setCellStyle(cellStyle5);
        }
        //这个是用来写下拉的,不同的下拉的,
        setXSSFValidation(sheet);

        // 创建样式
        CellStyle cellStyle3 = createRedRightAlignedCellStyle2(writer.getWorkbook());
        Row row3 = sheet.getRow(2);
        Cell cell3 = row3.getCell(0);
        cell3.setCellStyle(cellStyle3);

		//创建新的sheet
        writer.setSheet("Sheet2");
        List<String> header1 = Lists.newArrayList();
        header1.add("岗位族信息");
        writer.writeHeadRow(header1);
        List<Map<String,Object>> personnelContractManagementList = personnelContractManagementMapper.jobFamilyList();
        List<String> personnelContractManagementSheet = new ArrayList<>();
        for (int i = 0; i < personnelContractManagementList.size(); i++) {
            personnelContractManagementSheet.add(String.valueOf(personnelContractManagementList.get(i).get("ZHUANYE")));
        }
        writer.write(personnelContractManagementSheet, true);

        setSizeColumn(writer.getSheet());
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=人员维护导入模板.xlsx");
        ServletOutputStream out = null;
        try {
            out = response.getOutputStream();
            writer.flush(out, true);
            out.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            writer.close();
        }
    }
private static CellStyle createRedRightAlignedCellStyle(Workbook workbook) {
        CellStyle cellStyle = workbook.createCellStyle();
        cellStyle.setWrapText(true);
        Font font = workbook.createFont();
        font.setColor(IndexedColors.RED.getIndex());
        cellStyle.setFont(font);
        cellStyle.setAlignment(HorizontalAlignment.LEFT);
        return cellStyle;
    }

    private static CellStyle createRedRightAlignedCellStyle2(Workbook workbook) {
        CellStyle cellStyle = workbook.createCellStyle();
        cellStyle.setWrapText(true);
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        return cellStyle;
    }

    private static CellStyle createRedRightAlignedCellStyle3(Workbook workbook) {
        CellStyle cellStyle = workbook.createCellStyle();
        cellStyle.setWrapText(true);
        Font font = workbook.createFont();
        font.setColor(IndexedColors.RED.getIndex());
        cellStyle.setFont(font);
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        return cellStyle;
    }


    private static CellStyle createRedRightAlignedCellStyle5(Workbook workbook) {
        CellStyle cellStyle = workbook.createCellStyle();
        cellStyle.setWrapText(true);
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        return cellStyle;
    }
 /**
     *
     * @param sheet
     * @return
     */
    private static Sheet setXSSFValidation(Sheet sheet){
        String onelist[] = {"是","否"};
        String joinEnterpriseWay[] = {"校园招聘","社会招聘","接收复转军人","成建制划转","劳务派遣"};

        Workbook workbook = sheet.getWorkbook();

        /**
         * 创建一个名称为hidden的sheet页,用于是否启用约束区县
         */
        Sheet hidden = workbook.createSheet("hidden");
        Cell cell = null;
        for (int i = 0, length = onelist.length; i < length; i++){
            String name = onelist[i];
            Row roww = hidden.createRow(i);
            cell = roww.createCell(0);
            cell.setCellValue(name);
        }
        Name namedCell = workbook.createName();
        namedCell.setNameName("hidden");
        namedCell.setRefersToFormula("hidden!$A$1:$A$" + onelist.length);
        //将第二个sheet页设置为隐藏
        workbook.setSheetHidden(1, true);
        XSSFDataValidationHelper dvHelper = new XSSFDataValidationHelper((XSSFSheet) sheet);
        //将名称为hidden的数据进行加载
        XSSFDataValidationConstraint constraint = (XSSFDataValidationConstraint) dvHelper.createFormulaListConstraint("hidden");
        //设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列
        CellRangeAddressList regions = new CellRangeAddressList(1, 1000, 3, 3);
        XSSFDataValidation data_validation_list = (XSSFDataValidation) dvHelper.createValidation(constraint, regions);
        data_validation_list.setErrorStyle(XSSFDataValidation.ErrorStyle.STOP);
        data_validation_list.createErrorBox("提示", "不允许自己输入,请选择下拉框里的数据");
        sheet.addValidationData(data_validation_list);

        /**
         * 创建一个名称为hidden的sheet页,用于是否启用约束区县
         */
        Sheet hidden1 = workbook.createSheet("hidden1");
        Cell cell1 = null;
        for (int i = 0, length = onelist.length; i < length; i++){
            String name1 = onelist[i];
            Row row1 = hidden1.createRow(i);
            cell1 = row1.createCell(0);
            cell1.setCellValue(name1);
        }
        Name namedCell1 = workbook.createName();
        namedCell1.setNameName("hidden1");
        namedCell1.setRefersToFormula("hidden1!$A$1:$A$" + onelist.length);
        //将第二个sheet页设置为隐藏
        workbook.setSheetHidden(2, true);
        //将名称为hidden的数据进行加载
        XSSFDataValidationConstraint constraint1 = (XSSFDataValidationConstraint) dvHelper.createFormulaListConstraint("hidden1");
        //设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列
        CellRangeAddressList regions1 = new CellRangeAddressList(1, 1000, 7, 7);
        XSSFDataValidation data_validation_list1 = (XSSFDataValidation) dvHelper.createValidation(constraint1, regions1);
        data_validation_list1.setErrorStyle(XSSFDataValidation.ErrorStyle.STOP);
        data_validation_list1.createErrorBox("提示", "不允许自己输入,请选择下拉框里的数据");
        sheet.addValidationData(data_validation_list1);


        Sheet hidden2 = workbook.createSheet("hidden2");
        Cell cell2 = null;
        for (int i = 0; i < joinEnterpriseWay.length; i++) {
            String name = joinEnterpriseWay[i];
            Row row = hidden2.createRow(i);
            cell2 = row.createCell(0);
            cell2.setCellValue(name);

        }
        Name namedCell2 = workbook.createName();
        namedCell2.setNameName("hidden2");
        namedCell2.setRefersToFormula("hidden2!$A$1:$A$" + joinEnterpriseWay.length);
        //将第二个sheet页设置为隐藏
        workbook.setSheetHidden(3, true);
        //将名称为hidden的数据进行加载
        XSSFDataValidationConstraint constraint2 = (XSSFDataValidationConstraint) dvHelper.createFormulaListConstraint("hidden2");
        //设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列
        CellRangeAddressList regions2 = new CellRangeAddressList(1, 1000, 2, 2);
        XSSFDataValidation data_validation_list2 = (XSSFDataValidation) dvHelper.createValidation(constraint2, regions2);
        data_validation_list2.setErrorStyle(XSSFDataValidation.ErrorStyle.STOP);
        data_validation_list2.createErrorBox("提示", "不允许自己输入,请选择下拉框里的数据");
        sheet.addValidationData(data_validation_list2);

        return sheet;
    }

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

docker实战之搭建MYSQL8.0主从同步

目录 环境配置容器创建主服务器创建MYSQL容器新增my.cnf文件创建用户并授权 从服务器创建MYSQL容器新增my.cnf文件重启MYSQL容器配置主从同步 验证主从同步彩蛋 MySQL 主从同步&#xff08;Master-Slave Replication&#xff09;是一种常用的解决方案&#xff0c;它允许一个主服…

【Redis7】Redis持久化机制之RDB

文章目录 1.RDB简介2.RDB配置触发设置3.RDB的优缺点4.如何检查修复RDB文件5.如何禁用RDB6.RDB参数优化7.总结 1.RDB简介 Redis持久化机制中的RDB&#xff08;Redis Database&#xff09;是一种将Redis在某个时间点的数据以快照形式保存到磁盘上的方法。 原理&#xff1a;RDB通…

python:pycharm虚拟解释器报错环境位置目录为空

目录 解释器分控制台解释器 和 pycharm解释器 控制台解释器切换&#xff1a; pycharm解释器 解释器分控制台解释器 和 pycharm解释器 控制台解释器切换&#xff1a; 切换到解释器下 激活解释器 查看解释器 where python 激活成功 这时在控制台使用python xxx.py 可以…

java面试框架篇(Spring常见问题、SpringBoot、SpringMVC、mybatis经典问题、SpringCloud组件)

文章目录 面试专题-java框架篇1. spring常见问题1.1. spring是什么?1.2. 谈谈你对AOP的理解1.3. 谈谈你对IOC的理解1.4. Spring Boot、 Spring MVC和Spring有什么区别1.5. spring bean 生命周期1.6. spring事务传播机制有哪些?1.7. 循环依赖1.8. spring框架中使用了哪些设计模…

在链游中,智能合约如何被用于实现游戏内的各种功能

随着区块链技术的快速发展&#xff0c;链游&#xff08;Blockchain Games&#xff09;作为区块链技术的重要应用领域之一&#xff0c;正逐渐展现出其独特的魅力和优势。其中&#xff0c;智能合约作为链游的核心技术之一&#xff0c;对于实现游戏内的各种功能起到了至关重要的作…

k8s的网路配置

目录 1、k8s相关网络类型 1.1 K8S中Pod网络通信 1.2 Overlay Network 1.3 VXLAN 1.3.1 vlan和vxlan的区别 2、Flannel 2.1 简介 2.2 Flannel工作原理 2.3 ETCD之Flannel提供说明 2.4 Flannel部署 2.4.1 在node节点上操作 2.4.2 在master01节点上操作 2.4.2.1 安装f…

LangChain llamaindex

LangChain 参考&#xff1a; 全流程 | Windows 系统本地部署开源模型阿里通义千问 QWEN 1.5&#xff0c;结合 LangChain-Chatchat 框架和向量数据库 FAISS、Milvus - 知乎

MySQL 插入数据的时候自动忽略重复数据

MySQL中插入数据&#xff0c;如果插入的数据在表中已经存在&#xff08;主键或者唯一键已存在&#xff09;&#xff0c;使用insert into语法的时候&#xff0c;如果遇到重复数据&#xff0c;会直接报错&#xff0c;导致事务回滚&#xff0c;所有插入数据&#xff0c;全部失败。…

Go语言直接使用Windows的IOCP API写一个echo服务器

Go的标准库中Windows下的网络是使用了IOCP的&#xff0c;参见go源码go/src/runtime/netpoll_windows.go&#xff0c;标准库为了与Epoll、kqueue等不同平台的IO模式使用统一的API&#xff0c;进行了封装。 如果想直接使用Windows的IOCP API编程&#xff0c;比如想按照&#xff…

iOS swift5 提示信息显示,提示弹框,第三方框架XHToastSwift

文章目录 1.github地址(亲测好用)2.源代码 1.github地址(亲测好用) XHToastSwift - github 2.源代码 XHToast.swift // // XHToast.swift // XHToastSwiftExample // // Created by xiaohui on 16/8/12. // Copyright © 2016年 CoderZhuXH. All rights reserved. …

x264 码率控制原理:rate_estimate_qscale 函数

rate_estimate_qscale 函数 原理 函数功能:根据目前使用的实际比特数更新一帧的qscale;是一个复杂的决策过程,需要考虑多种因素,如帧类型、编码的复杂度、目标比特率、缓冲区大小等,以确保视频质量和文件大小之间的平衡。函数参数分析:x264_t *h :编码器上下文信息结构…

鸿蒙开发ArkUI-X基础知识:【ArkUI代码工程及构建介绍】

代码工程及构建介绍 背景 ArkUI作为OpenHarmony的默认开发框架&#xff0c;在本项目&#xff08;ArkUI-X&#xff09;中需要做到一套代码同时支持多平台构建&#xff0c;所以会采取共仓开发的方式&#xff0c;部分仓直接指向OpenHarmony相关开源仓。 代码结构及仓库结构 代…

基于YOLO系列算法(YOLOv5、YOLOv6、YOLOv8以及YOLOv9)和Streamlit框架的行人头盔检测系统

摘要 本文基于最新的基于深度学习的目标检测算法 (YOLOv5、YOLOv6、YOLOv8)以及YOLOv9) 对头盔数据集进行训练与验证&#xff0c;得到了最好的模型权重文件。使用Streamlit框架来搭建交互式Web应用界面&#xff0c;可以在网页端实现模型对图像、视频和实时摄像头的目标检测功能…

C语言-atoi()库函数的模拟实现

文章目录 前言一、atoi()库函数的介绍及使用1.1 atoi()库函数介绍1.2 atoi()库函数使用 二、atoi()库函数的模拟实现2.1 函数设计2.2 函数实现思路2.3 具体实现2.4 测试 总结 前言 本篇文章介绍c语言中库函数atoi()的使用&#xff0c;以及模拟实现库函数。 一、atoi()库函数的…

【linux】详解linux权限

目录 用户 文件属性 更改文件权限 更改文件拥有者 更改文件所属组 用户的权限 文件掩码 粘滞位 总结 基本指令可参考&#xff1a; 【linux】详解linux基本指令-CSDN博客 【linux】详解linux基本指令-CSDN博客 用户 超级用户&#xff08;root&#xff09;&#xff…

Redis篇 在linux系统上安装Redis

安装Redis 在Ubuntu上安装Redis 在Ubuntu上安装Redis 在linux系统中,我们安装Redis,必须先使它有root权限. 那么在linux中,如何切换到root用户权限呢? sudo su 就可切换到用户权限了. 在切换到用户权限后,我们需要用一条命令来搜索Redis相关的软件包 apt search redis 会出现非…

怎样下载Android Studio历史版本文件包

1.在官网上下载都是推荐最新版本&#xff0c;想下载历史版本比较费劲&#xff0c;绕来绕去的。 2.进入这个网站可以下载其他版本https://android-studio.en.uptodown.com/windows/versions Older versions of Android Studio Its not uncommon for the latest version of an a…

解耦:哪些方法可以用来解耦代码

目录 1.引用 2.为何解耦如此重要 3.如何判断代码是否需要解耦 4.如何给代码解耦 5.思考题 1.引用 前面我们曾经讲到&#xff0c;重构可以分为大型重构和小型重构。小型重构的主要目的是提高代码的可读性&#xff0c;大型重构的主要目的是解耦。本节讲解如何对代码进行解耦…

webgl three 模型操作

模型位置操作是改变相关属性 平移改变位置 缩放改变缩放值 旋转改变角度 webgl中是4x4矩阵 前三排是原始状态 第四排是改变值 .position 位置 .scale 缩放 .rotation 绕轴旋转 .quaternion 绕axis旋转 其实和svg差不多 缩放 缩放是操作对角线 // Matrix4x4 …

大语言模型的工程技巧(三)——分布式计算

相关说明 这篇文章的大部分内容参考自我的新书《解构大语言模型&#xff1a;从线性回归到通用人工智能》&#xff0c;欢迎有兴趣的读者多多支持。 本文将讨论如何利用多台机器进行神经网络的分布式训练。利用多台机器来加速大语言模型的训练&#xff0c;是其获得成功的重要原…