历史文章(文章累计460+)
《国内最全的Spring Boot系列之一》
《国内最全的Spring Boot系列之二》
《国内最全的Spring Boot系列之三》
《国内最全的Spring Boot系列之四》
《国内最全的Spring Boot系列之五》
《国内最全的Spring Boot系列之六》
66个ChatGPT副业赚钱技巧 - 第3篇
ChatGPT+剪映·副业赚钱技巧实战教程·《制作阿凡达解说视频》- 第4篇
1分钟快速制作思维导图「ChatGPT+XMind」—— 跟上时代的脚步,这辈子就起飞了 - 第5篇
ChatGPT应用场景实战,拥有ChatGPT等于拥有最强大脑 - 第6篇
悟纤:师傅,最近好烦呢?
师傅:徒儿,你这是怎么了?
悟纤:项目经理让我将最近的订单信息用Excel表格导出,然后我找了一个框架POI,用的脑瓜疼呢。
师傅:那你问对人了,我最近发现了一个不错的框架。
悟纤:怎么说?
师傅:几行代码就可以实现导出,还有提供各种的导出注解。爽歪歪的。
悟纤:那师傅,你不能就自己爽呢,也带徒儿爽一下。
师傅:抓好扶手,准备起飞 🛫 🛫 🛫
导读
Hi,大家好,我是悟纤。
我就是我,不一样的烟火。我就是我,与众不同的小苹果。
在项目的开发工程中,经常有导入导出数据的常见功能场景,Apache的POI是处理导入导出中最常用的,但是其原生的用法太复杂,很繁琐,总是在Copy… ,无意间发现一款简单粗暴的神器EasyPoi,EasyPoi也是基于POI的,在Spring Boot中也是做了很好的封装,让我们能够在Spring Boot 快速地使用EasyPoi 进行开发,很方便,而且支持多种格式的导入导出。
一、EasyPoi初识
EasyPoi功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员
就可以方便的写出Excel导出,Excel模板导出,Excel导入,Word模板导出,通过简单的注解和模板语言(熟悉的表达式语法),完成以前复杂的写法
1.1 EasyPoi的主要特点
l 设计精巧,使用简单
l 接口丰富,扩展简单
l 默认值多,write less do more
l spring mvc支持,web导出可以简单明了
1.2 EasyPoi的功能
Excel自适应xls和xlsx两种格式,word只支持docx模式
Excel转html、pdf导出
Excel导入:
Ø 注解导入
Ø Map导入
Ø 大数据量导入sax模式
Ø 导入文件保存
Ø 文件校验
Ø 字段校验
Excel导出:
Ø 注解导出
Ø 模板导出
Ø html导出
1.3 EasyPoi为谁开发
Ø 不太熟悉poi的
Ø 不想写太多重复太多的
Ø 只是简单的导入导出的
Ø 喜欢使用模板的
1.4 EasyPoi的目标
EasyPoi的目标不是替代poi,而是让一个不懂导入导出的快速使用poi完成Excel和word的各种操作,而不是看很多api才可以完成这样工作
1.5 EasyPoi独特功能
· 基于注解的导入导出,修改注解就可以修改Excel
· 支持常用的样式自定义
· 基于map可以灵活定义的表头字段
· 支持一堆多的导出,导入
· 支持模板的导出,一些常见的标签,自定义标签
· 支持HTML/Excel转换,如果模板还不能满足用户的变态需求,请用这个功能
· 支持word的导出,支持图片,Excel
1.6 EasyPoi的基本使用
-
easypoi 父包–作用大家都懂得
-
easypoi-annotation 基础注解包,作用与实体对象上,拆分后方便maven多工程的依赖管理
-
easypoi-base 导入导出的工具包,可以完成Excel导出,导入,Word的导出,Excel的导出功能
-
easypoi-web 耦合了spring-mvc 基于AbstractView,极大的简化spring-mvc下的导出功能
-
sax 导入使用xercesImpl这个包(这个包可能造成奇怪的问题哈),word导出使用poi-scratchpad,都作为可选包了
-
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-base</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-web</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-annotation</artifactId>
<version>4.1.0</version>
</dependency>
二、EasyPoi导出数据实战
在项目中,经常会有需求导出数据,比如用户信息的数据,商城订单的数据,使用EasyPoi来实现就很简单了。
环境说明:
(1)JDK:1.8
(2)idea:IntelliJ IDEA
(3)Spring Boot : 2.7.10
(4)easypoi-spring-boot-starter:4.4.0
(5)easypoi:4.4.0
(6)POI:4.1.1
使用步骤:
(1)添加依赖easypoi-spring-boot-starter
(2)编写Excel操作工具类
(3)编写数据VO
(4)编写导出Excel代码
(5)测试导出
2.1 添加依赖
没有项目的,可以先构建一个Spring Boot项目,取名为:spring-boot-easypoi-demo,有项目的直接使用开发即可。
在pom.xml添加依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.10</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>spring-boot-easypoi-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-easypoi-demo</name>
<description>spring-boot-easypoi-demo</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-spring-boot-starter</artifactId>
<version>4.4.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
和导出/导入相关的核心依赖是:easypoi-spring-boot-starter。
2.2 编写Excel操作工具类
Easypoi提供了对于Excel的基本操作,根据web的导出,我们进行简单的封装即可:
package com.example.demo;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
/**
* 导入导出工具类
* @Author huoqiang
**/
public class ExcelUtil {
public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass,String fileName, HttpServletResponse response){
defaultExport(list, pojoClass, fileName, response, new ExportParams(title, sheetName));
}
private static void defaultExport(List<?> list, Class<?> pojoClass, String fileName, HttpServletResponse response, ExportParams exportParams) {
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list);
if (workbook != null) {
downLoadExcel(fileName, response, workbook);
}
}
public static void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook) {
try {
response.setCharacterEncoding("UTF-8");
response.setHeader("content-Type", "application/vnd.ms-excel");
response.setHeader("Content-Disposition",
"attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
workbook.write(response.getOutputStream());
} catch (IOException e) {
throw new RuntimeException(e.getMessage());
}
}
public static void exportExcelX(List<?> list, String title, String sheetName, Class<?> pojoClass,String fileName, HttpServletResponse response){
defaultExportX(list, pojoClass, fileName, response, new ExportParams(title, sheetName,ExcelType.XSSF));
}
private static void defaultExportX(List<?> list, Class<?> pojoClass, String fileName, HttpServletResponse response, ExportParams exportParams) {
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list);
if (workbook != null) {
downLoadExcelX(fileName, response, workbook);
}
}
private static void downLoadExcelX(String fileName, HttpServletResponse response, Workbook workbook) {
try {
response.setCharacterEncoding("UTF-8");
response.setHeader("content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition",
"attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
workbook.write(response.getOutputStream());
} catch (IOException e) {
throw new RuntimeException(e.getMessage());
}
}
public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass,String fileName,boolean isCreateHeader, HttpServletResponse response){
ExportParams exportParams = new ExportParams(title, sheetName);
exportParams.setCreateHeadRows(isCreateHeader);
defaultExport(list, pojoClass, fileName, response, exportParams);
}
public static void exportExcel(List<Map<String, Object>> list, String fileName, HttpServletResponse response){
defaultExport(list, fileName, response);
}
private static void defaultExport(List<Map<String, Object>> list, String fileName, HttpServletResponse response) {
Workbook workbook = ExcelExportUtil.exportExcel(list, ExcelType.HSSF);
if (workbook != null) {
downLoadExcel(fileName, response, workbook);
}
}
public static <T> List<T> importExcel(String filePath,Integer titleRows,Integer headerRows, Class<T> pojoClass){
if (StringUtils.isBlank(filePath)){
return null;
}
ImportParams params = new ImportParams();
params.setTitleRows(titleRows);
params.setHeadRows(headerRows);
List<T> list = null;
try {
list = ExcelImportUtil.importExcel(new File(filePath), pojoClass, params);
}catch (NoSuchElementException e){
throw new RuntimeException("模板不能为空");
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
return list;
}
public static <T> List<T> importExcel(MultipartFile file, Integer titleRows, Integer headerRows, Class<T> pojoClass){
if (file == null){
return null;
}
ImportParams params = new ImportParams();
params.setTitleRows(titleRows);
params.setHeadRows(headerRows);
List<T> list = null;
try {
list = ExcelImportUtil.importExcel(file.getInputStream(), pojoClass, params);
}catch (NoSuchElementException e){
throw new RuntimeException("excel文件不能为空");
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
return list;
}
}
2.3 编写表格数据VO
对于Excel表格对应的单元格数据VO:
package com.example.demo.vo;
import cn.afterturn.easypoi.excel.annotation.Excel;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* author:悟纤「公众号SpringBoot」
* date:2023/4/19
*/
@Data
@AllArgsConstructor
public class UserExportVO implements Serializable {
@Excel(name = "姓名")
private String realName;
@Excel(name = "性别")
private Integer sex;
@Excel(name = "出生日期")
private Date birthday;
@Excel(name = "手机号码")
private String phone;
@Excel(name = "邮箱")
private String email;
@Excel(name = "头像地址")
private String avatar;
@Excel(name = "描述")
private String remark;
}
这里使用到了核心的一个注解@Excel,通过指定属性name来指定excel单元格的表头。
2.4 编写导出代码
编写一个Controller进行导出:
package com.example.demo;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.example.demo.vo.UserExportVO;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* author:悟纤「公众号SpringBoot」
* date:2023/4/19
*/
@RestController
@RequestMapping("/demo")
public class DemoController {
@GetMapping("/exportExcel")
public void export(HttpServletResponse response) {
//查询要导出的数据
//List<UserExportVO> users = userService.getUserExportList();
// 模拟数据
List<UserExportVO> users = new ArrayList<>();
users.add(new UserExportVO("悟纤",1,new Date(),"18688888888","1688@qq.com","https://picx.zhimg.com/80/v2-e141b3376b01e54409346bfcc9037e62_1440w.jpg","公众号SpringBoot"));
users.add(new UserExportVO("师傅",1,new Date(),"18666666666","1888@qq.com","https://picx.zhimg.com/80/v2-e141b3376b01e54409346bfcc9037e62_1440w.jpg","公众号SpringBoot"));
ExcelUtil.exportExcelX(users, "测试导出表", "sheet1", UserExportVO.class, "测试导出表.xlsx", response);
}
}
2.5 测试导出
启动项目,访问地址:
http://127.0.0.1:8080/demo/exportExcel
导出就是如此之简单。
总结
如果用过POI导出的,那么再用EasyPoi就会发现EasyPoi使用起来就会简单很多了。本节就先介绍到此为止,简单的做下总结:
(1)导入导出数据可以使用Apache的POI来进行实现。
(2)为什么没使用POI?其原生的用法太复杂,很繁琐
(3)EasyPoi也是基于POI的。
(4)EasyPoi在Spring Boot中的使用:添加依赖,easypoi-spring-boot-starter,然后使用EasyPoi提供的Excel导出类ExcelExportUtil的exportExcel方法,构建一个Workbook;最后利用response进行下载excel文件。
悟纤:师傅,导出是可以来了,但我这导出还存在一些问题呐。
师傅:何以见得?
悟纤:我给你罗列一下哦
(1)姓名单元格都快把你我挤坏了。
(2)性别怎么能显示数字呢,不得显示对应的男/女吗?
(3)图片显示的地址问题也不大,但是产品还是希望能够显示为图片呢。
(4)出生日期格式也不友好呀。
师傅:徒儿,不错,不错,思考的很到位。你说的这些问题,都是需要优化和调整的,下节咱们继续来学习。
「关注我不迷路,带你探索新技术」
我是一名热爱技术、分享经验的 IT 从业者。如果您也热爱计算机、喜欢编程、探寻新技术,那么我们一定会成为好朋友!我的微信号是 [wuqian5268],如果你想随时和我交流、讨论技术或者了解我最新的项目和成果,请不要犹豫,立即扫码或者添加我吧!
我就是我,是颜色不一样的烟火。
我就是我,是与众不同的小苹果。
à悟纤学院:https://t.cn/Rg3fKJD
学院中有Spring Boot相关的课程!点击「阅读原文」进行查看!
SpringBoot视频:http://t.cn/A6ZagYTi
SpringBoot交流平台:https://t.cn/R3QDhU0
SpringSecurity5.0视频:http://t.cn/A6ZadMBe
ShardingJDBC分库分表:http://t.cn/A6ZarrqS
分布式事务解决方案:http://t.cn/A6ZaBnIr
JVM内存模型调优实战:http://t.cn/A6wWMVqG
Spring入门到精通:https://t.cn/A6bFcDh4
大话设计模式之爱你:https://dwz.cn/wqO0MAy7