Springboot开发之 Excel 处理工具(二)-- Easyexcel

一、Easyexcel 简介

EasyExcel是一个基于Java的Excel处理工具库,它的核心设计理念是快速、简洁,并且能够有效解决处理大文件时的内存溢出问题。使用EasyExcel,开发者可以在几乎不需要考虑性能和内存消耗的情况下,轻松实现Excel文件的读写操作。

  • Easyexcel 官方文档:https://easyexcel.opensource.alibaba.com/docs/current/
  • github地址:https://github.com/alibaba/easyexcel
  • gitee地址:https://gitee.com/easyexcel/easyexcel

二、为何选择 Easyexcel

1. 现有框架的问题

  • Apache POI 和 jxl: 这两个Java框架用于解析和生成Excel文件,但它们的主要问题是内存消耗大。
  • 内存溢出问题: 处理大型Excel文件时,这些框架可能会消耗大量内存,导致内存溢出。

2. Apache POI 的局限性

  • SAX模式: Apache POI 提供了SAX模式的API来部分解决内存问题,但仍然存在不足。
  • 内存消耗: 即使使用SAX模式,Apache POI 在处理Excel 2007版(.xlsx)文件时,由于解压缩和存储过程在内存中进行,内存消耗依然很大。

3. EasyExcel 的优势

  • 重写解析: EasyExcel 重写了Apache POI对Excel 2007版的解析方式,显著降低了内存消耗。
  • 内存优化: 一个3MB的Excel文件在使用Apache POI的SAX模式解析时可能需要约100MB内存,而EasyExcel可以将内存需求降低到几MB。
  • 大文件处理: 使用EasyExcel,即使更大的Excel文件也不会导致内存溢出。
  • 03版Excel处理: 对于Excel 2003版(.xls),EasyExcel依赖于Apache POI的SAX模式,并在此基础上进行了模型转换封装,使得使用更加简单和方便。

三、Springboot 项目集成 EasyExcel

1. pom 文件引入依赖:

<dependency>  <groupId>com.alibaba</groupId>  <artifactId>easyexcel</artifactId>  <version>3.1.0</version> <!-- 请检查并使用最新版本 -->  
</dependency>

2. 实体类(例如 UserData)

import com.alibaba.excel.annotation.ExcelProperty;  public class UserData {  @ExcelProperty(value = "ID", index = 0)  private Integer id;  @ExcelProperty(value = "姓名", index = 1)  private String name;  @ExcelProperty(value = "年龄", index = 2)  private Integer age;  // 省略 getter 和 setter 方法  // ...  
}

3. EasyExcel 操作帮助类

import com.alibaba.excel.EasyExcel;  
import com.alibaba.excel.context.AnalysisContext;  
import com.alibaba.excel.event.AnalysisEventListener;  
import com.alibaba.excel.read.builder.ExcelReaderBuilder;  
import com.alibaba.excel.read.builder.ExcelReaderSheetBuilder;  
import com.alibaba.excel.write.builder.ExcelWriterBuilder;  
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;  
import com.alibaba.excel.write.metadata.WriteSheet;  import org.springframework.web.multipart.MultipartFile;  import java.io.ByteArrayInputStream;  
import java.io.ByteArrayOutputStream;  
import java.io.IOException;  
import java.io.InputStream;  
import java.util.ArrayList;  
import java.util.List;  public class EasyExcelUtils {  // 导出 Excel  public static byte[] exportExcel(List<?> data, String sheetName, Class<?> head) {  try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {  ExcelWriterBuilder writerBuilder = EasyExcel.write(out, head);  ExcelWriterSheetBuilder sheetBuilder = writerBuilder.sheet(sheetName);  WriteSheet writeSheet = sheetBuilder.build();  EasyExcel.write(out, data, writeSheet).finish();  return out.toByteArray();  } catch (IOException e) {  throw new RuntimeException("导出 Excel 失败", e);  }  }  // 导入 Excel  public static <T> List<T> importExcel(MultipartFile file, Class<T> clazz) {  try (InputStream inputStream = file.getInputStream()) {  ExcelReaderBuilder readerBuilder = EasyExcel.read(inputStream, clazz, new AnalysisEventListener<T>() {  private List<T> list = new ArrayList<>();  @Override  public void invoke(T data, AnalysisContext context) {  list.add(data);  }  @Override  public void doAfterAllAnalysed(AnalysisContext context) {  // 数据解析完成后,可以在这里处理解析结果  }  });  ExcelReaderSheetBuilder sheetBuilder = readerBuilder.sheet();  sheetBuilder.doRead();  return list;  } catch (IOException e) {  throw new RuntimeException("导入 Excel 失败", e);  }  }  // 其他可能需要的帮助方法...  
}

4. 在 Controller 中使用

import org.springframework.http.HttpHeaders;  
import org.springframework.http.MediaType;  
import org.springframework.http.ResponseEntity;  
import org.springframework.web.bind.annotation.GetMapping;  
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.util.Arrays;  
import java.util.List;  @RestController  
public class ExcelController {  @PostMapping("/exportExcel")  public ResponseEntity<byte[]> exportExcel() {  List<UserData> data = Arrays.asList(  new UserData(1, "Alice", 25),  new UserData(2, "Bob", 30),  new UserData(3, "Charlie", 35)String fileName = "users.xlsx";  byte[] excelBytes = EasyExcelUtils.exportExcel(data, fileName, UserData.class);  HttpHeaders headers = new HttpHeaders();  headers.setContentDispositionFormData("attachment", fileName);  headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);  return ResponseEntity.ok()  .headers(headers)  .body(excelBytes);  }  @PostMapping("/importExcel")  public ResponseEntity<?> importExcel(@RequestParam("file") 		MultipartFile file) {  List<UserData> userDataList = EasyExcelUtils.importExcel(file, UserData.class);  // 假设你需要在这里处理导入的数据,比如保存到数据库等  // ...  return ResponseEntity.ok("Excel 导入成功,共导入 " + userDataList.size() + " 条数据");  
}

四、前端 vue 页面调用示例

<script>  
import axios from 'axios';  export default {  // ... 其他选项和数据 ...  methods: {  exportExcel() {  // 假设你有一个要发送到服务器的对象(如果需要的话)  const params = {  // 例如: filter: 'someValue'  };  axios({  method: 'post',  url: '/api/exportExcel', // 修改为你的实际API地址  data: params, // 如果需要的话  responseType: 'blob', // 告诉axios我们期望返回一个blob  })  .then((response) => {  // 创建一个Blob对象来表示二进制数据  const blob = new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });  // 创建一个指向该Blob对象的URL  const url = window.URL.createObjectURL(blob);  // 创建一个a标签并模拟点击来下载文件  const link = document.createElement('a');  link.href = url;  link.setAttribute('download', 'users.xlsx'); // 设置下载文件名  document.body.appendChild(link);  link.click();  // 清理  window.URL.revokeObjectURL(url);  document.body.removeChild(link);  })  .catch((error) => {  console.error('导出Excel失败:', error);  this.message = '导出Excel失败';  });  },  // ... 其他方法 ...  },  
};  
</script>

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

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

相关文章

第六节 LLava模型数据处理源码解读(input_ids/labels/attention_mask/image,下篇)

文章目录 前言一、数据格式标签二、LazySupervisedDataset的__gettitem__函数源码解读1、source获取2、图像数据处理1、对话内容source获取(存在图像条件)2、对话内容source获取(不存在图像条件)3、对话文本数据加工4、data_dict进一加工5、data_dict的image元素添加6、返回…

肾虚学习实验第T1周:实现mnist手写数字识别

>- **&#x1f368; 本文为[&#x1f517;365天深度学习训练营](https://mp.weixin.qq.com/s/0dvHCaOoFnW8SCp3JpzKxg) 中的学习记录博客** >- **&#x1f356; 原作者&#xff1a;[K同学啊](https://mtyjkh.blog.csdn.net/)** 目录 一、前言 作为一名研究牲&#xff0…

全面讲解,使用Python搭建自己的后端服务(FastAPI),并提供API接口

全面讲解,使用Python搭建自己的后端服务(FastAPI),并提供API接口 开始工作推荐的项目结构详细步骤配置 Uvicorn 以在 `0.0.0.0` 上运行配置日志记录查看日志完整的项目结构其它解释为什么要对 `start.sh` 赋予执行权限背景为什么要创建 `start.sh` 脚本?为什么要对 `start…

树和二叉树的定义

目录 一、树的定义 1.1概念 1.2表示方式 1.3基本术语 1.4树结构和线性结构的比较 二、二叉树的定义 2.1概念 2.2二叉树的5种基本形态 三、二叉树的性质和存储结构 3.1二叉树的性质 3.1.1满二叉树 3.1.2完全二叉树 3.2二叉树的存储结构 3.2.1二叉树的顺序存储 3.2.…

在Ubuntu上解决 “qmake: could not find a Qt installation of ‘‘” 错误

在Ubuntu上运行qmake命令生成Makefile时&#xff0c;遇到了以下错误&#xff1a; qmake: could not find a Qt installation of 即使我安装了以下软件包&#xff0c;也未能解决此问题&#xff1a; sudo apt-get install qt4-qmake sudo apt-get install qt5-qmake如果你也遇到…

海量数据处理——bitMap/BloomFilter、hash + 统计 + 堆/归并/快排

前言&#xff1a;海量数据处理是面试中一道常考的问题&#xff0c; 生活中也容易遇到这种问题。 通常就是有一个大文件&#xff0c; 让我们对这个文件进行一系列操作——找出现次数最多的数据、求交集、是否重复出现等等。 因为文件的内容太多&#xff0c; 我们的内存通常是放不…

目标跟踪算法(bytetrack)-tensorrt部署教程

一、本机安装python环境 conda create -n bytetrace_env python=3.8 activate bytetrace_env conda install pytorch torchvision cudatoolkit=10.1 -c检测GPU是否可用,不可用不行 import torch print(torch.cuda.is_available())安装bytetrack git clone https://github.c…

计算机专业的发展前景与选择建议。

身份角度一&#xff1a;一名曾经的计算机专业学生  在我当年选择计算机专业的时候&#xff0c;计算机科学与技术、人工智能、网络安全、软件工程等专业确实是炙手可热的热门选择。然而&#xff0c;随着时间的推移&#xff0c;市场竞争加剧和市场饱和度提高&#xff0c;这些专…

ELK Kibana搜索框模糊搜索包含不包含

默认是KQL,点击切换Lucene搜索&#xff0c;搜索日志中包含Exception关键字&#xff0c;不包含BizException、IllegalArgumentException、DATA_SYNC_EXCEPTION关键字的日志&#xff0c;如下&#xff1a; message: *Exception AND !(message : *BizException OR message : *Ille…

数据库复习——模式分解

模式分解这边主要包括无损分解和保持函数依赖的分解两种形式&#xff0c;简单整理一下。 无损分解 把一个 R R R 分成 ρ { R 1 , R 2 , ⋯ , R k } \rho \{R_1,R_2,\cdots,R_k\} ρ{R1​,R2​,⋯,Rk​}&#xff0c;然后通过自然连接 R 1 ⋈ R 2 ⋈ ⋯ ⋈ R k R_1\bowtie R…

容器之布局容器的演示

代码; #include <gtk-2.0/gtk/gtk.h> #include <glib-2.0/glib.h> #include <gtk-2.0/gdk/gdkkeysyms.h> #include <stdio.h>void change_image(GtkFileChooserButton *filebutton, // GdkEvent *event,GtkImage *image) {gtk_image_set_from_file(im…

鸿蒙开发通信与连接:【@ohos.wifiext (WLAN)】

WLAN 说明&#xff1a; 本模块首批接口从API version 8开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 该文档中的接口只供非通用类型产品使用&#xff0c;如路由器等&#xff0c;对于常规类型产品&#xff0c;不应该使用这些接口。 导入模块 …

手写方法实现整型例如:123与字符串例如:“123“相互转化(下篇)

目录 一、前言 二、整型转化为字符串 1. 初始化变量 2.数字1转字符1 3.取出value中的每一项数字 4.将字符放入字符数组中 5.最终代码 三、最后 一、前言 本篇文章紧跟上篇文章&#xff0c;本片内容为整型转化为字符串类型。至于我为什么要分两篇文章&#xff0c;主要…

艺术创作加速器:三款AI绘画软件,让你的工作效率倍增!

在数字化浪潮的推动下&#xff0c;艺术创作正迎来革命性的变化。AI绘画软件的出现&#xff0c;不仅为艺术家提供了全新的创作工具&#xff0c;也为艺术爱好者开辟了一片创意的新天地。这些软件利用人工智能技术&#xff0c;根据用户的简单描述或草图&#xff0c;快速生成独特的…

Linux基础知识笔记

1.配置VNC linux&#xff1a; yum install tigervnc-server vncpasswd vncserver & New ‘2SCOM-RH72-1:1 (root)’ desktop is 2SCOM-RH72-1:1 windows: 软件: VNC-Viewer-6.20.113-Windows-64bit 连接信息 192.168.1.1:1 2.重置root密码 第一步: 开机后再内核上敲击e 第…

视频汇聚安防综合管理系统EasyCVR平台GB28181设备注册未上线的原因排查与解决

视频汇聚安防综合管理平台EasyCVR视频监控系统基于云边端架构&#xff0c;可支持海量视频汇聚集中管理&#xff0c;能提供视频监控直播、云端录像、云存储、录像检索与回看、告警&#xff08;协议告警/智能告警/1400视图库告警&#xff09;、平台级联、AI智能分析接入等视频能力…

从艳彩山水到艳彩艺术 薛永年:郭泰来艳彩艺术填补了中国美术史的空白

薛永年先生 自6月12日开展以来&#xff0c;郭泰来现代艺术大展杭州如火如荼地进行着&#xff0c;吸引了众多艺术爱好者和专业人士前往。毫不夸张地说&#xff0c;总统和清洁工人都能在他的作品中找到自己心中的那一块共振带并与之产生强烈的共鸣&#xff0c;这便是郭泰来先生的…

矩阵中严格递增的单元格数

题目链接&#xff1a;leetcode:矩阵中严格递增的单元格数 描述 给你一个下标从 1 开始、大小为 m x n 的整数矩阵 mat&#xff0c;你可以选择任一单元格作为 起始单元格 。 从起始单元格出发&#xff0c;你可以移动到 同一行或同一列 中的任何其他单元格&#xff0c;但前提是目…

【JavaEE进阶】Spring统一功能处理:拦截器的使用

目录 1.什么是拦截器? 2.拦截器的使用 2.1定义拦截器 2.2 注册配置拦截器 3.拦截器详解 3.1 拦截路径 3.2 拦截器的执行流程 4. 使用拦截器实现登录校验 4.1 定义拦截器 4.2 注册配置拦截器 1.什么是拦截器? 拦截器是Spring框架提供的核心功能之⼀, 主要用来拦截用…

AI赋能前端:你的Chrome 控制台需要AI(爱)

像会永生那样去学习,像明天就要死亡那样去生活。——圣雄甘地 大家好,我是柒八九。一个专注于前端开发技术/Rust及AI应用知识分享的Coder 此篇文章所涉及到的技术有 AI(Gemini)ChromeDevTool🪜魔法接码平台因为,行文字数所限,有些概念可能会一带而过亦或者提供对应的学习…