SpringBoot整合POI实现Excel文件读写操作
1.环境准备
1、导入sql脚本:
create database if not exists springboot default charset utf8mb4;use springboot;create table if not exists `user`
(`id` bigint(20) primary key auto_increment comment '主键id',`username` varchar(255) not null comment '用户名',`sex` char(1) not null comment '性别',`phone` varchar(22) not null comment '手机号',`city` varchar(255) not null comment '所在城市',`position` varchar(255) not null comment '职位',`salary` decimal(18, 2) not null comment '工资:长度18位,保留2位小数'
) engine InnoDB comment '用户表';INSERT INTO `user` (`username`, `sex`, `phone`, `city`, `position`, `salary`) VALUES
('张三', '男', '13912345678', '北京', '软件工程师', 10000.00),
('李四', '女', '13723456789', '上海', '数据分析师', 12000.00),
('王五', '男', '15034567890', '广州', '产品经理', 15000.00),
('赵六', '女', '15145678901', '深圳', '前端工程师', 11000.00),
('刘七', '男', '15856789012', '成都', '测试工程师', 9000.00),
('陈八', '女', '13967890123', '重庆', 'UI设计师', 8000.00),
('朱九', '男', '13778901234', '武汉', '运维工程师', 10000.00),
('杨十', '女', '15089012345', '南京', '数据工程师', 13000.00),
('孙十一', '男', '15190123456', '杭州', '后端工程师', 12000.00),
('周十二', '女', '15801234567', '天津', '产品设计师', 11000.00);
2、创建springboot工程 (springboot版本为2.7.13)
3、引入依赖:
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-test</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.13</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.2</version></dependency>
</dependencies>
4、修改yml配置:
server:port: 8001# 数据库配置
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2b8&allowPublicKeyRetrieval=trueusername: rootpassword: 123456# mybatisplus配置
mybatis-plus:mmapper-locations: classpath:mapper/*.xml #mapper文件存放路径type-aliases-package: cn.z3inc.exceldemo.entity # 类型别名(实体类所在包)configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #配置标准sql输出
5、使用 MyBatisPlus
插件生成基础代码:
① 配置数据库:
② 使用代码生成器生成代码:
2. POI
Excel报表的两种方式:
在企业级应用开发中,Excel报表是一种常见的报表需求,Excel报表开发一般分为两种形式:
-
把Excel中的数据导入到系统中;(上传)
-
通过Java代码生成Excel报表。(下载)
Excel版本:
目前世面上的Excel分为两个大版本:Excel2003 和 Excel2007及以上版本;
Excel2003是一个特有的二进制格式,其核心结构是复合文档类型的结构,存储数据量较小;Excel2007 的核心结构是 XML 类型的结构,采用的是基于 XML 的压缩方式,使其占用的空间更小,操作效率更高。
Excel 2003 | Excel 2007 | |
---|---|---|
后缀 | xls | xlsx |
结构 | 二进制格式,其核心结构是复合文档类型的结构 | XML类型结构 |
单sheet数据量(sheet,工作表) | 表格共有65536行,256列 | 表格共有1048576行,16384列 |
特点 | 存储容量有限 | 基于xml压缩,占用空间小,操作效率高 |
Apache POI:
Apache POI(全称:Poor Obfuscation Implementation),是Apache软件基金会的一个开源项目,它提供了一组API,可以让Java程序读写 Microsoft Office 格式的文件,包括 word、excel、ppt等。
Apache POI是目前最流行的操作Microsoft Office的API组件,借助POI可以为工作提高效率,如 数据报表生成,数据批量上传,数据备份等工作。
官网地址:https://poi.apache.org/
POI针对Excel的API如下:
- Workbook:工作薄,Excel的文档对象,针对不同的Excel类型分为:HSSFWorkbook(2003)和XSSFWorkbook(2007);
- Sheet:Excel的工作单(表);
- Row:Excel的行;
- Cell:Excel的格子,单元格。
Java中常用的excel报表工具有:POI、easyexcel、easypoi等。
POI快速入门:
引入POI依赖:
<!--excel POI依赖-->
<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.0.1</version>
</dependency>
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.0.1</version>
</dependency>
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml-schemas</artifactId><version>4.0.1</version>
</dependency>
示例1:批量写操作(大数据量时会出现内存异常问题)
写入excel文件步骤:
- 创建工作簿:workbook
- 创建工作表:sheet
- 创建行:row
- 创建列(单元格):cell
- 具体数据写入
package cn.z3inc.exceldemo.controller;import cn.z3inc.exceldemo.entity.User;
import cn.z3inc.exceldemo.service.IUserService;
import lombok.RequiredArgsConstructor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;/*** <p>* 用户表 前端控制器* </p>** @author 白豆五* @since 2023-10-01*/
@CrossOrigin
@RestController
@RequiredArgsConstructor
@RequestMapping("/user")
public class UserController {private final IUserService userService;/*** 导出excel*/@RequestMapping("/export")public void exportExcel(HttpServletResponse response) throws IOException {// 1. 创建excel工作簿(workbook):excel2003使用HSSF,excel2007使用XSSF,excel2010使用SXSSF(大数据量)XSSFWorkbook workbook = new XSSFWorkbook();// 2. 创建excel工作表(sheet)Sheet sheet = workbook.createSheet("用户表");// 3. 在表中创建标题行(row): 表头Row titleRow = sheet.createRow(0); // 通过索引表示行,0表示第一行// 4. 在标题行中创建7个单元格 且 为每个单元格设置内容数据String[] titleArr = {"用户ID", "姓名", "性别", "电话", "所在城市", "职位", "薪资"};for (int i = 0; i < titleArr.length; i++) {Cell cell = titleRow.createCell(i); //设置单元格的位置,从0开始cell.setCellValue(titleArr[i]); // 为单元格填充数据}// 5. 查询所有用户数据List<User> userList = userService.list();// 6. 遍历用户list,获取每个用户,并填充每一行单元格的数据for (int i = 0; i < userList.size(); i++) {User user = userList.get(i);// 创建excel的行Row row = sheet.createRow(i+1); // 从第二行开始,索引为1// 为每个单元格填充数据row.createCell(0).setCellValue(user.getId());row.createCell(1).setCellValue(user.getUsername());row.createCell(2).setCellValue(user.getSex());row.createCell(3).setCellValue(user.getPhone());row.createCell(4).setCellValue(user.getCity());row.createCell(5).setCellValue(user.getPosition());row.createCell(6).setCellValue(user.getSalary().doubleValue());}// 7. 输出文件// 7.1 把excel文件写到磁盘上FileOutputStream outputStream = new FileOutputStream("d:/1.xlsx");workbook.write(outputStream); // 把excel写到输出流中outputStream.close(); // 关闭流// 7.2 把excel文件输出到浏览器上// 设置响应头信息response.setContentType("application/vnd.ms-excel");response.setHeader("Content-Disposition", "attachment; filename=1.xlsx");ServletOutputStream servletOutputStream = response.getOutputStream();workbook.write(servletOutputStream);servletOutputStream.flush(); // 刷新缓冲区servletOutputStream.close(); // 关闭流workbook.close();}
}
示例2:大数量写操作
/*** 大数据量批量导出excel:SXSSF(同样兼容XSSF)* 官方提供了SXSSF来解决大文件写入问题,它可以写入非常大量的数据,比如上百万条数据,并且写入速度更快,占用内存更少* SXSSF在写入数据时会将数据分批写入硬盘(会产生临时文件),而不是一次性将所有数据写入硬盘。* SXSSF通过滑动窗口限制内存读取的行数(默认100行,超过100行就会写入磁盘),而XSSF将文档中所有行加载到内存中。那些不在滑动窗口中的数据是不能访问的,因为它们已经被写到磁盘上了。这样可以节省大量内存空间 。*/
@RequestMapping("/export2")
public void exportExcel2(HttpServletResponse response) throws IOException {long star = System.currentTimeMillis();// 1. 创建excel工作簿(workbook):SXSSFWorkbookSXSSFWorkbook workbook = new SXSSFWorkbook();//默认窗口大小为100// 2. 创建excel工作表(sheet)Sheet sheet = workbook.createSheet("用户表");// 3. 在表中创建标题行(row): 表头Row titleRow = sheet.createRow(0); // 通过索引表示行,0表示第一行// 4. 在标题行中创建7个单元格 且 为每个单元格设置内容数据String[] titleArr = {"用户ID", "姓名", "性别", "电话", "所在城市", "职位", "薪资"};for (int i = 0; i < titleArr.length; i++) {Cell cell = titleRow.createCell(i); //设置单元格的位置,从0开始cell.setCellValue(titleArr[i]); // 为单元格填充数据}// 5. 查询所有用户数据List<User> userList = userService.list();// 6. 遍历用户list,获取每个用户,并填充每一行单元格的数据for (int i = 0; i < 65536; i++) {User user;if (i > userList.size() - 1) {user = userList.get(userList.size() - 1);} else {user = userList.get(i);}// 创建excel的行Row row = sheet.createRow(i + 1); // 从第二行开始,索引为1// 为每个单元格填充数据row.createCell(0).setCellValue(user.getId());row.createCell(1).setCellValue(user.getUsername());row.createCell(2).setCellValue(user.getSex());row.createCell(3).setCellValue(user.getPhone());row.createCell(4).setCellValue(user.getCity());row.createCell(5).setCellValue(user.getPosition());row.createCell(6).setCellValue(user.getPosition());}// 7. 输出文件// 7.1 把excel文件写到磁盘上FileOutputStream outputStream = new FileOutputStream("d:/2.xlsx");workbook.write(outputStream); // 把excel写到输出流中outputStream.close(); // 关闭流workbook.close();long end = System.currentTimeMillis();log.info("大数据量批量数据写入用时: {} ms", end - star);
}
经测试XSSF大概十秒左右输出excel文件,而SXSSF一秒左右输出excel文件。
示例:读取excel文件
读取excel文件步骤:(通过文件流读取)
- 获取工作簿
- 获取工作表(sheet)
- 获取行(row)
- 获取单元格(cell)
- 读取数据
// 读取excel文件
@RequestMapping("/upload")
public void readExcel(MultipartFile file) {InputStream is = null;XSSFWorkbook workbook = null;try {// 1. 创建excel工作簿(workbook)is = file.getInputStream();workbook = new XSSFWorkbook(is);// 2. 获取要解析的工作表(sheet)Sheet sheet = workbook.getSheetAt(0); // 获取第一个sheet// 3. 获取表格中的每一行,排除表头,从第二行开始User user;List<User> list = new ArrayList<>();for (int i = 1; i <= sheet.getLastRowNum(); i++) {Row row = sheet.getRow(i); // 获取第i行// 4. 获取每一行的每一列,并为user对象的属性赋值,添加到list集合中user = new User();user.setUsername(row.getCell(1).getStringCellValue());user.setSex(row.getCell(2).getStringCellValue());user.setPhone(row.getCell(3).getStringCellValue());user.setCity(row.getCell(4).getStringCellValue());user.setPosition(row.getCell(5).getStringCellValue());user.setSalary(new BigDecimal(row.getCell(6).getNumericCellValue()));list.add(user);}// 5. 批量保存userService.saveBatch(list);} catch (IOException e) {e.printStackTrace();throw new RuntimeException("批量导入失败");} finally {try {if (is != null) {is.close();}if (workbook != null) {workbook.close();}} catch (IOException e) {e.printStackTrace();throw new RuntimeException("批量导入失败");}}
}
3. EasyExcel
EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。他能让你在不用考虑性能、内存的等因素的情况下,快速完成Excel的读、写等功能。
官网地址:https://easyexcel.opensource.alibaba.com/
文档地址:https://easyexcel.opensource.alibaba.com/docs/current/
示例代码:https://github.com/alibaba/easyexcel/tree/master/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo
pom依赖:
<!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.2.1</version>
</dependency>
最后,EasyExcel的官方文档非常全面,我就不一一赘述了。
相关文章:

SpringBoot整合POI实现Excel文件读写操作
1.环境准备 1、导入sql脚本: create database if not exists springboot default charset utf8mb4;use springboot;create table if not exists user (id bigint(20) primary key auto_increment comment 主键id,username varchar(255) not null comment 用…...

从零开始的力扣刷题记录-第八十七天
力扣每日四题 129. 求根节点到叶节点数字之和-中等130. 被围绕的区域-中等437. 路径总和 III-中等376. 摆动序列-中等总结 129. 求根节点到叶节点数字之和-中等 题目描述: 给你一个二叉树的根节点 root ,树中每个节点都存放有一个 0 到 9 之间的数字。 …...

【1】c++设计模式——>UML类图的画法
UML介绍 UML:unified modeling language 统一建模语言 面向对象设计主要就是使用UML类图,类图用于描述系统中所包含的类以及他们之间的相互关系,帮助人们简化对系统的理解,他是系统分析和设计阶段的重要产物,也是系统编码和测试的…...

SAP UI5 指定 / 变更版本
SAP UI5 指定 / 变更版本 Currently, SAP Fiori tools support SAP Fiori elements and SAPUI5 freestyle projects with minimum SAPUI5 versions 1.65 or higher. In case there’s a need to test an existing projects with a lower SAPUI5 version, the following worka…...

SpringMVC中异常处理详解
单个控制器异常处理 // 添加ExceptionHandler,表示该方法是处理异常的方法,属性为处理的异常类ExceptionHandler({java.lang.NullPointerException.class,java.lang.ArithmeticException.class})public String exceptionHandle1(Exception ex, Model mo…...

PPT课件培训视频生成系统实现全自动化
前言 困扰全动自化的重要环节,AI语音合成功能,终于可以实现自动化流程,在此要感谢团队不懈的努力和韧性的精神! 实现原理 请参照我的文章《Craneoffice云PPT课件培训视频生成系统》 基本流程 演示视频 PPT全自动 总结 过去实…...

基于腾讯云的OTA远程升级
一、OTA OTA即over the air,是一种远程固件升级技术,它允许在设备已经部署在现场运行时通过网络远程更新其固件或软件。OTA技术有许多优点,比如我们手机系统有个地方做了优化,使用OTA技术我们就不用召回每部手机,直接通过云端就可…...

如何在VS2022中进行调试bug,调试的快捷键,debug与release之间有什么区别
什么是bug 在学习编程的过程中,应该都听说过bug吧,那么bug这个词究竟是怎么来的呢? 其实Bug的本意是“虫子”或者“昆虫”,在1947年9月9日,格蕾丝赫柏,一位为美国海军工作的电脑专家,也是最早…...

初识jmeter及简单使用
目录 1、打开页面: 2、添加线程组: 3、线程组中设置参数: 4、添加请求 5、添加一个http请求后,设置请求内容 6、添加察看结果树 7、执行,查看结果 一般步骤是:在测试计划下面新建一个线程组…...

Spring 在多线程环境下如何确保事务一致性
问题在现 如何解决异步执行 多线程环境下如何确保事务一致性 事务王国回顾 事务实现方式回顾 编程式事务 利用编程式事务解决问题 问题分析完了,那么如何解决问题呢? 小结 问题在现 我先把问题抛出来,大家就明白本文目的在于解决什…...

[Machine Learning] Learning with Noisy Data
文章目录 Probabilistic Perspective of NoiseBias and VarianceRobustness among Surrogate Loss FunctionsNMF Probabilistic Perspective of Noise 假设数据来源于一个确定的函数,叠加了高斯噪声。我们有: y h ( x ) ϵ y h(x) \epsilon yh(x)ϵ…...

C++中有哪些常用的标准库?
C中有许多常用的标准库,这些库提供了丰富的功能和工具,方便开发人员进行各种任务。以下是一些常见的C标准库: iostream:用于输入和输出操作,包括cin、cout和cerr等类和函数。algorithm:提供了许多常用的算…...

软考-信息安全工程师概述
本文为作者学习文章,按作者习惯写成,如有错误或需要追加内容请留言(不喜勿喷) 本文为追加文章,后期慢慢追加 2023年10月 信息考试大纲 通过本考试的合格人员能够掌握网络信息安全的基础知识和技术原理,…...

2023-2024年华为ICT网络赛道模拟题库
2023-2024年网络赛道模拟题库上线啦,全面覆盖网络,安全,vlan考点,都是带有解析 参赛对象及要求: 参赛对象:现有华为ICT学院及未来有意愿成为华为ICT学院的本科及高职院校在校学生。 参赛要求:…...

英特尔参与 CentOS Stream 项目
导读红帽官方发布公告欢迎英特尔参与进 CentOS Stream 项目,并表示 “这一举措不仅进一步深化了我们长期的合作关系,也构建在英特尔已经在 Fedora 项目中积极贡献的基础之上。” 目前,CentOS Stream 共包括以下特别兴趣小组(SIG&a…...

Centos 服务器 MySQL 8.0 快速开启远程访问
环境: MySQL 8.0(低版本会有些不同), Rocky Linux 9.0(CentOS) 直接上干货,相信大家看到这个文章的时候都已经安装完了。 1. 先从服务器上使用 root 进行登录(刚安装完默认只能本地…...

充电保护芯片TP4054国产替代完全兼容DP4054DP4054H 锂电充电芯片
■产品概述 DP4054H是-款完整的采用恒定电流/恒定电压单节锂离子电池充电管理芯片。其SOT小封装和较少的外部元件数目使其成为便携式应用的理想器件,DP4054H可 以适合USB电源和适配器电源工作。 由于采用了内部PMOSFET架构,加上防倒充电路,所以不需要外…...

Java Spring Boot中的爬虫防护机制
随着互联网的发展,爬虫技术也日益成熟和普及。然而,对于某些网站来说,爬虫可能会成为一个问题,导致资源浪费和安全隐患。本文将介绍如何使用Java Spring Boot框架来防止爬虫的入侵,并提供一些常用的防护机制。 引言&a…...

状态模式 行为型模式之六
1.定义 允许一个对象在其对象内部状态改变时改变它的行为。 2.组成结构 Context:定义客户感兴趣的接口;维护一个ConcreteState子类的实例,这个实例定义当前的状态。State:定义一个接口来封装Context的与特定状态相关的行为。Co…...

JAVA NIO深入剖析
4.1 Java NIO 基本介绍 Java NIO(New IO)也有人称之为 java non-blocking IO是从Java 1.4版本开始引入的一个新的IO API,可以替代标准的Java IO API。NIO与原来的IO有同样的作用和目的,但是使用的方式完全不同,NIO支持面向缓冲区的、基于通道的IO操作。NIO将以更加高效的方…...

企业电子招投标系统源码之电子招投标系统建设的重点和未来趋势
功能描述 1、门户管理:所有用户可在门户页面查看所有的公告信息及相关的通知信息。主要板块包含:招标公告、非招标公告、系统通知、政策法规。 2、立项管理:企业用户可对需要采购的项目进行立项申请,并提交审批,查看所…...

基于正点原子alpha开发板的第三篇系统移植
系统移植的三大步骤如下: 系统uboot移植系统linux移植系统rootfs制作 一言难尽,踩了不少坑,当时只是想学习驱动开发,发现必须要将第三篇系统移植弄好才可以学习后面驱动,现将移植好的文件分享出来: 仓库&…...

数据结构与算法设计分析——贪心算法的应用
目录 一、贪心算法的定义二、贪心算法的基本步骤三、贪心算法的性质(一)最优子结构性质(二)贪心选择性质 四、贪心算法的应用(一)哈夫曼树——哈夫曼编码(二)图的应用——求最小生成…...

Leetcode 2895. Minimum Processing Time
Leetcode 2895. Minimum Processing Time 1. 解题思路2. 代码实现 题目链接:2895. Minimum Processing Time 1. 解题思路 这一题整体上来说其实没啥难度,就是一个greedy算法,只需要想明白耗时长的任务一定要优先执行,不存在某个…...

学信息系统项目管理师第4版系列21_范围管理
1. 产品范围 1.1. 某项产品、服务或成果所具有的特征和功能 1.2. 产品范围的完成情况是根据产品需求来衡量的 1.3. “需求”是指根据特定协议或其他强制性规范,产品、服务或成果必须具备的条件或能力 2. 项目范围 2.1. 包括产品范围,是为交付具有规…...

threejs 透明贴图,模型透明,白边
问题 使用Threejs加载模型时,模型出现了上面的问题。模型边缘部分白边,或者模型出现透明问题。 原因 出现这种问题是模型制作时使用了透明贴图。threejs无法直接处理贴图。 解决 场景一 模型有多个贴图时(一个透贴和其他贴图࿰…...

CCF CSP认证 历年题目自练Day21
题目一 试题编号: 201909-1 试题名称: 小明种苹果 时间限制: 2.0s 内存限制: 512.0MB 题目分析(个人理解) 先看输入,第一行输入苹果的棵树n和每一次掉的苹果数m还是先如何存的问题…...

【Python_PySide2学习笔记(十六)】多行文本框QPlainTextEdit类的的基本用法
多行文本框QPlainTextEdit类的的基本用法 前言正文1、创建多行文本框2、多行文本框获取文本3、多行文本框获取选中文本4、多行文本框设置提示5、多行文本框设置文本6、多行文本框在末尾添加文本7、多行文本框在光标处插入文本8、多行文本框清空文本9、多行文本框拷贝文本到剪贴…...

linux上negix部署静态页面
1.看配置文件 进入cndf.d 这里的是配置部署项目中的文件 进入一个查看下 上面的是服务的域名,服务是http://test.fun-med.cn/#/,后面加服务名(你的前端) 2.看下页面位置 和上面的路径要匹配...