EasyPoi导出 导入(带校验)简单示例 EasyExcel

官方文档 : http://doc.wupaas.com/docs/easypoi

pom的引入:

<!--        easyPoi-->
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-spring-boot-starter</artifactId>
            <version>4.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.4.1.Final</version>
        </dependency>
<!--        hutool-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-core</artifactId>
            <version>5.7.7</version>
        </dependency>

1.建立一个对象体

@Data
public class EasyPoiEntity {
    @Excel(name = "姓名")
    private String name;
    @Excel(name = "年龄")
    private int age;
    @Excel(name = "地址")
    private String addr;

}

2.导出代码

    @GetMapping("/exportExcel")
    public void test(HttpServletRequest request, HttpServletResponse response)throws IOException {
    //模拟数据  实际基本查数据
        EasyPoiEntity easyPoiEntity = new EasyPoiEntity();
        easyPoiEntity.setName("张三");
        easyPoiEntity.setAddr("中国");
        easyPoiEntity.setAge(18);
        List<EasyPoiEntity> list = new ArrayList<>();
        list.add(easyPoiEntity);
        //2.封装成表格
        //参数1:表格标题,参数2:sheet名称
//        ExportParams exportParams = new ExportParams("学生信息", "1班学生信息");
        ExportParams exportParams = new ExportParams();
        exportParams.setSheetName("学生信息");
        exportParams.setStyle(EasyExcelStyleType.ONE.getCla());
        //参数1:表格参数  参数2:实体类  参数3:数据
        Workbook sheets = ExcelExportUtil.exportExcel(exportParams, EasyPoiEntity.class, list);

        //3.返回表格
        //设置表格文件名字
        // 生成时间戳
        String timestamp = DateUtil.format(LocalDateTime.now(), "yyyyMMddHHmmss");
        String fileName = "一班学生数据-"+timestamp;
        fileName = URLEncoder.encode(fileName,"UTF8");
        //设置返回数据类型
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xls");

        //将表格输出
        sheets.write(response.getOutputStream());

    }

导出Excel
在这里插入图片描述

导入例子

1.对象加上校验注解 实现 IExcelDataModel, IExcelModel

@Data
public class EasyPoiEntity implements IExcelDataModel, IExcelModel {
    @Excel(name = "姓名")
    @Pattern(regexp = "[\u4E00-\u9FA5]*", message = "不是中文")
    private String name;
    @Max(value = 15,message = "max 最大值不能超过15")
    @Excel(name = "年龄")
    private int age;
    @NotNull(message = "地址不能为空")
    @Excel(name = "地址")
    private String addr;

    /**
     * 行号
     */
    private int rowNum;

    /**
     * 错误消息
     */
    private String errorMsg;

}

导入代码 params.setVerifyHandler(excelVerifyInfo);看后面

    @PostMapping("/importExcel")
    @ResponseBody
    public Object importUser(@RequestParam("uploadFile") MultipartFile multipartFile,HttpServletResponse resp) {
        ImportParams params = new ImportParams();

        /**
         * 这里需要注意表头的行数设置一定要正确!否则集合数据将无法读取,
         * 可以通过WPS或者office查看实际表头所占用的行数,
         * 一定要区分表头与标题的区别,表头是列名称,标题是表头上面的文字,
         * 本文示例文件中没有标题,所以setTitleRows为0
         */
        // 设置表头行数
        params.setHeadRows(1);
        // 标题行设置为0行,默认是0,可以不设置
        params.setTitleRows(0);
//        代表导入这里是需要验证的(根据字段上的注解校验)
        params.setNeedVerify(true);
        //设及一个自定义校验 (自定义校验名字不可重复)
        params.setVerifyHandler(excelVerifyInfo);
        try {
            ExcelImportResult<EasyPoiEntity> importResult = ExcelImportUtil.importExcelMore(multipartFile.getInputStream(), EasyPoiEntity.class, params);
            boolean verfiyFail = importResult.isVerfiyFail();
            System.out.println(verfiyFail);
            System.out.println(importResult.getFailList().toString());
            System.out.println(importResult.getList().toString());

            //验证是否有失败的数据
            if (importResult.isVerfiyFail()) {
                ServletOutputStream fos = resp.getOutputStream();
                //mime类型
                resp.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
                // 生成时间戳
                String timestamp = DateUtil.format(LocalDateTime.now(), "yyyyMMddHHmmss");

                resp.setHeader("Content-disposition", "attachment;filename=" + timestamp + "-error.xlsx");
                importResult.getFailWorkbook().write(fos);
                fos.close();
            }
            return importResult.getList();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

导入Excel例子
在这里插入图片描述
返回的异常Excel
在这里插入图片描述
对于想自定义异常的 自己写一个实现类实现 IExcelVerifyHandler<>即可
代码如下:

@Component
public class  ExcelVerifyInfo implements IExcelVerifyHandler<EasyPoiEntity> {
    private final ThreadLocal<List<EasyPoiEntity>> threadLocal = new ThreadLocal<>();
    @Override
    public ExcelVerifyHandlerResult verifyHandler(EasyPoiEntity easyPoiEntity) {
        StringJoiner joiner = new StringJoiner(",");
        List<EasyPoiEntity> threadLocalVal = threadLocal.get();
        if (threadLocalVal == null) {
            threadLocalVal = new ArrayList<>();
        }

        /**
         * 所有的自定义校验 可以再这里写 比如查数据 比较之类
         */
//        if (easyPoiEntity.getName().equals("张三")){
//            joiner.add("eeeeee");
//        }


        threadLocalVal.forEach(e -> {
            if (e.getName().equals(easyPoiEntity.getName())) {
                int lineNumber = e.getRowNum() + 1;
                joiner.add("名字与" + lineNumber + "行重复");
            }
        });
        // 添加本行数据对象到ThreadLocal中
        threadLocalVal.add(easyPoiEntity);
        threadLocal.set(threadLocalVal);
        if (!Objects.equals(joiner.length(),0)) {
            return new ExcelVerifyHandlerResult(false, joiner.toString());
        }
        return new ExcelVerifyHandlerResult(true);
    }
}

关于空行问题

Excel经常会有空行但是有格式的行 我们读取的时候 会读到这些行 然后对象就都是空的 这可能会影响到数据的处理 我是在校验类里面做了判断 如下:

@Component
public class  ExcelVerifyInfo implements IExcelVerifyHandler<EasyPoiEntity> {
    private final ThreadLocal<List<EasyPoiEntity>> threadLocal = new ThreadLocal<>();
    @Override
    public ExcelVerifyHandlerResult verifyHandler(EasyPoiEntity easyPoiEntity) {
        if ( StringUtils.isAllBlank(easyPoiEntity.getName(), easyPoiEntity.getAddr()) && Objects.equals(easyPoiEntity.getAge(),0)) {
            // 空行数据,返回false表示无效,EasyPoi会过滤掉该行数据
            return new ExcelVerifyHandlerResult(false);
        } else {
            // 非空行数据,返回true表示有效
            StringJoiner joiner = new StringJoiner(",");
            List<EasyPoiEntity> threadLocalVal = threadLocal.get();
            if (threadLocalVal == null) {
                threadLocalVal = new ArrayList<>();
            }

            /**
             * 所有的自定义校验 可以再这里写 比如查数据 比较之类
             */
//        if (easyPoiEntity.getName().equals("张三")){
//            joiner.add("eeeeee");
//        }


            threadLocalVal.forEach(e -> {
                if (e.getName().equals(easyPoiEntity.getName())) {
                    int lineNumber = e.getRowNum() + 1;
                    joiner.add("名字与" + lineNumber + "行重复");
                }
            });
            // 添加本行数据对象到ThreadLocal中
            threadLocalVal.add(easyPoiEntity);
            threadLocal.set(threadLocalVal);
            if (!Objects.equals(joiner.length(),0)) {
                return new ExcelVerifyHandlerResult(false, joiner.toString());
            }
            return new ExcelVerifyHandlerResult(true);
        }

    }
}

假如你对象属性多 不用全都判断是都空 只要找几个必填属性 然后判断为空就认为是空行就行了

数据翻译

1.简单的方式 直接用replace 会在导出导入进行翻译 比如你导出 一般状态是数字 会翻译成中文 导入则相反

    @Excel(name = "状态",replace = {"进行中_1", "完成_2","结束_3"})
    private String status;

Excel导入校验并返回异常Excel

    @PostMapping("/importExcel")
    @ResponseBody
    public void importUser(@RequestParam("uploadFile") MultipartFile multipartFile, HttpServletResponse response) {
        try {
        //自己找一个读的utlis
            List<User> read = EasyExcelUtil.read(multipartFile.getInputStream(), User.class);
            //拿到数据 校验数据 有问题就set导msg 然后把流写出
            List<User> errList = new ArrayList<>();
            for (User user : read) {
                if (user.getName().equals("张三")){
                    user.setMsg("这是一个错误数据");
                    errList.add(user);
                }
            }
            if (CollectionUtil.isNotEmpty(errList)){
                // 生成时间戳
                String timestamp = DateUtil.format(LocalDateTime.now(), "yyyyMMddHHmmss");
                EasyExcelUtil.write(response,"err_"+timestamp,errList,"test");
            }
            System.out.println(read);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

对象

@Data
public class User {
    private String name;
    private String phone;
    private String addr;

    @ContentFontStyle(color = Font.COLOR_RED)
    @ColumnWidth(value = 25)
    private String msg;

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/67747.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

学习笔记-JVM-工具包(JVM分析工具)

常用工具 JDK工具 ① jps: JVM Process status tool&#xff1a;JVM进程状态工具&#xff0c;查看进程基本信息 ② jstat: JVM statistics monitoring tool &#xff1a; JVM统计监控工具&#xff0c;查看堆&#xff0c;GC详细信息 ③ jinfo&#xff1a;Java Configuration I…

【学习】若依源码(前后端分离版)之 “ 获取角色权限信息及动态路由”

大型纪录片&#xff1a;学习若依源码&#xff08;前后端分离版&#xff09;之 “ 获取角色权限信息及动态路由” 获取用户信息获取路由信息 承接上回&#xff0c;我们发现在login请求后面跟了两个请求&#xff0c;今天我们就来了解一下两个请求的含义。 获取用户信息 先看 ‘…

MySQL及SQL语句(3)

MySQL及SQL语句(3) 文章目录 MySQL及SQL语句(3)一、多表查询1.1 准备sql1.2 笛卡尔积1.3 多表查询的分类&#xff1a;内连接查询外连接查询子查询多表查询练习 二、事务2.1 事务的基本介绍概念操作实例事务提交的两种方式 2.2 事务的四大特征原子性持久性隔离性一致性 2.3 事务…

SpringBoot学习——springboot整合email springboot整合阿里云短信服务

目录 引出springboot整合email配置邮箱导入依赖application.yml配置email业务类测试类 springboot整合阿里云短信服务申请阿里云短信服务测试短信服务获取阿里云的accessKeyspringboot整合阿里云短信导包工具类 总结 引出 1.springboot整合email&#xff0c;qq邮箱&#xff0c;…

第7章 通过内网本机IP获取微信code值及其对code值的回调。

在第5章中讲述了怎样通过内网穿透外外网从而获取微信code值&#xff0c;实际上微信测试帐号管理页中也支持通过内网本机IP获取微信code值。 1 重构launchSettings.json "https": { "commandName": "Project", "dotnetRunMessages": t…

vscode ssh远程的config/配置文件无法保存解决

问题 之前已经有了一个config&#xff0c;我想更改连接的地址和用户名&#xff0c;但是无法保存&#xff0c;显示需要管理员权限&#xff0c;但以管理员启动vscode或者以管理员权限保存都不行 未能保存“config”: Command failed: “D:\vscode\Microsoft VS Code\bin\code.c…

Docker 方式 部署 vue 项目 (docker + vue + nginx)

1.安装好 nginx 。 2. 把 vue 项目的源码克隆到确定目录下。用 git 管理&#xff0c;所以直接 git clone 到既定目录就行了。 如我的目录是&#xff1a;/root/jiangyu/projects/gentle_vue/gentle_vue_code 。 3. 项目打包&#xff1a; npm run build 复制 会自动生成 dist…

【QT】 QT开发PDF阅读器

很高兴在雪易的CSDN遇见你 &#xff0c;给你糖糖 欢迎大家加入雪易社区-CSDN社区云 前言 本文分享QT开发PDF阅读器技术&#xff0c;希望对各位小伙伴有所帮助&#xff01; 感谢各位小伙伴的点赞关注&#xff0c;小易会继续努力分享&#xff0c;一起进步&#xff01; 你的点…

matplotlib 笔记 plt.grid

用于添加网格线 主要参数 visible 布尔值&#xff0c;True表示画网格 which表示要显示的刻度线类型&#xff0c;可以是 major&#xff08;主刻度&#xff09;或 minor&#xff08;次刻度&#xff09;&#xff0c;或者同时显示&#xff08;both&#xff09;alpha 透明度 …

培训报名小程序-订阅消息发送

目录 1 创建API2 获取模板参数3 编写自定义代码4 添加订单编号5 发送消息6 发布预览 我们上一篇讲解了小程序如何获取用户订阅消息授权&#xff0c;用户允许我们发送模板消息后&#xff0c;按照模板的参数要求&#xff0c;我们需要传入我们想要发送消息的内容给模板&#xff0c…

Vue实战技巧:从零开始封装全局防抖和节流函数

前言 你是否曾经遇到过用户频繁点击按钮或滚动页面导致反应迟钝的问题&#xff1f;这是因为事件被连续触发&#xff0c;导致性能下降。在本文中&#xff0c;我将为大家介绍 vue 中的防抖和节流策略&#xff0c;并展示如何封装全局的防抖节流函数&#xff0c;以避免频繁触发事件…

米尔瑞萨RZ/G2L开发板-01 开箱+环境搭建+交叉编译FFMPEG

标题有点长哈&#xff0c;首先要感谢米尔电子提供的开发板&#xff0c;异构的板子说实话还真的是最近才开始接触的&#xff0c;在我提交申请后&#xff0c;很快就收到板子了&#xff0c;而且还是顺丰给发来的&#xff0c;其实我估计很多人就是为了骗板子&#xff0c;因为米尔的…

LeetCode150道面试经典题-移除元素(简单)

目录 1.题目 2.解题思路 3.解题代码 1.题目 移除元素 给你一个数组 nums 和一个值 val&#xff0c;你需要原地移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并原地修改输入数组。 元素…

Idea中侧面栏不见了,如何设置?

一、打开idea点击File然后点击Setting 二、点击Appearance,然后划到最下面&#xff0c;勾选Show tool windows bars和Side-by-side layout on the left 三、侧面栏目正常显示

Chatgpt AI newbing作画,文字生成图 BingImageCreator 二次开发,对接wxbot

开源项目 https://github.com/acheong08/BingImageCreator 获取cookie信息 cookieStore.get("_U").then(result > console.log(result.value)) pip3 install --upgrade BingImageCreator import os import BingImageCreatoros.environ["http_proxy"]…

微信小程序的项目解构

视频链接 黑马程序员前端微信小程序开发教程&#xff0c;微信小程序从基础到发布全流程_企业级商城实战(含uni-app项目多端部署)_哔哩哔哩_bilibili 接口文档 https://www.escook.cn/docs-uni-shop/mds/1.start.html 1&#xff1a;微信小程序宿主环境 1&#xff1a;常见的宿…

无涯教程-Perl - index函数

描述 此函数返回STR中第一次出现的SUBSTR的位置,该位置从开头(从零开始)开始,或者从POSITION(如果指定)开始。 语法 以下是此函数的简单语法- index STR, SUBSTR, POSITIONindex STR, SUBSTR返回值 失败时此函数返回-1,否则返回匹配字符串的位置(第一个字符从零开始)。 例…

【从0开始离线数仓项目】——数据仓库的环境搭建(1)

目录 一、服务器环境准备 1.2 编写集群分发脚本xsync 1.3 SSH无密登录配置 1.4 JDK准备 1.5 环境变量配置说明 二、集群所有进程查看脚本 三、Zookeeper安装 3.1 分布式安装部署 3.2 ZK集群启动停止脚本 3.3 客户端命令行操作 一、服务器环境准备 CentOS 7 怎么从命…

【uniapp】一文读懂app端安装包升级

一、前言 首先&#xff0c;在app端开发上线的过程中&#xff0c;会面临一个问题&#xff0c;就是关于app端的版本升级的问题。如果不做相关处理来引导用户的话&#xff0c;那么app就会出现版本没有更新出现的各种问题&#xff0c;我们常见的有在线升级和去指定地址下载安装两种…

web-xss

一、简介 XSS 又称CSS(Cross Site Scripting)或跨站脚本攻击&#xff0c;攻击者在网页中插入由JavaScript编写的恶意代码&#xff0c;当用户浏览被嵌入恶意代码的网页时&#xff0c;恶意代码将会在用户的浏览器上执行。 二、xss的攻击方式 Dom&#xff1a;这是一种将任意 Jav…