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

lxf2023-11-15 11:50:01
摘要

这篇文章主要介绍了使用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项目即可

    项目目录结构

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

    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 keylink">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 ></script>
        <script keylink">iOS/dist/axios.min.js"></script>
      </head>
      <body>
        <div >
          <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;
        }
    
        
        @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  >
        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一致奥

    
    @Data
    public class ExcelStudentDTO {
    	// excel中的列名
        @ExcelProperty("姓名")
        private String name;
        @ExcelProperty("生日")
        private Date birthday;
        @ExcelProperty("薪资")
        private BigDecimal salary;
    }

    Student

    
    @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

    
    @Slf4j
    //@AllArgsConstructor //全参
    @NoArgsConstructor //无参
    public class ExcelDictDTOListener extends AnalysisEventListener<ExcelStudentDTO> {
        
        private static final int BATCH_COUNT = 5;
        List<ExcelStudentDTO> list = new ArrayList<ExcelStudentDTO>();
        private StudentMapper studentMapper;
        //传入mapper对象
        public ExcelDictDTOListener(StudentMapper studentMapper) {
            this.studentMapper = studentMapper;
        }
        
        @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 {
    
        
        @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哦

    页面效果图

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

    导出效果

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

    注意

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

    到此这篇关于使用VUE+SpringBoot+EasyExcel 整合导入导出数据的文章就介绍到这了,更多相关vue springboot easyexcel导入导出数据内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.adminjs.cn!