Springboot使用EasyExcel导入导出Excel文件

news2025/3/2 2:14:33

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,接口测试导出

在这里插入图片描述

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[鹏城杯 2022]简单的php 取反的另一种无数字字母rce 通过请求头执行命令

鹏城杯2022部分web-CSDN博客 无字母webshell | Bypass-腾讯云开发者社区-腾讯云 这里记录一下 首先获取过滤if(strlen($code) > 80 or preg_match(/[A-Za-z0-9]|\|"||\ |,|\.|-|\||\/|\\|<|>|\$|\?|\^|&|\|/is,$code)) 写个脚本看看还有什么没有被过滤 …

低成本语音芯片是如何写入语音到芯片里面otp和flash型

一、简介 低成本语音芯片是如何写入语音到芯片里面otp和flash型。低成本其实是一个相对的概念&#xff0c;比如&#xff1a;玩具类型的巨量产品&#xff0c;简单&#xff0c;它的低成本就是最低&#xff0c;能抠出来一分&#xff0c;就是一分。所以对芯片的要求就很高&#xf…

基于单片机设计的太阳能跟踪器

一、前言 随着对可再生能源的需求不断增长&#xff0c;太阳能作为一种清洁、可持续的能源形式&#xff0c;受到越来越多的关注和应用。太阳能光板通常固定在一个固定的角度上&#xff0c;这限制了它们对太阳光的接收效率。为了充分利用太阳能资源&#xff0c;提高太阳能光板的…

Oracle(10)Managing Undo Data

目录 一、基础知识 1、AUM :Init Parameters AUM:初始化参数 2、AUM:Other Parameters AUM:其他参数 3、AUM:Sizing an UNDO TS AUM:调整UNDOTS的大小 4、AUM :Undo Quota AUM:撤消配额 5、Get Undo Segment Info 获取撤消段信息 二、基础操作 1、AUM:UNDO Tablespace …

2、循环依赖详解(二)

bean的实例化过程源码解析 建议用IDEA的debug模式来观察Spring的IOC过程 进入到此类的构造方法中 查看setConfigLocations&#xff0c;就是将配置文件加载到configLocations里去 向下执行&#xff0c;查看refresh() this.prepareRefresh(): 此方法是准备工作&#xff0c;大家…

Spring Boot 3 整合 xxl-job 实现分布式定时任务调度,结合 Docker 容器化部署(图文指南)

目录 前言初始化数据库Docker 部署 xxl-job下载镜像创建容器并运行访问调度中心 SpringBoot 整合 xxl-jobpom.xmlapplication.ymlXxlJobConfig.java执行器注册查看 定时任务测试添加测试任务配置定时任务测试结果 结语附录xxl-job 官方文档xxl-job 源码测试项目源码 前言 xxl-…

防雷接地测试方法完整方案

防雷接地是保障电力系统、电子设备和建筑物安全的重要措施&#xff0c;防雷接地测试是检验防雷接地装置是否合格的必要手段。本文介绍了防雷接地测试的原理、方法和注意事项&#xff0c;以及如何编写防雷接地测试报告。 地凯科技防雷接地测试的原理 防雷接地测试的基本原理是…

人工智能快速发展时代下的“AI诈骗防范”

当前&#xff0c;AI技术的广泛应用为社会公众提供了个性化智能化的信息服务&#xff0c;也给网络诈骗带来可乘之机&#xff0c;如不法分子通过面部替换语音合成等方式制作虚假图像、音频、视频仿冒他人身份实施诈骗、侵害消费者合法权益。你认为AI诈骗到底应该如何防范&#xf…

TimeGPT-1——第一个时间序列数据领域的大模型他来了

一直有一个问题:时间序列的基础模型能像自然语言处理那样存在吗?一个预先训练了大量时间序列数据的大型模型&#xff0c;是否有可能在未见过的数据上产生准确的预测?最近刚刚发表的一篇论文&#xff0c;Azul Garza和Max Mergenthaler-Canseco提出的TimeGPT-1&#xff0c;将ll…

国内某发动机制造工厂RFID智能制造应用解决方案

一、工厂布局和装备 国内某发动机制造工厂的装配车间布局合理&#xff0c;设备先进&#xff0c;在这个5万平方米的生产区域内&#xff0c;各个工位之间流程紧密&#xff0c;工厂采用了柔性设备&#xff0c;占比达到了67%&#xff0c;数控化率超过90%&#xff0c;自动化率达到了…

AD教程(四)排针类元件模型的创建

AD教程&#xff08;四&#xff09;排针类元件模型的创建 新建元件&#xff0c;输入排针型号作为元件命名 快捷键TC 快速创建元件 放置外框 放置管脚&#xff0c;排针管脚号在原理图上一般不显示&#xff0c;需要将管脚号隐藏&#xff0c;但一般不建议隐藏&#xff0c;如果将管…

如何在《阴阳师》游戏中使用Socks5搭建工具

题目&#xff1a;如何在《阴阳师》游戏中使用S5搭建工具S5一键搭建脚本进行游戏战队组建&#xff1f; 引言&#xff1a; 游戏加速和游戏战队组建已经成为《阴阳师》玩家们非常关心的话题。在这篇文章中&#xff0c;我们将向您展示如何在《阴阳师》游戏中使用S5搭建工具S5一键搭…

有奖快来抱走全新HUAWEI WATCH GT4

亲爱的openGauss用户&#xff0c; 为了给您提供更好的社区体验&#xff0c;现诚邀您参与openGauss社区满意度问卷调研。您的每一个宝贵建议都是我们进步的方向。 手机扫描二维码即可填写问卷&#xff0c;请根据您真实的体验情况填写问卷&#xff0c;问卷反馈越真实有效越有机…

Kafka基本原理、生产问题总结及性能优化实践 | 京东云技术团队

Kafka是最初由Linkedin公司开发&#xff0c;是一个分布式、支持分区的&#xff08;partition&#xff09;、多副本的&#xff08;replica&#xff09;&#xff0c;基于zookeeper协调的分布式消息系统&#xff0c;它的最大的特性就是可以实时的处理大量数据以满足各种需求场景&a…

超越终端:Java语言在命令行环境中的无限潜力

&#x1f52d; 嗨&#xff0c;您好 &#x1f44b; 我是 vnjohn&#xff0c;在互联网企业担任 Java 开发&#xff0c;CSDN 优质创作者 &#x1f4d6; 推荐专栏&#xff1a;Spring、MySQL、Nacos、Java&#xff0c;后续其他专栏会持续优化更新迭代 &#x1f332;文章所在专栏&…

为什么要安装防静电门禁闸机

安装防静电门禁闸机可以带来以下几个方面的好处&#xff1a; 防止静电干扰&#xff1a;静电是一种非常危险的物理现象&#xff0c;它可以对电子元器件、电路板和其他敏感设备造成损害&#xff0c;甚至导致设备故障和生产中断。防静电门禁闸机可以有效地防止静电的产生和传导&am…

药监局瑞数6 分析 2023版

网站地址 aHR0cHM6Ly93d3cubm1wYS5nb3YuY24veWFvcGluL3lwamdkdC9pbmRleC5odG1s 清除cookie 选中脚本调试 第一次获取的结果ts 第二次获取的结果是一个294cc83.js&#xff0c;可以固定 第三次获取的结果 content和ts属性每次都要换,还有ts属性一定要和content对应,否则你怎么…

面试算法47:二叉树剪枝

题目 一棵二叉树的所有节点的值要么是0要么是1&#xff0c;请剪除该二叉树中所有节点的值全都是0的子树。例如&#xff0c;在剪除图8.2&#xff08;a&#xff09;中二叉树中所有节点值都为0的子树之后的结果如图8.2&#xff08;b&#xff09;所示。 分析 下面总结什么样的节…

【C++项目实战】基于多设计模式下的同步于异步的日志系统(完整详细)

&#x1f307;个人主页&#xff1a;平凡的小苏 &#x1f4da;学习格言&#xff1a;命运给你一个低的起点&#xff0c;是想看你精彩的翻盘&#xff0c;而不是让你自甘堕落&#xff0c;脚下的路虽然难走&#xff0c;但我还能走&#xff0c;比起向阳而生&#xff0c;我更想尝试逆风…

机器人仿真-gazebo学习笔记(4)xacro和传感器添加

1.xacro简介 URDF文件不具备代码复用的特性&#xff08;在上一篇文章也能发现&#xff0c;其实左右轮是极其相似的但还是要单独描述&#xff09;&#xff0c;一个复杂的机器人模型会拥有大量了的传感器和关节组件&#xff0c;这时候使用URDF文件就太难阅读了。精简化、可复用、…