• SpringBoot——快速整合EasyExcel实现Excel的上传下载


    文章目录:

    1.EasyExcel

    2.Excel的上传(读Excel)

    3.Excel的下载(写Excel)

    4.结语


    1.EasyExcel

    Hello,大家好啊,好久不见了,自工作之后真的很难腾出时间来写博客(给大家分享我在技术中遇到的那些事),在华为真的挺忙的,这不突然来了一个双休,我也不想闲着,回想起很早之前学过的一个东西SpringBoot以及EasyExcel,于是就想着把它俩整合一下搞点简单的功能玩玩。


    首先,这里给出EasyExcel的官方文档:https://easyexcel.opensource.alibaba.com/

    alibaba.com不用我多说了吧,大家都认识,这个东西就是阿里开发的:EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。
    他能让你在不用考虑性能、内存的等因素的情况下,快速完成Excel的读、写等功能。
    (这段话听着好牛的样子,没错,官方给出的你说呢)

    那么由于下面的案例中,涉及到Excel表格的样式问题,所以我这里采用了 EasyExcel 3.1.x的版本。https://easyexcel.opensource.alibaba.com/docs/current/

    开始吧,👇👇👇

    2.Excel的上传(读Excel)

    我这里首先给大家分享一下SpringBoot结合EasyExcel实现对 Excel 中数据的读取,并且将读取到的数据存入MySQL数据库

    说到这里,要加什么依赖大家肯定都心知肚明了。😄😄😄

    1. <dependency>
    2. <groupId>org.springframework.bootgroupId>
    3. <artifactId>spring-boot-starter-webartifactId>
    4. dependency>
    5. <dependency>
    6. <groupId>org.mybatis.spring.bootgroupId>
    7. <artifactId>mybatis-spring-boot-starterartifactId>
    8. <version>2.1.4version>
    9. dependency>
    10. <dependency>
    11. <groupId>mysqlgroupId>
    12. <artifactId>mysql-connector-javaartifactId>
    13. <version>5.1.9version>
    14. dependency>
    15. <dependency>
    16. <groupId>org.projectlombokgroupId>
    17. <artifactId>lombokartifactId>
    18. <optional>trueoptional>
    19. dependency>
    20. <dependency>
    21. <groupId>com.alibabagroupId>
    22. <artifactId>easyexcelartifactId>
    23. <version>3.1.1version>
    24. dependency>
    25. <dependency>
    26. <groupId>com.alibabagroupId>
    27. <artifactId>fastjsonartifactId>
    28. <version>1.2.28version>
    29. dependency>

    由于用到MyBatis,所以一定不要忘记加下面的这段代码,否则你的mapper是编译不到你的classpath中的。

    1. <resources>
    2. <resource>
    3. <directory>src/main/javadirectory>
    4. <includes>
    5. <include>**/*.xmlinclude>
    6. includes>
    7. resource>
    8. resources>

    既然要读取Excel,同时存入数据库,那么就必然需要对应的表了,这就引出了  表对应的实体类。

    我这里写了两个,这是因为 Excel 对应了一个类,而数据库表对应的是另外一个,原因考虑到可能Excel表格会增加一些不必要的字段,而这些字段并不需要存入数据库中(反过来也是一样,可能数据库实体类中有10个字段,而Excel这边仅有6个字段,而剩余的4个字段我们可能会从其他渠道获取)。

    上面我说的可能是在公司实际开发中会遇到的某些场景吧,但是为了方便大家理解,这两个类我还是定义的相同的字段。

    1. package com.szh.dto;
    2. import com.alibaba.excel.annotation.ExcelProperty;
    3. import com.alibaba.excel.annotation.format.DateTimeFormat;
    4. import lombok.AllArgsConstructor;
    5. import lombok.Data;
    6. import lombok.NoArgsConstructor;
    7. /**
    8. *
    9. */
    10. @Data
    11. @NoArgsConstructor
    12. @AllArgsConstructor
    13. public class GoodsExcelDTO {
    14. @ExcelProperty(index = 0)
    15. private Integer id;
    16. @ExcelProperty(index = 1)
    17. private String name;
    18. @ExcelProperty(index = 2)
    19. private String info;
    20. @ExcelProperty(index = 3)
    21. @DateTimeFormat(value = "yyyy-MM-dd HH:mm:ss")
    22. private String buyTime;
    23. }
    1. package com.szh.model;
    2. import com.fasterxml.jackson.annotation.JsonFormat;
    3. import lombok.AllArgsConstructor;
    4. import lombok.Data;
    5. import lombok.NoArgsConstructor;
    6. import org.springframework.format.annotation.DateTimeFormat;
    7. import java.util.Date;
    8. /**
    9. *
    10. */
    11. @Data
    12. @NoArgsConstructor
    13. @AllArgsConstructor
    14. public class Goods {
    15. private Integer id;
    16. private String name;
    17. private String info;
    18. //@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    19. @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    20. private Date buyTime;
    21. }

    大家应该能发现,Excel对应的类中 buyTime是 String类型,而数据库实体类的 buyTime是Date类型,这是因为:👇👇👇 (阿里官方文档给出的规定)

    下面给出goods这张表的sql脚本。

    1. SET NAMES utf8mb4;
    2. SET FOREIGN_KEY_CHECKS = 0;
    3. -- ----------------------------
    4. -- Table structure for goods
    5. -- ----------------------------
    6. DROP TABLE IF EXISTS `goods`;
    7. CREATE TABLE `goods` (
    8. `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
    9. `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '商品名称',
    10. `info` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '商品信息',
    11. `buyTime` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '购买时间',
    12. PRIMARY KEY (`id`) USING BTREE
    13. ) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
    14. -- ----------------------------
    15. -- Records of goods
    16. -- ----------------------------
    17. INSERT INTO `goods` VALUES (1, 'Java核心技术卷I', 'Java四大名著之一', '2021-12-01 13:05:23');
    18. INSERT INTO `goods` VALUES (2, 'Java核心技术卷II', 'Java四大名著之一', '2022-02-28 09:21:55');
    19. INSERT INTO `goods` VALUES (3, 'Java编程思想', 'Java四大名著之一', '2020-05-15 14:16:18');
    20. INSERT INTO `goods` VALUES (4, 'Effective Java', 'Java四大名著之一', '2022-07-06 22:33:44');
    21. INSERT INTO `goods` VALUES (5, '深入理解Java虚拟机', 'JVM由此开始', '2021-06-06 20:59:37');
    22. INSERT INTO `goods` VALUES (6, 'SpringBoot实战应用教程', 'SpringBoot极速开发框架', '2020-03-17 10:02:31');
    23. INSERT INTO `goods` VALUES (7, '快速上手SSM', '一本优秀的书籍', '2021-08-14 19:08:26');
    24. INSERT INTO `goods` VALUES (8, 'MySQL是怎样运行的', '深入学习MySQL', '2022-04-09 15:37:05');
    25. INSERT INTO `goods` VALUES (9, 'Java并发编程', '并发编程之美', '2020-01-18 21:12:13');
    26. INSERT INTO `goods` VALUES (10, 'Java从入门到精通', '小白的Java之路', '2021-09-11 17:18:21');
    27. SET FOREIGN_KEY_CHECKS = 1;

    大家参考官方文档之后,肯定知道,针对Excel的读,我们需要写一个监听器,去不断的监听读取Excel的每一行数据,最终加入数据库类似这样的操作。

    下面就是监听器代码。

    有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去。这也就是监听器中需要声明 

    private GoodsService goodsService; 这个成员变量的原因。

    invoke 方法:解析Excel中的每一条数据都会来调用它。

    invokeHead 方法:针对Excel表头的一些操作。

    doAfterAllAnalysed 方法:所有数据解析完成了会来调用它。

    1. package com.szh.listener;
    2. import com.alibaba.excel.context.AnalysisContext;
    3. import com.alibaba.excel.metadata.data.ReadCellData;
    4. import com.alibaba.excel.read.listener.ReadListener;
    5. import com.alibaba.excel.util.ConverterUtils;
    6. import com.alibaba.excel.util.ListUtils;
    7. import com.alibaba.fastjson.JSON;
    8. import com.szh.dto.GoodsExcelDTO;
    9. import com.szh.model.Goods;
    10. import com.szh.service.GoodsService;
    11. import lombok.extern.slf4j.Slf4j;
    12. import org.springframework.beans.BeanUtils;
    13. import java.text.ParseException;
    14. import java.text.SimpleDateFormat;
    15. import java.time.format.DateTimeFormatter;
    16. import java.util.Date;
    17. import java.util.List;
    18. import java.util.Map;
    19. import java.util.Set;
    20. /**
    21. * Excel模板的读取类
    22. * 有个很重要的点 DemoDataListener 不能被spring管理
    23. * 要每次读取excel都要new, 然后里面用到spring可以构造方法传进去
    24. */
    25. @Slf4j
    26. public class GoodsListener implements ReadListener {
    27. private GoodsService goodsService;
    28. private List goodsExcelDTOList = ListUtils.newArrayList();
    29. private final List goodsList = ListUtils.newArrayList();
    30. private int count = 0;
    31. public GoodsListener() {
    32. }
    33. public GoodsListener(GoodsService goodsService) {
    34. this.goodsService = goodsService;
    35. }
    36. @Override
    37. public void invoke(GoodsExcelDTO goodsExcelDTO, AnalysisContext analysisContext) {
    38. log.info("解析到第 {} 条数据:{}", (++count), JSON.toJSONString(goodsExcelDTO));
    39. goodsExcelDTOList.add(goodsExcelDTO);
    40. }
    41. @Override
    42. public void invokeHead(Map> headMap, AnalysisContext context) {
    43. Map stringMap = ConverterUtils.convertToStringMap(headMap, context);
    44. Set keySet = stringMap.keySet();
    45. System.out.println("该Excel表头信息是:");
    46. for (int i = 0; i < keySet.size(); i++) {
    47. System.out.println("第 " + (i + 1) + " 列 = " + stringMap.get(i));
    48. }
    49. }
    50. @Override
    51. public void doAfterAllAnalysed(AnalysisContext analysisContext) {
    52. log.info("该Excel的所有数据解析完成!!!");
    53. goodsExcelDTOList.forEach(item -> {
    54. try {
    55. Goods goods = new Goods();
    56. goods.setId(item.getId());
    57. goods.setName(item.getName());
    58. goods.setInfo(item.getInfo());
    59. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    60. Date date = sdf.parse(item.getBuyTime());
    61. goods.setBuyTime(date);
    62. goodsList.add(goods);
    63. } catch (ParseException e) {
    64. log.error(e.getMessage());
    65. }
    66. });
    67. goodsExcelDTOList = ListUtils.newArrayList();
    68. goodsService.batchInsert(goodsList);
    69. }
    70. }

    好的,下面就是我们的mapper、service、controller了。这都是大家很熟悉的东西了。

    1. package com.szh.mapper;
    2. import com.szh.dto.GoodsExcelDTO;
    3. import com.szh.model.Goods;
    4. import java.util.List;
    5. /**
    6. *
    7. */
    8. public interface GoodsMapper {
    9. /**
    10. * 批量插入
    11. */
    12. void batchInsert(List goodsList);
    13. }
    1. "1.0" encoding="UTF-8" ?>
    2. mapper
    3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    5. <mapper namespace="com.szh.mapper.GoodsMapper">
    6. <insert id="batchInsert" parameterType="java.util.List">
    7. insert into goods
    8. values
    9. <foreach collection="list" item="item" index="index" separator=",">
    10. (#{item.id}, #{item.name}, #{item.info}, #{item.buyTime})
    11. foreach>
    12. insert>
    13. mapper>
    1. package com.szh.service;
    2. import com.szh.model.Goods;
    3. import java.util.List;
    4. /**
    5. *
    6. */
    7. public interface GoodsService {
    8. void batchInsert(List goodsList);
    9. }
    1. package com.szh.service.impl;
    2. import com.szh.mapper.GoodsMapper;
    3. import com.szh.model.Goods;
    4. import com.szh.service.GoodsService;
    5. import lombok.extern.slf4j.Slf4j;
    6. import org.springframework.beans.factory.annotation.Autowired;
    7. import org.springframework.stereotype.Service;
    8. import org.springframework.transaction.annotation.Transactional;
    9. import java.util.List;
    10. /**
    11. *
    12. */
    13. @Slf4j
    14. @Service
    15. public class GoodsServiceImpl implements GoodsService {
    16. @Autowired
    17. private GoodsMapper goodsMapper;
    18. @Transactional
    19. @Override
    20. public void batchInsert(List goodsList) {
    21. goodsMapper.batchInsert(goodsList);
    22. }
    23. }
    1. package com.szh.controller;
    2. import com.alibaba.excel.EasyExcel;
    3. import com.alibaba.excel.util.MapUtils;
    4. import com.alibaba.fastjson.JSON;
    5. import com.szh.dto.GoodsExcelDTO;
    6. import com.szh.dto.StudentExcelDTO;
    7. import com.szh.listener.GoodsListener;
    8. import com.szh.service.GoodsService;
    9. import com.szh.service.StudentService;
    10. import org.springframework.beans.factory.annotation.Autowired;
    11. import org.springframework.web.bind.annotation.GetMapping;
    12. import org.springframework.web.bind.annotation.PostMapping;
    13. import org.springframework.web.bind.annotation.RequestMapping;
    14. import org.springframework.web.bind.annotation.RestController;
    15. import org.springframework.web.multipart.MultipartFile;
    16. import javax.servlet.http.HttpServletResponse;
    17. import java.io.IOException;
    18. import java.net.URLEncoder;
    19. import java.util.List;
    20. import java.util.Map;
    21. /**
    22. *
    23. */
    24. @RestController
    25. @RequestMapping(value = "/excel")
    26. public class EasyExcelController {
    27. @Autowired
    28. private GoodsService goodsService;
    29. /**
    30. * Excel文件上传
    31. */
    32. @PostMapping(value = "/upload")
    33. public String upload(MultipartFile file) throws IOException {
    34. EasyExcel.read(file.getInputStream(), GoodsExcelDTO.class, new GoodsListener(goodsService)).sheet().headRowNumber(1).doRead();
    35. return "success";
    36. }
    37. }

    再然后就是SpringBoot的核心配置文件和主启动类。

    1. server:
    2. port: 8001
    3. servlet:
    4. context-path: /boot
    5. spring:
    6. application:
    7. name: web-easyexcel
    8. datasource:
    9. driver-class-name: com.mysql.jdbc.Driver
    10. url: jdbc:mysql://localhost:3306/excel?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8
    11. username: root
    12. password: 12345678
    13. mybatis:
    14. configuration:
    15. log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    1. package com.szh;
    2. import org.mybatis.spring.annotation.MapperScan;
    3. import org.springframework.boot.SpringApplication;
    4. import org.springframework.boot.autoconfigure.SpringBootApplication;
    5. @SpringBootApplication
    6. @EnableTransactionManagement
    7. @MapperScan(basePackages = "com.szh.mapper")
    8. public class WebEasyExcelApplication {
    9. public static void main(String[] args) {
    10. SpringApplication.run(WebEasyExcelApplication.class, args);
    11. }
    12. }

    由于这是上传操作,所以我这里也给大家提供我创建的Excel文档。可以看到和上面的goods表的字段都是对应好的。

    下面我们启动项目,在postman中对上传Excel接口进行测试。

    从上面的IDEA中的控制台可以看到,Excel的解析没有问题,顺利执行完毕,同时10条数据也成功写入数据库中。😄😄😄 


    3.Excel的下载(写Excel)

    这里仍然用到的和上面的读Excel是同一个SpringBoot项目,所以依赖、核心配置文件、主启动类这些都是一样的,就不再给出了,大家参考上面的就行了。

    那么对于Excel的下载,也就是说向Excel中写入数据,相较于上传操作就要简单多了。

    来看下面的步骤:👇👇👇

    这里模拟的场景是:从数据库中的某张表获取到对应的数据集,然后将这个List集合写入Excel中。

    所以自然也是需要实体类,那么和上面的上传操作一样,我仍然是创建两个类,一个是Excel表格对应的实体类,另一个是我们数据库对应的实体类。

    1. package com.szh.dto;
    2. import com.alibaba.excel.annotation.ExcelIgnore;
    3. import com.alibaba.excel.annotation.ExcelProperty;
    4. import com.alibaba.excel.annotation.write.style.*;
    5. import com.alibaba.excel.enums.poi.HorizontalAlignmentEnum;
    6. import lombok.AllArgsConstructor;
    7. import lombok.Data;
    8. import lombok.NoArgsConstructor;
    9. /**
    10. * 类上面的注解,来自lombok和EasyExcel官方,用来自定义表头、宽度等信息
    11. */
    12. @Data
    13. @NoArgsConstructor
    14. @AllArgsConstructor
    15. @ColumnWidth(25)
    16. @HeadRowHeight(30)
    17. @ContentRowHeight(20)
    18. @HeadStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER)
    19. @ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER)
    20. public class StudentExcelDTO {
    21. @ExcelProperty({"学生综述", "学生编号"})
    22. private Integer id;
    23. @ExcelProperty({"学生综述", "学生姓名"})
    24. private String name;
    25. @ExcelProperty({"学生综述", "学生年龄"})
    26. private Integer age;
    27. @ExcelProperty({"学生综述", "学生爱好"})
    28. private String hobby;
    29. @ExcelIgnore
    30. private String address;
    31. }
    1. package com.szh.model;
    2. import lombok.AllArgsConstructor;
    3. import lombok.Data;
    4. import lombok.NoArgsConstructor;
    5. /**
    6. *
    7. */
    8. @Data
    9. @NoArgsConstructor
    10. @AllArgsConstructor
    11. public class Student {
    12. private Integer id;
    13. private String name;
    14. private Integer age;
    15. private String hobby;
    16. private String address;
    17. }

    student这张表的sql脚本,我也给到大家。

    1. SET NAMES utf8mb4;
    2. SET FOREIGN_KEY_CHECKS = 0;
    3. -- ----------------------------
    4. -- Table structure for student
    5. -- ----------------------------
    6. DROP TABLE IF EXISTS `student`;
    7. CREATE TABLE `student` (
    8. `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键,暂定学生编号',
    9. `name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '学生姓名',
    10. `age` int(11) NOT NULL COMMENT '学生年龄',
    11. `hobby` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '学生爱好',
    12. `address` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '学生住址',
    13. PRIMARY KEY (`id`) USING BTREE
    14. ) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
    15. -- ----------------------------
    16. -- Records of student
    17. -- ----------------------------
    18. INSERT INTO `student` VALUES (1, '张三', 41, '睡觉', '湖北省武汉市');
    19. INSERT INTO `student` VALUES (2, '李四', 66, '吃饭', '湖南省长沙市');
    20. INSERT INTO `student` VALUES (3, '王五', 28, '打游戏', '江苏省南京市');
    21. INSERT INTO `student` VALUES (4, '赵六', 35, '玩手机', '浙江省杭州市');
    22. INSERT INTO `student` VALUES (5, '田七', 52, '旅游', '上海市黄浦区');
    23. INSERT INTO `student` VALUES (6, '小哥', 22, '盗墓', '河南省洛阳市');
    24. INSERT INTO `student` VALUES (7, '张起灵', 18, '倒斗', '北京市海淀区');
    25. INSERT INTO `student` VALUES (8, '闷油瓶', 20, '挖坟', '广东省深圳市');
    26. SET FOREIGN_KEY_CHECKS = 1;

    下面就是我们的mapper、service、controller了,还是大家熟悉的那一套。

    1. package com.szh.mapper;
    2. import com.szh.model.Student;
    3. import java.util.List;
    4. /**
    5. *
    6. */
    7. public interface StudentMapper {
    8. /**
    9. * 获取学生列表
    10. */
    11. List queryAllStudents();
    12. }
    1. "1.0" encoding="UTF-8" ?>
    2. mapper
    3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    5. <mapper namespace="com.szh.mapper.StudentMapper">
    6. <sql id="student_column_list">
    7. id, name, age, hobby, address
    8. sql>
    9. <resultMap id="studentMap" type="com.szh.model.Student">
    10. <id column="id" property="id">id>
    11. <result column="name" property="name">result>
    12. <result column="age" property="age">result>
    13. <result column="hobby" property="hobby">result>
    14. <result column="address" property="address">result>
    15. resultMap>
    16. <select id="queryAllStudents" resultMap="studentMap">
    17. select <include refid="student_column_list">include>
    18. from student
    19. select>
    20. mapper>
    1. package com.szh.service;
    2. import com.szh.dto.StudentExcelDTO;
    3. import java.util.List;
    4. /**
    5. *
    6. */
    7. public interface StudentService {
    8. List queryAllStudents();
    9. }
    1. package com.szh.service.impl;
    2. import com.szh.dto.StudentExcelDTO;
    3. import com.szh.mapper.StudentMapper;
    4. import com.szh.model.Student;
    5. import com.szh.service.StudentService;
    6. import lombok.extern.slf4j.Slf4j;
    7. import org.springframework.beans.BeanUtils;
    8. import org.springframework.beans.factory.annotation.Autowired;
    9. import org.springframework.stereotype.Service;
    10. import java.util.ArrayList;
    11. import java.util.List;
    12. /**
    13. *
    14. */
    15. @Slf4j
    16. @Service
    17. public class StudentServiceImpl implements StudentService {
    18. @Autowired
    19. private StudentMapper studentMapper;
    20. @Override
    21. public List queryAllStudents() {
    22. List studentList = studentMapper.queryAllStudents();
    23. List students = new ArrayList<>();
    24. studentList.forEach(item -> {
    25. StudentExcelDTO student = new StudentExcelDTO();
    26. BeanUtils.copyProperties(item, student);
    27. students.add(student);
    28. });
    29. return students;
    30. }
    31. }

    这里的controller和上面的Excel上传是同一个controller,代码可以合并。 

    1. package com.szh.controller;
    2. import com.alibaba.excel.EasyExcel;
    3. import com.alibaba.excel.util.MapUtils;
    4. import com.alibaba.fastjson.JSON;
    5. import com.szh.dto.GoodsExcelDTO;
    6. import com.szh.dto.StudentExcelDTO;
    7. import com.szh.listener.GoodsListener;
    8. import com.szh.service.GoodsService;
    9. import com.szh.service.StudentService;
    10. import org.springframework.beans.factory.annotation.Autowired;
    11. import org.springframework.web.bind.annotation.GetMapping;
    12. import org.springframework.web.bind.annotation.PostMapping;
    13. import org.springframework.web.bind.annotation.RequestMapping;
    14. import org.springframework.web.bind.annotation.RestController;
    15. import org.springframework.web.multipart.MultipartFile;
    16. import javax.servlet.http.HttpServletResponse;
    17. import java.io.IOException;
    18. import java.net.URLEncoder;
    19. import java.util.List;
    20. import java.util.Map;
    21. /**
    22. *
    23. */
    24. @RestController
    25. @RequestMapping(value = "/excel")
    26. public class EasyExcelController {
    27. @Autowired
    28. private StudentService studentService;
    29. /**
    30. * Excel文件下载
    31. */
    32. @GetMapping(value = "/download")
    33. public void download(HttpServletResponse response) throws IOException {
    34. response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    35. response.setCharacterEncoding("utf-8");
    36. //这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
    37. String fileName = URLEncoder.encode("学生信息表", "UTF-8").replaceAll("\\+", "%20");
    38. response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
    39. List studentList = studentService.queryAllStudents();
    40. EasyExcel.write(response.getOutputStream(), StudentExcelDTO.class).sheet("sheet1").doWrite(studentList);
    41. }
    42. /**
    43. * Excel文件下载并且失败的时候返回json
    44. */
    45. @GetMapping(value = "/downloadFailedUsingJson")
    46. public void downloadFailedUsingJson(HttpServletResponse response) throws IOException {
    47. try {
    48. response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    49. response.setCharacterEncoding("utf-8");
    50. //这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
    51. String fileName = URLEncoder.encode("学生信息表", "UTF-8").replaceAll("\\+", "%20");
    52. response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
    53. List studentList = studentService.queryAllStudents();
    54. EasyExcel.write(response.getOutputStream(), StudentExcelDTO.class).autoCloseStream(Boolean.FALSE).sheet("sheet1").doWrite(studentList);
    55. } catch (Exception e) {
    56. //重置response
    57. response.reset();
    58. response.setContentType("application/json");
    59. response.setCharacterEncoding("utf-8");
    60. Map map = MapUtils.newHashMap();
    61. map.put("status", "failure");
    62. map.put("message", "Excel文件下载失败" + e.getMessage());
    63. response.getWriter().println(JSON.toJSONString(map));
    64. }
    65. }
    66. }

    核心配置文件、主启动类这些都是和上面的案例一样的,就不再给出了。

    下面直接启动项目,在postman中进行测试。

    这里大家注意一下,有的小伙伴可能直接点了Send,然后postman反馈了一堆乱码,但是此时把接口地址拿到浏览器中是可以直接访问的。

    解决办法就是:点击下图中的 Send and Download。

    保存之后,我们的Excel下载接口就可以正常跑通,下面就是下载成功的Excel了。😄😄😄 


    4.结语

    上面的两个案例就是SpringBoot整合EasyExcel,实现Excel的读写(上传下载)的操作。

    我这里所有的整合步骤均来自阿里的EasyExcel官方文档,所以大家有什么疑问都可以去官方文档中查找,地址在文章开头已经给出了。

    或者大家也可以在文章下面评论,我都会一一回复的,和大家一起讨论技术话题。😄😄😄

  • 相关阅读:
    【Linux operation 55】centos 9 steam 在线安装docker
    92、船员调度
    DOM常用方法以及项目
    SSL证书部署
    Mac如何搭建Vue项目
    python之对接有道翻译API接口实现批量翻译
    BLCD无刷电机三相电流采样说明与总结
    js中dom和bom有什么区别
    程序员必看的十步高分电影,强推第八部
    图像运算和图像增强九
  • 原文地址:https://blog.csdn.net/weixin_43823808/article/details/126677985