文件上传+easyExcel

news2025/7/20 11:06:01

文章目录

  • 需求描述
  • 实现
      • 0、依赖
      • 1、编写配置类
      • 2、文件上传工具类
      • 3、编写Controller
      • 4、编写Service
      • 5、编写excel对应的类
      • 6、创建easyExcel的监听器
      • 7、最终效果

需求描述

页面中当用户将excel表格上传到服务器后,将该excel文件保存在本地然后在服务器中将excel中的数据读取出来然后存入数据库

实现

0、依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.1.4</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.75</version>
</dependency>
 <!-- 糊涂工具类-->
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.11</version>
</dependency>

1、编写配置类

文件上传的路径:用户传来的文件存放在哪

  # 文件上传
spring:
  servlet:
    multipart:
      max-file-size: 5MB
      max-request-size: 50MB

## 文件上传路径
savepath: C:\Users\86186\Desktop\pp

2、文件上传工具类

文件上传时需要使用到的一些方法

/**
 * 文件上传的工具类
 */
public class FileUploadUtil {
    /**
     * 得到filename文件名的后缀名
     * @param filename  文件名
     *                 aasdsad.jpg asaa.gif
     * @return
     */
    public static String getFileSuffix(String filename){
        if(filename == null || filename.isEmpty()){
            throw new RuntimeException("文件名不能为空,filename:"+filename);
        }
        return filename.substring(filename.lastIndexOf("."));
    }

    /**
     * 使用UUID生成一个唯一的字符串
     * @return
     */
    public static String randomFilename(){
        return UUID.randomUUID().toString().replaceAll("-","");
    }

    /**
     * 基于时间戳生成文件名
     * @return
     */
    public static String randomFilename2(){
        return System.currentTimeMillis()+"";
    }
    /**
     * 基于时间戳 + UUID生成文件名
     * @return
     */
    public static String randomFilename3(){
        return System.currentTimeMillis()+randomFilename();
    }


    /**
     * 创建目录
     */
    public static void mkdir(String path){
        File file = new  File(path);
        if(!file.exists()){ //不存在
            file.mkdirs();
        }
    }

    /**
     * 基于当前时间创建文件名
     */
    public static String getTimeFilename(){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyy-MM-dd-HH-mm-ss");
        Date date = new Date(System.currentTimeMillis());
        return simpleDateFormat.format(date)+"-"+randomFilename2();
    }
}

3、编写Controller

需要接受前端返回回来的文件

/**
    * excel文件导入进数据库中
    * @param file
    * @return
    */
   @Autowired
   private FileUploadService fileUploadService;

   @PostMapping("excelImport")
   public ResponseData excelImport(MultipartFile file) throws Exception {
   		// 由于easyExcel所以需要传入fileUploadService对象
       String upload = fileUploadService.upload(file,fileUploadService);
       return ResponseDataUtil.buildOk(upload);
   }

4、编写Service

@Service("fileUploadService")
@Slf4j
public class FileUploadServiceImpl implements FileUploadService {
	// 注入environment来获取在配置文件中文件保存的路径
    @Autowired
    private Environment environment;
    // 注入数据层的对象
    @Autowired
    private productMapper productMapper;

    @Override
    public String upload(MultipartFile file, FileUploadService fileUploadService) throws Exception {
        if (file == null) {
            throw new Exception("文件不可以为空");
        }
        //得到上传的保存路径
        String savePath = environment.getProperty("savepath");
        //创建目录
        FileUploadUtil.mkdir(savePath);
        String dbPath = "";

        //得到上传的原文件名
        String originalFilename = file.getOriginalFilename();
        String suffix = FileUploadUtil.getFileSuffix(originalFilename);
        String filename = FileUploadUtil.getTimeFilename() + suffix;
        dbPath += filename;
        //保存
        file.transferTo(new File(savePath, filename));
        dbPath = savePath +"\\"+ dbPath;

        //调用方法进行读取
        EasyExcel.read(dbPath, ExcelDTO.class, new PageReadListener<ExcelDTO>(dataList -> {
            for (ExcelDTO demoData : dataList) {
                log.info("读取到一条数据{}", JSON.toJSONString(demoData));
                insert(demoData);
            }
        })).sheet().doRead();

        return dbPath;
    }

	// 插入数据到数据库中
    @Override
    public void insert(ExcelDTO excelDTO) {
    	// 使用hutool工具类将excelDTO类转换成product类,因为product类对应的是数据库中的字段
        Product product = BeanUtil.copyProperties(excelDTO, Product.class);
        productMapper.insert(product);
    }

}

5、编写excel对应的类

@Data
public class ExcelDTO {
   @ExcelProperty("药品名称")
   private String pname;
   @ExcelProperty("药品价格")
   private BigDecimal pprice;
   @ExcelProperty("药品数量")
   private String pcount;
   @ExcelProperty("药品描述")
   private String pdes;
   @ExcelProperty("药品类别")
   private Integer ptype;
}

6、创建easyExcel的监听器

ExcelDTO = excel对应的类
fileUploadService = service对象

@Slf4j
@Component
public class DataListener extends AnalysisEventListener<ExcelDTO> {

    public FileUploadService fileUploadService;

    public  DataListener(FileUploadService fileUploadService) {
        this.fileUploadService = fileUploadService;
    }

    public  DataListener() {
    }

    //读取excel内容,一行一行读取
    @Override
    public void invoke(ExcelDTO excelDTO, AnalysisContext analysisContext) {
        if (excelDTO == null) {
            try {
                throw new Exception("文件数据为空");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {

    }
}

7、最终效果

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/368756.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

预编译(回顾)

浏览器运行机制变量提升机制私有变量提升步骤全局对象 GO 和全局变量对象 VO的区别带var和不带var的区别系统输出顺序变量提升在条件判断下的处理防止函数的变量提升 浏览器运行机制 为了能够让代码执行&#xff0c;浏览器首先会形成一个执行环境栈 ECStack(Execution Contex…

15- 答题卡识别及分数判定项目 (OpenCV系列) (项目十五)

项目要点 图片读取 : img cv2.imread(./images/test_01.png)灰度图: gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)高斯模糊: blurred cv2.GaussianBlur(gray, (5, 5), 0) # 去噪点边缘检测: edged cv2.Canny(blurred, 75, 200)检测轮廓: cnts cv2.findContours(e…

Ai作画studio环境布置

大家好&#xff0c;今天跟大家介绍如何用stable diffusion webui布置自己的Ai作画工作环境。这部分主要就是实操&#xff0c;没有太多理论知识介绍。跟着做就好了&#xff0c;当成是一次计算机实验上机课就好基础环境布置这次开发环境选择的是AutoDL的GPU云环境&#xff0c;链接…

ros下用kinectv2运行orbslam2

目录 前提 创建工作空间 orbslam2源码配置、测试&#xff1a; 配置usb_cam ROS功能包 配置kinect 前提 vim 、 cmake 、 git 、 gcc 、 g 这些一般都装了 主要是Pangolin 、 OpenCV 、 Eigen的安装 18.04建议Pangolin0.5 创建工作空间 我们在主目录下创建一个catkin_…

听车企做开发朋友说,面试Framework 必问~

近期听在车企工作的朋友说&#xff0c;今年去他们公司面试的人比往年增长了30%左右&#xff0c;但实际面试达到标准的人屈指可数&#xff0c;大多都是从 Android 开发方向转过来的。 车企招聘要求有哪些&#xff1f; 每个车企因为业务部门的不同&#xff0c;他们的要求也会有…

Tapdata Connector 实用指南:实时数仓场景之数据实时同步至 ClickHouse

【前言】作为中国的 “Fivetran/Airbyte”, Tapdata 是一个以低延迟数据移动为核心优势构建的现代数据平台&#xff0c;内置 60 数据连接器&#xff0c;拥有稳定的实时采集和传输能力、秒级响应的数据实时计算能力、稳定易用的数据实时服务能力&#xff0c;以及低代码可视化操作…

搭建直播平台服务器什么配置最合适?直播平台专用服务器(驰网i9-13900k服务器)

如今&#xff0c;视频直播越来越受欢迎&#xff0c;视频和直播平台也越来越多&#xff0c;直播平台和视频网站都需要更好的服务器来支持。那么&#xff0c;视频直播平台需要什么服务器呢&#xff1f;以一个简单的直播网站为例。如果每天在线人数约1000人&#xff0c;同时在线人…

Win10 22H2 19045.2670系统原版镜像

相比以前系统&#xff0c;修复了如下KB5022906 修复了诸多问题&#xff0c;IT之家将官方更新日志翻译如下&#xff1a;修复了在 Microsoft Excel 中无法打开超链接的问题修复了影响 Appx 状态存储库的问题。在用户删除用户配置文件后&#xff0c;相关清理工作未能妥善完成&…

【nohup引发磁盘读写高】nohup命令导致服务器磁盘读写占满该如何修复?

【写在前面】自己在跑一个项目的时候&#xff0c;猛然发现服务器挂了&#xff0c;直接访问不了&#xff0c;呈现出一种卡死现象&#xff0c;我当时都懵了&#xff0c;难道阿里在后端升级&#xff0c;也不会选择在工作日的时间升级吧&#xff0c;于是乎就咨询了一下客服。才有下…

【项目精选】jsp码头船只出行及配套货柜码放管理系统的设计与实现(视频+源码+论文)

点击下载源码 jsp码头船只出行及配套货柜码放管理系统主要用于实现高校在线考试&#xff0c;基本功能包括&#xff1a;用户登录、修改个人信息、查看码头信息&#xff1b;系统管理人员管理&#xff1b;船只信息管理&#xff1b;船只路线信息管理&#xff1b;货柜信息管理等。本…

Vue-cli脚手架在做些什么(源码角度分析)

什么是Vue脚手架&#xff1f;在学习初期&#xff0c;我们的项目往往需要借助webpack、vite等打包工具配置Vue的开发环境&#xff0c;但是在真实开发中我们不可能每个项目从头来完成所有的webpack配置&#xff0c;这样显得开发的效率会大大的降低&#xff1b;所有的真实开发中&a…

手写SpringBoot的starter

自定义SpringBoot的starter 引言 starter命名格式&#xff1a; 官方的 starter 的命名格式为 spring-boot-starter-{xxxx} 比如spring-boot-starter-activemq 第三方我们自己的命名格式为 {xxxx}-spring-boot-starter。比如mybatis-spring-boot-starter。 如果我们忽略这种约定…

【Git】与“三年经验”就差个分支操作的距离

前言 Java之父于胜军说过&#xff0c;曾经一位“三年开发经验”的程序员粉丝朋友&#xff0c;刚入职因为不会解决分支问题而被开除&#xff0c;这是不是在警示我们什么呢&#xff1f; 针对一些Git的不常用操作&#xff0c;我们通过例子来演示一遍 1.版本回退 1.1已提交但未p…

【Nginx】|入门连续剧——安装

作者&#xff1a;狮子也疯狂 专栏&#xff1a;《Nginx从入门到超神》 坚持做好每一步&#xff0c;幸运之神自然会降临在你的身上 目录一. &#x1f981; 前言Ⅰ. &#x1f407; 为啥我们要使用Nginx&#xff1f;二. &#x1f981; 搭建流程Ⅰ. &#x1f407; 环境准备Ⅱ. &…

LeetCode 热题 C++ 141. 环形链表 142. 环形链表 II(详解!)

力扣141 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置&am…

图片和ppm文件互转

一、代码结构 二、代码实现 Denoise.java&#xff1a; package com.xj.ppm.toimg;import java.awt.FlowLayout; import java.awt.image.BufferedImage; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel;/*** Image noise reduction pro…

I.MX6ULL内核开发10:设备树

目录 一、设备树简介 二、设备树源码 三、获取设备树信息 1、增加设备节点 2、内核编译设备树 3、替换设备树文件 4、查看设备树节点 5、在驱动中获取节点的属性 6、编译驱动模块 7、加载模块 一、设备树简介 设备树的作用是描述一个硬件平台的硬件资源。这个“设备树…

Redis主从和哨兵搭建

今天主要分享Redis主从架构和哨兵的搭建。 主从集群搭建 总共三个节点&#xff0c;一个主节点和两个从节点。都安装在一台机器上模拟主从集群&#xff0c;信息如下&#xff1a; IPPORT角色192.168.246.1407001slave192.168.246.1407002master192.168.246.1407003slave 我们只…

FreeRTOS入门(04):中断、内存、追踪与调试

文章目录目的中断内存堆&#xff08;heap&#xff09;栈&#xff08;stack&#xff09;断言调试总结目的 有了前面的几篇文章 FreeRTOS 基本上已经可以在项目中使用上了&#xff1a; 《FreeRTOS入门&#xff08;01&#xff09;&#xff1a;基础说明与使用演示》 《FreeRTOS入门…

【java 8】强大的 Stream API

&#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是阿牛&#xff0c;全栈领域优质创作者。&#x1f61c;&#x1f4dd; 个人主页&#xff1a;馆主阿牛&#x1f525;&#x1f389; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4d…