easyexcel 实现表头批注

这篇具有很好参考价值的文章主要介绍了easyexcel 实现表头批注。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

场景;在业务逻辑中,导出的时候需要给客户提供下载的模版,上传的文件有些字段值需要验证,如果不按照验证的规则,后端解析的时候就会失败,所以在导出模版需要给客户一个提示,一种方法是下载的模版中加入示例数据,另外一种就是在表头添加上备注。

以下是表头代码实现;

easyexcel 依赖以及对应的poi
  <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>3.1.1</version>
            <exclusions>
                <exclusion>
                    <groupId>javax.servlet</groupId>
                    <artifactId>servlet-api</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.poi</groupId>
                    <artifactId>poi</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.poi</groupId>
                    <artifactId>poi-ooxml</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.poi</groupId>
                    <artifactId>poi-ooxml-schemas</artifactId>
                </exclusion>
            </exclusions>

        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.2</version>
        </dependency>

easyexcel实体类
@Data
public class CtmsSubSaeExcel implements Serializable {




    /**
     * 受试者筛选号
     */
    @ExcelProperty(value = "受试者筛选号",index = 0)
    @ColumnWidth(12)
    @ExcelValid(message = "受试者筛选号不能为空")
    @ExcelNotation(value = "受试者筛选号不能为空",remarkColumnWide =(short) 1)
    private String subjectCode;


    /**
     * SAE编号
     */
    @ExcelProperty(value = "SAE编号唯一标识",index = 1)
    @ExcelValid(message = "SAE编号不能为空")
    @ColumnWidth(12)
    private String saeNum;

    
    @ExcelProperty(value = "SAE的医学术语",index = 2)
    @ColumnWidth(12)
    private String saeMedicalTerm;
    
}
@ExcelValid ;校验必填字段
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelValid {

    String message() default "导入有未填入的字段";

}

@ExcelNotation ;自定义备注注解 。注意 @ExcelProperty必须加上index 不然获取的时候会有问题
@Target(FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelNotation {

    /**
     * 文本内容
     */
    String value() default "";

    /**
     * 批注行高, 一般不用设置
     * 这个参数可以设置不同字段 批注显示框的高度
     * @return
     */
    int remarkRowHigh() default 0;

    /**
     * 批注列宽, 根据导出情况调整
     * 这个参数可以设置不同字段 批注显示框的宽度
     * @return
     */
    int remarkColumnWide() default 0;

校验是否为空 工具
public class ExcelImportValid {


    /**
     * Excel导入字段校验
     * @param object 校验的JavaBean 其属性须有自定义注解
     */
    public static void valid(Object object) {
        Field[] fields = object.getClass().getDeclaredFields();
        for (Field field : fields) {
            //设置可访问
            field.setAccessible(true);
            //属性的值
            Object fieldValue = null;
            try {
                fieldValue = field.get(object);
            } catch (IllegalAccessException e) {
                throw ServiceExceptionUtil.exception(new ErrorCode(9999,
                        field.getAnnotation(ExcelValid.class).message()));
            }
            //是否包含必填校验注解
            boolean isExcelValid = field.isAnnotationPresent(ExcelValid.class);
            if (isExcelValid && Objects.isNull(fieldValue)) {
				// 返回自定义的异常 提示
                throw ServiceExceptionUtil.exception(new ErrorCode(9999,field.getAnnotation(ExcelValid.class).message()));
            }

        }
    }



}
导入数据的监听器
public class SubSAEListener extends AnalysisEventListener<CtmsSubSaeExcel> {


    @Override
    public void invoke(CtmsSubSaeExcel data, AnalysisContext context) {
    	// 获取行号
        Integer rowIndex = context.readRowHolder().getRowIndex();
        // 校验必填
        ExcelImportValid.valid(data);
  		// 操作数据值
     
    }

    @Override
    public void onException(Exception exception, AnalysisContext context) throws Exception {
        batchAddList.clear();
        batchUpdateList.clear();
        super.onException(exception, context);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
		// 操作数据库

    }
}
备注使用的实体
@Data
public class ExcelComment {

    /** 列号 */
    private Integer column;

    /** 批注值 */
    private String remarkValue;

    /** 批注行高 */
    int remarkRowHigh;

    /** 批注列宽 */
    int remarkColumnWide;

    /**
     * 批注所在行
     *
     * @return int
     */
    int row;



}

备注注册器
public class CommentCellWriteHandler implements CellWriteHandler {


    /**
     * 批注
     */
    private final Map<Integer, ExcelComment> notationMap;

    public CommentCellWriteHandler(Map<Integer, ExcelComment> notationMap) {
        this.notationMap = notationMap;
    }



    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
                                 List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
		// 这里使用isHead判断 是否是表头的时候为true ,填入数据的时候是false , 之前使用head判断,调整表头备注只能有一个,切记
        if(isHead){ 
            Sheet sheet = writeSheetHolder.getSheet();
            Drawing<?> drawingPatriarch = sheet.createDrawingPatriarch();
            if (CollUtil.isNotEmpty(notationMap) && notationMap.containsKey(cell.getColumnIndex())) {
                // 批注内容
                ExcelComment excelComment = notationMap.get(cell.getColumnIndex());
                if(Objects.nonNull(excelComment)){
                    // 创建绘图对象
                    Comment comment = drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), 0,
                        (short)excelComment.getRemarkColumnWide(), 1));
                    comment.setString(new XSSFRichTextString(excelComment.getRemarkValue()));
                    cell.setCellComment(comment);
                }

            }
        }
    }


}

红线部分。是用来这是批注的宽度和高度,默认是0 ,我这里是从对应的实体中设置获取的。
easyexcel 写表头,easyexcel,java

备注解析
    /**
     * 获取批注Map
     *
     * @param clazz 类class
     * @return java.util.Map<java.lang.Integer, java.lang.String>
     * @author SunLingDa
     * @date 2022/11/3 13:24
     */
    public static Map<Integer, ExcelComment> getNotationMap(Class<?> clazz) {
        Map<Integer, ExcelComment> notationMap = new HashMap<>();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            if (!field.isAnnotationPresent(ExcelNotation.class) ) {
                continue;
            }
            ExcelComment excelComment = new ExcelComment();
            ExcelNotation excelNotation = field.getAnnotation(ExcelNotation.class);
            ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
            excelComment.setRemarkValue(excelNotation.value());
            excelComment.setRemarkColumnWide(excelNotation.remarkColumnWide());
            notationMap.put(excelProperty.index(), excelComment);
        }
        return notationMap;
    }

业务实现
 @PostMapping("/test")
    public void exportSubSAEExcel(HttpServletResponse response){

        try {
       
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            // 防止中文乱码
            String fileName = URLEncoder.encode("SAE", "UTF-8")
                    .replaceAll("\\+","%20");
            response.setHeader("Content-disposition", "attachment;filename*=UTF-8''" + fileName + ExcelTypeEnum.XLSX.getValue());
            //响应的输入流
            ServletOutputStream outputStream = response.getOutputStream();
            // workbook
            ExcelWriterBuilder writeWorkBook = EasyExcel.write(outputStream, CtmsSubSaeExcel.class).inMemory(Boolean.TRUE).inMemory(Boolean.TRUE)
                    .head(CtmsSubSaeExcel.class)
                    .useDefaultStyle(false)
                    .registerWriteHandler(new CommentCellWriteHandler(getNotationMap(CtmsSubSaeExcel.class))));// 添加备注的监听器
           
            // sheet
            writeWorkBook.sheet().sheetName("SAE").sheetNo(0).doWrite(ctmsSubSaeExcels);
            outputStream.flush();
            outputStream.close();


        }catch (IOException e){
            throw ServiceExceptionUtil.exception(new ErrorCode(9999,"导出失败"));
        }catch (IllegalArgumentException e){
            throw ServiceExceptionUtil.exception(new ErrorCode(9999,e.getMessage()));
        }

    }

效果;

easyexcel 写表头,easyexcel,java文章来源地址https://www.toymoban.com/news/detail-639202.html

到了这里,关于easyexcel 实现表头批注的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • EasyExcel复杂表头数据导入

    参考文章:EasyExcel动态复杂表头导出方法

    2024年02月06日
    浏览(42)
  • EasyExcel解析动态表头及导出

    前言 excel文件导入及导出,是日常开发中经常遇到的需求。本次笔者以EasyExcel为例,针对在项目中遇到的 动态表头解析及导出 的场景,详细介绍具体的代码实现过程。 参考地址 https://github.com/alibaba/easyexcel 前端下载 模板下载 excel文件导入功能,常常需要进行模板下载,在

    2023年04月09日
    浏览(35)
  • 使用easyexcel 导出多级表头demo

    先看效果: 1、引入maven依赖 2、实体类 3、web导出 controller 4、在拦截器中对表头的样式进行自定义的覆盖

    2024年01月18日
    浏览(42)
  • EasyExcel复杂表头导出(一对多)升级版

            在之前写的 EasyExcel复杂表头导出(一对多)的博客的结尾,受限于当时的能力和精力,留下一些问题及展望。现在写下此博客,目的就是解决之前遗留的问题。         背景介绍,见上述链接指向的博客,这里主要通过 自定义拦截器 的形式来完美解决。 对于图

    2024年02月06日
    浏览(59)
  • easyExcel 获取多个sheet中复杂表头的数据

    EasyExcel是一个强大且易于使用的Java库,用于简化Excel文件的读写操作。它是阿里巴巴开源的一个基于POI实现的Excel处理工具,并提供了一组简单的API来处理Excel文件,包括读取、写入和转换。 EasyExcel的特点包括: 易于使用:EasyExcel提供了简单而直观的API,使得读取、写入和转

    2024年01月21日
    浏览(40)
  • 【EasyExcel】导出excel冻结表头和冻结指定列并支持筛选器

    需求背景:         导出excel的同时冻结表头和前两列基础信息,方便导出后用户查看信息。 一、技术选型:         easyExcel的自定义写策略处理:SheetWriteHandler 二、方案设计:(基于实现 SheetWriteHandler 接口)         1、重写afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder,

    2024年01月24日
    浏览(44)
  • java poi实现Excel多级表头导出

    最近碰到一个导出,比较繁琐,也查询了许多博客,在其中一篇博客的基础上修改,实现了最终想要的效果。话不多说,直接上效果图 1.主代码: 2.合并单元格 3.设置表头单元格的宽度 4.填充数据(注:我这里的数据格式是ListMapString, Object类型,可以根据自己的实际情况来封

    2024年02月03日
    浏览(45)
  • JAVA实现easyExcel批量导入

    注解 类型 描述 ExcelProperty 导入 指定当前字段对应excel中的那一列。可以根据名字或者Index去匹配。当然也可以不写,默认第一个字段就是index=0,以此类推。千万注意,要么全部不写,要么全部用index,要么全部用名字去匹配。千万别三个混着用,除非你非常了解源代码中三个

    2024年04月27日
    浏览(38)
  • Java 使用 EasyExcel 实现导入导出(新手篇教程)

    官网镇楼↓,觉得我写的不好的同学可以去官网看哦 EasyExcel 示例: 如上一个简易 Excel 表格,表头占了两行,且第三列开始才为有效数据,那么我们应该如何导入? 建造实体类 首先无论是导入还是导出,都需要先建对应的实体类  如图所示,因为我的示例 Excel 一共需要读

    2024年04月17日
    浏览(40)
  • java实现excel的导出之使用easyExcel

    在我们的项目需求中,经常会遇到导出的需求,其中excel的导出最为常见。生成Excel比较有名的框架有Apache poi,jxl等,但他们都存在一个严重的问题就是非常的耗内存,如果你的系统并发量不大的话可能还行,但是一旦并发上来后一定会OOM或者JVM频繁的full gc. EasyExcel是阿里巴巴

    2024年02月15日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包