当前位置: 首页 > news >正文

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数据库。

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.9</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>3.1.1</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.28</version>
        </dependency>

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

        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>

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

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

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

package com.szh.dto;

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 *
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class GoodsExcelDTO {

    @ExcelProperty(index = 0)
    private Integer id;

    @ExcelProperty(index = 1)
    private String name;

    @ExcelProperty(index = 2)
    private String info;

    @ExcelProperty(index = 3)
    @DateTimeFormat(value = "yyyy-MM-dd HH:mm:ss")
    private String buyTime;
}
package com.szh.model;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;

import java.util.Date;

/**
 *
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Goods {

    private Integer id;

    private String name;

    private String info;

    //@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date buyTime;
}

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

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

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for goods
-- ----------------------------
DROP TABLE IF EXISTS `goods`;
CREATE TABLE `goods`  (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '商品名称',
  `info` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '商品信息',
  `buyTime` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '购买时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of goods
-- ----------------------------
INSERT INTO `goods` VALUES (1, 'Java核心技术卷I', 'Java四大名著之一', '2021-12-01 13:05:23');
INSERT INTO `goods` VALUES (2, 'Java核心技术卷II', 'Java四大名著之一', '2022-02-28 09:21:55');
INSERT INTO `goods` VALUES (3, 'Java编程思想', 'Java四大名著之一', '2020-05-15 14:16:18');
INSERT INTO `goods` VALUES (4, 'Effective Java', 'Java四大名著之一', '2022-07-06 22:33:44');
INSERT INTO `goods` VALUES (5, '深入理解Java虚拟机', 'JVM由此开始', '2021-06-06 20:59:37');
INSERT INTO `goods` VALUES (6, 'SpringBoot实战应用教程', 'SpringBoot极速开发框架', '2020-03-17 10:02:31');
INSERT INTO `goods` VALUES (7, '快速上手SSM', '一本优秀的书籍', '2021-08-14 19:08:26');
INSERT INTO `goods` VALUES (8, 'MySQL是怎样运行的', '深入学习MySQL', '2022-04-09 15:37:05');
INSERT INTO `goods` VALUES (9, 'Java并发编程', '并发编程之美', '2020-01-18 21:12:13');
INSERT INTO `goods` VALUES (10, 'Java从入门到精通', '小白的Java之路', '2021-09-11 17:18:21');

SET FOREIGN_KEY_CHECKS = 1;

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

下面就是监听器代码。

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

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

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

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

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

package com.szh.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ConverterUtils;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.fastjson.JSON;
import com.szh.dto.GoodsExcelDTO;
import com.szh.model.Goods;
import com.szh.service.GoodsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Excel模板的读取类
 * 有个很重要的点 DemoDataListener 不能被spring管理
 * 要每次读取excel都要new, 然后里面用到spring可以构造方法传进去
 */
@Slf4j
public class GoodsListener implements ReadListener<GoodsExcelDTO> {

    private GoodsService goodsService;
    private List<GoodsExcelDTO> goodsExcelDTOList = ListUtils.newArrayList();
    private final List<Goods> goodsList = ListUtils.newArrayList();
    private int count = 0;

    public GoodsListener() {
    }

    public GoodsListener(GoodsService goodsService) {
        this.goodsService = goodsService;
    }

    @Override
    public void invoke(GoodsExcelDTO goodsExcelDTO, AnalysisContext analysisContext) {
        log.info("解析到第 {} 条数据:{}", (++count), JSON.toJSONString(goodsExcelDTO));
        goodsExcelDTOList.add(goodsExcelDTO);
    }

    @Override
    public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {
        Map<Integer, String> stringMap = ConverterUtils.convertToStringMap(headMap, context);
        Set<Integer> keySet = stringMap.keySet();
        System.out.println("该Excel表头信息是:");
        for (int i = 0; i < keySet.size(); i++) {
            System.out.println("第 " + (i + 1) + " 列 = " + stringMap.get(i));
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        log.info("该Excel的所有数据解析完成!!!");
        goodsExcelDTOList.forEach(item -> {
            try {
                Goods goods = new Goods();
                goods.setId(item.getId());
                goods.setName(item.getName());
                goods.setInfo(item.getInfo());
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date date = sdf.parse(item.getBuyTime());
                goods.setBuyTime(date);
                goodsList.add(goods);
            } catch (ParseException e) {
                log.error(e.getMessage());
            }
        });
        goodsExcelDTOList = ListUtils.newArrayList();
        goodsService.batchInsert(goodsList);
    }
}

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

package com.szh.mapper;

import com.szh.dto.GoodsExcelDTO;
import com.szh.model.Goods;

import java.util.List;

/**
 *
 */
public interface GoodsMapper {

    /**
     * 批量插入
     */
    void batchInsert(List<Goods> goodsList);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.szh.mapper.GoodsMapper">
    <!-- 使用insert、update、delete、select标签编写sql语句 -->

    <insert id="batchInsert" parameterType="java.util.List">
        insert into goods
        values
        <foreach collection="list" item="item" index="index" separator=",">
            (#{item.id}, #{item.name}, #{item.info}, #{item.buyTime})
        </foreach>
    </insert>
</mapper>
package com.szh.service;

import com.szh.model.Goods;

import java.util.List;

/**
 *
 */
public interface GoodsService {

    void batchInsert(List<Goods> goodsList);
}
package com.szh.service.impl;

import com.szh.mapper.GoodsMapper;
import com.szh.model.Goods;
import com.szh.service.GoodsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 *
 */
@Slf4j
@Service
public class GoodsServiceImpl implements GoodsService {

    @Autowired
    private GoodsMapper goodsMapper;

    @Transactional
    @Override
    public void batchInsert(List<Goods> goodsList) {
        goodsMapper.batchInsert(goodsList);
    }
}
package com.szh.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.util.MapUtils;
import com.alibaba.fastjson.JSON;
import com.szh.dto.GoodsExcelDTO;
import com.szh.dto.StudentExcelDTO;
import com.szh.listener.GoodsListener;
import com.szh.service.GoodsService;
import com.szh.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

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

/**
 *
 */
@RestController
@RequestMapping(value = "/excel")
public class EasyExcelController {

    @Autowired
    private GoodsService goodsService;

    /**
     * Excel文件上传
     */
    @PostMapping(value = "/upload")
    public String upload(MultipartFile file) throws IOException {
        EasyExcel.read(file.getInputStream(), GoodsExcelDTO.class, new GoodsListener(goodsService)).sheet().headRowNumber(1).doRead();
        return "success";
    }

}

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

server:
  port: 8001
  servlet:
    context-path: /boot

spring:
  application:
    name: web-easyexcel
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/excel?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8
    username: root
    password: 12345678

mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
package com.szh;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan(basePackages = "com.szh.mapper")
public class WebEasyExcelApplication {

    public static void main(String[] args) {
        SpringApplication.run(WebEasyExcelApplication.class, args);
    }

}

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

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

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


3.Excel的下载(写Excel)

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

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

来看下面的步骤:👇👇👇

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

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

package com.szh.dto;

import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.*;
import com.alibaba.excel.enums.poi.HorizontalAlignmentEnum;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 类上面的注解,来自lombok和EasyExcel官方,用来自定义表头、宽度等信息
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@ColumnWidth(25)
@HeadRowHeight(30)
@ContentRowHeight(20)
@HeadStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER)
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER)
public class StudentExcelDTO {

    @ExcelProperty({"学生综述", "学生编号"})
    private Integer id;

    @ExcelProperty({"学生综述", "学生姓名"})
    private String name;

    @ExcelProperty({"学生综述", "学生年龄"})
    private Integer age;

    @ExcelProperty({"学生综述", "学生爱好"})
    private String hobby;

    @ExcelIgnore
    private String address;
}
package com.szh.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 *
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {

    private Integer id;

    private String name;

    private Integer age;

    private String hobby;

    private String address;
}

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

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student`  (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键,暂定学生编号',
  `name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '学生姓名',
  `age` int(11) NOT NULL COMMENT '学生年龄',
  `hobby` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '学生爱好',
  `address` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '学生住址',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES (1, '张三', 41, '睡觉', '湖北省武汉市');
INSERT INTO `student` VALUES (2, '李四', 66, '吃饭', '湖南省长沙市');
INSERT INTO `student` VALUES (3, '王五', 28, '打游戏', '江苏省南京市');
INSERT INTO `student` VALUES (4, '赵六', 35, '玩手机', '浙江省杭州市');
INSERT INTO `student` VALUES (5, '田七', 52, '旅游', '上海市黄浦区');
INSERT INTO `student` VALUES (6, '小哥', 22, '盗墓', '河南省洛阳市');
INSERT INTO `student` VALUES (7, '张起灵', 18, '倒斗', '北京市海淀区');
INSERT INTO `student` VALUES (8, '闷油瓶', 20, '挖坟', '广东省深圳市');

SET FOREIGN_KEY_CHECKS = 1;

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

package com.szh.mapper;

import com.szh.model.Student;

import java.util.List;

/**
 *
 */
public interface StudentMapper {

    /**
     * 获取学生列表
     */
    List<Student> queryAllStudents();
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.szh.mapper.StudentMapper">
    <!-- 使用insert、update、delete、select标签编写sql语句 -->

    <sql id="student_column_list">
        id, name, age, hobby, address
    </sql>

    <resultMap id="studentMap" type="com.szh.model.Student">
        <id column="id" property="id"></id>
        <result column="name" property="name"></result>
        <result column="age" property="age"></result>
        <result column="hobby" property="hobby"></result>
        <result column="address" property="address"></result>
    </resultMap>

    <select id="queryAllStudents" resultMap="studentMap">
        select <include refid="student_column_list"></include>
        from student
    </select>

</mapper>
package com.szh.service;

import com.szh.dto.StudentExcelDTO;

import java.util.List;

/**
 *
 */
public interface StudentService {

    List<StudentExcelDTO> queryAllStudents();
}
package com.szh.service.impl;

import com.szh.dto.StudentExcelDTO;
import com.szh.mapper.StudentMapper;
import com.szh.model.Student;
import com.szh.service.StudentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 *
 */
@Slf4j
@Service
public class StudentServiceImpl implements StudentService {

    @Autowired
    private StudentMapper studentMapper;

    @Override
    public List<StudentExcelDTO> queryAllStudents() {
        List<Student> studentList = studentMapper.queryAllStudents();
        List<StudentExcelDTO> students = new ArrayList<>();
        studentList.forEach(item -> {
            StudentExcelDTO student = new StudentExcelDTO();
            BeanUtils.copyProperties(item, student);
            students.add(student);
        });
        return students;
    }
}

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

package com.szh.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.util.MapUtils;
import com.alibaba.fastjson.JSON;
import com.szh.dto.GoodsExcelDTO;
import com.szh.dto.StudentExcelDTO;
import com.szh.listener.GoodsListener;
import com.szh.service.GoodsService;
import com.szh.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

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

/**
 *
 */
@RestController
@RequestMapping(value = "/excel")
public class EasyExcelController {

    @Autowired
    private StudentService studentService;

    /**
     * Excel文件下载
     */
    @GetMapping(value = "/download")
    public void download(HttpServletResponse response) throws IOException {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        //这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("学生信息表", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        List<StudentExcelDTO> studentList = studentService.queryAllStudents();
        EasyExcel.write(response.getOutputStream(), StudentExcelDTO.class).sheet("sheet1").doWrite(studentList);
    }

    /**
     * Excel文件下载并且失败的时候返回json
     */
    @GetMapping(value = "/downloadFailedUsingJson")
    public void downloadFailedUsingJson(HttpServletResponse response) throws IOException {
        try {
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            //这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            String fileName = URLEncoder.encode("学生信息表", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            List<StudentExcelDTO> studentList = studentService.queryAllStudents();
            EasyExcel.write(response.getOutputStream(), StudentExcelDTO.class).autoCloseStream(Boolean.FALSE).sheet("sheet1").doWrite(studentList);
        } catch (Exception e) {
            //重置response
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            Map<String, String> map = MapUtils.newHashMap();
            map.put("status", "failure");
            map.put("message", "Excel文件下载失败" + e.getMessage());
            response.getWriter().println(JSON.toJSONString(map));
        }
    }
}

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

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

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

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

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

 


4.结语

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

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

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

相关文章:

  • Vue 国际化之 vue-i18n 的使用
  • 7、Java——for循环打印九九乘法口诀表
  • 目标检测 YOLO 系列模型
  • Java开发五年跳槽涨薪从12K到35K,靠“狂刷”九遍面试题
  • DM数据库安装,docker镜像
  • 项目中的traceID
  • Webview+Viewpager左右滑动冲突
  • 【 C++ 】多态
  • jupyter 基本用法
  • Unity入门01——unity界面基础
  • 【05】Yarn
  • Flutter 从源码看Getx的依赖原理
  • JavaScript 知识梳理基础篇(二)
  • 【web-代码审计】(14.4)ASP.NET
  • 一、Maven-单一架构案例(创建工程,引入依赖,搭建环境:持久化层,)
  • 30天自制操作系统-2
  • 5分钟即可掌握的前端高效利器:JavaScript 策略模式
  • Angularjs之国际化
  • CentOS6 编译安装 redis-3.2.3
  • CSS3 聊天气泡框以及 inherit、currentColor 关键字
  • ES6之路之模块详解
  • Joomla 2.x, 3.x useful code cheatsheet
  • MySQL数据库运维之数据恢复
  • mysql外键的使用
  • Python代码面试必读 - Data Structures and Algorithms in Python
  • Spring框架之我见(三)——IOC、AOP
  • TypeScript实现数据结构(一)栈,队列,链表
  • vue脚手架vue-cli
  • Vue学习第二天
  • XML已死 ?
  • 大快搜索数据爬虫技术实例安装教学篇
  • 基于游标的分页接口实现
  • 解析 Webpack中import、require、按需加载的执行过程
  • 理解IaaS, PaaS, SaaS等云模型 (Cloud Models)
  • 强力优化Rancher k8s中国区的使用体验
  • 区块链分支循环
  • 如何学习JavaEE,项目又该如何做?
  • 跳前端坑前,先看看这个!!
  • 推荐一个React的管理后台框架
  • 我的业余项目总结
  • 线性表及其算法(java实现)
  • 小程序滚动组件,左边导航栏与右边内容联动效果实现
  • 移动端解决方案学习记录
  • 这几个编码小技巧将令你 PHP 代码更加简洁
  • 看到一个关于网页设计的文章分享过来!大家看看!
  • kubernetes资源对象--ingress
  • #在 README.md 中生成项目目录结构
  • (2)STM32单片机上位机
  • (3)nginx 配置(nginx.conf)
  • (C++20) consteval立即函数
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第2节(共同的基类)
  • (pojstep1.3.1)1017(构造法模拟)
  • (Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五
  • (笔记)Kotlin——Android封装ViewBinding之二 优化
  • (附源码)spring boot儿童教育管理系统 毕业设计 281442