文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

easyexcel 实现表头批注

2023-09-16 15:09

关注

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

以下是表头代码实现;

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实体类

@Datapublic class CtmsSubSaeExcel implements Serializable {        @ExcelProperty(value = "受试者筛选号",index = 0)    @ColumnWidth(12)    @ExcelValid(message = "受试者筛选号不能为空")    @ExcelNotation(value = "受试者筛选号不能为空",remarkColumnWide =(short) 1)    private String subjectCode;        @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 "";        int remarkRowHigh() default 0;        int remarkColumnWide() default 0;

校验是否为空 工具

public class ExcelImportValid {        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) {// 操作数据库    }}

备注使用的实体

@Datapublic class ExcelComment {        private Integer column;        private String remarkValue;        int remarkRowHigh;        int remarkColumnWide;        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 ,我这里是从对应的实体中设置获取的。
在这里插入图片描述

备注解析

        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()));        }    }

效果;

在这里插入图片描述

来源地址:https://blog.csdn.net/qq_43049310/article/details/130697234

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯