Springboot使用EasyExcel导入导出Excel文件

1,准备Excel文件和数据库表结果

在这里插入图片描述
在这里插入图片描述

2,导入代码

1,引入依赖

        <!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>3.1.0</version>
        </dependency>

2,创建请求body

import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;

/**
 * Description
 *
 * @author WangYaoLong
 * @createdate 2023/11/01 0001 11:43
 */
@Data
public class StudentImportExcelForm {
    @ExcelProperty(value = "学生姓名", index = 0)
    private String name;

    @ExcelProperty(value = "性别", index = 1)
    private String sex;

    @ExcelProperty(value = "学号", index = 2)
    private String stuId;

    @ExcelProperty(value = "身份证号", index = 3)
    private String identityNum;

    @ExcelProperty(value = "所在班级", index = 4)
    private String classesId;

    @ExcelProperty(value = "简介", index = 5)
    private String remarks;

    @ExcelProperty(value = "生日", index = 6)
    private String birthday;
}

3,Excel文件数据解析

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelAnalysisException;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.wang.dog.exception.BusinessException;
import com.wang.dog.pojo.form.StudentImportExcelForm;
import com.wang.dog.service.StudentService;
import com.wang.dog.utils.SpringContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;

/**
 * Description
 *
 * @author WangYaoLong
 * @createdate 2023/11/01 0001 11:42
 */
@Slf4j
public class StudentImportExcelListener extends AnalysisEventListener<StudentImportExcelForm> {

    private final List<StudentImportExcelForm> list = new ArrayList<>();

    private final StudentService studentService;

    public StudentImportExcelListener() {
        this.studentService = SpringContextHolder.getBean(StudentService.class);
    }

    private StringBuilder msg = new StringBuilder();

    @Override
    public void invoke(StudentImportExcelForm studentExcelForm, AnalysisContext analysisContext) {
        log.info("学生信息" + studentExcelForm);
        checkStudentFiled(studentExcelForm);
        list.add(studentExcelForm);
    }

    /**
     * 校验学生信息
     *
     * @param studentExcelForm 学生导入表单
     */
    private void checkStudentFiled(StudentImportExcelForm studentExcelForm) {
        String name = studentExcelForm.getName();
        String stuId = studentExcelForm.getStuId();
        String classesId = studentExcelForm.getClassesId();
        String sex = studentExcelForm.getSex();
        String identityNum = studentExcelForm.getIdentityNum();

        if (StringUtils.isBlank(name)) {
            msg.append("学生姓名不能为空!");
        }
        if (StringUtils.isBlank(stuId)) {
            msg.append("学生学号不能为空!");
        }
        if (StringUtils.isBlank(classesId)) {
            msg.append("学生所在班级不能为空!");
        }
        if (StringUtils.isBlank(sex)) {
            msg.append("学生性别不能为空!");
        }
        if (StringUtils.isBlank(identityNum)) {
            msg.append("学生身份证信息不能为空!");
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        if (StringUtils.isNotBlank(msg)) {
            throw new ExcelAnalysisException("导入失败!<br/>" + msg.toString());
        }
        if (CollectionUtils.isEmpty(list)) {
            throw new BusinessException("导入文件为空");
        }
        // 保存学生信息
        saveData();
        // 清空集合和异常信息
        msg = null;
        list.clear();
    }
    
    /**
     * 保存 加上存储数据库
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveData() {
        studentService.importExcelData(list);
    }
}

4,在StudentService中新增接口以及实现类保存数据

接口方法

   /**
     * 导入Excel学生信息
     *
     * @param list 学生信息集合
     */
    void importExcelData(List<StudentImportExcelForm> list);

实现类

    @Override
    public void importExcelData(List<StudentImportExcelForm> list) {
        List<Student> studentList = new ArrayList<>();
        list.forEach(s -> {
            Student student = new Student();
            student.setName(s.getName());
            student.setSex(Integer.parseInt(String.valueOf(s.getSex().equals("男") ? 0 : 1)));
            student.setStuId(s.getStuId());
            student.setIdentityNum(s.getIdentityNum());
            student.setClassesId(s.getClassesId());
            student.setCreateTime(new Date());
            student.setUpdateTime(new Date());
            student.setCreateBy(s.getName());
            student.setUpdateBy(s.getName());
            student.setDelFlag(0);
            student.setRemarks(s.getRemarks());
            student.setBirthday(s.getBirthday());
            studentList.add(student);
        });
        // 批量保存学生信息
        this.saveBatch(studentList);
    }

5,新增导入Excel接口

@Slf4j
@RequestMapping("/student")
@RestController
public class StudentController {

    @PostMapping("/import")
    public Result uploadStudentInfo(MultipartFile file) throws IOException {
        InputStream is = file.getInputStream();
        EasyExcel.read(is, StudentImportExcelForm.class, new StudentImportExcelListener())
                .sheet(0)
                .headRowNumber(1)
                .doRead();
        return Result.ok("success");
    }
}

6,测试

在这里插入图片描述

3,导出Excel

1,导出Excel表单请求

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
 * Description
 *
 * @author WangYaoLong
 * @createdate 2023/11/01 0001 13:03
 */
@Data
public class StudentExportExcelForm {
    @ApiModelProperty(value = "姓名", example = "")
    private String name;

    @ApiModelProperty(value = "身份证号", example = "")
    private String identityNum;

    @ApiModelProperty(value = "所在班级", example = "")
    private String classesId;

    @ApiModelProperty(value = "性别", example = "")
    private String sex;

}

2,返回表单

@Data
@HeadRowHeight(15)	// 高度
@HeadFontStyle(fontHeightInPoints = 10)
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER)	// 字体居中显示
public class StudentExportExcelVo {
    @ExcelProperty(value = "学生姓名", order = 1)
    @ColumnWidth(20)	// excel 单元格间距
    private String name;

    @ExcelProperty(value = "性别", order = 2)
    @ColumnWidth(20)
    private String sex;

    @ExcelProperty(value = "学号", order = 3)
    @ColumnWidth(20)
    private String stuId;

    @ExcelProperty(value = "身份证号", order = 4)
    @ColumnWidth(20)
    private String identityNum;

    @ExcelProperty(value = "所在班级", order = 5)
    @ColumnWidth(20)
    private String classesId;

    @ExcelProperty(value = "简介", order = 6)
    @ColumnWidth(20)
    private String remarks;

    @ExcelProperty(value = "生日", order = 7)
    @ColumnWidth(20)
    private String birthday;
}

3,导出查询接口

    @GetMapping("/export")
    public void exportStudentExcel(StudentExportExcelForm studentExportExcelForm, HttpServletResponse response) throws Exception {
        List<StudentExportExcelVo> list = studentService.exportStudent(studentExportExcelForm);
        // 不带表头
        //DownExcelUtils.download(response, StudentExportExcelVo.class, list, "学生信息导出");
        // 增加表头
        DownExcelUtils.download(response, StudentExportExcelVo.class, list, "学生信息导出", ExportStudentExcelHandler.class);
    }

4,学生数据查询

    /**
     * 查询学生信息
     *
     * @param studentExportExcelForm 学生请求表单
     * @return List
     */
    List<StudentExportExcelVo> exportStudent(StudentExportExcelForm studentExportExcelForm);

实现类:

    @Override
    public List<StudentExportExcelVo> exportStudent(StudentExportExcelForm form) {
        List<StudentExportExcelVo> list = Lists.newArrayList();
        LambdaQueryWrapper<Student> studentQueryWrapper = Wrappers.<Student>lambdaQuery()
                .orderByAsc(Student::getBirthday);
        if (StringUtils.isNotBlank(form.getName())) {
            studentQueryWrapper.like(Student::getName, form.getName());
        }
        if (StringUtils.isNotBlank(form.getIdentityNum())) {
            studentQueryWrapper.eq(Student::getIdentityNum, form.getIdentityNum());
        }
        if (StringUtils.isNotBlank(form.getClassesId())) {
            studentQueryWrapper.eq(Student::getClassesId, form.getClassesId());
        }
        if (StringUtils.isNotBlank(form.getSex())) {
            studentQueryWrapper.eq(Student::getSex, form.getSex().equals("男") ? 0 : 1);
        }
        List<Student> studentList = studentMapper.selectList(studentQueryWrapper);
        if (CollectionUtils.isNotEmpty(studentList)) {
            studentList.forEach(s -> {
                StudentExportExcelVo vo = new StudentExportExcelVo();
                BeanUtils.copyProperties(s, vo);
                vo.setSex(s.getSex() == 0 ? "男" : "女");
                list.add(vo);
            });
        }
        return list;
    }

5,导出工具类

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.handler.WriteHandler;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;

/**
 * @author: WangYaoLong
 * @date: 2022/8/1
 * @description: excel导出工具类
 */
public class DownExcelUtils {

	/**
	 * 带有表头提示
	 *
	 * @param response
	 * @param t
	 * @param list
	 * @param fileName
	 * @param z
	 * @throws IOException
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 */
	public static void download(HttpServletResponse response, Class t, List list, String fileName, Class z) throws IOException, IllegalAccessException, InstantiationException {
		// 设置文本内省
		response.setContentType("application/vnd.ms-excel");
		response.setCharacterEncoding("utf-8");
		response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");
		EasyExcel.write(response.getOutputStream(), t)
				.sheet(fileName)
				//设置拦截器或自定义样式
				.registerWriteHandler((WriteHandler) z.newInstance())
				//这里1代表第二行开始
				.relativeHeadRowIndex(1)
				.doWrite(list);
	}

	/**
	 * 不带表头提示
	 *
	 * @param response
	 * @param t
	 * @param list
	 * @param fileName
	 * @throws IOException
	 */
	public static void download(HttpServletResponse response, Class t, List list, String fileName) throws IOException {
		response.setContentType("application/vnd.ms-excel");
		response.setCharacterEncoding("utf-8");
		response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");
		EasyExcel.write(response.getOutputStream(), t)
				.sheet(fileName)
				.doWrite(list);
	}
}

6,表头类

import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;

public class ExportStudentExcelHandler implements SheetWriteHandler {
    @Override
    public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
    }

    @Override
    public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
        Workbook workbook = writeWorkbookHolder.getWorkbook();
        Sheet sheet = workbook.getSheetAt(0);

        CellStyle cellStyle = workbook.createCellStyle();
        // 自动换行
        cellStyle.setWrapText(true);
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        //第一行
        //设置标题
        Row row = sheet.createRow(0);
        row.setHeight((short) 900);
        Cell cell = row.createCell(0);
        cell.setCellStyle(cellStyle);
        cell.setCellValue("这是学生信息导出表格(注:xxxxxxxxx数据内容不可更改)");
        sheet.addMergedRegionUnsafe(new CellRangeAddress(0, 0, 0, 7));
    }
}

7,接口测试导出

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

掌握微信批量添加好友技巧,让你的社交更高效

微信作为当今的热门通讯工具&#xff0c;在企业营销中扮演着越来越重要的角色。然而&#xff0c;微信并没有提供自动批量添加好友的功能&#xff0c;给运营者带来了不小的挑战。一个个手动添加不仅耗时&#xff0c;而且频繁操作还容易导致账号被封。本文将介绍几种手动批量添加…

PHP foreach 循环跳过本次循环

$a [[id>1],[id>2],[id>3],[id>4],[id>5],[id>6],[id>7],[id>18],];foreach($a as $v){if($v[id] 5){continue;}$b[] $v[id];}return show_data(,$b); 结果&#xff1a;

Linux软件安装包管理器yum

Linux软件安装 Linux软件安装的本质 ​ 对于安装软件最基本的理解就是把可执行程序拷贝到指定路径下&#xff0c;我们知道直接输入指令就可以实现想要的功能&#xff0c;这些指令本质上都是放在指定路径下的可执行文件&#xff0c;如果我们把写好的程序编译后的可执行文件放到…

dubbo没有找到生产者

1、没有找到生产者 com.alibaba.dubbo.rpc.RpcException: No provider available from registry 127.0.0.1:2181 for service .... , please check status of providers(disabled, not registered or in blacklist)2、 查看是不是 对应的providers 没有 注册上去 找到 zk 对应…

Java 为什么不推荐在 while 循环中使用 sleep() 我悟了

文章目录 前言原因是否正确方案是否合理定时轮询场景事件机制等待和唤醒 个人简介 前言 最近逛 CSDN 看到一篇文章&#xff0c;文章大意是说为什么在循环中不推荐使用 sleep 操作&#xff0c;原因在于线程挂起和唤醒会有很大的性能消耗&#xff0c;并推荐使用 Timer 及 Schedu…

[SpringCloud | Linux] CentOS7 部署 SpringCloud 微服务

目录 一、环境准备 1、工具准备 2、虚拟机环境 3、Docker 环境 二、项目准备 1、配置各个模块&#xff08;微服务&#xff09;的 Dockerfile 2、配置 docker-compose.yml 文件 3、Maven 打包 4、文件整合并传输 三、微服务部署 1、部署至 Docker 2、访问微服务 四…

视频特效制作After Effects 2024 for Mac(ae)

After Effects 2024是一款由Adobe公司开发的专业的视频特效和动态图形设计软件&#xff0c;它可以帮助用户创建各种令人惊叹的视觉效果&#xff0c;例如粒子系统、合成特效、绿屏抠像等。该软件支持动画制作&#xff0c;包括关键帧动画、形状动画、运动跟踪等工具&#xff0c;可…

SpringCloud(二) Eureka注册中心的使用

在SpringCloud(一)中,我们学会了使用RestTemplate进行远程调用,但是在调用user-service时候需要在order-service中发送http请求,请求中需要书写对应微服务的ip和端口号,十分不方便,如果此时有多个user-service实例的话,就不知道调用哪个了(除非每次调用的时候都对ip和端口号进行…

【java零基础入门到就业】第四天:Notepad++软件的下载和安装

文章目录 Notepad软件简介下载安装 Notepad软件 简介 Notepad&#xff08;又称Notepad Plus Plus&#xff09;是一款免费的文本编辑器&#xff0c;是Windows操作系统下非常受欢迎的开源软件。它提供了许多强大的功能&#xff0c;适合用于编写各种编程语言的源代码、编辑文本文…

Redis缓存穿透、击穿、雪崩问题原理和解决方案

目录 一、Redis缓存穿透1.1、缓存穿透原理1.2、缓存穿透代码演示1.3、缓存穿透解决方案解决方案一&#xff08;数据库中查询不到数据也将key进行缓存&#xff09;解决方案二&#xff08;使用布隆过滤器&#xff09; 二、Redis缓存击穿&#xff08;缓存失效&#xff09;三、Redi…

Notes/Domino中的JVM版本

大家好&#xff0c;才是真的好。 这篇内容主要写给同时关注Domino和Java的技术人员。 很多人都知道&#xff0c;从Notes/Domino R5&#xff08;1999年&#xff09;版本&#xff0c;开始自带一个Java虚拟机&#xff0c;用来支持Java应用运行。但很多人不知道&#xff0c;这个J…

【c++|opencv】二、灰度变换和空间滤波---4.高斯滤波

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 1. 高斯滤波 #include <iostream> #include <opencv2/opencv.hpp> #include"Salt.h"using namespace std; using namespace cv;/…

中国人民大学与加拿大女王大学金融硕士——人生是旷野,不是一条轨道

在这个瞬息万变的时代&#xff0c;我们每个人都像是一颗流星&#xff0c;在宇宙中独自燃烧。我们每个人都有自己的梦想&#xff0c;自己的追求&#xff0c;自己的道路。然而&#xff0c;很多时候&#xff0c;我们却发现自己被现实的轨道所束缚&#xff0c;无法自由地追求自己的…

【一、http】go的http基本请求方法

1、http的基本请求 package mainimport ("bytes""fmt""io""net/http""net/url" )func post(){r, err : http.Post("http://httpbin.org/post", "", nil)if err ! nil {fmt.Println("ss")}de…

电子凭证会计数据标准试点深化后,企业管理的关键点在于什么?

为了加快建设数字中国、发展数字经济发展&#xff0c;并推动经济社会绿色化、低碳化发展&#xff0c;政府部门一直大力推动企业的数字化转型。 企业的经营活动也越来越活跃。企业在经营中产生了大量的票据&#xff0c;由于电子凭证分属不同的部门管理&#xff0c;数据不兼容&am…

竞赛选题 深度学习实现行人重识别 - python opencv yolo Reid

文章目录 0 前言1 课题背景2 效果展示3 行人检测4 行人重识别5 其他工具6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习的行人重识别算法研究与实现 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c…

IDEA远程调试代码

IDEA->RUN->Edit Configurations 端口随便选一个&#xff0c;选择调试模块&#xff0c;然后用IDEA生成的命令调试 java -agentlib:jdwptransportdt_socket,servery,suspendn,address*:8081 -jar backend-1.18.11.jar &

word插入图片不显示

段落格式要设置成非固定的。

约数之和 (普通快速幂求逆元做法)

假设现在有两个自然数 A 和 B&#xff0c;S 是 AB 的所有约数之和。 请你求出 Smod9901 的值是多少。 输入格式 在一行中输入用空格隔开的两个整数 A 和 B 。 输出格式 输出一个整数&#xff0c;代表 Smod9901 的值。 数据范围 0≤A,B≤5107 输入样例&#xff1a; …

【JavaEE初阶】 网络编程基础与Socket套接字

文章目录 &#x1f38b;网络编程基础&#x1f6a9;为什么需要网络编程&#xff1f;&#x1f6a9;什么是网络编程&#xff1f;&#x1f6a9;网络编程中的基本概念&#x1f4cc;发送端和接收端&#x1f4cc;请求和响应&#x1f4cc;客户端和服务端&#x1f4cc;常见的客户端服务端…