SpringBoot中Excel表的导入、导出功能的实现

文章目录

  • 一、easyExcel简介
  • 二、Excel表的导出
    • [2.1 添加 Maven 依赖](#2.1 添加 Maven 依赖)
    • [2.2 创建导出数据的实体类](#2.2 创建导出数据的实体类)
    • [4. 编写导出接口](#4. 编写导出接口)
    • [5. 前端代码](#5. 前端代码)
    • [6. 实现效果](#6. 实现效果)
  • 三、excel表的导出
    • [1. Excel表导入的整体流程](#1. Excel表导入的整体流程)
      • [1.1 配置文件存储路径](#1.1 配置文件存储路径)
    • [2. 前端实现](#2. 前端实现)
      • [2.1 文件上传组件](#2.1 文件上传组件)
    • [2.2 文件上传逻辑](#2.2 文件上传逻辑)
    • [3. 后端实现](#3. 后端实现)
      • [3.1 文件上传接口](#3.1 文件上传接口)
    • [3.2 数据解析接口](#3.2 数据解析接口)
    • [4. 实现效果](#4. 实现效果)

一、easyExcel简介

Excel表的导入导出有很多种方式,这里我们使用easyExel。EasyExcel 是阿里巴巴推出的一个处理 Excel 文件的库,特别适合大数据量的 Excel 文件操作,具有性能优越、内存占用小等特点。

二、Excel表的导出

集成 EasyExcel 到 Spring Boot 项目

2.1 添加 Maven 依赖

首先,在 pom.xml 中添加 EasyExcel 的依赖:

xml 复制代码
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.0.6</version> <!-- 版本号可以根据需要调整 -->
</dependency>

2.2 创建导出数据的实体类

根据需要创建实体类,使用@ExcelProperty注解标注实体类的字段,指定表头名称和列索引,EasyExcel 会根据这个类的字段和注解来生成 Excel 文件。

java 复制代码
@Data
public class PersonVO {
    @ExcelProperty(value = "人员ID", index = 0)
    private Integer personId;

    @ExcelIgnore
    private Integer communityId;

    @ExcelProperty(value = "单元名称", index = 2)
    private String termName;

    @ExcelProperty(value = "房号", index = 3)
    private String houseNo;

    @ExcelProperty(value = "姓名", index = 4)
    private String userName;

    @ExcelProperty(value = "性别", index = 5)
    private String sex;

    @ExcelProperty(value = "手机号", index = 6)
    private String mobile;

    @ExcelIgnore
    private String faceUrl;

    @ExcelProperty(value = "居住性质", index = 7)
    private String personType;

    @ExcelIgnore
    private Integer state;

    @ExcelIgnore
    private String creater;

    @ExcelIgnore
    private Date createTime;

    @ExcelProperty(value = "备注", index = 8)
    private String remark;

    @ExcelProperty(value = "社区名称", index = 1)
    private String communityName;
}

不需要导出的列使用@ExcelIgnore忽略

4. 编写导出接口

java 复制代码
@RestController
public class ExcelController {

    @GetMapping("/exportExcel")
    public Result exportExcel(PersonListForm personListForm){
    	//查询数据
       	PageVO pageVO = this.personService.personList(personListForm);
        List<PersonVO> list = pageVO.getList();

        // 设置文件路径和文件名
        String path = "D:/community/excel_export/";
        String fileName = path + "personInfo_" + System.currentTimeMillis() + ".xlsx";

        // 使用 EasyExcel 导出数据
        EasyExcel.write(fileName, PersonVO.class)
                .sheet("人员信息")
                .doWrite(list);  // 直接写入数据

        return Result.ok().put("data", fileName);
    }
}

5. 前端代码

bash 复制代码
//导出按钮
 <el-form-item>
          <el-button type="primary" icon="el-icon-download" @click="handleExcel">导出</el-button>
 </el-form-item>
 
handleExcel() {
	    this.$confirm('是否确认导出所有数据项?').then(() => {
	        exportExcel(this.listQuery).then(res => {
	            const fileUrl = process.env.VUE_APP_BASE_API + '/sys/person/exportExcel?fileName=' + res.data;
	            const link = document.createElement('a');
	            link.href = fileUrl;
	            link.download = res.data; // 下载文件的名称
	            link.click();
	        });
	    }).catch(() => {});
	}

6. 实现效果

三、excel表的导出

1. Excel表导入的整体流程

前端部分:

  • 用户通过上传组件选择Excel文件。
  • 文件上传到后端服务器。
  • 后端返回文件路径或标识符。
  • 前端调用解析接口,将文件路径传递给后端。
  • 后端解析Excel文件,将数据保存到数据库。
  • 返回解析结果给前端,提示用户成功或失败信息。

后端部分:

  • 提供文件上传接口,接收Excel文件并保存到服务器。
  • 提供解析接口,读取Excel文件内容并处理数据。
  • 将解析的数据保存到数据库。
  • 返回解析结果。

1.1 配置文件存储路径

确保文件存储路径是动态配置的,避免硬编码。可以在application.yml中配置文件存储路径:

bash 复制代码
upload:
  excel: D:/community/upload/excel/

在代码中读取配置:

bash 复制代码
@Value("${upload.excel}")
    private String excel;

2. 前端实现

2.1 文件上传组件

使用Element UI的el-upload组件实现文件上传功能。

bash 复制代码
<template>
  <el-dialog
    :title="'上传住户资料'"
    :close-on-click-modal="false"
    :visible.sync="visible"
    width="60%"
  >
    <el-form label-width="100px" style="width:95%;" @keyup.enter.native="dataFormSubmit()">
      <el-row>
        <el-col :span="24">
          <el-form-item label="导入住户资料">
            <el-upload
              class="avatar-uploader"
              :headers="headers"
              :action="uploadUrl"
              :show-file-list="false"
              :on-success="handleAvatarSuccess"
              name="uploadExcel"
              :before-upload="beforeAvatarUpload">
              <i class="el-icon-plus avatar-uploader-icon"></i>
            </el-upload>
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="模板下载">
            <a :href="process.env.VUE_APP_BASE_API + '/community/upload/excel/personInfo.xls'" download>点击下载Excel模板</a>
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <span style="color:red" v-html="errorInfo" />
        </el-col>
      </el-row>
    </el-form>
    <span slot="footer" class="dialog-footer">
      <el-button type="primary" @click="dataFormSubmit()">确 定</el-button>
    </span>
  </el-dialog>
</template>

2.2 文件上传逻辑

在beforeAvatarUpload方法中,限制文件类型和大小

js 复制代码
beforeAvatarUpload(file) {
  this.errorInfo = '';
  const ext = file.name.substring(file.name.lastIndexOf('.') + 1).toLowerCase();
  const imgSize = file.size / 1024 / 1024 < 10;
  if (!['xls', 'xlsx'].includes(ext)) {
    this.$message.error('文件格式只能为xls或xlsx文件');
    return false;
  }
  if (!imgSize) {
    this.$message.error('文件大小不能超过10MB');
    return false;
  }
  return true;
}

在handleAvatarSuccess方法中,处理上传成功后的逻辑:

js 复制代码
handleAvatarSuccess(response, file) {
  if (response && response.code === 200) {
    parsefile(response.data).then(res => {
      if (res && res.code === 200) {
        if (res.status === 'success') {
          this.errorInfo = res.data;
          this.$message.success('上传成功');
        } else {
          this.errorInfo = res.data;
          this.$message.error('上传失败');
        }
      } else {
        this.errorInfo = '解析文件失败';
        this.$message.error('解析文件失败');
      }
    }).catch(error => {
      console.error('解析文件失败', error);
      this.errorInfo = '解析文件失败';
      this.$message.error('解析文件失败');
    });
  } else {
    this.errorInfo = '文件上传失败';
    this.$message.error('文件上传失败');
  }
}

3. 后端实现

3.1 文件上传接口

接收上传的Excel文件,并保存到服务器的临时目录中:

java 复制代码
@PostMapping("/excelUpload")
public Result excelUpload(@RequestParam("uploadExcel") MultipartFile file) throws Exception {
    if (file.getOriginalFilename().equals("")) {
        return Result.error("没有选中要上传的文件");
    } else {
        String picName = UUID.randomUUID().toString();
        String oriName = file.getOriginalFilename();
        String extName = oriName.substring(oriName.lastIndexOf("."));
        String newFileName = picName + extName;
        File targetFile = new File(excel, newFileName);
        // 保存文件
        file.transferTo(targetFile);
        return Result.ok().put("data", newFileName);
    }
}

3.2 数据解析接口

读取Excel文件内容,解析数据并保存到数据库:

bash 复制代码
@LogAnnotation("导入数据")
@PostMapping("/parsefile/{fileName}")
public Result parsefile(@PathVariable("fileName") String fileName, HttpSession session) {
    User user = (User) session.getAttribute("user");
    try {
        String basePath = excel + fileName;
        List<ExcelVo> dataList = EasyExcel.read(new File(basePath), ExcelVo.class).sheet().doReadSync();

        for (ExcelVo vo : dataList) {
            Person single = new Person();
            single.setPersonId(0);
            single.setState(1);
            single.setFaceUrl("");
            single.setCommunityId(vo.getCommunityId());
            single.setTermName(vo.getTermName());
            single.setHouseNo(vo.getHouseNo());
            single.setUserName(vo.getUserName());
            single.setSex(vo.getSex());
            single.setMobile(vo.getMobile());
            single.setPersonType(vo.getPersonType());
            single.setRemark(vo.getRemark());
            single.setCreater(user.getUsername());
            this.personService.save(single);
        }
        return Result.ok().put("status", "success").put("data", "数据导入完成!");
    } catch (Exception e) {
        e.printStackTrace();
        return Result.error().put("status", "fail").put("data", "解析文件失败:" + e.getMessage());
    }
}

4. 实现效果




相关推荐
uzong2 小时前
技术故障复盘模版
后端
GetcharZp3 小时前
基于 Dify + 通义千问的多模态大模型 搭建发票识别 Agent
后端·llm·agent
桦说编程3 小时前
Java 中如何创建不可变类型
java·后端·函数式编程
IT毕设实战小研3 小时前
基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
java·开发语言·spring boot·后端·spring·毕业设计·课程设计
wyiyiyi4 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
一只爱撸猫的程序猿4 小时前
使用Spring AI配合MCP(Model Context Protocol)构建一个"智能代码审查助手"
spring boot·aigc·ai编程
甄超锋5 小时前
Java ArrayList的介绍及用法
java·windows·spring boot·python·spring·spring cloud·tomcat
阿华的代码王国5 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
Jimmy5 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程
AntBlack5 小时前
不当韭菜V1.1 :增强能力 ,辅助构建自己的交易规则
后端·python·pyqt