前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >POI设置某一单元格的字体颜色等样式(踩坑记录)

POI设置某一单元格的字体颜色等样式(踩坑记录)

作者头像
天罡gg
发布于 2022-12-02 07:29:10
发布于 2022-12-02 07:29:10
10.5K11
代码可运行
举报
文章被收录于专栏:天罡gg天罡gg
运行总次数:1
代码可运行

项目场景

最近项目使用POI按模板导出Excel, 需要设置一些单元格的字体为红色. 这里遇到一个容易踩坑的点,所以记录一下,希望能让更多的人少走弯路.


问题描述

我只想修改某个单元格字体为红色,心想这还不简单吗?Cell->CellStyle->Font->color,看起来是那么湿滑,红色是生效了,但。。。没想到却影响了很多类似的单元格。Why?

先上代码:我相信这应该是99%的人的逻辑:

  1. 获取要修改的cell.CellStyle和Font
  2. 设置cell.Font颜色为红色:IndexedColors.RED.getIndex()
  3. 将修改设置回cell.Font和CellStyle
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for (Cell cell : redColorCellList) {
    CellStyle cellStyle = cell.getCellStyle();
    Font font = workbook.getFontAt(cellStyle.getFontIndexAsInt());
    font.setColor(IndexedColors.RED.getIndex());
    cellStyle.setFont(font);
    cell.setCellStyle(cellStyle);
}

必备基础:设置新创建的单元格样式

我的项目场景是需要修改单元格字体为红色,但这里有必要先提下新创建的单元格如何设置样式的。 设置基本样式的示例代码:

新建 excel和sheet

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 新建 excel
Workbook workbook = new XSSFWorkbook();
// 新建一个 sheet
Sheet sheet = workbook.createSheet();

创建单元格样式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CellStyle cellStyle = workbook.createCellStyle();
cellStyle.setFillForegroundColor(IndexedColors.LIGHT_YELLOW.getIndex()); // 背景色: 浅黄色
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); // 背景色填充样式:单色填充
cellStyle.setAlignment(HorizontalAlignment.CENTER); // 水平布局:居中
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 垂直布局:居中
cellStyle.setBorderBottom(BorderStyle.DOUBLE); // 双边框
cellStyle.setBorderLeft(BorderStyle.THIN);// 薄边框
cellStyle.setBorderRight(BorderStyle.DOUBLE); // 双边框
cellStyle.setBorderTop(BorderStyle.THIN);// 薄边框
cellStyle.setBottomBorderColor(IndexedColors.WHITE.getIndex()); // 下边框:白色
cellStyle.setRightBorderColor(IndexedColors.GREEN.getIndex()); // 右边框:绿色
cellStyle.setWrapText(true); // 文本自动换行

设置字体,设置字体颜色的关键代码:font.setColor(IndexedColors.BLACK.getIndex());,这里IndexedColors里很多颜色可以选择。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Font font = workbook.createFont();
font.setBold(false); // 加粗
font.setFontName("微软雅黑"); // 字体
font.setFontHeightInPoints((short) 14); // 字体高度
font.setColor(IndexedColors.BLACK.getIndex()); // 字体颜色:黑色
cellStyle.setFont(font);

这里为了看效果,我创建一个5行*5列的表格:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for (int i = 0; i < 5 ; i++) {
    // 设置列宽
    sheet.setColumnWidth(i, 30 * 160);
    // 新增一行 row
    Row row = sheet.createRow(i);
    row.setHeightInPoints(40);
    for (int j = 0; j < 5; j++) {
        // 新增一个单元格 cell
        Cell cell = row.createCell(j);
        cell.setCellValue("Hello_" + i + j);
        cell.setCellStyle(cellStyle);
    }
}

保存excel文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
FileOutputStream outputStream = new FileOutputStream("D:\\poi-excel-style-demo.xlsx");
workbook.write(outputStream);
outputStream.flush();
outputStream.close();
workbook.close();

看下效果


解决方案:修改单元格颜色

基于上面我们知道:如果是设置新创建的cell的样式,我们直接新建cellStyle并设置 cell.setCellStyle(cellStyle); 即可, 回到我遇到的问题,因为我们的项目需求是按模板导出,原有的样式不能改,只是将字的颜色修改一下,那么我们该如何做呢?

还是基于上面的代码,我们只修改第一行 为 红色字体,并加粗,其它样式不变,先上效果:

这里关键点有两步,也是容易踩坑的点:

  1. 克隆Style:新建的redCellStyle要从现有的cell拷贝cellStyle:redCellStyle.cloneStyleFrom(cell.getCellStyle());
  2. 克隆Font:新建的redFont要从现有的cellStyle拷贝font:这个POI没有封装,只能手动拷贝。。。

实现代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 设置第一行为红色,并加粗
CellStyle redCellStyle = null;
for (int m = 0; m < 5; m++) {
    Cell cell = sheet.getRow(0).getCell(m);
    if (redCellStyle == null) {
        redCellStyle = workbook.createCellStyle();
        // 重点:从现有样式克隆style,只修改Font,其它style不变
        redCellStyle.cloneStyleFrom(cell.getCellStyle());
        // 获取原有字体
        Font oldFont = workbook.getFontAt(redCellStyle.getFontIndexAsInt());
        // 创建新字体
        Font redFont = workbook.createFont();
        // 重点:保留原字体样式
        redFont.setFontName(oldFont.getFontName()); // 保留原字体
        redFont.setFontHeightInPoints(oldFont.getFontHeightInPoints()); // 保留原字体高度
        redFont.setBold(true); // 加粗
        redFont.setColor(IndexedColors.RED.getIndex());  // 字体颜色:红色
        // 设置红色字体
        redCellStyle.setFont(redFont);
    }
    // 设置样式
    cell.setCellStyle(redCellStyle);
}

那么我也做了相应的封装,让修改Font方法变得更通用,拿走不谢,如果对你有帮助,也请点赞支持,你的鼓励也是我创作的动力~

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public static void setCellFont(List<Cell> cellList, FontParam fontParam) {
        if (CollectionUtils.isEmpty(cellList) || fontParam == null) {
            return;
        }
        CellStyle cellStyle = null;
        for (Cell cell : cellList) {
            if (cellStyle == null) {
                Workbook workbook = cell.getSheet().getWorkbook();
                cellStyle = workbook.createCellStyle();
                // 从现有样式克隆style,只修改Font,其它style不变
                cellStyle.cloneStyleFrom(cell.getCellStyle());
                // 获取原有字体
                Font oldFont = workbook.getFontAt(cellStyle.getFontIndexAsInt());
                // 创建新字体
                Font newFont = workbook.createFont();
                newFont.setFontName(fontParam.getFontName() == null? oldFont.getFontName(): fontParam.getFontName());
                newFont.setFontHeightInPoints(fontParam.getFontHeightInPoints() == null? oldFont.getFontHeightInPoints(): fontParam.getFontHeightInPoints());
                newFont.setBold(fontParam.getBold() == null? oldFont.getBold(): fontParam.getBold());
                newFont.setItalic(fontParam.getItalic() == null? oldFont.getItalic(): fontParam.getItalic());
                newFont.setStrikeout(fontParam.getStrikeout() == null? oldFont.getStrikeout(): fontParam.getStrikeout());
                newFont.setUnderline(fontParam.getUnderline() == null? oldFont.getUnderline(): fontParam.getUnderline());
                newFont.setColor(fontParam.getColor() == null? oldFont.getColor(): fontParam.getColor());
                // 设置字体
                cellStyle.setFont(newFont);
            }
            // 设置样式
            cell.setCellStyle(cellStyle);
        }
    }

    /**
     * 字体参数类,为null代表不设置
     */
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class FontParam {

        /**
         * 字体名
         */
        private String fontName;
        /**
         * 字体像素高度
         */
        private Short fontHeightInPoints;
        /**
         * 是否加粗
         */
        private Boolean bold;
        /**
         * 是否斜体
         */
        private Boolean italic;
        /**
         * 是否删除线
         */
        private Boolean strikeout;
        /**
         * 下划线类型
         * @see #U_NONE
         * @see #U_SINGLE
         * @see #U_DOUBLE
         * @see #U_SINGLE_ACCOUNTING
         * @see #U_DOUBLE_ACCOUNTING
         */
        private Byte underline;
        /**
         * 字体颜色
         */
        private Short color;

        /**
         * not underlined
         */
        public final static byte U_NONE = 0;

        /**
         * single (normal) underline
         */
        public final static byte U_SINGLE = 1;

        /**
         * double underlined
         */
        public final static byte U_DOUBLE = 2;

        /**
         * accounting style single underline
         */
        public final static byte U_SINGLE_ACCOUNTING = 0x21;

        /**
         * accounting style double underline
         */
        public final static byte U_DOUBLE_ACCOUNTING = 0x22;
    }

参考

POI设置单个单元格的样式 POI设置某一单元格的字体颜色

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-10-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
1 条评论
热度
最新
只需要根据for循环最外面那层判断就行。最外层的for循环是行。 Cell cell = row.createCell(j); cell.setCellValue("Hello_" + i + j); if (i==3){ cell.setCellStyle(cellStyle1); }else { cell.setCellStyle(cellStyle); }
只需要根据for循环最外面那层判断就行。最外层的for循环是行。 Cell cell = row.createCell(j); cell.setCellValue("Hello_" + i + j); if (i==3){ cell.setCellStyle(cellStyle1); }else { cell.setCellStyle(cellStyle); }
回复回复点赞举报
推荐阅读
编辑精选文章
换一批
Java常用工具类之Excel导出
package com.wazn.learn.util; import java.util.List; import java.util.Map; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.Font; im
二十三年蝉
2018/02/28
1.9K0
java导出Excel表格
最近自己着手写了一个前后端分离的后台管理系统(主要是写着玩,java还是熟悉一点,所以前后端均是自己写),后端使用的Java SpringMVC。后来想着在用户管理中添加一个导出功能,所以就上网查了资料,实现了简单的导出功能,在这里记录下自己的过程。 1、在java项目中引入导出功能需要的jar包   poi-3.9.jar   poi-examples-3.9.jar   poi-excelant-3.9.jar   poi-ooxml-3.9.jar   poi-ooxml-schemas-3.9.ja
用户1174387
2018/01/17
4.6K0
java导出Excel表格
Java 导出 Excel,相同列数据相同的情况下合并单元格【POI的相关依赖自行百度添加】
Java 导出 Excel,相同列数据相同的情况下合并单元格【POI的相关依赖自行百度添加】
无忧摸鱼
2022/05/31
4.3K0
Java 导出 Excel,相同列数据相同的情况下合并单元格【POI的相关依赖自行百度添加】
java按需导出Excel并自动合同单元格
最近公司有一个需求,就是按到模版导出数据报表,并内容相同的单元格实现自动合并.具体业务设计图如下所示
java攻城狮
2020/11/30
1.1K0
java按需导出Excel并自动合同单元格
POI设置单元格样式
POI设置单元格样式时,明明只是想设置一个单元格,结果其他很多都被设置了。这里猜想应该是默认共用了一个。
用户3293499
2024/12/04
780
java工具类1-ExcelUtils
用户9363686
2025/01/17
610
Spring Boot + EasyExcel导入导出,简直太好用了!
老项目主要采用的POI框架来进行Excel数据的导入和导出,但经常会出现OOM的情况,导致整个服务不可用。后续逐步转移到EasyExcel,简直不能太好用了。
程序新视界
2022/08/03
4.4K0
Spring Boot + EasyExcel导入导出,简直太好用了!
重构:以Java POI 导出EXCEL为例2
上一篇博文已经将一些对象抽象成成员变量以及将一些代码块提炼成函数。这一节将会继续重构原有的代码,将一些函数抽象成类,增加成员变量,将传入的参数合成类等等。
云枭
2019/02/25
8720
爱不释手的Excel导出工具类
最近了不起做的需求中有一个需求是要求导出Excel表格,有大约十几张表需要导出吧。
灬沙师弟
2023/09/29
3440
爱不释手的Excel导出工具类
技术汇总:第一章:使用poi实现表单下载成xls文件并打印
分享链接:https://www.cnblogs.com/gudongcheng/p/8268909.html
Java廖志伟
2022/09/28
2610
技术汇总:第一章:使用poi实现表单下载成xls文件并打印
poi导出excel中含有超链接并且头部样式问题
多余的代码网上都有就不多贴了 我这边的sheet来自于writer 各位看官可自行改成自己的
全栈程序员站长
2021/04/07
6470
纳税服务系统二(用户模块)【POI、用户唯一性校验】
前言 用户模块:本文主要的知识点有以下: 使用POI来操作Excel,对数据进行导入和导出 对用户进行唯一性校验,不能同时出现相同的用户 POI基础 再次回到我们的用户模块上,我们发现还有两个功能没有
Java3y
2018/04/02
2.6K0
纳税服务系统二(用户模块)【POI、用户唯一性校验】
springboot项目导出excel 合并单元格表格
六月的雨在Tencent
2024/03/28
1650
springboot项目导出excel 合并单元格表格
【POI框架实战】——POI设置Excel单元格格式
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyuyang6688/article/details/49911537
DannyHoo
2018/09/13
5.3K0
【POI框架实战】——POI设置Excel单元格格式
EXCLS 的导出 下载
/** * 下载 * @param response * @param request * @return * @throws Exception */ /*@RequestMapping(value="downExels") public String typeExls(HttpServletResponse response ,HttpServletRequest request)throws Exc
斯文的程序
2019/11/07
4150
一脸懵逼学习Java操作Excel之POI(Apache POI)
根据给定的文章内容,撰写摘要总结。
别先生
2018/01/02
3.3K0
一脸懵逼学习Java操作Excel之POI(Apache POI)
10、借助POI实现Java生成并打印excel报表(1)
该文章介绍了如何利用Excel表格进行数据分析。文章首先介绍了如何导入Excel表格,然后介绍了如何使用VLOOKUP函数和IF函数对数据进行分析和处理。接着,文章介绍了如何使用Excel表格进行数据可视化,包括创建柱状图和折线图。最后,文章介绍了如何使用Excel表格进行数据导出和打印。
YGingko
2017/12/28
5.3K0
【小家java】一个基于POI的Excel导入、导出工具处理类(支持xls,xlsx格式),另有SpringMVC的导入、导出案例讲解
表格的导入、导出可谓开发过程中经常会碰到的功能。然后这种模版化的东西并不需要每次都去编码一次,因此我就整理了一个Excel的万能处理类。能够实现兼容2003、2007的各种Excel格式的导入导出功能,使用起来也非常的方面,适用于所有业务场景,下面会有案例讲解
YourBatman
2019/09/03
2.3K0
【小家java】一个基于POI的Excel导入、导出工具处理类(支持xls,xlsx格式),另有SpringMVC的导入、导出案例讲解
poi-util 加强 POI 相关操作工具包
导入功能还是基于注解部分,会去查找你实体类@Field注解值和Excel表头对应的上的字段,然后将数值对实体类进行数据填充
java攻城狮
2021/01/18
8820
java -POI的基本操作Excel
导入依赖 <dependencies> <!--操作旧版本--> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.0.1</version> </dependency> <!--操作新版本--> <dependency> <groupId>org.apache.poi</groupId>
用户9006224
2022/12/21
9820
推荐阅读
相关推荐
Java常用工具类之Excel导出
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文