当前位置: 首页 > news >正文

EasyPOI 实战总结

EasyPOI实战总结

简介

easypoi功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员 就可以方便的写出Excel导出,Excel模板导出,Excel导入,Word模板导出,通过简单的注解和模板 语言(熟悉的表达式语法),完成以前复杂的写法

使用EasyPOI

环境搭建

# 1.引入相关依赖
<dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-base</artifactId><version>3.2.0</version>
</dependency><dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-web</artifactId><version>3.2.0</version>
</dependency><dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-annotation</artifactId><version>3.2.0</version>
</dependency>

在这里插入图片描述

相关注解

# 1.注解说明
- easypoi起因就是Excel的导入导出,最初的模板是实体和Excel的对应,model--row,filed--col 这样利用注解我们可以和容易做到excel到导入导出经过一段时间发展,现在注解有5个类分别是
  • @Excel 作用到filed上面,是对Excel一列的一个描述
  • @ExcelCollection 表示一个集合,主要针对一对多的导出,比如一个老师对应多个科目,科目就可以用集合表示
  • @ExcelEntity 表示一个继续深入导出的实体,但他没有太多的实际意义,只是告诉系统这个对象里面同样有导出的字段
  • @ExcelIgnore 和名字一样表示这个字段被忽略跳过这个导导出
  • @ExcelTarget 这个是作用于最外层的对象,描述这个对象的id,以便支持一个对象可以针对不同导出做出不同处理

@ExcelTarget

# 1.说明
- 用在实体类上标识是一个可以通过EasyPOI导入导出的实体类
- 相关属性:value:  		[String][定义id唯一标识,不能重复]    `常用`height: 		[Double][定义单元格高度]fontSize:		[short ][定义单元格字体大小]# 2.使用
@ExcelTarget("users")
public class User implements Serializable {//..... 省略属性 相关GET,SET方法
}

在这里插入图片描述


@Excel

# 1.说明
- 用在filed(属性)上面,是对Excel一列的一个描述
- 常用属性: name		 : 			 [String][生成Excel表格中列名]needMerge:			 [boolean][是否需要纵向合并单元格(用于含有list中,单个的单元格,合并list创建的多个row)]orderNum :       [String][指定生成Excel中列的顺序,按照数字自然顺序排序]savePath :       [String][指定导入Excel中图片的保存路径]type		 :       [String][导出类型 1 是文本 2 是图片,3 是函数,10 是数字 默认是文本]width    :			 [Double][指定导出Excel时列的宽度]isImportField:   [boolean][是否是导入字段,如果没有说明是错误的Excel]exportFormat:    [String][导出Excel的时间格式]importFormat:    [String][导入Excel的时间格式]format	 :       [String][相当于同时设置了exportFormat和importFormat]imageType:  		 [int   ][导出类型 1 从file读取 2 是从数据库中读取 默认是文件 同样导入也是一样的]suffix	 :       [String][文字后缀,如% 90 变成90%]
public class User implements Serializable {@Excel(name="编号",orderNum="1",replace = {"xxx_1","nnn_2"})private String id;@Excel(name="姓名",orderNum="2")private String name;@Excel(name="年龄",orderNum="4",suffix = " $")private Integer age;@Excel(name="生日",orderNum = "3",width = 20.0,exportFormat = "yyyy年MM月dd日")private Date bir;//...省略GET、SET方法
}

在这里插入图片描述


@ExcelEntity

# 1.说明
- 标记是不是导出excel 标记为实体类,一遍是一个内部属性类,标记是否继续穿透
- 常用属性:name: [String][定义唯一标识]
@ExcelTarget("users")
public class User implements Serializable {//... 省略GET SET和其他属性@ExcelEntity(name="身份信息")private Card card;
}@ExcelTarget("card")
public class Card  implements Serializable {@Excel(name="身份证号",orderNum = "6")private String id;@Excel(name="家庭住址",orderNum = "7")private String address;
}

在这里插入图片描述

在这里插入图片描述


@ExcelCollection

# 1.说明
- 一对多的集合注解,用以标记集合是否被数据以及集合的整体排序
- 常用属性:name		: 		[String][定义集合列名]orderNum:			[int][用来指定导出excel集合内列的顺序]type		:     [Class\<?>][用来指定导出是创建对象类型]
@ExcelTarget("users")
public class User implements Serializable {    //....省略GET SET其他属性@ExcelCollection(name="订单",orderNum = "5")private List<Order> orders;
}@ExcelTarget("orders")
public class Order implements Serializable {//....省略GET SET方法@Excel(name = "订单编号")private String id;@Excel(name = "订单名称")private String name;
}

在这里插入图片描述

在这里插入图片描述


@ExcelIgnore

# 1.说明
- 用在属性上,导出Excel时忽略这个属性

导出Excel

1.导出基本数据

注意:导出Excel的对象必须实现对象序列化接口

# 1.定义对象
@ExcelTarget("users")
public class User implements Serializable {@Excel(name="编号",orderNum="1",replace = {"xxx_1","nnn_2"})private String id;@Excel(name="姓名",orderNum="2")private String name;@Excel(name="年龄",orderNum="4",suffix = " $")private Integer age;@Excel(name="生日",orderNum = "3",width = 20.0,exportFormat = "yyyy年MM月dd日")private Date bir;//省略GET、SET方法。。。
}
# 2.定义测试数据
//测试数据 
public static List<User> getUsers(){List<User> users = new ArrayList<>();for (int i = 0; i < 10; i++) {User user = new User();user.setId(String.valueOf(i));user.setName("小陈");user.setAge(20+i);user.setBir(new Date());users.add(user);}return users;
}
# 3.导出Excel
Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("用户列表","测试"),User.class,getUsers());
FileOutputStream outputStream = new FileOutputStream("/Users/chenyannan/Desktop/aa.xls");
workbook.write(outputStream);
outputStream.close();
workbook.close();
# 4.查看Excel

在这里插入图片描述


2.导出指定字段

//@Excel(name="年龄",orderNum="4",suffix = " $")
@ExcelIgnore
private Integer age;

在这里插入图片描述

3.导出list集合

# 1.说明
- 往往有时候导出的对象中含有数组或者集合,需要导出这样的数据可以直接使用@Excel进行导出
@ExcelTarget("users")
public class User implements Serializable {@Excel(name="爱好",orderNum = "5",width = 20.0)private List<String> habbys;//....
}

在这里插入图片描述

# 2.说明
- 从上面运行结果可以看出,导出的格式默认是上述图片中格式,如果需要自定义导出格式怎么办?
- 自定义导出格式可以在对应的set方法中进行处理即可
@ExcelTarget("users")
public class User implements Serializable {@ExcelIgnore  //忽略原始list集合private List<String> habbys;@Excel(name="爱好",orderNum = "5",width = 20.0)private String habbysstr; //定义一个list集合字符串,用来存储集合数据public String getHabbysstr(){ //修改get方法StringBuilder sb = new StringBuilder();this.habbys.forEach(s->sb.append(s).append("、"));return sb.toString();}
}

在这里插入图片描述

# 3.导出查看结果

在这里插入图片描述


3.导出对象中含有对象

# 1.说明
- 导出对象中含有对象的Excel
@ExcelTarget("users")
public class User implements Serializable {@ExcelEntity(name="card") //定义对象private Card card;//.....
}@ExcelTarget("card")
public class Card  implements Serializable {@Excel(name="身份证号",orderNum = "6")private String id;@Excel(name="家庭住址",orderNum = "7")private String address;
}
# 2.为导出对象赋值
//测试数据
public static List<User> getUsers(){List<User> users = new ArrayList<>();for (int i = 0; i < 10; i++) {User user = new User();user.setId(String.valueOf(i));user.setName("小陈");user.setAge(20+i);user.setBir(new Date());user.setHabbys(Arrays.asList("看书","听歌","打篮球"));user.setCard(new Card("11000103422323212342","北京市朝阳区"));users.add(user);}return users;
}
# 3.导出Excel
Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("用户列表","测试"),User.class,getUsers());
FileOutputStream outputStream = new FileOutputStream("/Users/chenyannan/Desktop/aa.xls");
workbook.write(outputStream);
outputStream.close();
workbook.close();

在这里插入图片描述


4.导出一对多关系

# 1.说明
- 往往在业务比较复杂时,我们需要导出一对多关联关系处理,如 导出学生课程信息,导出用户的所有订单信息等等....
- 在Easypoi中如何处理一对多关系呢? 
@ExcelTarget("users")
public class User implements Serializable {//......@ExcelCollection(name="订单信息",orderNum="8")private List<Order> orders; //定义集合
}
@ExcelTarget("orders")
public class Order implements Serializable {@Excel(name = "订单编号")private String id;   @Excel(name = "订单名称")private String name;
}
# 2.测试数据
 //测试数据
public static List<User> getUsers(){List<User> users = new ArrayList<>();for (int i = 0; i < 10; i++) {User user = new User();user.setId(String.valueOf(i));user.setName("小陈");user.setAge(20+i);user.setBir(new Date());user.setHabbys(Arrays.asList("看书","听歌","打篮球"));user.setCard(new Card("11000103422323212342","北京市朝阳区"));user.setOrders(Arrays.asList(new Order("1","超短裙"), new Order("2","iphone X")));users.add(user);}return users;
}
# 3.导出Excel
Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("用户列表","测试"),User.class,getUsers());
FileOutputStream outputStream = new FileOutputStream("/Users/chenyannan/Desktop/aa.xls");
workbook.write(outputStream);
outputStream.close();
workbook.close();

在这里插入图片描述


5.导出图片

# 1.说明
- 往往随着业务不断变化,可能需要在导出excel时将图片信息也一并导出,如商品图标,用户头像信息等数据,这个时候easypoi该如何处理呢?
@ExcelTarget("users")
public class User implements Serializable {//.....@Excel(name="头像信息",type = 2,orderNum = "0",width = 12,height = 12)//type的值一定要指定为2private String photo;//定义头像 直接写指定图片路径
}
# 2.准备图片放入指定路径中,并在测试数据中进行赋值
//测试数据
public static List<User> getUsers(){List<User> users = new ArrayList<>();for (int i = 0; i < 10; i++) {User user = new User();user.setId(String.valueOf(i));user.setName("小陈");user.setAge(20+i);user.setBir(new Date());user.setHabbys(Arrays.asList("看书","听歌","打篮球")); //设置爱好user.setCard(new Card("11000103422323212342","北京市朝阳区"));//设置对象user.setOrders(Arrays.asList(new Order("1","超短裙"), new Order("2","iphone X")));//设置集合user.setPhoto("/Users/chenyannan/Desktop/1.jpeg");//设置头像users.add(user);}return users;
}

在这里插入图片描述

# 3.导出Excel查看结果

在这里插入图片描述


6.大数据量导出

# 1.说明
- 大数据导出是当我们的导出数量在几万,到上百万的数据时,一次从数据库查询这么多数据加载到内存然后写入会对我们的内存和CPU都产生压力,这个时候需要我们像分页一样处理导出分段写入Excel缓解Excel的压力
Workbook workbook1 = ExcelExportUtil.exportBigExcel(new ExportParams("用户列表", "测试"), User.class, getUsers());
workbook1.write(outputStream);
ExcelExportUtil.closeExportBigExcel();

注意:最好大量数据进行分页处理,每次导出数据最好不要超过1W条记录


导入Excel

1.导入基本数据

# 0.准备导入的目标Excel

在这里插入图片描述

# 1.定义导出数据基本对象
- 为了节省篇幅,一下代码统一忽略getter,setter
public class Student  implements Serializable {@Excel(name="编号")private String id;@Excel(name="姓名")private String name;@Excel(name="年龄")private Integer age;@Excel(name="生日",format = "yyyy年MM月dd日")private Date bir;
}

在这里插入图片描述

# 2.导入excel中数据
@Test
public void test(){//定义导入参数ImportParams importParams = new ImportParams();importParams.setTitleRows(1);//标题列占几行importParams.setHeadRows(1);//列名占几行//导出数据 餐数1:当如excel文件  参数2:导入对象的类型 参数3:导入参数配置List<Student> students = ExcelImportUtil.importExcel(new File("/Users/chenyannan/Desktop/student.xls"), Student.class,importParams);students.forEach(s-> System.out.println(s));
}
# 3.查看导入结果

在这里插入图片描述


2.导入小技巧

# 1.技巧说明
- 读取指定的sheet比如要读取上传得第二个sheet 那么需要把startSheetIndex = 1 就可以了- 读取几个sheet 比如读取前2个sheet,那么 sheetNum=2 就可以了- 读取第二个到第五个sheet设置 startSheetIndex = 1 然后sheetNum = 4- 读取全部的sheetsheetNum  设置大点就可以了- 判断一个Excel是不是合法的Excel importFields 设置下值,就是表示表头必须至少包含的字段,如果缺一个就是不合法的excel,不导入

3.带图片导入

# 0.准备数据

在这里插入图片描述

# 1.说明
- 有图片的导出就有图片的导入,导入的配置和导出是一样的,但是需要设置保存路径
public class Student  implements Serializable {@Excel(name="编号")private String id;@Excel(name="姓名")private String name;@Excel(name="年龄")private Integer age;@Excel(name="生日",format = "yyyy年MM月dd日")private Date bir;@Excel(name="头像信息",type = 2,savePath = "/Users/chenyannan/IdeaProjects/180codes/baizhimail/src/main/webapp")private String photo;
}

在这里插入图片描述

# 2.导入Excel
@Test
public void test(){//定义导入参数ImportParams importParams = new ImportParams();importParams.setTitleRows(1);importParams.setHeadRows(1);importParams.setImportFields(new String[]{"生日"});importParams.setNeedSave(false);//是否保存上传的excelimportParams.setSaveUrl("/Users/chenyannan/IdeaProjects/180codes/baizhimail/src/main/webapp");//导出数据 餐数1:当如excel文件  参数2:导入对象的类型 参数3:导入参数配置List<Student> students = ExcelImportUtil.importExcel(new File("/Users/chenyannan/Desktop/students.xls"), Student.class,importParams);students.forEach(s-> System.out.println(s));
}

在这里插入图片描述

# 3.测试导入结果

在这里插入图片描述


集成web实现导入导出

1.搭建springboot+mybatis项目环境

# 1.创建springboot项目

在这里插入图片描述

# 2.引入相关依赖
- mybatis
- mysql
- druid
- easypoi
- 引入thymelaf
<!--引入mybatis-->
<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.3</version>
</dependency>
<!--引入mysql-->
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.38</version>
</dependency>
<!--引入druid-->
<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.19</version>
</dependency>
<!--引入thymelaf-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--引入easypoi-->
<dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-base</artifactId><version>3.2.0</version>
</dependency>
<dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-web</artifactId><version>3.2.0</version>
</dependency>
<dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-annotation</artifactId><version>3.2.0</version>
</dependency>
# 3.编写配置文件
server.port=8989
spring.application.name=easypoispring.thymeleaf.cache=falsespring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/easypoi?characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=rootmybatis.mapper-locations=classpath:com/baizhi/mapper/*.xml
mybatis.type-aliases-package=com.baizhi.entity
# 4.创建包结构

在这里插入图片描述

# 5.启动项目检测环境搭建是否成功

在这里插入图片描述


2.开发测试页面

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>导入excel的主页面</title><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body><div class="container-fluid"><div class="row"><div class="col-md-12"><h1>选择Excel文件导入到数据中</h1><form action="" method="post" class="form-inline"><div class="form-group"><input class="form-control" type="file" name="excelFile"><input type="submit" class="btn btn-danger" value="导入数据"></div></form></div><div class="col-md-12"><h1>显示导入数据列表</h1><table class="table table-bordered" ><tr><th>编号</th><th>头像</th><th>姓名</th><th>年龄</th><th>生日</th></tr><tr><td>1</td><td><img src="" alt=""></td><td>小王</td><td>23</td><td>2012-12-12</td></tr><tr><td>1</td><td><img src="" alt=""></td><td>小王</td><td>23</td><td>2012-12-12</td></tr></table><hr><input type="button" class="btn btn-info" value="导出excel"></div></div></div>
</body>
</html>

在这里插入图片描述


3.查询所有

# 0.准备数据Excel

在这里插入图片描述

# 1.根据Excel抽取库表结构
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for t_user
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (`id` int(6) NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,`bir` timestamp NULL DEFAULT NULL,`photo` varchar(150) DEFAULT NULL,`habbys` varchar(100) DEFAULT NULL,`cardno` varchar(18) DEFAULT NULL,`address` varchar(60) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;SET FOREIGN_KEY_CHECKS = 1;
# 2.创建实体类
@Data
@ExcelTarget("users")
public class User implements Serializable {@Excel(name="编号")private String id;@Excel(name="姓名")private String name;@Excel(name="生日",format = "yyyy年MM月dd日")private Date bir;@Excel(name="头像信息",type = 2,savePath = "/Users/chenyannan/IdeaProjects/180codes/easypoi/src/main/resources/static/imgs")private String photo;@Excel(name="爱好",width = 12.0)private String habbys;@Excel(name="身份证号",width = 15.0)private String cardno;@Excel(name="家庭住址",width = 15.0)private String address;
}
# 3.创建DAO接口
@Mapper
public interface UserDAO {//查询所有List<User> findAll();
}
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.baizhi.dao.UserDAO"><!--查询所有--><select id="findAll" resultType="User">select id,name,bir,photo,habbys,cardno,address from t_user</select>
</mapper>
# 4.创建Service接口&实现
public interface UserService {List<User> findAll();
}
@Service
@Transactional
public class UserServiceImpl implements UserService {@Autowiredprivate UserDAO userDAO;@Overridepublic List<User> findAll() {return userDAO.findAll();}
}
# 5.创建Controller完成查询所有
@Controller
@RequestMapping("/user")
@Slf4j
public class UserController {@Autowiredprivate UserService userService;//查询所有@RequestMapping("/findAll")public String findAll(HttpServletRequest request){List<User> users = userService.findAll();request.setAttribute("users",users);return "index";}
}
# 6.修改index.html展示所有数据

引入thymeleaf语法解析:<html lang="en" xmlns:th="http://www.thymeleaf.org">

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>导入excel的主页面</title><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body><div class="container-fluid"><div class="row"><div class="col-md-12"><h1>选择Excel文件导入到数据中</h1><form th:action="@{/user/import}" method="post" enctype="multipart/form-data" class="form-inline"><div class="form-group"><input class="form-control" type="file" name="excelFile"><input type="submit" class="btn btn-danger" value="导入数据"></div></form></div><div class="col-md-12"><h1>显示导入数据列表</h1><table class="table table-bordered" ><tr><th>编号</th><th>头像</th><th>姓名</th><th>生日</th><th>爱好</th><th>身份证号</th><th>家庭住址</th></tr><tr th:each="user : ${users}"><td th:text="${user.id}"></td><td><img th:src="${'/imgs/'+ user.photo}" height="60px" alt=""></td><td th:text="${user.name}"></td><td th:text="${#dates.format(user.bir,'yyyy-MM-dd')}"></td><td th:text="${user.habbys}"></td><td th:text="${user.cardno}"></td><td th:text="${user.address}"></td></tr></table><hr><a th:href="@{/user/export}" class="btn btn-info">导出excel</a></div></div></div></body>
</html>

在这里插入图片描述

# 7.启动项目进行访问

在这里插入图片描述


4.导入数据

# 1.开发DAO&Mapper
@Mapper
public interface UserDAO {//查询所有List<User> findAll();//插入记录void save(User user);
}

在这里插入图片描述

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.baizhi.dao.UserDAO"><!--查询所有--><select id="findAll" resultType="User">select id,name,bir,photo,habbys,cardno,address from t_user</select><!--插入记录--><insert id="save" parameterType="User" useGeneratedKeys="true" keyProperty="id">insert into t_user values (#{id},#{name},#{bir},#{photo},#{habbys},#{cardno},#{address})</insert>
</mapper>

在这里插入图片描述

# 2.开发Service接口和实现类
public interface UserService {//查询所有List<User> findAll();//批量保存void saveAll(List<User> users);
}

在这里插入图片描述

@Service
@Transactional
public class UserServiceImpl implements UserService {@Autowiredprivate UserDAO userDAO;@Overridepublic List<User> findAll() {return userDAO.findAll();}@Overridepublic void saveAll(List<User> users) {users.forEach(user -> {user.setId(null);user.setPhoto(user.getPhoto().substring(user.getPhoto().lastIndexOf("/")+1));userDAO.save(user);});}}

在这里插入图片描述

# 3.开发controller
//导入excel
@RequestMapping("/import")
public String importExcel(MultipartFile excelFile) throws Exception {log.info("文件名称: [{}]",excelFile.getOriginalFilename());ImportParams params = new ImportParams();params.setTitleRows(1);//设置一级标题行为1行params.setHeadRows(1);//设置header标题为1行List<User> users = ExcelImportUtil.importExcel(excelFile.getInputStream(), User.class, params);log.info("导入总数为: [{}]", users.size());userService.saveAll(users);return "redirect:/user/findAll";
}

在这里插入图片描述

# 4.编辑页面index.html
- 表单提交方式必须是post
- 表单的enctype必须为multipart/form-data
<form th:action="@{/user/import}" method="post" enctype="multipart/form-data" class="form-inline"><div class="form-group"><input class="form-control" type="file" name="excelFile"><input type="submit" class="btn btn-danger" value="导入数据"></div>
</form>

在这里插入图片描述

# 5.启动项目导入Excel数据

在这里插入图片描述


5.导出数据

# 1.开发Controller
//导出excel
@RequestMapping("/export")
public void exportExcel(HttpServletResponse response,HttpServletRequest request) throws IOException {List<User> users = userService.findAll();users.forEach(user -> {try {Excel excelAnn = user.getClass().getDeclaredField("photo").getAnnotation(Excel.class);user.setPhoto(excelAnn.savePath()+'/'+user.getPhoto());} catch (NoSuchFieldException e) {e.printStackTrace();}});Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("用户列表", "用户信息"), User.class, users);response.setHeader("content-disposition","attachment;fileName="+ URLEncoder.encode("用户列表.xls","UTF-8"));ServletOutputStream os = response.getOutputStream();workbook.write(os);os.close();workbook.close();
}
# 2.编辑index.html页面

在这里插入图片描述

# 3.启动项目测试excel导出

在这里插入图片描述

在这里插入图片描述


相关文章:

EasyPOI 实战总结

EasyPOI实战总结 简介 easypoi功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员 就可以方便的写出Excel导出,Excel模板导出,Excel导入,Word模板导出,通过简单的注解和模板 语言(熟悉的表达式语法),完成以前复杂的写法 使用EasyPOI 环境搭建 # 1.引入相关依…...

【LeetCode-困难题】42. 接雨水

题目 题解一&#xff1a;暴力双重for循环&#xff08;以行计算水量&#xff09; 1.先找出最高的柱子有多高&#xff08;max 3&#xff09; 2.然后第一个for为行数&#xff08;1&#xff0c;2&#xff0c;3&#xff09; 3.第二个for计算每一行的雨水量&#xff08;关键在于去除…...

npm install 安装依赖,报错 Host key verification failed

设置 git 的身份和邮箱 git config --global user.name "你的名字" > 用户名 git config --global user.email “你的邮箱" > 邮箱进入 > 用户 > [你的用户名] > .ssh文件夹下,删除 known_hosts 文件即可 进入之后有可能会看到 known_hosts…...

SOLIDWORKS焊件是什么?

SOLIDWORKS是一款广泛应用于机械设计领域的三维计算机辅助设计软件。SOLIDWORKS提供了强大的焊件功能&#xff0c;可以帮助工程师们以更高的效率设计焊接件。本文将介绍SOLIDWORKS焊件的概念、特点以及使用方法&#xff0c;以期帮助读者更好地理解和应用这一关键技术。 SOLIDWO…...

2023国赛数学建模D题思路模型代码 高教社杯

本次比赛我们将会全程更新思路模型及代码&#xff0c;大家查看文末名片获取 之前国赛相关的资料和助攻可以查看 2022数学建模国赛C题思路分析_2022国赛c题matlab_UST数模社_的博客-CSDN博客 2022国赛数学建模A题B题C题D题资料思路汇总 高教社杯_2022国赛c题matlab_UST数模社…...

git协议实现管理(三个步骤)

GitHub官网访问&#xff1a; https://github.com/dashboard 初次使用git的用户要使用git协议大概需要三个步骤: 一、生成密钥对 二、设置远程仓库(本文以github为例)上的公钥 三、把git的remote url远程仓库URL可访问路径修改为git协议(以上两个步骤初次设置过以后&#xff0c…...

“深入理解JVM:探索Java虚拟机的内部机制“

标题&#xff1a;深入理解JVM&#xff1a;探索Java虚拟机的内部机制 摘要&#xff1a; Java虚拟机&#xff08;Java Virtual Machine&#xff0c;JVM&#xff09;是Java语言的核心&#xff0c;负责将Java源代码编译成可执行的字节码并运行。本篇博客将深入探索JVM的内部机制&a…...

Unity——各种特效的基本使用方法

特效是游戏制作不可或缺的一环&#xff0c;作为游戏开发者最重要的工作就是将特效添加到游戏中&#xff0c;并在合适的时机、合适的位置将特效播放出来&#xff0c;同时还要注意特效的管理和销毁。 某些种类的特效&#xff0c;如动效、贴花&#xff0c;还要编写脚本代码以实现…...

smiley-http-proxy-servlet 实现springboot 反向代理,结合项目鉴权,安全的引入第三方项目服务

项目中反向代理 集成第三方的服务接口或web监控界面&#xff0c;并实现与自身项目相结合的鉴权方法 依赖 smiley-http-proxy-servlet GitHub链接 2.0 版开始&#xff0c;代理切换到jakarta servlet-api<!--HTTP 代理 Servlet--><dependency><groupId>org.mit…...

(vue)多级表头且转为百分比显示

(vue)多级表头且转为百分比显示 <el-table-column align"center" label"近三个月数据情况"><el-table-column align"center" prop"amount" :label"tableLast[0]"><template slot-scope"{ row }"&g…...

Linux下C++开发

Linux下C开发 Linux 系统介绍 简介 Linux属于多用户多任务操作系统&#xff0c;而Windows属于单用户多任务操作系统Linux一切皆文件目录结构 bin 存储二进制可执行文件dev 存放的是外接设备&#xff0c;例如磁盘&#xff0c;光盘等。在其中的外接设备是不能直接被使用的&…...

GPT-3.5——从 人工智障 到 大人工智障

有人说&#xff0c;GPT是从人工智障到人工智能的蜕变&#xff0c;但是。。。 我认为&#xff0c;GPT是从 人工智障 到 大人工智障 的退化。。。 从 人工智障 到 大人工智障 GPT-3.5学术介绍No.1---- 西红柿炒钢丝球基本信息详细制作方法材料步骤 幕后花絮 No.2---- 顶尖数学家…...

创建型(四) - 原型模式

一、概念 原型模式&#xff08;Prototype Pattern&#xff09;&#xff1a;利用对已有对象&#xff08;原型&#xff09;进行复制&#xff08;或者叫拷贝&#xff09;的方式来创建新对象&#xff0c;以达到节省创建时间的目的。 使用场景&#xff1a;如果对象的创建成本比较大…...

ABAP 定义复杂的数据结构

最近有个需求是实现ABAP数据类型与JASON类型的转换。想要创建个ABAP的数据类型来接JASON类型是个挺麻烦的事。例如下面这个JASON数据&#xff0c;是个很简单的数据结构。但对ABAP来说有4层了&#xff0c;就有点复杂了。 不过ABAP的数据类型也是支持直接定义数据结构的嵌套的。如…...

HCIP第四节-----------------------------BGP

一、BGP基础 1、BGP得概述 &#xff08;1&#xff09;、AS OSPF、IS-IS等IGP路由协议在组织机构网络内部广泛应用&#xff0c;随着网络规模扩大&#xff0c;网络中路由数量不断增长&#xff0c;IGP已无法管理大规模网络&#xff0c;AS的概念由此诞生。 AS指的是在同一个组织…...

Temu闯关日韩受挫?跨境电商卖家如何打磨好营销链路

海外版拼多多 Temu 先后在日本和韩国上线&#xff0c;然而效果不似预期&#xff0c;日韩市场对这套“低价补贴”策略并不买账。作为一个尚未被日韩消费者熟悉的网站&#xff0c;其价格之便宜无法让消费者信任。除此之外更大的问题是&#xff0c;在日本卷不过线下零售与百元店&a…...

console的几个常用用法

console.log() 其一、主要表示&#xff1a;向 Web 控制台输出一条消息; 其二、而具体是什么信息就以传递的实参为准&#xff0c;然后就是在控制台就能显示自己传递参数的结果&#xff1b; console.log([1,3,5,7]) // 输出 [1, 3, 5, 7] console.log({}) // 输出 {} conso…...

服务器数据恢复-HP EVA存储VDISK被删除的数据恢复案例

服务器数据恢复环境&#xff1a; 某单位有一台HP EVA存储&#xff0c;连接2组扩展柜&#xff0c;扩展柜中有12块FATA磁盘和10块FC磁盘&#xff0c;不确定数量的LUN&#xff0c;主机安装WINDOWS SERVER操作系统&#xff0c;存储设备用来存放该单位的重要资料。 服务器故障初检&…...

(搜索) 剑指 Offer 13. 机器人的运动范围 ——【Leetcode每日一题】

❓剑指 Offer 13. 机器人的运动范围 难度&#xff1a;中等 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动&#xff0c;它每次可以向左、右、上、下移动一格&#xff08;不能移动到方格外&#xff09;&…...

Java并发编程之线程池详解

目录 &#x1f433;今日良言:不悲伤 不彷徨 有风听风 有雨看雨 &#x1f407;一、简介 &#x1f407;二、相关代码 &#x1f43c;1.线程池代码 &#x1f43c;2.自定义实现线程池 &#x1f407;三、ThreadPoolExecutor类 &#x1f433;今日良言:不悲伤 不彷徨 有风听风 有…...

开源数据库Mysql_DBA运维实战 (总结)

开源数据库Mysql_DBA运维实战 &#xff08;总结&#xff09; SQL语句都包含哪些类型 DDL DCL DML DQL Yum 安装MySQL的配置文件 配置文件&#xff1a;/etc/my.cnf日志目录&#xff1a;/var/log/mysqld.log错误日志&#xff1a;/var/log/mysql/error.log MySQL的主从切换 查看主…...

图神经网络与分子表征:1. 分子图和图神经网络基础

CSDN的朋友们大家好&#xff0c;好久没写系列文章了。 近期读了很多图神经网络&#xff08;GNN&#xff09;和分子表征&#xff08;molecular representation&#xff09;的论文&#xff0c;正好最近不是很忙&#xff0c;所以我决定把自己的学习过程记录下来&#xff0c;与大家…...

Spring Boot与Redisson的整合。分布式锁

Spring Boot与Redisson的整合可以帮助您在Spring Boot应用程序中使用分布式锁、缓存等功能。下面是一些基本步骤来整合Spring Boot与Redisson&#xff1a; 添加Maven/Gradle依赖&#xff1a; 在您的Spring Boot项目的pom.xml&#xff08;Maven&#xff09;或build.gradle&#…...

Lua中逻辑运算符and,or,not 区别与用法

在Lua中&#xff0c;逻辑运算符包括 and、or 和 not。它们用于对布尔值进行逻辑运算。 and运算符&#xff1a; 当同时满足两个表达式时&#xff0c;返回第二个表达式的值&#xff1b;否则&#xff0c;返回第一个表达式的值。如果第一个表 达式的值为false或nil&#xff0c;则…...

使用 spaCy 增强 NLP 管道

介绍 spaCy 是一个用于自然语言处理 (NLP) 的 Python 库。SpaCy 的 NLP 管道是免费且开源的。开发人员使用它来创建信息提取和自然语言理解系统,例如 Cython。使用该工具进行生产,拥有简洁且用户友好的 API。 如果您处理大量文本,您会想了解更多相关信息。例如,它是关于什…...

【HCIP】08.ISIS中间系统

链路状态协议&#xff0c;传递LSA信息ISIS基于数据链路层封装在OSI时&#xff0c;也有自己的网络层地址和自己的路由协议&#xff0c;即ISIS。之前的ISIS支持OSI的网络层地址&#xff0c;是为OSI中的CLNP&#xff08;无连接网络协议&#xff09;网络设计的路由协议&#xff0c;…...

Android 13 Framework 添加自定义的系统服务CustomService

目的: 添加自定义的系统服务,在自定义的服务中开发定制的API接口和功能,独立于系统核心服务,方便开发和维护。 开发环境:Android 13 MTK平台 涉及修改的文件如下 device/mediatek/sepolicy/base/private/service_contexts device/mediatek/sepolicy/base/vendor/platfo…...

前端食堂技术周刊第 95 期:Fresh 1.4、Rollup 迁移至 SWC计划、RSC Devtools、使用开源库的边界、AI 帮你讲论文

美味值&#xff1a;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f; 口味&#xff1a;冰葡美式 食堂技术周刊仓库地址&#xff1a;https://github.com/Geekhyt/weekly 大家好&#xff0c;我是童欧巴。欢迎来到前端食堂技术周刊&#xff0c;我们先来看下…...

【TypeScript】枚举类型

在 TypeScript 中&#xff0c;枚举&#xff08;Enum&#xff09;是一种用于定义命名常量集合的数据类型。枚举使代码更加可读和可维护&#xff0c;因为它们为一组具有语义的值提供了命名。 以下是 TypeScript 中枚举的基本用法和特点&#xff1a; // 声明一个枚举 enum Direc…...

快速通过华为HCIP认证

你可以按照以下步骤进行准备和学习&#xff1a; 华为认证课程和资料--提取码:1234https://pan.baidu.com/s/1YJhD8QbocHhZ30MvrKm8hg 了解认证要求&#xff1a;查看华为官方网站上的HCIP认证要求和考试大纲&#xff0c;了解考试的内容、考试形式和考试要求。 学习相关知识&am…...

派森 #P124. 公式计算

描述 输入数正整数m&#xff0c;输出0! 1! ...m!的计算结果。 样例 输入 5 输出 154 代码&#xff1a; m int(input()) result 1 factorial 1 for i in range(1, m 1):factorial * iresult factorial print(result) # 法2def factorial(n):"""计…...

opencv进阶14-Harris角点检测-cv2.cornerHarris

类似于人的眼睛和大脑&#xff0c;OpenCV可以检测图像的主要特征并将这 些特征提取到所谓的图像描述符中。然后&#xff0c;可以将这些特征作为数据 库&#xff0c;支持基于图像的搜索。此外&#xff0c;我们可以使用关键点将图像拼接起 来&#xff0c;组成更大的图像。&#x…...

JVM中对象和GC Root之间的四种引用关系

1. 强引用 只有所有 GC Roots 对象都不通过【强引用】引用该对象&#xff0c;该对象才能被垃圾回收 由GC Root直接new出来的对象是强引用&#xff0c;只有当GC Root不再引用该对象的时候&#xff0c;才会被回收 例子&#xff1a; List<String> list new ArrayList<&…...

【李宏毅机器学习】注意力机制

输出 我们会遇到不同的任务&#xff0c;针对输出的不一样&#xff0c;我们对任务进行划分 给多少输出多少 给一堆向量&#xff0c;输出一个label&#xff0c;比如说情感分析 还有一种任务是由机器决定的要输出多少个label&#xff0c;seq2seq的任务就是这种&#xff0c;翻译也…...

Nginx使用keepalived配置VIP

VIP常用于负载均衡的高可用&#xff0c;使用VIP可以给多个主机绑定一个IP&#xff0c;这样&#xff0c;当某个负载应用挂了之后&#xff0c;可以自动切到另一个负载。 我这里是在k8s环境中做的测试&#xff0c;集群中有6个节点&#xff0c;我给140和141两个节点配置VIP。 1. 安…...

C语言编写图形界面

文章目录 环境使用库基础概念句柄 程序的入口创建窗口定义窗口类注册窗口类创建窗口 完整代码运行效果 环境 使用的是VSCode MinGW&#xff1b; 使用库 我们使用windows.h库来实现图形化界面。 头文件如下&#xff1a; #include <windows.h>windows.h是 Windows 操作…...

K8s学习笔记3

Kubernetes功能&#xff1a; Kubernetes是一个轻便的可扩展的开源平台&#xff0c;用于管理容器化应用和服务。通过Kubernetes能够进行应用的自动化部署和扩缩容。在Kubernetes中&#xff0c;会将组成应用的容器组合成一个逻辑单元以更易管理和发现。Kubernetes积累了作为Goog…...

ceph集群的扩容缩容

文章目录 集群扩容添加osd使用ceph-deploy工具手动添加 添加节点新节点前期准备新节点安装ceph&#xff0c;出现版本冲突 ceph-deploy增加节点 集群缩容删除osd删除节点 添加monitor节点删除monitor节点使用ceph-deploy卸载集群 实验所用虚拟机均为Centos 7.6系统&#xff0c;8…...

gremlin安装使用 详细步骤

gremlin是一个图数据库查询工具&#xff0c;注意他只是一个工具类似于dbeaver&#xff0c;navicat&#xff0c;sqlyog&#xff0c;是专门来分析图数据库的一个工具。 下载 下载地址Apache Download Mirrors 省事的可以直接 wget https://www.apache.org/dyn/closer.lua/tin…...

Java语言怎么编写一个程序计算出租车的运输费用:出租车起步15公里以内20块钱,需要支付调头费用

下面是一个Java语言编写的计算出租车运输费用的程序&#xff1a; java import java.util.Scanner; public class TaxiFareCalculator { public static void main(String[] args) { Scanner input new Scanner(System.in); System.out.print("请输入出租车行驶的里程&…...

十、flume的安装

1.解压 2.改名 3.修改权限 4.编辑环境变量并source export FLUME_HOME/usr/local/flume export PATH$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$HIVE_HOME/bin:$HBASE_HOME/bin:$SQOOP_HOME/bin:$PIG_HOME/bin:$FLUME_HOME/bin 5.配置 6.查看版本 7.启动Hadoo…...

互联网广告及产品变现认知分析整理

深入学习互联网广告及产品&#xff0c;并且高效利用这一模式进行变现。 字节先是建立了一个非常强大的用户产品——抖音&#xff0c;通过各种渠道让抖音快速成长起来&#xff0c;收获了一大批初始用户。有了用户基础之后&#xff0c;字节开始打造它的广告产品&#xff0c;逐渐…...

item_search_img-按图搜索淘宝商品(拍立淘)

一、接口参数说明&#xff1a; item_search_img-按图搜索淘宝商品&#xff08;拍立淘&#xff09;&#xff0c;点击更多API调试&#xff0c;请移步注册API账号点击获取测试key和secret 公共参数 请求地址: https://api-gw.onebound.cn/taobao/item_search_img 名称类型必须描…...

OWASP Top 10(2021)漏洞学习(最新)

A01:2021-权限控制失效 从第五位上升到第一位&#xff0c;94%的应用程序都接受了某种形式的针对“失效的访问控制”的测试&#xff0c;该事件的 平均发生率为 3.81%&#xff0c;该漏洞在提供的数据集中出现漏洞的应用数量最多&#xff0c;总发生漏洞应用数量超过31.8万多 次。 …...

mysql 、sql server 游标 cursor

游标 声明的位置 游标必须在声明处理程序之前被声明&#xff0c;并且变量和条件还必须在声明游标或处理程序之前被声明 游标的使用步骤 声明游标打开游标使用游标关闭游标 &#xff08;sql server 关闭游标和释放游标&#xff09; sql server 游标 declare my_cursor curs…...

dockers搭建基本服务

1、使用mysql:5.6和 owncloud 镜像&#xff0c;构建一个个人网盘。 拉取mysql-5.6和owncloud的镜像 docker run -d --name mdb --env MYSQL_ROOT_PASSWORD123 cytopia/mysql-5.6 docker run -d -p 90:80 --name webdcloud --link mdb:mdb owncloud 注册的时候&#xff0c;数据…...

微信小程序纯前端从阿里云OSS下载json数据-完整版

起因 因为云开发开始收费(貌似很久了),准备改造在以前的小程序,数据转到oss上,小程序使用原生,不算专业领域, 所以先百度.... 网上的教程真的是千篇一律,大部分开局就是require(ali-oss); 好点的npm install ali-oss --save开局,拼凑操作到最后发现要用云开发,因为云…...

【微服务实战】01-工程结构概览

文章目录 工程结构概览:定义应用分层及依赖关系1.应用分层2.定义Entity3.仓储层3.1 工作单元&#xff1a;事务管理3.2 仓储层 4.领域事件5.APIController最佳实践 工程结构概览:定义应用分层及依赖关系 1.应用分层 领域模型层基础设施层 ⇒ 仓储应用层 ⇒ Api、后台任务Job共…...

论文导读|European Journal of Operational Research近期文章精选:旅行商问题专题

推文作者&#xff1a;王松阁 编者按 在“European Journal of Operational Research近期论文精选”中&#xff0c;我们有主题、有针对性地选择了European Journal of Operational Research中一些有趣的文章&#xff0c;不仅对文章的内容进行了概括与点评&#xff0c;而且也对文…...

playwright迭代元素

DOM结构 <ul><li>apple</li><li>banana</li><li>orange</li> </ul>迭代元素操作 通过 page.get_by_role("listitem") 会匹配到 apple, banana, orange&#xff0c; 如果要对这一组数据中的每个元素进行操作&#…...