EasyExcel版本说明

<!-- easy excel -->
<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.0.5</version>
</dependency>

自定义的注解方式实现, 这篇是我之前的写过的博客功能基础上做的补充添加.

@ExcelRequired: 作用字段, 设置Excel列头字体颜色, 默认为红色, 标记此列为必填项, 可传参IndexedColors枚举指定颜色;

@ExcelNotation: 作用字段, 设置Excel列批注说明, 默认为空, 可以传参批注想要的备注信息内容;

@ExcelSelector: 作用字段, 导出Excel单元格的下拉选默认数据, 如不需要, 可以忽略, 如有需要可以找我博客, 有具体说明使用, 使用说明链接地址: https://blog.csdn.net/weixin_41481806/article/details/126978596

展示效果

类ExcelRequired

@Target(FIELD)
@Retention(RUNTIME)
public @interface ExcelRequired {/*** 字体颜色*/IndexedColors frontColor() default IndexedColors.RED;
}

类ExcelNotation

@Target(FIELD)
@Retention(RUNTIME)
public @interface ExcelNotation {/*** 文本内容*/String value() default "";
}

Excel工具类

@Slf4j
public class ExcelUtil {/*** 默认的sheet名称*/private static final String DEFAULT_SHEET_NAME = "Sheet1";/*** 写Excel数据** @param response response* @param fileName 文件名称* @param data     数据* @param clazz    类class* @author SunLingDa* @date 2022/9/6 13:59*/public static <T> void writeExcel(HttpServletResponse response, String fileName, List<T> data, Class<?> clazz) {writeExcel(response, fileName, DEFAULT_SHEET_NAME, data, clazz);}/*** 写Excel数据** @param response  response* @param fileName  文件名称* @param sheetName sheet名称* @param data      数据* @param clazz     类class* @author SunLingDa* @date 2022/9/6 13:58*/public static <T> void writeExcel(HttpServletResponse response, String fileName, String sheetName, List<T> data, Class<?> clazz) {OutputStream outputStream = null;Map<Integer, Short> requiredMap = getRequiredMap(clazz);Map<Integer, String> notationMap = getNotationMap(clazz);Map<Integer, ExcelSelectorResolve> selectedMap = getSelectedMap(clazz);ExcelSelectorDataWriteHandler writeHandler = new ExcelSelectorDataWriteHandler(notationMap, requiredMap, selectedMap);try {outputStream = getOutputStream(response, fileName, ExcelTypeEnum.XLSX);ExcelWriterSheetBuilder builder = EasyExcel.write(outputStream, clazz).excelType(ExcelTypeEnum.XLSX).sheet(sheetName);builder.registerWriteHandler(writeHandler).doWrite(data);} catch (Exception e) {log.error(e.getMessage(), e);} finally {if (outputStream != null) {try {outputStream.close();} catch (IOException e) {log.error(e.getMessage(), e);}}}}/*** 读取不包含头信息的Excel** @param file  文件* @param clazz 类class* @author SunLingDa* @date 2022/9/6 13:20*/public static <T> List<T> readExcelNotContainHeader(MultipartFile file, Class<T> clazz) throws IOException {return readExcel(1, file, clazz);}/*** 读取包含头信息的Excel** @param file  文件* @param clazz 类class* @author SunLingDa* @date 2022/9/6 13:20*/public static <T> List<T> readExcelContainHeader(MultipartFile file, Class<T> clazz) throws IOException {return readExcel(0, file, clazz);}/*** 读取Excel** @param rowNum 行数* @param file   文件* @param clazz  类class* @author SunLingDa* @date 2022/9/6 13:20*/public static <T> List<T> readExcel(int rowNum, MultipartFile file, Class<T> clazz) throws IOException {String fileName = file.getOriginalFilename();InputStream inputStream = file.getInputStream();return readExcel(rowNum, fileName, inputStream, clazz);}/*** 读取不包含头信息的Excel** @param fileName    文件名称* @param inputStream 流* @param clazz       类* @author SunLingDa* @date 2022/9/6 13:16*/public static <T> List<T> readExcelNotContainHeader(String fileName, InputStream inputStream, Class<T> clazz) {return readExcel(1, fileName, inputStream, clazz);}/*** 读取包含头信息的Excel** @param fileName    文件名称* @param inputStream 流* @param clazz       类* @param listener    监听* @author SunLingDa* @date 2022/9/6 13:16*/public static <T> List<T> readExcelContainHeader(String fileName, InputStream inputStream, Class<T> clazz, ExcelCellDataListener<T> listener) {return readExcel(0, fileName, inputStream, clazz);}/*** 读取Excel** @param rowNum      行数* @param fileName    文件名称* @param inputStream 流* @param clazz       类* @author SunLingDa* @date 2022/9/6 13:16*/public static <T> List<T> readExcel(int rowNum, String fileName, InputStream inputStream, Class<T> clazz) {ExcelCellDataListener<T> dataListener = new ExcelCellDataListener<>();try {ExcelReader excelReader = getExcelReader(rowNum, fileName, inputStream, clazz, dataListener);if (excelReader == null) {return null;}List<ReadSheet> sheetList = excelReader.excelExecutor().sheetList();for (ReadSheet sheet : sheetList) {excelReader.read(sheet);}excelReader.finish();} finally {try {inputStream.close();} catch (IOException e) {log.error(e.getMessage(), e);}}return dataListener.getData();}/*** 获取OutputStream** @param response response* @param fileName 文件名称* @return java.io.OutputStream* @author SunLingDa* @date 2022/9/6 13:44*/private static OutputStream getOutputStream(HttpServletResponse response, String fileName, ExcelTypeEnum typeEnum) throws Exception {fileName = URLEncoder.encode(fileName, "UTF-8");response.setStatus(200);response.setCharacterEncoding("UTF-8");if (ExcelTypeEnum.CSV.equals(typeEnum)) {response.setContentType("application/csv");} else {response.setContentType("application/vnd.ms-excel");}response.setHeader("Content-Disposition", "attachment;filename=" + fileName + typeEnum.getValue());return response.getOutputStream();}/*** 获取ExcelReader** @param rowNum      行数* @param fileName    文件名称* @param inputStream 流* @param clazz       类class* @param listener    监听* @return com.alibaba.excel.ExcelReader* @author SunLingDa* @date 2022/9/6 13:19*/private static ExcelReader getExcelReader(int rowNum, String fileName, InputStream inputStream, Class<?> clazz, ReadListener listener) {if (StrUtil.isBlank(fileName)) {return null;}String fileExtName = getFileExtName(fileName);EasyExcelTypeEnum typeEnum = EasyExcelTypeEnum.parseType(fileExtName);if (typeEnum == null) {log.info("表格类型错误");}return EasyExcel.read(inputStream, clazz, listener).headRowNumber(rowNum).build();}/*** 获取文件后缀名称 .xxx** @param fileName 文件名称* @return java.lang.String* @author SunLingDa* @date 2022/9/6 11:23*/private static String getFileExtName(String fileName) {if (StrUtil.isBlank(fileName)) {return null;}int lastIndex = fileName.lastIndexOf(StrUtil.DOT);if (lastIndex != -1) {return fileName.substring(lastIndex);}return null;}/*** 获取样式** @return com.alibaba.excel.write.style.HorizontalCellStyleStrategy* @author SunLingDa* @date 2022/9/6 16:20*/private static HorizontalCellStyleStrategy getStyleStrategy() {// 表头样式WriteCellStyle headStyle = new WriteCellStyle();// 设置表头居中对齐headStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);// 内容样式WriteCellStyle contentStyle = new WriteCellStyle();// 设置内容靠左对齐contentStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);return new HorizontalCellStyleStrategy(headStyle, contentStyle);}/*** 获取下拉的map** @param clazz 类class* @return java.util.Map<java.lang.Integer, cn.com.zxelec.common.resolve.ExcelSelectorResolve>* @author SunLingDa* @date 2022/9/20 17:45*/private static Map<Integer, ExcelSelectorResolve> getSelectedMap(Class<?> clazz) {Map<Integer, ExcelSelectorResolve> selectedMap = CollUtil.newHashMap();Field[] fields = clazz.getDeclaredFields();for (Field field : fields) {if (!field.isAnnotationPresent(ExcelSelector.class) || !field.isAnnotationPresent(ExcelProperty.class)) {continue;}ExcelSelector excelSelector = field.getAnnotation(ExcelSelector.class);ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);ExcelSelectorResolve resolve = new ExcelSelectorResolve();String[] data = resolve.resolveExcelSelector(excelSelector);if (ArrayUtil.isNotEmpty(data)) {resolve.setSelectorData(data);selectedMap.put(excelProperty.index(), resolve);}}return selectedMap;}/*** 获取必填列Map** @param clazz 类class* @return java.util.Map<java.lang.Integer, java.lang.Short>* @author SunLingDa* @date 2022/11/3 13:23*/private static Map<Integer, Short> getRequiredMap(Class<?> clazz) {Map<Integer, Short> requiredMap = CollUtil.newHashMap();Field[] fields = clazz.getDeclaredFields();for (Field field : fields) {if (!field.isAnnotationPresent(ExcelRequired.class) || !field.isAnnotationPresent(ExcelRequired.class)) {continue;}ExcelRequired excelRequired = field.getAnnotation(ExcelRequired.class);ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);requiredMap.put(excelProperty.index(), excelRequired.frontColor().getIndex());}return requiredMap;}/*** 获取批注Map** @param clazz 类class* @return java.util.Map<java.lang.Integer, java.lang.String>* @author SunLingDa* @date 2022/11/3 13:24*/private static Map<Integer, String> getNotationMap(Class<?> clazz) {Map<Integer, String> notationMap = CollUtil.newHashMap();Field[] fields = clazz.getDeclaredFields();for (Field field : fields) {if (!field.isAnnotationPresent(ExcelNotation.class) || !field.isAnnotationPresent(ExcelRequired.class)) {continue;}ExcelNotation excelNotation = field.getAnnotation(ExcelNotation.class);ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);notationMap.put(excelProperty.index(), excelNotation.value());}return notationMap;}
}

主要的内容, 如下图, 下拉选不需要可以忽略, 然后主要的就是对应的处理器了

Excel处理器的代码, 主要的三个Map, 可根据自己的需求选择

@Data
public class ExcelSelectorDataWriteHandler implements SheetWriteHandler, CellWriteHandler {/*** 批注*/private final Map<Integer, String> notationMap;/*** 头列字体颜色*/private final Map<Integer, Short> headColumnMap;/*** 下拉选数据*/private final Map<Integer, ExcelSelectorResolve> selectedMap;@Overridepublic void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {Sheet sheet = writeSheetHolder.getSheet();DataValidationHelper helper = sheet.getDataValidationHelper();if (CollUtil.isEmpty(selectedMap)) {return;}selectedMap.forEach((k, v) -> {// 下拉 首行 末行 首列 末列CellRangeAddressList list = new CellRangeAddressList(v.getStartRow(), v.getEndRow(), k, k);// 下拉值DataValidationConstraint constraint = helper.createExplicitListConstraint(v.getSelectorData());DataValidation validation = helper.createValidation(constraint, list);validation.setErrorStyle(DataValidation.ErrorStyle.STOP);validation.setShowErrorBox(true);validation.setSuppressDropDownArrow(true);validation.createErrorBox("提示", "请输入下拉选项中的内容");sheet.addValidationData(validation);});}@Overridepublic void afterCellDispose(CellWriteHandlerContext context) {WriteCellData<?> cellData = context.getFirstCellData();WriteCellStyle writeCellStyle = cellData.getOrCreateStyle();DataFormatData dataFormatData = new DataFormatData();// 单元格设置为文本格式dataFormatData.setIndex((short) 49);writeCellStyle.setDataFormatData(dataFormatData);if (context.getHead()) {Cell cell = context.getCell();WriteSheetHolder writeSheetHolder = context.getWriteSheetHolder();Sheet sheet = writeSheetHolder.getSheet();Workbook workbook = writeSheetHolder.getSheet().getWorkbook();Drawing<?> drawing = sheet.createDrawingPatriarch();// 设置标题字体样式WriteFont headWriteFont = new WriteFont();// 加粗headWriteFont.setBold(true);if (CollUtil.isNotEmpty(headColumnMap) && headColumnMap.containsKey(cell.getColumnIndex())) {// 设置字体颜色headWriteFont.setColor(headColumnMap.get(cell.getColumnIndex()));}writeCellStyle.setWriteFont(headWriteFont);CellStyle cellStyle = StyleUtil.buildCellStyle(workbook, null, writeCellStyle);cell.setCellStyle(cellStyle);if (CollUtil.isNotEmpty(notationMap) && notationMap.containsKey(cell.getColumnIndex())) {// 批注内容String notationContext = notationMap.get(cell.getColumnIndex());// 创建绘图对象Comment comment = drawing.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), 0, (short) 5, 5));comment.setString(new XSSFRichTextString(notationContext));cell.setCellComment(comment);}}}
}

主要在方法afterCellDispose的if (context.getHead()) 部分, 如下图

EasyExcel导出设置表头字体样式和批注相关推荐

  1. easyexcel 导出设置标题_EasyPoi设置Excel导出样式(边框,背景色,字体)

    **导出样式如下图** **使用方式** 创建一个样式工具类.工具类如下: import cn.afterturn.easypoi.excel.entity.params.ExcelExportEnt ...

  2. EasyExcel 批量设置单元格样式(字体样式、底纹样式、边框样式、对齐方式、自动换行、旋转文字、竖向文字、数据格式、自动收缩)

    目录 1 Maven配置 2 CellStyleModel 3 CustomCellStyleHandler 4 调试代码 5 调试结果 注: 1 Maven配置 <!--hutool工具包-- ...

  3. Android中对同一个TextView设置不同字体样式

    这个只是做一个笔记,详情见代码: 代码中的注释也有说明. TextView textView = (TextView) findViewById(R.id.textView1);SpannableSt ...

  4. 在html中设置全局字体样式

    背景 需要对一个没有设置布局样式的html文档中所有文字样式进行修改,作为一个不是很了解前端开发的人来说,自然是想有没有那种比较简单,能在html中加几行代码就把所有段落字体样式进行统一修改的案例,网 ...

  5. java如何设置控制台打印的字体颜色、背景、字体样式(idea设置打印字体样式)工具类 - 附插件方式

    效果: 设置控制台打印字体颜色.背景.字体样式,java工具类 package org.dxl.log;import java.util.Arrays;/*** 在控制台按照传入格式输出 ** @au ...

  6. java读取word文件并设置其字体样式_Java读取word文件,字体,颜色(示例代码)

    在Android读取Word文件时,在网上查看时可以用tm-extractors,但好像没有提到怎么读取Word文档中字体的颜色,字体,上下标等相关的属性.但由于需要,要把doc文档中的内容(字体,下 ...

  7. html字体字号颜色怎么设置,html字体样式大全 html怎么改变字体大小和颜色

    网页字体样式华文黑体:STHeiti 网页字体样式华文楷体:STKaiti 网页字体样式华文宋体:STSong 网页字体样式华文仿宋:STFangsong 网页字体样式黑体:SimHei 网页字体样式 ...

  8. 【CSS】CSS 文本样式 ② ( font 字体设置 | CSS 2.0手册使用 | font-weight 字体粗细设置 | font-style 字体斜体设置 | font 字体样式综合写法 )

    文章目录 一. CSS 2.0手册使用 1. 按照文档层次查找 2. 搜索关键字查找文档 二. font-weight 字体粗细设置 1. 语法简介 2. 代码示例 三. font-style 字体斜 ...

  9. 详解CSS设置默认字体样式

    浏览器默认的样式往往在不同的浏览器.不同的语言版本甚至不同的系统版本都有不同的设置,这就导致如 果直接利用默认样式的页面在各个浏览器下显示非常不一致,于是就有了类似YUI的reset之类用来尽量重写浏 ...

  10. [转]解析CSS设置默认字体样式

    默认字体样式会因为浏览器不同,版本不同,甚至操作系统不同的设置不同导致如果直接利用默认样式的页面在各个浏览器下显示非常不一致,于是就有了类似YUI的reset之类用来尽量重写浏览器的默认设置保证各个浏 ...

最新文章

  1. FineUIMvc随笔(6)对比WebForms和MVC中表格的数据库分页
  2. Parameter 对象
  3. Spark数据倾斜的完美解决
  4. java uuid静态方法_Java UUID version()方法与示例
  5. 多路归并排序_字节跳动面试:5 亿整数的大文件,如何排序 ?
  6. 第三章 第一部分 不定积分例题
  7. 当年叱咤风云的框架Struts2,你可知Struts2内功如何修炼之体系结构
  8. 在Pandas DataFrame中重塑数据
  9. java 进销存源码_JAVA 进销存管理系统的源码 - 下载 - 搜珍网
  10. windows10专业版安装详细教程
  11. python函数自己调用自己_python怎么调用自己的函数
  12. 用python画满屏爱心_python怎么画爱心
  13. 关于技术部管理的一些思考
  14. 怎么做百度360今日头条1688搜狗下拉词?宙斯下拉、54小超人下拉、超人2下拉
  15. 使用C#通过串口控制IT6333B电流源
  16. DOS窗口命令--实用完整版
  17. 服务机器人常用的定位导航技术及优缺点分析
  18. 【前端】particle.js页面粒子效果
  19. DH2F200N6S-ASEMI快恢复模块200A 600V
  20. 惟缓存DNS服务器与备用DNS服务器配置

热门文章

  1. 浙江大学黄杨思博计算机学院,竺可桢学院2010-2011学年荣誉称号发文名单
  2. 长安清酒·花酿清酒一瓣心醉的甜香
  3. kthreaddk病毒查杀记录
  4. 动手学数据分析(三)- 数据重构
  5. 票务公司加价将儿童机票售成年人赚取差价
  6. 无法查找网络工作组计算机,无法查看工作组计算机怎么解决
  7. 数据库无法连接的几种情况
  8. 硅谷的工作狂文化在冠状病毒的压力下变化-苹果,谷歌,Facebook,LinkedIn和优步推出了新的在家工作政策
  9. 世界五大黑客:代码创造他们,他们改变世界!
  10. 奇安信天擎的退出以及卸载