【springboot+vue项目(十一)】springboot整合EasyExcel

news2024/11/18 7:29:31

        EasyExcel是阿里巴巴开源的一个Java库,用于操作Excel文件。它提供了简单易用的API,可以读取、写入和转换Excel文件,支持大量数据的导入和导出操作。

一、添加依赖(版本3.2)

<!--easyexcel操作excel-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.2.0</version>
</dependency>

二、根据Excel来建立数据库表

        根据Excel的表头建立数据库表,注意每一张表有2个字段需要添加,即id和period(账期),建在最前面,此项工作可以借助chatgpt来完成

三、快速生成代码

        使用EasyCode 快速生成代码entity、service、mapper、servicelmpl

四、修改实体类entity

修改实体类entity,添加“账期”字段的自动插入

五、类继承、引用的方法引入

entity、service、mapper.、servicelmpl类继承、引用的方法引入,使用Alt+Enter键

六、easyExcel的model和listeners

package com.pbcnn.easyExcelCollector.excel.model;

import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;

import java.math.BigDecimal;

@Data
public class SheetSucffiBwbModel {

    @ExcelProperty(index = 1)
    private String indexName;

    @ExcelProperty(index = 2)
    private BigDecimal currentBalance;

    @ExcelProperty(index = 3)
    private BigDecimal currentMonthChange;

    @ExcelProperty(index = 4)
    private BigDecimal currentYearChange;

    @ExcelProperty(index = 5)
    private BigDecimal yearChangeRate;

    @ExcelProperty(index = 6)
    private BigDecimal lastYearBalance;

    @ExcelProperty(index = 7)
    private BigDecimal lastTwoYearsBalance;

    @ExcelProperty(index = 8)
    private BigDecimal lastYearGrowthRate;

}
package com.pbcnn.easyExcelCollector.excel.listeners;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.fastjson2.JSON;
import com.pbcnn.easyExcelCollector.common.SpringUtil;
import com.pbcnn.easyExcelCollector.entity.data.User;
import com.pbcnn.easyExcelCollector.excel.model.ExcelUserData;
import com.pbcnn.easyExcelCollector.mapper.UploadFileMapper;
import com.pbcnn.easyExcelCollector.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

/**
 * ExcelModelListener 不能被spring管理,要每次读取 excel 都要 new,然后里面用到 spring 可以构造方法传进去
 *
 * @author makejava
 * @create 2023-01-19 20:59
 */
@Slf4j
public class UserDataListener implements ReadListener<ExcelUserData> {


    /**
     * 每隔5条存储数据库,实际使用中可以100条,然后清理 list ,方便内存回收,避免 OOM
     */
    private static final int BATCH_COUNT = 100;
    /**
     * 缓存的数据,在 invoke 函数中存储每次读到的数据,这里的泛型虽业务变化而变化,存储的可以是excel表数据处理后的数据
     * 假如我要啊存入数据库中就需要将 ExcelUserData 转换成 User 那么这里的泛型就是User,在 invoke 中处理后添加
     */
    private List<ExcelUserData> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

    /**
     * 这个是一个DAO,当然有业务逻辑这个也可以是一个service。可以用来解析数据后操作数据库
     */
    @Autowired
    private UserService userService;

    @Autowired
    private UploadFileMapper uploadFileMapper;

    /**
     * 每读到一条数据都会调用这个函数,可以在这里对数据的预处理
     *
     * @param excelUserData
     * @param analysisContext
     */
    @Override
    public void invoke(ExcelUserData excelUserData, AnalysisContext analysisContext) {
        log.info("解析到一条数据:{}", JSON.toJSONString(excelUserData));
        cachedDataList.add(excelUserData);
        // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
        if (cachedDataList.size() >= BATCH_COUNT) {
            log.info("已达到BATCH_COUNT,共{}条数据", cachedDataList.size());

            // 调用储存数据函数
            saveData();

            // 存储完成清理 list
            cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
        }
    }

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

    /**
     * 加上存储数据库
     */
    private void saveData() {
        log.info("{}条数据,开始存储数据库!", cachedDataList.size());

        //  TODO 数据存储,使用批处理操作防止多次连接数据库,例如 userService.saveBatch();
        if (cachedDataList.size() > 0) {
            List<User> userList = BeanUtil.copyToList(cachedDataList, User.class, null);
            UserService userService = SpringUtil.getBean(UserService.class);
            userService.saveBatch(userList);
        }

        log.info("存储数据库成功!");
    }

}

添加的时候:

  1. model,复制entity的类,然后添加@ExcelProperty(index = 1),去掉id和period(账期)
  2. Listeners,直接复制其他类,然后将类的名字替换掉即可。

七、controller 解析Excel

package com.pbcnn.easyExcelCollector.controller;

import com.alibaba.excel.EasyExcel;
import com.pbcnn.easyExcelCollector.excel.listeners.UserDataListener;
import com.pbcnn.easyExcelCollector.excel.model.ExcelUserData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;

@RestController
public class UploadController {

    @Value("${file.upload-dir}")
    private String uploadDir;


    @PostMapping(value = "/uploadFiles", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> upload(@RequestParam("files") MultipartFile[] files) {
        try {
            List<String> fileNames = new ArrayList<>();
            for (MultipartFile file : files) {
                if (!file.isEmpty()) {
                    String fileName = UUID.randomUUID().toString() + "_" + StringUtils.cleanPath(file.getOriginalFilename());
                    Path dest = Path.of(uploadDir, fileName);
                    try (InputStream inputStream = file.getInputStream()) {
                        Files.copy(inputStream, dest, StandardCopyOption.REPLACE_EXISTING);
                    }
                    fileNames.add(fileName);

                    // 异步保存上传信息到数据库
                    //CompletableFuture.runAsync(() -> {
                    //    UploadFile uploadFile = new UploadFile();
                    //    uploadFile.(fileName);
                    //    uploadFile.setFilePath(dest.toString());
                    //    uploadFile.setUploadTime(new Date());
                    //    uploadFile.setStatus(0);
                    //    uploadFileMapper.insert(uploadFile);
                    //});

                    /*
                        根据文件路径读取excel
                     */
                    String pathName = dest.toString();
                    CompletableFuture.runAsync(() -> {
                        EasyExcel.read(pathName, ExcelUserData.class, new UserDataListener()).sheet().doRead();

                    });
                }
            }
            return ResponseEntity.ok(fileNames);
        } catch (IOException e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("上传文件失败");
        }
    }
}

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

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

相关文章

风靡全网的Jmeter+ant+jenkins接口自动化测试框架

大致思路&#xff1a;Jmeter可以做接口测试&#xff0c;也能做压力测试&#xff0c;而且是开源软件&#xff1b;Ant是基于Java的构建工具&#xff0c;完成脚本执行并收集结果生成报告&#xff0c;可以跨平台&#xff0c;Jenkins是持续集成工具。将这三者结合起来可以搭建一套We…

Prometheus 不能访问k8s的中的一些metrics的问题(controller-manager、scheduler、etcd)

主要有三个点 controller-manager、scheduler、etcd 参考&#xff1a; https://www.cnblogs.com/ltaodream/p/15448953.html kube-scheduler 在每台master节点执行 vim /etc/kubernetes/manifests/kube-scheduler.yaml 将 --bind-address127.0.0.1 改为 --bind-address…

基于SSM框架的宠物商城系统

开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.3.9 功能模块&…

软件测试|一篇文章带你深入理解SQL约束

深入理解SQL约束&#xff1a;保障数据完整性和一致性的重要工具 SQL约束是在关系型数据库中用于保障数据完整性和一致性的重要工具。本文将深入探讨SQL约束的概念、类型以及应用&#xff0c;以帮助读者更好地理解和使用SQL约束来确保数据库中的数据质量。 SQL约束 约束&…

vue动态组件、保持存活

加 component :is 引入组件名称 <component :is"tabcom"></component> keep-alive 保持存活 <keep-alive> <component :is"tabcom"></component></keep-alive> 保持存活&#xff1a;切换组件后&#xff0c;不重…

人机交互主板定制_基于MT8735安卓核心板的自助查询机方案

人机交互主板是一种商显智能终端主板&#xff0c;广泛应用于广告机、工控一体机、教学一体机、智能自助终端、考勤机、智能零售终端、O2O智能设备、取号机、计算机视觉、医疗健康设备、机器人设备等领域。 人机交互主板采用联发科MTK8735芯片平台&#xff0c;四核Cortex-A53架构…

Sectigo与Geotrust ov多域名证书的区别

Sectigo和Geotrust都是比较知名的CA认证机构。其中&#xff0c;Sectigo原名Comodo&#xff0c;在2018年整合SSL证书业务&#xff0c;改名为Sectigo&#xff0c;旗下的SSL证书产品根证书也变为Sectigo。Geotrust则是另一个备受信任的数字证书品牌&#xff0c;现在是Digicert旗下…

Python Gradio构建简单的交互界面

Gradio 是一个用于构建机器学习和数据科学的交互式应用程序的 Python 库&#xff0c;但是我们可以用它来构建一些简单的交互界面&#xff0c;其代码之简单令人震惊 文本输入输出 import gradio as grdef szu(text):return textinterface gr.Interface(fnszu, inputs"text…

43 tmpfs/devtmpfs 文件系统

前言 在 linux 中常见的文件系统 有很多, 如下 基于磁盘的文件系统, ext2, ext3, ext4, xfs, btrfs, jfs, ntfs 内存文件系统, procfs, sysfs, tmpfs, squashfs, debugfs 闪存文件系统, ubifs, jffs2, yaffs 文件系统这一套体系在 linux 有一层 vfs 抽象, 用户程序不用…

keras 深度学习框架实现 手写数字识别

阅读本文之前&#xff0c;请先参考--------win10搭建keras深度学习框架 安装运行环境 阅读本文之前&#xff0c;请先参考--------keras人工智能框架 MNIST 数据集 随机展示 查看训练图片 完整代码如下图&#xff1a; 在sublimeText中 使用ctrlB运行代码&#xff0c;结果如…

没有一家车企能绕开「数据闭环」

作者 |张祥威 编辑 |德新 2023年&#xff0c;在比亚迪那次公布智驾数据规模后&#xff0c;智能化下半场的战斗就正式打响了。 如今&#xff0c;自动驾驶正在沿着特斯拉提出的「BEVTransformer」急速推进&#xff0c;这条技术路线短短几年就得到了验证&#xff0c;随着智驾起较…

报表控件Stimulsoft 2023回顾:都做了哪些产品的改变?

在2023年过去一年中&#xff0c;报表控件Stimulsoft 针各类控件都做了重大改变&#xff0c;其中新增了某些产品、同时加强了很多产品的性能和UI设计&#xff0c;更加符合开发者需求&#xff0c;下面就跟随小编一起来回顾&#xff0c;具体都有哪些↓↓↓ Stimulsoft Ultimate &…

静图如何做成动态gif图?手把手教你一招制作

我们在跟小伙伴聊天时&#xff0c;都会发送gif动图&#xff0c;能够让我们的心情更加开心。当我们找不到合适的图片时&#xff0c;就可以自己制作专属于自己的gif动图&#xff0c;那么怎能操作呢&#xff1f;很简单&#xff0c;通过使用gif在线生成&#xff08;https://www.gif…

MIT_线性代数笔记:第 24 讲 马尔可夫矩阵;傅里叶级数

目录 马尔可夫矩阵 Markov matrices傅里叶级数 Fourier series 本讲学习马尔可夫矩阵和傅里叶级数&#xff0c;两者是关于特征值和投影矩阵的应用。 马尔可夫矩阵 Markov matrices A [ 0.1 0.01 0.3 0.2 0.99 0.3 0.7 0 0.4 ] A \begin{bmatrix} 0.1 & 0.01 & 0.3 \\…

Python爬虫实战技巧:如何在爬取过程中动态切换代理IP

目录 前言 第一步&#xff1a;获取代理IP列表 第二步&#xff1a;测试代理IP的可用性 第三步&#xff1a;动态切换代理IP 总结 前言 在进行爬虫开发的过程中&#xff0c;有时候需要使用代理IP来访问目标网站&#xff0c;以避免被封IP或者降低访问频率的限制。本文将介绍如…

菜单显示博客页

结果图 难点及其实现 滚动条自定义&#xff1a; .card::-webkit-scrollbar { width: 4px;} .card::-webkit-scrollbar-thumb { border-radius: 8px; box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2); background: #666666; } .card::-webkit-scrollbar-thumb:hover { backgr…

c# windows10大小端试

测试代码&#xff1a; unsafe public void ceshi() {byte[] by BitConverter.GetBytes(0x12345678);Debug.WriteLine(" byte[0] 0x" by[0].ToString("x2"));Debug.WriteLine(" byte[1] 0x" by[1].ToString("x2"));Debug.WriteLi…

MinIO 批处理框架添加了对过期时间的支持

您现在可以使用 MinIO 批处理框架执行 S3 删除操作&#xff0c;以通过单个 API 请求删除大量对象。借助 MinIO 批处理框架&#xff0c;可以快速轻松地在 MinIO 部署中执行重复或批量操作&#xff0c;例如批量复制和批量密钥轮换。MinIO 批处理框架处理所有手动工作&#xff0c;…

【自动化测试总结】优点、场景、流程、项目人员构成

一、自动化测试的概念 以程序测试程序&#xff0c;以代码代替思维&#xff0c;以脚本的运行代替手工测试&#xff0c;可以大大提高工作测试的效率。 二、自动化测试的优点 1.回归测试更为方便&#xff0c;可靠。自动化测试最主要的任务和特点&#xff0c;特别是在程序修改比较…

Minitab 20安装包下载及安装教程

Minitab 20下载链接&#xff1a;https://docs.qq.com/doc/DUmNYVGxtUnZkWUpk 1.选中下载好的安装包&#xff0c;鼠标右键解压到”Minitab 20“文件夹 2.选中Setup&#xff0c;鼠标右击选择“以管理员身份运行” 3.点击“下一步” 4.点击“下一步” 5.勾选我接受许可协议中的条…