EasyExcel 批量设置单元格样式(字体样式、底纹样式、边框样式、对齐方式、自动换行、旋转文字、竖向文字、数据格式、自动收缩)
目录
1 Maven配置
2 CellStyleModel
3 CustomCellStyleHandler
4 调试代码
5 调试结果
注:
1 Maven配置
<!--hutool工具包--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.5.1</version></dependency><!-- EasyExcel文档处理工具 --><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.2.8</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency>
2 CellStyleModel
样式信息类。
package com.xudongbase.easyexcel.model;import com.xudongbase.easyexcel.model.builder.CellStyleModelBuilder;
import com.xudongbase.easyexcel.model.common.SheetCellModel;
import lombok.Getter;/*** 样式信息类(Builder构建者模式)** @author xudongmaster*/
@Getter
public class CellStyleModel extends SheetCellModel {/*** 样式信息*/private final StyleModel styleModel;public CellStyleModel(CellStyleModelBuilder builder) {this.sheetName = builder.getSheetName();this.colIndex = builder.getColIndex();this.rowIndex = builder.getRowIndex();this.styleModel = builder.getStyleModel();}/*** 生成样式信息** @param sheetName sheet页名称* @param rowIndex 行号* @param columnIndex 列号* @param styleModel 样式信息* @return*/ public static CellStyleModel createCellStyleModel(String sheetName, int rowIndex, int columnIndex, StyleModel styleModel) {return CellStyleModelBuilder.builder(sheetName, rowIndex, columnIndex, styleModel).build();}}
3 CustomCellStyleHandler
自定义单元格样式处理器,可支持字体样式、底纹样式、边框样式、对齐方式、自动换行、旋转文字、竖向文字、数据格式、自动收缩。
package com.xudongbase.easyexcel.handler;import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.write.handler.AbstractRowWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import com.xudongbase.easyexcel.annotation.ReflectField;
import com.xudongbase.easyexcel.constant.StyleModelConstant;
import com.xudongbase.easyexcel.enums.BorderSideEnum;
import com.xudongbase.easyexcel.model.CellStyleModel;
import com.xudongbase.easyexcel.model.StyleModel;
import com.xudongbase.easyexcel.model.common.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.extensions.XSSFCellBorder;import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;/*** 自定义单元格样式处理器* 支持字体样式、底纹信息、边框样式、对齐方式、自动换行、旋转文字、竖向文字、数据格式、自动收缩** @author xudongmaster*/
@Slf4j
public class CustomCellStyleHandler extends AbstractRowWriteHandler {/*** sheet页名称列表*/private List<String> sheetNameList;/*** 样式信息*/private Map<String, Map<Integer, List<CellStyleModel>>> sheetCellStyleMap = new HashMap<>();/*** styleModel和CellStyle映射map*/private final Map<StyleModel, CellStyle> styleCellStyleMap = new HashMap<>();/*** 自定义样式适配器构造方法** @param cellStyleList 样式信息*/public CustomCellStyleHandler(List<CellStyleModel> cellStyleList) {if (CollUtil.isEmpty(cellStyleList)) {return;}Map<String, List<CellStyleModel>> allCellStyleModelMap = cellStyleList.stream().filter(x ->StrUtil.isNotBlank(x.getSheetName()) && x.getStyleModel() != null).collect(Collectors.groupingBy(SheetModel::getSheetName));if (allCellStyleModelMap == null || CollUtil.isEmpty(allCellStyleModelMap.keySet())) {return;}sheetNameList = new ArrayList<>(allCellStyleModelMap.keySet());//为了方便筛选数据Map<Integer, List<CellStyleModel>> sheetCellStyleModelMap;for (String sheetName : sheetNameList) {sheetCellStyleModelMap = allCellStyleModelMap.get(sheetName).stream().collect(Collectors.groupingBy(SheetCellModel::getRowIndex));sheetCellStyleMap.put(sheetName, sheetCellStyleModelMap);}}@Overridepublic void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Integer relativeRowIndex, Boolean isHead) {//跳过表头if (isHead) {return;}Sheet sheet = writeSheetHolder.getSheet();//不需要添加样式,或者当前sheet页不需要添加样式if (sheetCellStyleMap == null || CollUtil.isEmpty(sheetCellStyleMap.keySet()) || !sheetNameList.contains(sheet.getSheetName())) {return;}Map<Integer, List<CellStyleModel>> rowCSMMap = sheetCellStyleMap.get(sheet.getSheetName());//获取当前行的样式信息List<CellStyleModel> rowCellStyleList = rowCSMMap.get(relativeRowIndex);//该行不需要设置样式if (CollUtil.isEmpty(rowCellStyleList)) {return;}Cell cell;for (CellStyleModel cellStyleModel : rowCellStyleList) {//列索引int colIndex = cellStyleModel.getColIndex();//边框样式cell = row.getCell(colIndex) == null ? row.createCell(colIndex) : row.getCell(colIndex);//样式不追加,并且CellStyle也存在if (!cellStyleModel.getStyleModel().isAppend()&& styleCellStyleMap.get(cellStyleModel.getStyleModel()) != null) {//样式优化,styleModel对象相同时,CellStyle对象也相同cell.setCellStyle(styleCellStyleMap.get(cellStyleModel.getStyleModel()));} else {//设置单元格样式setCellStyle(cellStyleModel, cell);}}//删除已添加的样式信息rowCSMMap.remove(relativeRowIndex);}/*** 给单元格设置样式** @param cellStyleModel 样式信息* @param cell 单元格对象*/private void setCellStyle(CellStyleModel cellStyleModel, Cell cell) {//优先从CellStyleMap取,没有再创建StyleModel styleModel = cellStyleModel.getStyleModel();XSSFCellStyle style = styleCellStyleMap.get(styleModel) == null? (XSSFCellStyle) cell.getRow().getSheet().getWorkbook().createCellStyle() : (XSSFCellStyle) styleCellStyleMap.get(styleModel);// 克隆出一个 stylestyle.cloneStyleFrom(cell.getCellStyle());//可追加的CellStyle对象不放入CellStyleMap中if (!styleModel.isAppend()) {styleCellStyleMap.put(styleModel, style);}List<Field> fieldList = FieldUtils.getFieldsListWithAnnotation(StyleModel.class, ReflectField.class);if (CollUtil.isNotEmpty(fieldList)) {//使用反射给CellStyle赋值for (Field field : fieldList) {field.setAccessible(true);String fieldName = field.getName();ReflectField reflectField = field.getAnnotation(ReflectField.class);String invokeMethodName = reflectField.invokeMethodName();Object fieldValue;try {fieldValue = field.get(styleModel);} catch (IllegalAccessException e) {log.error("获取StyleModel的{}属性值失败:", fieldName, e);continue;}//当前字段没有赋值if (fieldValue == null) {continue;}//数据格式(从String转化为DataFormat)if (StrUtil.equals(StyleModelConstant.ATTR_NAME_DATA_FORMAT, fieldName)) {DataFormat dataFormat = cell.getRow().getSheet().getWorkbook().createDataFormat();fieldValue = dataFormat.getFormat((String) fieldValue);}ReflectUtil.invoke(style, invokeMethodName, fieldValue);}}//设置底纹if (styleModel.getCellShadingModel() != null) {setCellShading(style, styleModel.getCellShadingModel());}//设置字体样式FontModel fontModel = styleModel.getFontModel();if (fontModel != null) {setFontStyle(cell, style, fontModel);}//设置边框样式Map<BorderSideEnum, BorderModel> borderModelMap = styleModel.getBorderModelMap();if (borderModelMap != null && borderModelMap.size() > 0) {setBorderStyle(style, borderModelMap);}cell.setCellStyle(style);}/*** 设置底纹信息** @param style 单元格样式* @param cellShadingModel 底纹信息*/private void setCellShading(XSSFCellStyle style, CellShadingModel cellShadingModel) {//背景颜色Object backgroundColor = cellShadingModel.getBackgroundColor();//前景色Object foregroundColor = cellShadingModel.getForegroundColor();//底纹样式FillPatternType fillPatternType = cellShadingModel.getFillPattern();fillPatternType = fillPatternType == null ? FillPatternType.SOLID_FOREGROUND : fillPatternType;//背景颜色和前景色不存在时,不设置底纹if (backgroundColor == null && foregroundColor == null) {style.setFillPattern(fillPatternType);return;}//设置背景颜色(背景色和前景色都存在的情况)if (backgroundColor != null && foregroundColor != null) {//使用IndexedColors定义的颜色if (backgroundColor instanceof IndexedColors) {style.setFillBackgroundColor(((IndexedColors) backgroundColor).getIndex());}//使用自定义的RGB颜色else if (backgroundColor instanceof XSSFColor) {style.setFillBackgroundColor((XSSFColor) backgroundColor);}}//前景色不存在,设置背景色(前景色存在设置前景色)foregroundColor = foregroundColor == null ? backgroundColor : foregroundColor;//使用IndexedColors定义的颜色if (foregroundColor instanceof IndexedColors) {style.setFillForegroundColor(((IndexedColors) foregroundColor).getIndex());}//使用自定义的RGB颜色else if (foregroundColor instanceof XSSFColor) {style.setFillForegroundColor((XSSFColor) foregroundColor);}//设置底纹样式style.setFillPattern(fillPatternType);}/*** 设置字体样式** @param cell 单元格对象* @param style 单元格样式* @param fontModel 字体信息*/private void setFontStyle(Cell cell, XSSFCellStyle style, FontModel fontModel) {XSSFFont font;//样式存在字体对象时,使用原有的字体对象if (style.getFontIndex() != 0) {font = style.getFont();}//样式不存在字体对象时,创建字体对象else {font = (XSSFFont) cell.getRow().getSheet().getWorkbook().createFont();//默认字体为宋体font.setFontName("宋体");}List<Field> fieldList = FieldUtils.getFieldsListWithAnnotation(FontModel.class, ReflectField.class);if (CollUtil.isNotEmpty(fieldList)) {//使用反射给CellStyle赋值for (Field field : fieldList) {field.setAccessible(true);String fieldName = field.getName();ReflectField reflectField = field.getAnnotation(ReflectField.class);String invokeMethodName = reflectField.invokeMethodName();Object fieldValue;try {fieldValue = field.get(fontModel);} catch (IllegalAccessException e) {log.error("获取FontModel的{}属性值失败:", fieldName, e);continue;}//当前字段没有赋值if (fieldValue == null) {continue;}//字段值为IndexedColors时,字段值取索引值if (fieldValue instanceof IndexedColors) {fieldValue = ((IndexedColors) fieldValue).getIndex();}ReflectUtil.invoke(font, invokeMethodName, fieldValue);}}style.setFont(font);}/*** 设置边框样式** @param style 单元格样式* @param borderModelMap 边框信息map*/private void setBorderStyle(XSSFCellStyle style, Map<BorderSideEnum, BorderModel> borderModelMap) {//设置边框线条类型和边框线条颜色for (Map.Entry<BorderSideEnum, BorderModel> borderModelEntry : borderModelMap.entrySet()) {BorderModel borderModel = borderModelEntry.getValue();BorderSideEnum borderSideEnum = borderModelEntry.getKey();//设置边框线条类型BorderStyle borderStyle = borderModel.getBorderStyle();if (borderStyle != null) {ReflectUtil.invoke(style, borderSideEnum.getBorderStyleMethodName(), borderStyle);}//设置边框线条颜色Object borderColor = borderModel.getBorderColor();if (borderColor != null) {//使用IndexedColors定义的颜色,使用索引值if (borderColor instanceof IndexedColors) {borderColor = ((IndexedColors) borderColor).getIndex();}ReflectUtil.invoke(style, borderSideEnum.getBorderColorMethodName(), borderColor);}}}
}
4 调试代码
/*** 测试设置自定义单元格样式(支持字体样式、底纹信息、边框样式、对齐方式、自动换行、旋转文字、竖向文字、数据格式、自动收缩)*/@Testpublic void testCellStyle() {try {File file = new File("D:/easyexcel/testCellStyle.xlsx");FileUtil.createNewFile(file);//生成表格数据List<List<Object>> dataList = new ArrayList<>();dataList.add(new ArrayList<>(Arrays.asList(new Object[]{"表头11", "表头2", "表头3", "表头4"})));dataList.add(new ArrayList<>(Arrays.asList(new Object[]{"表头17777777777", "表头2", "表头3", "表头4444"})));dataList.add(new ArrayList<>(Arrays.asList(new Object[]{"表头31", "表头2", "表头3", "表头4"})));dataList.add(new ArrayList<>(Arrays.asList(new Object[]{11.111, 11.111, "11.111", "表头4444444444444444"})));//导出文件List<CellStyleModel> cellStyleList = new ArrayList<>();//设置单元格字体(黑体),单元格大小 18号,字体颜色红色,加粗,斜体,下划线,上标,删除线cellStyleList.add(CellStyleModel.createCellStyleModel("模板", 2, 0, StyleModel.createFontStyleModel(FontModel.createFontModel("黑体", 18D, IndexedColors.RED, true, true, Font.U_SINGLE, Font.SS_SUPER, true))));//设置单元格背景颜色cellStyleList.add(CellStyleModel.createCellStyleModel("模板", 0, 1, StyleModel.createCellShadingStyleModel(CellShadingModel.createCellShadingModel(null, IndexedColors.BLUE, null))));//设置单元格底纹cellStyleList.add(CellStyleModel.createCellStyleModel("模板", 0, 3, StyleModel.createCellShadingStyleModel(CellShadingModel.createCellShadingModel(FillPatternType.THICK_HORZ_BANDS, IndexedColors.RED, IndexedColors.BLUE))));//设置单元格边框类型和边框颜色cellStyleList.add(CellStyleModel.createCellStyleModel("模板", 0, 2, StyleModel.createBorderStyleModel(BorderModel.createBorderModel(BorderStyle.DOUBLE, IndexedColors.RED))));//设置对齐方式cellStyleList.add(CellStyleModel.createCellStyleModel("模板", 0, 3, StyleModel.createAlignmentStyleModel(HorizontalAlignment.RIGHT, VerticalAlignment.BOTTOM)));//设置自动换行cellStyleList.add(CellStyleModel.createCellStyleModel("模板", 1, 0, StyleModel.createWrapTextStyleModel(true)));//设置旋转角度cellStyleList.add(CellStyleModel.createCellStyleModel("模板", 0, 0, StyleModel.createRotationStyleModel((short) 90)));//设置旋转角度cellStyleList.add(CellStyleModel.createCellStyleModel("模板", 1, 0, StyleModel.createRotationStyleModel((short) -90)));//设置竖向文字cellStyleList.add(CellStyleModel.createCellStyleModel("模板", 2, 1, StyleModel.createVerticalTextStyleModel()));//设置数据格式cellStyleList.add(CellStyleModel.createCellStyleModel("模板", 3, 0, StyleModel.createDataFormatStyleModel("00")));//设置数据格式cellStyleList.add(CellStyleModel.createCellStyleModel("模板", 3, 1, StyleModel.createDataFormatStyleModel("00.00")));//设置数据格式cellStyleList.add(CellStyleModel.createCellStyleModel("模板", 3, 2, StyleModel.createDataFormatStyleModel("00.00")));//设置自动收缩cellStyleList.add(CellStyleModel.createCellStyleModel("模板", 3, 3, StyleModel.createShrinkToFitStyleModel(true)));FileOutputStream fileOutputStream = new FileOutputStream(file);ExcelWriter excelWriter = EasyExcel.write(fileOutputStream).registerWriteHandler(new CustomCellStyleHandler(cellStyleList)).build();WriteSheet writeSheet = EasyExcel.writerSheet("模板").build();excelWriter.write(dataList, writeSheet);//千万别忘记finish 会帮忙关闭流excelWriter.finish();} catch (Exception e) {e.printStackTrace();}}
5 调试结果
注:
(1)有关字体样式更详细的设置请查看以下博客。
EasyExcel 设置字体样式(字体、字体大小、字体颜色、字体加粗、字体斜体、字体下划线、字体上标下标、字体删除线)https://blog.csdn.net/qq_38974638/article/details/117388442
(2)有关自定义RGB颜色的使用请查看以下博客。
EasyExcel 单元格背景颜色、字体颜色使用2种设置颜色方法(IndexedColors中定义的颜色,自定义RGB颜色)实现https://blog.csdn.net/qq_38974638/article/details/117395831
(3)有关边框样式更详细的设置请查看以下博客。
EasyExcel 设置边框样式(线条类型和线条颜色)https://blog.csdn.net/qq_38974638/article/details/117453000
(4)觉得这篇博客写的不错的可以前往Gitee/GitCode点个Star,源码请查看Gitee/GitCode的xudongbase项目easyexcel分支。
文件 · easyexcel · 旭东怪 / Xudongbase · GitCode主要是项目中可以用到的共通方法,现有easyexcel分支在持续更新中。 欢迎大家Star和提交Issues。 easyexcel分支:批量设置样式,批量添加批注,批量合并单元格,设置冻结行和列,设置行高列宽,隐藏行和列,绑定下拉框数据,设置水印,插入图片https://gitcode.net/qq_38974638/xudongbase/-/tree/easyexcel
nullhttps://gitee.com/xudong_master/xudongbase/tree/easyexcel/
旭东怪的个人空间_哔哩哔哩_Bilibili旭东怪,人生低谷不可怕,可怕的是坚持不到人生转折点的那一天;旭东怪的主页、动态、视频、专栏、频道、收藏、订阅等。哔哩哔哩Bilibili,你感兴趣的视频都在B站。https://space.bilibili.com/484264966?spm_id_from=333.1007.0.0
EasyExcel 批量设置单元格样式(字体样式、底纹样式、边框样式、对齐方式、自动换行、旋转文字、竖向文字、数据格式、自动收缩)相关推荐
- excel 自动换行后批量设置单元格上下边距
excel 自动换行后 单元格的上下边距挨的很紧,看起来很不舒服 如下图 现在教大家 如何批量设置 单元格中有多行文本后的上下间距,设置成功后 如下图所示: 具体步骤: 1.鼠标悬停在 excel 中 ...
- PyQT5 (四十三) 在 QTableWidget 表格中设置单元格的字体和颜色 的案例
在 QTableWidget 表格中设置单元格的字体和颜色 的案例 import sysfrom PyQt5 import QtPrintSupport, QtGui from PyQt5.QtCor ...
- java 批量设置单元格边框,VC下设置Excel单元格的边框 (转)
为了能使得输出到Excel中的数据显示表格,可以调用事先设置好的模板,但是不灵活.我花了一个中午的时间摸索出如何设置它了. 具体代码如下: LPDISPATCH pRange; CString c ...
- Excel_VBA 设置单元格的字体属性(字体、字号、加粗、斜体、颜色等)
Public Sub 4_144() Dim myRange As Range Dim myFont As Font Set myRange = Range("A1") '指定任意 ...
- 设置单元格填充方式_单元格的选择及设置单元格格式
数据输入完毕,接下来可以设置字体.对齐方式.添加边框和底纹等方式设置单元格格式,从而美化工作表.要对单元格进行设置,首先要选中单元格. 选择单元格 选择单元格是指在工作表中确定活动单元格以便在单元格中 ...
- Excel VBA:设置单元格边框
Border 对象 代表对象的边框. 说明 大多数具有边框的对象(除 Range 和 Style 对象外)都将边框作为单一实体处理,而不管边框有几个边.整个边框必须作为一个整体单位返回.例如,使用 T ...
- easyExcel 导出文件时,设置单元格样式,自适应列宽
目录 1.自适应列宽实现类 2.单元格样式实现类 3.导出的时候,特殊数据类型,需要设置转换类,不然注解导出方式会报错 注解使用方式 日期转换类 4.web导出excel(将excel数据写入到res ...
- java poi excel 单元格样式_java poi批量导出excel 设置单元格样式
POI中可能会用到一些需要设置EXCEL单元格格式的操作小结: 先获取工作薄对象: HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sheet = wb ...
- XSSFWorkbook 设置单元格样式_6.6 使用单元格样式
在工作表中通常需要对单元格中的数据进行格式设置,绝大部分用户都采用手工一步一步去设置相应的格式,如下次需要在其他区域或其他工作表中设置同样的格式,又需要再进行手工设置,这样的格式设置往往十分低效,并且 ...
最新文章
- [JSOI2018]军训列队
- 错误---获取Input的值为空字符串
- java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Integer.intValue()'
- 透露抖音、腾讯、阿里、美团招开发岗位硬核面试题,轻轻松松收到offer
- VS 2013 Preview 自定义 SharePoint 2013 列表 之 两个Bug
- 使用NavigationUI更新UI组件
- oracle自带调优,oracle 参数调优
- 应届生拿到offer之后的流程_【经验】我是如何一步步拿到拼多多amp;京东amp;艺龙等多个产品offer的...
- MySQL开发医药管理系统_医药管理系统struts+hibernat+mySql,内含需求分析,详细设计文档...
- 第三方支付接口申请和开发
- Xilinx zynqmp VCU使用
- 【有利可图网】不懂ps排版?超详细排版教程送上!
- Android模拟器运行MIUI,电脑上玩小米枪战吃鸡手游 逍遥安卓模拟器设置教程
- 资深Android开发带你入门Framework,深夜思考
- Java Runtime.exec() hangs
- Java判断经纬度点是否在给定区域内
- 自定义彩色进度条效果
- gstreamer element创建
- 应用金数据在线订单功能 为中小企业带来真正价值
- 安鸾CMS系列之Wordpress02