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

[Spring boot] Spring boot 实现Excel批量导入数据并将文件保存到本地

目录

前言

成果展示

了解Excel表格基本属性

表设计

引入依赖 

工具类

Controller

entity

Mapper

UserService

测试

总结


前言

  当我们给数据库中的表中添加数据时一般都是进入图形化界面进行手动添加,或者进直接导入现成的sql文件,但是有的时候我们会需要去导入大量的数据,这个时候我们不论是使用写好的接口还是去图形化界面添加都是十分费时费力的,这个时候使用Excel读取表格数据并进行导入就十分有必要了。本篇更着重于单个功能的开发,不会从头构建一个项目。

成果展示

 只是为了证明功能正常运行所以并没有加太多

了解Excel表格基本属性

workbook :一整个表格文件  

一个文件中有多个sheet

row 是 行

cell是一个单元格

 这是打开了一个表跟文件,可以看出是可以有多个Sheet的,知道这几点也就够用了

表设计

这里使用的是我之前的用户表。

字段比较多我们只取关注2~4 也就是用户名,密码,个性签名.id是自增的我们导入数据也不会去有用户id这一项。这三个都是varchar类型,一会儿传入时转成String类型就行,如果是int的话我们需要先转成Double再使用intValue即可。

引入依赖 

<!--        表格处理-->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.16</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.16</version>
        </dependency>

工具类

public class ExcelUtil {
    public static  Object getCellValue(Cell cell){
        switch (cell.getCellTypeEnum()){
            //字符串
            case STRING:
                return cell.getStringCellValue();
            //布尔
            case BOOLEAN:
                return cell.getBooleanCellValue();
            //数值
            case NUMERIC:
                return cell.getNumericCellValue();
        }
        return null;
    }
}

Controller

 @PostMapping("/send/upload")
    @ResponseBody
    public ApiRestResponse uploadUser(@RequestParam("file")MultipartFile multipartFile) throws IOException {
                //获取文件名
                String fileName = multipartFile.getOriginalFilename();
                String fixName = fileName.substring(fileName.lastIndexOf("."));
                //生成唯一UUID
                UUID uuid = UUID.randomUUID();
                String newFileName = uuid.toString() + fixName;
                //创建文件
                File file = new File(Constant.FILE_UPLOAD_DIR);
                File destFile = new File(Constant.FILE_UPLOAD_DIR + newFileName);
                if(!file.exists()){
                    if(!file.mkdir()){
                        throw new XatuMallException(0000000,"文件创建失败");
                    }
                }
                try {
                    multipartFile.transferTo(destFile);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                userService.addUserList(destFile);
                return ApiRestResponse.success();
    }

这里注意,我们这个文件地址是需要配置的,并不是写一个路径就行。Springboot图片上传_天海奈奈的博客-CSDN博客_springboot 图片上传

配置方法这里有说,但是要记得还要在appli那个配置文件里加一行 

file.upload.dir=D:/pictures/ 每个人不一样,但是这与你contant类里的地址是绑定的

entity

public class User {
    private Integer id;

    private String username;

    private String password;

    private String personalizedSignature;

    private Integer role;

    private Date createTime;

    private Date updateTime;

    private String emailAddress;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username == null ? null : username.trim();
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password == null ? null : password.trim();
    }

    public String getPersonalizedSignature() {
        return personalizedSignature;
    }

    public void setPersonalizedSignature(String personalizedSignature) {
        this.personalizedSignature = personalizedSignature == null ? null : personalizedSignature.trim();
    }

    public Integer getRole() {
        return role;
    }

    public void setRole(Integer role) {
        this.role = role;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Date getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }

    public String getEmailAddress() {
        return emailAddress;
    }

    public void setEmailAddress(String emailAddress) {
        this.emailAddress = emailAddress == null ? null : emailAddress.trim();
    }
}


Mapper

public interface UserMapper {
  

    User selectByName(String username);


}

 xml

  <select id="selectByName" parameterType="java.lang.String" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List"></include>
    from xatu_mall_user
    where username = #{username,jdbcType=VARCHAR}
  </select>

理解原理就好,不要去纠结表名。

UserService

Imp

 @Override
    public void addUserList(File destFile) throws IOException {
        List<User> users = readUsersFromExcel(destFile);
        for (int i = 0; i < users.size(); i++){
            User user = users.get(i);
            User userOld = userMapper.selectByName(user.getUsername());
            if(userOld != null){
                System.out.println("重名");
            }
            int count = userMapper.insertSelective(user);
            if(count == 0){
                System.out.println("添加失败");
            }
        }

    }
    private List<User> readUsersFromExcel(File excelFile) throws IOException {
        ArrayList<User> listUser =new ArrayList<>();
        FileInputStream fileInputStream = new FileInputStream(excelFile);

        XSSFWorkbook xssfWorkbook = new XSSFWorkbook(fileInputStream);
        XSSFSheet firstSheet = xssfWorkbook.getSheetAt(0);
        Iterator<Row> iterator = firstSheet.iterator();
        while(iterator.hasNext()){
            org.apache.poi.ss.usermodel.Row nextRow = iterator.next();
            Iterator<Cell> cellIterator = nextRow.cellIterator();
            User aUser = new User();

            while(cellIterator.hasNext()){
                Cell nextCell = cellIterator.next();
                int columnIndex = nextCell.getColumnIndex();
                switch (columnIndex){
                    case 0:
                        aUser.setUsername((String) ExcelUtil.getCellValue(nextCell));
                        break;
                    case 1:
                        aUser.setPassword((String) ExcelUtil.getCellValue(nextCell));
                        break;
                    case 2:
                        aUser.setPersonalizedSignature((String) ExcelUtil.getCellValue(nextCell));
                        break;


                }
            }
            listUser.add(aUser);
        }
        xssfWorkbook.close();
        fileInputStream.close();
        return listUser;

    }

重名那里偷懒了,按理说应该抛出异常的。

   void addUserList(File destFile) throws IOException;

测试

打开postman  这里需要注意的地方是我们是postMapping 并且

 

选择的是Body 和form-data 

 

后面就能去选择我么要读取的表格文件了,但是我们读取的是xlsx xls是不能读的,你改后缀也是不行的,要建立时就是xlsx。

总结

  这个技术也是很实用的技术,让我们可以很便捷的快速从表格中读取数据并将数据上传。文件保存到本地可以去看放的链接,实际上与上传图片是一样的。

相关文章:

  • linux下安装javaJDK和hadoop
  • Java数据结构——代码实现双向链表的方法
  • 蓝牙耳机哪款延迟低?延迟最低的真无线蓝牙耳机推荐
  • 使用OpenCV快速解决迷宫问题
  • springcloud-Ribbon详解(含java代码)
  • AI自主图像生成 之 stable-diffusion—运行效果展示
  • Day28、MySQL事务、索引、数据恢复和备份
  • 【ML】第九章 无监督学习技术
  • 普通人如何找到直播里的赚钱密码?
  • 前后端交互
  • 2022-09-23 日常问题
  • PX4模块设计之四十三:icm20689模块
  • 【Android安全】Android中的应用沙箱和UID | Android多用户
  • 基于 Web 的 LDAP 认证,访问资源就是这么安全
  • 软件工程毕设选题 - SSM共享充电宝管理系统(含源码+论文)
  • 【Leetcode】101. 对称二叉树
  • [rust! #004] [译] Rust 的内置 Traits, 使用场景, 方式, 和原因
  • 07.Android之多媒体问题
  • CNN 在图像分割中的简史:从 R-CNN 到 Mask R-CNN
  • echarts的各种常用效果展示
  • ECS应用管理最佳实践
  • JS创建对象模式及其对象原型链探究(一):Object模式
  • OpenStack安装流程(juno版)- 添加网络服务(neutron)- controller节点
  • PHP 7 修改了什么呢 -- 2
  • Puppeteer:浏览器控制器
  • Python进阶细节
  • SpingCloudBus整合RabbitMQ
  • Stream流与Lambda表达式(三) 静态工厂类Collectors
  • 入口文件开始,分析Vue源码实现
  • 腾讯大梁:DevOps最后一棒,有效构建海量运营的持续反馈能力
  • 以太坊客户端Geth命令参数详解
  • 在Mac OS X上安装 Ruby运行环境
  • 自制字幕遮挡器
  • 最简单的无缝轮播
  • 不要一棍子打翻所有黑盒模型,其实可以让它们发挥作用 ...
  • 教程:使用iPhone相机和openCV来完成3D重建(第一部分) ...
  • #基础#使用Jupyter进行Notebook的转换 .ipynb文件导出为.md文件
  • (1/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (C语言)strcpy与strcpy详解,与模拟实现
  • (附源码)springboot工单管理系统 毕业设计 964158
  • (提供数据集下载)基于大语言模型LangChain与ChatGLM3-6B本地知识库调优:数据集优化、参数调整、Prompt提示词优化实战
  • (原創) X61用戶,小心你的上蓋!! (NB) (ThinkPad) (X61)
  • (转)Android学习笔记 --- android任务栈和启动模式
  • .NET Core实战项目之CMS 第一章 入门篇-开篇及总体规划
  • .NET Micro Framework初体验
  • .NET Reactor简单使用教程
  • .NET 表达式计算:Expression Evaluator
  • .net/c# memcached 获取所有缓存键(keys)
  • .Net+SQL Server企业应用性能优化笔记4——精确查找瓶颈
  • .NET开发不可不知、不可不用的辅助类(三)(报表导出---终结版)
  • /bin/rm: 参数列表过长"的解决办法
  • /usr/bin/python: can't decompress data; zlib not available 的异常处理
  • @Controller和@RestController的区别?
  • [ 英语 ] 马斯克抱水槽“入主”推特总部中那句 Let that sink in 到底是什么梗?
  • []常用AT命令解释()