SpringBoot整合EasyExcel实现导入导出数据

目录
  • 前言
  • 1.前端
  • 2.数据库
  • 3.后端
    • 3.1 contrller
    • 3.2 mapper
    • 3.3 bean
    • 3.4 listener
    • 3.5 config
    • 3.6 配置文件
  • 4.启动测试

前言

创建一个普通的maven项目即可

项目目录结构

1.前端

存放在resources/static 下

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <!-- 开发环境版本,包含了有帮助的命令行警告 -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <!-- 引入样式 -->
    <link
      rel="stylesheet"
      href="https://unpkg.com/element-ui/lib/theme-chalk/index.css" rel="external nofollow"
    />
    <!-- 引入组件库 -->
    <script src="https://unpkg.com/element-ui/lib/index.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  </head>
  <body>
    <div id="app">
      <div class="app-container">
        <div style="margin-bottom: 10px">
          <el-button
            @click="dialogVisible = true"
            type="primary"
            size="mini"
            icon="el-icon-download"
          >
            导入Excel
          </el-button>
          <el-dialog
            title="数据字典导入"
            :visible.sync="dialogVisible"
            width="30%"
          >
            <el-form>
              <el-form-item label="请选择Excel文件">
                <el-upload
                  :auto-upload="true"
                  :multiple="false"
                  :limit="1"
                  :on-exceed="fileUploadExceed"
                  :on-success="fileUploadSuccess"
                  :on-error="fileUploadError"
                  :action="importUrl"
                  name="file"
                  accept="application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
                >
                  <!--accept 只接受某种格式的文件-->
                  <el-button size="small" type="primary">点击上传</el-button>
                </el-upload>
              </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
              <el-button @click="dialogVisible = false">取消</el-button>
            </div>
          </el-dialog>

          <!-- 导出 -->
          <el-button
            @click="exportData"
            type="primary"
            size="mini"
            icon="el-icon-upload2"
          >
            导出Excel
          </el-button>

          <!-- 数据展示 -->
          <el-table :data="list" stripe style="width: 100%">
            <el-table-column prop="name" label="姓名" width="180">
            </el-table-column>
            <el-table-column prop="birthday" label="生日" width="180">
            </el-table-column>
            <el-table-column prop="salary" label="薪资"> </el-table-column>
          </el-table>
          <div>
            <el-pagination
              @size-change="handleSizeChange"
              @current-change="handleCurrentChange"
              :current-page="pageNum"
              :page-sizes="[2, 5, 10,  20]"
              :page-size="pageSize"
              background
              layout="total, sizes, prev, pager, next, jumper"
              :total="total"
            >
            </el-pagination>
          </div>
        </div>
      </div>
    </div>
  </body>
  <script>
    new Vue({
      el: '#app',
      data() {
        return {
          dialogVisible: false, //文件上传对话框是否显示
          list: [], // 字典的数据
          importUrl: 'http://localhost:8811/api/excel/import',
          pageNum: 1, // 页数
          pageSize: 5, // 每页条数
          total: 1000,
        }
      },
      created() {
        this.showList()
      },
      methods: {
        showList() {
          //使用自定义配置
          const request = axios.create({
            baseURL: 'http://localhost:8811', //url前缀
            timeout: 1000, //超时时间
            // headers: { token: 'helen123456' }, //携带令牌
          })
          request
            .get('/api/excel/list', {
              params: {
                pageNum: this.pageNum,
                pageSize: this.pageSize,
              },
            })
            .then((res) => {
              this.total = res.data.size
              this.list = res.data.list
              console.log(res)
            })
        },
        // 上传多于一个文件时
        fileUploadExceed() {
          this.$message.warning('只能选取一个文件')
        },
		// 导出
        exportData() {
          window.location.href = 'http://localhost:8811/api/excel/export'
        },

        //上传成功回调
        fileUploadSuccess(response) {
          if (response.code === 0) {
            this.$message.success('数据导入成功')
            this.dialogVisible = false
          } else {
            this.$message.error(response.message)
          }
        },

        //上传失败回调
        fileUploadError(error) {
          this.$message.error('数据导入失败')
        },
        /**
         * 用户所选择当前页面展示的数据条数
         */
        handleSizeChange(val) {
          console.log(`每页 ${val} 条`)
          this.pageSize = val
          this.showList()
        },
        handleCurrentChange(val) {
          console.log(`当前页: ${val}`)
          this.pageNum = val
          this.showList()
        },
      },
    })
  </script>
</html>

2.数据库

CREATE TABLE `student` (
  `name` varchar(255) DEFAULT NULL COMMENT '姓名',
  `birthday` datetime DEFAULT NULL COMMENT '生日',
  `salary` decimal(10,4) DEFAULT NULL COMMENT '薪资'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

3.后端

3.1 contrller

StudentController

@Slf4j
@RestController
@CrossOrigin
@RequestMapping("/api/excel/")
public class StudentController {

    @Resource
    private StudentMapper studentMapper;

    @GetMapping("list")
    public HashMap<String, Object> list(@RequestParam int pageNum,@RequestParam int pageSize){
        // 分页查询
        Page<Student> page = new Page<>(pageNum, pageSize);
        studentMapper.selectPage(page,null);

        // 封装数据
        HashMap<String, Object> map = new HashMap<>();
        ArrayList<ExcelStudentDTO> excelDictDTOList = new ArrayList<>();
        // 转换数据
        page.getRecords().forEach(student -> {
            ExcelStudentDTO studentDTO = new ExcelStudentDTO();
            BeanUtils.copyProperties(student,studentDTO);
            excelDictDTOList.add(studentDTO);
        });

        map.put("list",excelDictDTOList);
        map.put("size",page.getTotal());
        return map;
    }

    /**
     * 导入
     * @param file 文件对象
     */
    @RequestMapping("import")
    @Transactional(rollbackFor = {Exception.class})
    public String importData( @RequestParam("file") MultipartFile file){
        try {
            // 读取文件流
            EasyExcel.read
                    (file.getInputStream(),// 前端上传的文件
                            ExcelStudentDTO.class,// 跟excel对应的实体类
                            new ExcelDictDTOListener(studentMapper))// 监听器
                    .excelType(ExcelTypeEnum.XLSX)// excel的类型
                    .sheet("模板").doRead();
            log.info("importData finished");
        } catch (IOException e) {
           log.info("失败");
           e.printStackTrace();
        }
        return "上传成功";
    }

    /**
     * 导入
     */
    @GetMapping("export")
    public String exportData(HttpServletResponse response){

        try {
            // 设置响应体内容
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");

            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            String fileName = URLEncoder.encode("myStu", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            EasyExcel.write(response.getOutputStream()
                    ,ExcelStudentDTO.class).sheet().doWrite(studentMapper.selectList(null));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "上传成功";
    }

}

3.2 mapper

StudentMapper

@Mapper
public interface StudentMapper extends BaseMapper<Student> {
    void insertBatch(List<ExcelStudentDTO> list);
}

StudentMapper.xml

<?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="look.word.mapper.StudentMapper">
  <insert id="insertBatch" >
    insert into student(name, birthday, salary)
    values
    <foreach collection="list"   item="item" separator=",">
               (
        #{item.name} ,
        #{item.birthday} ,
        #{item.salary}
        )
    </foreach>
  </insert>
</mapper>

3.3 bean

ExcelStudentDTO

导入数据时 要保证excel中列名和ExcelStudentDTO一致奥

/**
 * excel对应的实体类
 * @author jiejie
 */
@Data
public class ExcelStudentDTO {
	// excel中的列名
    @ExcelProperty("姓名")
    private String name;

    @ExcelProperty("生日")
    private Date birthday;

    @ExcelProperty("薪资")
    private BigDecimal salary;
}

Student

/**
 * 数据库对应的实体类
 * @author jiejie
 */
@Data
@TableName(value = "student")
public class Student {
    /**
     * 姓名
     */
    @TableField(value = "name")
    private String name;

    /**
     * 生日
     */
    @TableField(value = "birthday")
    private Date birthday;

    /**
     * 薪资
     */
    @TableField(value = "salary")
    private BigDecimal salary;

    public static final String COL_NAME = "name";

    public static final String COL_BIRTHDAY = "birthday";

    public static final String COL_SALARY = "salary";
}

3.4 listener

官方文档

EasyExcel读取文件需要用到

ExcelDictDTOListener

/**
 * 监听
 * 再读取数据的同时 对数据进行插入操作
 * @author : look-word
 * @date : 2022-05-10 21:35
 **/
@Slf4j
//@AllArgsConstructor //全参
@NoArgsConstructor //无参
public class ExcelDictDTOListener extends AnalysisEventListener<ExcelStudentDTO> {

    /**
     * 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收
     */
    private static final int BATCH_COUNT = 5;
    List<ExcelStudentDTO> list = new ArrayList<ExcelStudentDTO>();

    private StudentMapper studentMapper;

    //传入mapper对象
    public ExcelDictDTOListener(StudentMapper studentMapper) {
        this.studentMapper = studentMapper;
    }

    /**
     *遍历每一行的记录
     * @param data
     * @param context
     */
    @Override
    public void invoke(ExcelStudentDTO data, AnalysisContext context) {
        log.info("解析到一条记录: {}", data);
        list.add(data);
        // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
        if (list.size() >= BATCH_COUNT) {
            saveData();
            // 存储完成清理 list
            list.clear();
        }
    }

    /**
     * 所有数据解析完成了 都会来调用
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 这里也要保存数据,确保最后遗留的数据也存储到数据库
        saveData();
        log.info("所有数据解析完成!");
    }

    /**
     * 加上存储数据库
     */
    private void saveData() {
        log.info("{}条数据,开始存储数据库!", list.size());
        studentMapper.insertBatch(list);  //批量插入
        log.info("存储数据库成功!");
    }
}

3.5 config

mybatisPlus分页插件

MybatisPlusConfig

@Configuration
public class MybatisPlusConfig {

    /**
     * 新的分页插件,一缓和二缓遵循mybatis的规则,
     * 需要设置 MybatisConfiguration#useDeprecatedExecutor = false
     * 避免缓存出现问题(该属性会在旧插件移除后一同移除)
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
        paginationInnerInterceptor.setDbType(DbType.MYSQL);
        paginationInnerInterceptor.setOverflow(true);
        interceptor.addInnerInterceptor(paginationInnerInterceptor);
        return interceptor;
    }

    @Bean
    public ConfigurationCustomizer configurationCustomizer() {
        return configuration -> configuration.setUseDeprecatedExecutor(false);
    }
}

3.6 配置文件

application.yaml

server:
  port: 8811
spring:
  datasource: # mysql数据库连接
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/2022_source_springboot?serverTimezone=GMT%2B8&characterEncoding=utf-8
    username: root
    password: 317311
mybatis-plus:
  configuration:# sql日志
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  mapper-locations:
    - classpath:mapper/*.xml

4.启动测试

启动springboot哦

页面效果图

导出效果

注意

导入数据时要保证excel中列名和ExcelStudentDTO一致奥

到此这篇关于SpringBoot整合EasyExcel实现导入导出数据的文章就介绍到这了,更多相关SpringBoot EasyExcel导入导出数据内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringBoot集成EasyExcel实现Excel导入的方法

    第一次正式的写文章进行分享,如果文章中有什么问题,欢迎大家在文末的群内反馈. 一.背景 为什么会用Easyexcel来做Excel上传 平时项目中经常使用EasyExcel从本地读取Excel中的数据,还有一个前端页面对需要处理的数据进行一些配置(如:Excel所在的文件夹,Excel的文件名,以及Sheet列名.处理数据需要的某些参数),由于每次都是读取的本地的文件,我就在想,如果某一天需要通过前端上传excel给我,让我来进行处理我又应该怎么办呢?我怎么才能在尽量少修改代码的前提下实现这个功

  • SpringBoot中EasyExcel实现Excel文件的导入导出

    前言 在我们日常的开发过程中经常会使用Excel文件的形式来批量地上传下载系统数据,我们最常用的工具是Apache poi,但是如果数据到底上百万时,将会造成内存溢出的问题,那么我们怎么去实现百万数据批量导入导出. 正文 Easyexcel Easyexcel 是阿里巴巴的开源项目,用来优化Excel文件处理过程: poi消耗内存严重:Java解析.生成Excel比较有名的框架有Apache poi.jxl.但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的

  • SpringBoot+easypoi实现数据的Excel导出

    本文实例为大家分享了SpringBoot+easypoi实现数据的Excel导出的具体代码,供大家参考,具体内容如下 maven <dependency> <groupId>cn.afterturn</groupId> <artifactId>easypoi-spring-boot-starter</artifactId> <version>4.1.0</version> </dependency> Contr

  • SpringBoot内存数据导出成Excel的实现方法

    前言 这是本人写的一个SpringBoot对Excel写入的方法,实测能用,待提升的地方有很多,有不足之处请多多指点. Excel2003版(后缀为.xls)最大行数是65536行,最大列数是256列. Excel2007以上的版本(后缀为.xlsx)最大行数是1048576行,最大列数是16384列. 若数据量超出行数,需要进行脚页的控制,这一点没做,因为一般100W行已够用. 提供3种方法写入: 1.根据给定的实体类列List和列名数组arr[]进行Excel写入 2.根据给定的List和k

  • SpringBoot 导出数据生成excel文件返回方式

    一.基于框架 1.IDE IntelliJ IDEA 2.软件环境 Spring boot mysql mybatis org.apache.poi 二.环境集成 1.创建spring boot项目工程 略过 2.maven引入poi <!--数据导出依赖 excel--> <!-- https://mvnrepository.com/artifact/org.apache.poi/poi --> <dependency> <groupId>org.apac

  • SpringBoot整合EasyExcel实现文件导入导出

    准备工作 注意:点击查看官网Demo 1. 引入pom依赖 <!--easyExcel--> <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> </dependency> 2. 实现功能 结合Vue前端,实现浏览器页面直接导出日志文件 实现文件的导入 Excel文件下载 3. 日志实体类 实体类里有自定义转换器:用于

  • SpringBoot整合EasyExcel实现导入导出数据

    目录 前言 1.前端 2.数据库 3.后端 3.1 contrller 3.2 mapper 3.3 bean 3.4 listener 3.5 config 3.6 配置文件 4.启动测试 前言 创建一个普通的maven项目即可 项目目录结构 1.前端 存放在resources/static 下 index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF

  • 使用VUE+SpringBoot+EasyExcel 整合导入导出数据的教程详解

    目录 1 前端 2 数据库 3 后端 3.1 contrller 3.2 mapper 3.3 bean 3.4 listener 3.5 config 3.6 配置文件 4 启动测试 创建一个普通的maven项目即可 项目目录结构 1 前端 存放在resources/static 下 index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo

  • SpringBoot整合EasyExcel实现Excel表格导出功能

    目录 栗子 1.组件介绍 2.配置文件 SpringBoot项目pom.xml 3.项目代码 项目结构 ExportController.java Mock.java CitySheet.java CompanySheet.java UserSheet.java SpringBootEasyexcelApplication.java 4.效果展示 单个sheet导出 多个sheet导出 5.总结 栗子 在后端管理系统的开发中,经常有需要导出当前表格数据的功能,有些前端表格组件可以直接做到,但是不

  • SpringBoot导入导出数据实现方法详解

    今天给大家带来的是一个 SpringBoot导入导出数据 首先我们先创建项目 注意:创建SpringBoot项目时一定要联网不然会报错 项目创建好后我们首先对 application.yml 进行编译 server:  port: 8081# mysqlspring:  datasource:    driver-class-name: com.mysql.cj.jdbc.Driver    url: jdbc:mysql://127.0.0.1:3306/dvd?characterEncodi

  • SpringBoot整合EasyExcel的完整过程记录

    目录 为什么要用EasyExcel 1.EasyExcel简介 2.使用EasyExcel实现写 2.1 创建实体类 2.2 测试写Excel 3.使用EasyExcel实现读 3.1 创建读取操作的监听器 3.2 测试读Excel 4.springboot项目实践EasyExcel 4.1 pom中引入相关依赖 4.2 创建数据库表及添加数据 4.3 实体类 4.4 Controller层 4.5 Service层 4.6 创建监听器(核心部分) 4.7 结果展示 总结 为什么要用EasyEx

  • SpringBoot整合EasyExcel进行大数据处理的方法详解

    目录 EasyExcel 需要的Maven 基础读案例 操作的excel 实体类 读取监听器 测试 基础写案例 实体类 测试 Excel模板方式 准备模块 实体类 测试 EasyExcel EasyExcel文档 我用过Poi和EasyPoi这些工具总体来说: POI 优点我觉得自由,但是迎来的就是复杂度,和大数据量时候性能的缺点 EasyPoi基于POI 的二次封装,解决了大部分的常用场景,简化了代码,但是特别复杂表格处理还是不行,而且性能的话和poi差不多,简单来说就是简化了Poi的操作,少

  • SpringBoot+Vue实现EasyPOI导入导出的方法详解

    目录 前言 一.为什么做导入导出 二.什么是 EasyPOI 三.项目简介 项目需求 效果图 开发环境 四.实战开发 核心源码 前端页面 后端核心实现 五.项目源码 小结 前言 Hello~ ,前后端分离系列和大家见面了,秉着能够学到知识,学会知识,学懂知识的理念去学习,深入理解技术! 项目开发过程中,很大的需求都有 导入导出功能,我们依照此功能,来实现并还原真实企业开发中的实现思路 一.为什么做导入导出 为什么做导入导出 导入 在项目开发过程中,总会有一些统一的操作,例如插入数据,系统支持单个

  • SQL Server Management Studio Express管理器 没有导入导出数据的向导的解决方法

    办法如下: sqlserver2005中,导入导出数据是通过SQL Server 2005 Integration Services (SSIS)实现的,那么可以在SQL 2005的安装目录下找到DTSWizard.exe,例如我的是在C:\Program Files\Microsoft SQL Server\90\DTS\Binn,在该目录下找到DTSWizard.exe,然后在命令提示符窗口中运行DTSWizard.exe,这时候就可以看到导入导出数据的向导了. 接下来就可以进行导入导出操作

  • mysql导入导出数据中文乱码解决方法小结

    linux系统中 linux默认的是utf8编码,而windows是gbk编码,所以会出现上面的乱码问题. 解决mysql导入导出数据乱码问题 首先要做的是要确定你导出数据的编码格式,使用mysqldump的时候需要加上--default-character-set=utf8, 例如下面的代码: 复制代码 代码如下: mysqldump -uroot -p --default-character-set=utf8 dbname tablename > bak.sql 那么导入数据的时候也要使用-

随机推荐