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);

image-20231001224214707

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 插件生成基础代码:

image-20231001224944713

① 配置数据库:

image-20231001224418894

image-20231001224520414

② 使用代码生成器生成代码:

image-20231001224612743

image-20231001225559406

image-20231002165231209


2. POI


Excel报表的两种方式:

在企业级应用开发中,Excel报表是一种常见的报表需求,Excel报表开发一般分为两种形式:

  • 把Excel中的数据导入到系统中;(上传)

  • 通过Java代码生成Excel报表。(下载)


Excel版本:

目前世面上的Excel分为两个大版本:Excel2003 和 Excel2007及以上版本;

Excel2003是一个特有的二进制格式,其核心结构是复合文档类型的结构,存储数据量较小;Excel2007 的核心结构是 XML 类型的结构,采用的是基于 XML 的压缩方式,使其占用的空间更小,操作效率更高。

Excel 2003Excel 2007
后缀xlsxlsx
结构二进制格式,其核心结构是复合文档类型的结构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();}
}

image-20231004224921153


示例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("批量导入失败");}}
}

image-20231007062047348

image-20231007062527489

image-20231007062019296


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的官方文档非常全面,我就不一一赘述了。

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

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

相关文章

Spring【@Resource、@Autowired+lombook+Bean的生命周期】

Resource 和 Autowired 的区别 在Spring中找Bean的两种方式&#xff1a;①先根据类型查找②再根据名称查找 Autowired先根据类型查找&#xff0c;再根据名称查找【根据上述查找结果不唯一&#xff0c;再添加一个 Qualifier(value“”)&#xff0c;就可以查找】 Resource先根据名…

unity中绑定动画的行为系统

主要代码逻辑是创建一个action队列,当动画播放结束时就移除队头,执行后面的事件 public class Enemy : MonoBehaviour {public event Action E_AnimatorFin;//当动画播放完毕时public Action DefaultAction;//默认事件public Dictionary<Action, string> EventAnimator n…

AndroidStudio添加一个虚拟设备

虚拟设备管理器 这个是AndroidStudio的启动界面 虚拟设备管理界面 点击加号&#xff0c;新增 选择手机型号 选择系统版本 虚拟设备名 完成

PHP 伪协议:使用 php://filter 为数据流应用过滤器

文章目录 参考环境PHP 伪协议概念为什么需要 PHP 伪协议&#xff1f; php://filter概念格式 基本使用普通读写file_get_contents 与 file_put_contentsinclude 过滤器的基本使用base64 的编码与解码rot13 加解密rot13 算法string.rot13 过滤器列表多个过滤器的使用注意事项 处理…

手摸手系列之批量修改MySQL数据库所有表中某些字段的类型

在迁移老项目的数据库时&#xff0c;使用Navicat Premium的数据传输功能同步了表结构和数据。但是&#xff0c;发现某些字段的数据类型出现了错误&#xff0c;例如&#xff0c;租户ID从Oracle的NUMBER类型变成了MySQL的decimal(10)&#xff0c;正确的应该是bigInt(20)。此外&am…

voc数据集格式与yolo数据集格式的区别及相互转化

Pascal VOC数据集是目标检测领域最常用的标准数据集之一&#xff0c;几乎所有检测方向的论文都会给出其在VOC数据集上训练并评测的效果。VOC数据集包含的信息非常全&#xff0c;它不仅被拿来做目标检测&#xff0c;也可以拿来做分割等任务&#xff0c;因此除了目标检测所需的文…

kafka与zookeeper的集群

基础配置 systemctl stop firewalld && systemctl disable firewalld setenforce 0 sed -i s/SELINUXenforcing/SELINUXdisabled/ /etc/selinux/configvi /etc/hosts ip1 node1 ip2 node2 ip3 node3zookeeper介绍 zookeeper是一个分布式的协调服务&#xff0c;主要用…

【window10】Dart+Android Studio+Flutter安装及运行

安装Dart SDK安装Android Studio安装Flutter在Android Studio中创建并运行Flutter项目 安装前&#xff0c;请配置好你的jdk环境&#xff0c;准备好你的梯子~ 安装Dart SDK 浅浅了解一下Dart&#xff1a; Dart 诞生于2011年&#xff0c;是由谷歌开发的一种强类型、跨平台的客户…

【计算机视觉 05】YOLO论文讲解:V1-V7

https://ai.deepshare.net/live_pc/l_63243a65e4b050af23b79338 Part1.目标检测与YOLO系列 1. 目标检测任务及发展脉络 2. YOLO的发展史 Anchors Base原理&#xff1a; Part2.YOLOV1-V3 3. YOLO V1的网络结构 4. YOLO V3的网络结构与实验结果 Part3.YOLO的进化 5. YOLO V4的网络…

每个前端都要学的【前端自动化部署】,Devops,CI/CD

原文发布于&#xff1a;2023-09-21 11:50 作者&#xff1a;65岁退休Coder 原文链接&#xff1a;https://juejin.cn/post/7102360505313918983 DevOps 当我们提到 Jenkins&#xff0c;大家首先想到的概念就是 CI/CD&#xff0c;在这之前我们应该再了解一个概念。 DevOps&#…

轻松实现时间录入自由!如何在Microsoft Word中轻松插入格式化的日期和时间

在文档中插入当前日期和时间有几个原因。你可能希望将其插入信函或页眉或页脚中。无论是什么原因&#xff0c;Word都可以轻松地将日期和时间插入文档。 如果希望在打开或打印文档时自动更新日期和时间&#xff0c;可以将其作为自动更新的字段插入。该字段也可以随时手动更新。…

六个交易日市值蒸发20亿港元,第四范式难逃AI大模型“魔咒”

AI独角兽第四范式终于敲钟了。 北京第四范式智能技术股份有限公司(06682.HK&#xff0c;下称“第四范式”)于9月28日正式挂牌港交所&#xff0c;发行价为55.60港元/股&#xff0c;IPO首日报收58.50港元/股。 上市后6个交易日&#xff0c;截至10月6日港股收盘&#xff0c;第四…