前面博主介绍了如何通过JXLS模板导出excel,如何通过POI直接导出excel;这里再介绍一种导出excel的方式:使用JueYue封装的工具类---Easypoi导出excel。
软硬件环境:Windows10、IntelliJ IDEA、SpringBoot 2.1.1.RELEASE
cn.afterturn
easypoi-base
3.1.0
cn.afterturn
easypoi-web
3.1.0
cn.afterturn
easypoi-annotation
3.1.0
/**
* 直接导出(无需模板)
* 注:此方式存在一些不足之处,在对性能、excel要求比较严格时不推荐使用
*
* @author JustryDeng
* @date 2018/12/5 11:44
*/
@Test
public void directExportExcel() throws IOException {
// Map作为每一行的数据容器,List作为行的容器
List
运行测试函数,成功导出excel:
导出的excel内容为:
相关的SchoolVO模型为:
import cn.afterturn.easypoi.excel.annotation.Excel;
/**
* 学校模型
*
* @author JustryDeng
* @date 2018/12/8 17:12
*/
public class SchoolVO {
/** 学校名称 */
@Excel(name = "学校名称", orderNum = "6", width = 20)
private String schoolName;
/** 学校地址 */
@Excel(name = "学校地址", orderNum = "8", width = 20)
private String schoolAddress;
public String getSchoolName() {
return schoolName;
}
public void setSchoolName(String schoolName) {
this.schoolName = schoolName;
}
public String getSchoolAddress() {
return schoolAddress;
}
public void setSchoolAddress(String schoolAddress) {
this.schoolAddress = schoolAddress;
}
@Override
public String toString() {
return "SchoolVO{schoolName='" + schoolName + "', schoolAddress='" + schoolAddress + "'}";
}
}
相关的StudentVO模型为:
import cn.afterturn.easypoi.excel.annotation.Excel;
import java.util.Date;
/**
* Student数据模型
*
* @author JustryDeng
* @date 2018/12/5 9:35
*/
public class StudentVO extends SchoolVO {
/**
* name指定导出excel时生成的列名
* orderNum可指定导出的该属性对应的所在列的位置
* width设置单元格宽度
* type设置导出类型 1是文本, 2是图片, 3是函数,10 数字 默认是文本
*/
@Excel(name = "学号", orderNum = "1", type = 10, width = 15)
private String studentID;
@Excel(name = "姓名", orderNum = "2", width = 15)
private String name;
/**
* 当gender为1时,导出的结果为 男, 当gender为0时,导出的结果为 女
* mergeVertical设置是否纵向合并列
*/
@Excel(name = "性别",mergeVertical = true, replace = {"男_1", "女_0"},orderNum = "3", width = 5)
private Integer gender;
/**
* type设置导出类型 1是文本, 2是图片, 3是函数,10 数字 默认是文本
*/
@Excel(name = "年龄",orderNum = "4", type = 10, width = 5)
private int age;
/**
* 将Data日期导出为yyyy-MM-dd格式
* mergeVertical设置是否纵向合并列
* mergeRely设置合并列的前提条件,即:只有当索引为2的列(即:"性别"列)已经
* 合并了时,那么此时这一列的纵向相同时,才能纵向合并;如果引为2的
* 列(即:"性别"列)纵向数据不同,那么就算此列的纵向数据相同,那么
* 也不会合并
*/
@Excel(name = "入校时间",mergeVertical = true, mergeRely = {2}, format = "yyyy-MM-dd", orderNum = "5", width = 20)
private Date entranceTime;
@Excel(name = "班级",orderNum = "7", width = 15)
private String className;
/**
* 无参构造
*/
public StudentVO() {
}
/**
* 全参构造
*/
public StudentVO(String studentID, String name, Integer gender,
int age, Date entranceTime, String className) {
this.studentID = studentID;
this.name = name;
this.gender = gender;
this.age = age;
this.entranceTime = entranceTime;
this.className = className;
}
public String getStudentID() {
return studentID;
}
public void setStudentID(String studentID) {
this.studentID = studentID;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getGender() {
return gender;
}
public void setGender(Integer gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public Date getEntranceTime() {
return entranceTime;
}
public void setEntranceTime(Date entranceTime) {
this.entranceTime = entranceTime;
}
@Override
public String toString() {
return "StudentVO{studentID='" + studentID + "', name='" + name + "', gender='"
+ gender + "', age=" + age + ", entranceTime=" + entranceTime
+ ", className='" + className + "'}";
}
}
导出excel的测试方法为:
/**
* 对象---直接导出(无需模板)
*
* 注:如果模型 的父类的属性也有@Excel注解,那么导出excel时,会连该模型的父类的属性也一会儿导出
*
* @author JustryDeng
* @date 2018/12/5 11:44
*/
@Test
public void directExportExcelByObject() throws IOException {
List list = new ArrayList<>(16);
StudentVO student;
Random random = new Random();
for (int i = 0; i < 10; i++) {
student = new StudentVO(i + "",
"name" + i,
random.nextInt(2),
random.nextInt(100),
new Date(),
"className" + i);
student.setSchoolName("学校名称" + i);
student.setSchoolAddress("学校地址" +i);
list.add(student);
}
ExportParams exportParams = new ExportParams();
exportParams.setSheetName("我是sheet名字");
// 生成workbook 并导出
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, StudentVO.class, list);
File savefile = new File("C:/Users/JustryDeng/Desktop/");
if (!savefile.exists()) {
boolean result = savefile.mkdirs();
System.out.println("目录不存在,创建" + result);
}
FileOutputStream fos = new FileOutputStream("C:/Users/JustryDeng/Desktop/student.xls");
workbook.write(fos);
fos.close();
}
运行测试函数,成功导出excel:
导出的excel内容为:
模板为:
注:本文末尾,会简单介绍一下模板语法。
模板位置在:
注:两个模板的内容是一样的,只是一个是xls,一个是xlsx,任选其一即可。
导出excel的测试方法为:
/**
* 模板导出---Map组装数据
*
* 注:.xls的模板可以导出.xls文件,也可以导出xlsx的文件;
* 同样的, .xlsx的模板可以导出.xls文件,也可以导出xlsx的文件;
*
* @author JustryDeng
* @date 2018/12/5 11:44
*/
@Test
public void templateExportExcelByMap() throws IOException {
// 加载模板
TemplateExportParams params = new TemplateExportParams("templates/templateMap.xls");
Map map = new HashMap<>(16);
map.put("title", "全亚洲,最帅气人员名单");
map.put("date", "2018-12-05");
map.put("interviewer", "JustryDeng");
List
运行测试函数,成功导出excel:
导出的excel内容为:
模板为:
注:本文末尾,会简单介绍一下模板语法。
模板位置在:
注:两个模板的内容是一样的,只是一个是xls,一个是xlsx,任选其一即可。
相关模型有HandsomeBoyPOJO:
/**
* 具体信息 模型
*
* @author JustryDeng
* @date 2018/12/5 16:57
*/
public class HandsomeBoyPOJO {
/** 姓名 */
private String name;
/** 性别 */
private String gender;
/** 年龄 */
private int age;
/** 爱好 */
private String hobby;
/** 帅气值 */
private String handsomeValue;
/** 座右铭 */
private String motto;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getHobby() {
return hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
public String getHandsomeValue() {
return handsomeValue;
}
public void setHandsomeValue(String handsomeValue) {
this.handsomeValue = handsomeValue;
}
public String getMotto() {
return motto;
}
public void setMotto(String motto) {
this.motto = motto;
}
@Override
public String toString() {
return "HandsomeBoyPOJO{name='" + name + "', gender='" + gender + "', age=" + age
+ ", hobby='" + hobby + "', handsomeValue='" + handsomeValue + "', motto='" + motto + "'}";
}
}
相关模型有ResultPOJO:
/**
* 采访结果 模型
*
* @author JustryDeng
* @date 2018/12/5 17:01
*/
public class ResultPOJO {
/** 标题 */
private String title;
/** 日期 */
private String date;
/** 采访人 */
private String interviewer;
/** 信息集合 */
private List list;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getInterviewer() {
return interviewer;
}
public void setInterviewer(String interviewer) {
this.interviewer = interviewer;
}
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
@Override
public String toString() {
return "ResultPOJO{title='" + title + "', date='" + date + "', interviewer='" + interviewer
+ "', list=" + list + '}';
}
}
导出excel的测试方法为:
/**
* 模板导出---对象组装数据
*
* 注:实际上仍然是"模板导出---Map组装数据",不过这里借助了工具类,将对象先转换为了Map
*
* 注:.xls的模板可以导出.xls文件,也可以导出xlsx的文件;
* 同样的, .xlsx的模板可以导出.xls文件,也可以导出xlsx的文件;
*
* @author JustryDeng
* @date 2018/12/5 11:44
*/
@Test
public void templateExportExcelByObject() throws IOException, IllegalAccessException {
// 加载模板
TemplateExportParams params = new TemplateExportParams("templates/templateObject.xlsx");
// 组装数据
ResultPOJO resultPOJO = new ResultPOJO();
resultPOJO.setTitle("全亚洲最帅人员名单");
resultPOJO.setInterviewer("邓沙利文");
resultPOJO.setDate("2018-12-05");
List list = new ArrayList<>(8);
resultPOJO.setList(list);
HandsomeBoyPOJO handsomeBoyPOJO;
for (int i = 0; i < 5; i++) {
handsomeBoyPOJO = new HandsomeBoyPOJO();
handsomeBoyPOJO.setAge(20 + i);
handsomeBoyPOJO.setGender(i % 2 == 0 ? "女" : "男");
handsomeBoyPOJO.setHandsomeValue(95 + i + "(满分100分)");
handsomeBoyPOJO.setHobby("女。。。。");
handsomeBoyPOJO.setMotto("我是一只小小小小鸟~");
handsomeBoyPOJO.setName("JustryDeng");
list.add(handsomeBoyPOJO);
}
// 生成workbook 并导出
Workbook workbook = ExcelExportUtil.exportExcel(params, objectToMap(resultPOJO));
File savefile = new File("C:/Users/JustryDeng/Desktop/");
if (!savefile.exists()) {
boolean result = savefile.mkdirs();
System.out.println("目录不存在,进行创建,创建" + (result ? "成功!" : "失败!"));
}
FileOutputStream fos = new FileOutputStream("C:/Users/JustryDeng/Desktop/templateObjectResult.xls");
workbook.write(fos);
fos.close();
}
/**
* 对象转换为Map的工具类
*
* @param obj
* 要转换的对象
* @return map
* @throws IllegalAccessException
*/
private static Map objectToMap(Object obj) throws IllegalAccessException {
Map map = new HashMap<>(16);
Class> clazz = obj.getClass();
for (Field field : clazz.getDeclaredFields()) {
field.setAccessible(true);
String fieldName = field.getName();
/*
* Returns the value of the field represented by this {@code Field}, on the
* specified object. The value is automatically wrapped in an object if it
* has a primitive type.
* 注:返回对象该该属性的属性值,如果该属性的基本类型,那么自动转换为包装类
*/
Object value = field.get(obj);
map.put(fieldName, value);
}
return map;
}
运行测试函数,成功导出excel:
导出的excel内容为:
注:上表中的标签语法,本人只亲测了一部分。
笔者个人看法:
> 在方便程度方面:Easypoi >= JXLS > POI
注:有时,方便程度 Easypoi ≈ JXLS
> 在性能方面: POI > Easypoi >= JXLS
注:灵活使用即可。