Easy Excel学习笔记
1 Easy Excel简介
1.1 Easy Excel介绍
EasyExcel是一个基于Java的简单的、省内存的读写Excel的开源项目。
在尽可能节约内存的情况下支持读写百M的Excel。
github地址: https://github.com/alibaba/easyexcel
JAVA解析Excel工具EasyExcel
Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。
easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析依然需要100M左右内存,改用easyexcel可以降低到几M,并且再大的excel也不会出现内存溢出;03版依赖POI的sax模式,在上层做了模型转换的封装,让使用者更加简单方便.
64M内存20秒读取75M(46W行25列)的Excel(3.0.2+版本)
1.2 Easy POI和Easy Excel对比
Easy POI:
Easy Excel:
(1)这两者都是引用Apache的poi 但是区别就是两者的解析不同
(2)Easy POI的解析方式是dom解析,把结果一次都读入内存操作,这样的操作平时是不会有问题的,但是并发量上来的时候就会出现OOM
(3)而阿里的Easy Excel 运用的SAX的解析方式,明显降低了内存,但是速率下降
2 环境搭建
maven依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.3</version>yuryyyyy
</dependency>
3 注解
3.1 @ExcelProperty
@ExcelProperty 这个注解的作用是描述设置Excel的表头
#常用属性
value [String[]] 列名
index [int] 列中的顺序
converter [StringImageConverter.class] 当使用String类型保存一个图片的时候需要使用StringImageConverter转换器
@ExcelProperty("姓名")
private String userName;
@ExcelProperty(converter = StringImageConverter.class)
private String string;
3.2 @DateTimeFormat
日期格式化
@DateTimeFormat("yyyy年MM月dd日") //日期格式
@ExcelProperty(value="工资",index = 4)
private Double salary;
3.2 @NumberFormat
数字格式化
@NumberFormat("#.##%") //数字格式 小数点后2位
@ExcelProperty(value="工资",index = 4)
private Double salary;
3 读取Excel
3.1 最简单的读取Excel方式一
user13.xlsx
DemoData.java
package com.tangguanlin.easyexcel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
/**
* 说明:
* 作者:汤观林
* 日期:2021年12月29日 18时
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class DemoData {
private String name;
private Date hirDate;
private Double salary;
}
ReadExcel1.java
package com.tangguanlin.easyexcel;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
/**
* 说明:最简单的读方式一
* 作者:汤观林
* 日期:2021年12月28日 21时
*/
public class ReadExcel1 {
public static void main(String[] args) {
String fileName = "user13.xlsx";
EasyExcel.read(fileName,DemoData.class,new AnalysisEventListener<DemoData>(){
//每解析一行Excel表格数据,就会调用一次
@Override
public void invoke(DemoData demoData, AnalysisContext analysisContext) {
System.out.println("解析数据为:"+demoData);
}
//当全部解析完,被调用
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
System.out.println("全部解析完");
}
}).sheet().doRead();
}
}
运行结果:
解析数据为:DemoData{name='作文1', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=15.1}
解析数据为:DemoData{name='作文2', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=15.2}
解析数据为:DemoData{name='作文6', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=15.6}
解析数据为:DemoData{name='作文7', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=15.7}
全部解析完
3.2 最简单的读取Excel方式二
ReadExcel2.java
package com.tangguanlin.easyexcel;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.read.metadata.ReadSheet;
/**
* 说明:最简单的读方式二
* 作者:汤观林
* 日期:2021年12月28日 21时
*/
public class ReadExcel2 {
public static void main(String[] args) {
String fileName = "user13.xlsx";
//创建excelReader
ExcelReader excelReader = EasyExcel.read(fileName, DemoData.class, new AnalysisEventListener<DemoData>() {
//每解析一行Excel表格数据,就会调用一次
@Override
public void invoke(DemoData demoData, AnalysisContext analysisContext) {
System.out.println("解析数据为:" + demoData);
}
//当全部解析完,被调用
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
System.out.println("全部解析完");
}
}).build();
//创建readSheet
ReadSheet readSheet = EasyExcel.readSheet(0).build();
//读
excelReader.read(readSheet);
//关闭流操作,在读取文件时创建临时文件,如果不关闭,磁盘会爆掉
excelReader.finish();
}
}
运行结果:
解析数据为:DemoData{name='作文1', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=15.1}
解析数据为:DemoData{name='作文2', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=15.2}
解析数据为:DemoData{name='作文6', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=15.6}
解析数据为:DemoData{name='作文7', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=15.7}
全部解析完
3.3 指定列名
user13.xlsx
DemoData.java
package com.tangguanlin.easyexcel;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
/**
* 说明:
* 作者:汤观林
* 日期:2021年12月29日 18时
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class DemoData {
@ExcelProperty("日期标题")
private Date hirDate;
@ExcelProperty("字符串标题")
private String name;
@ExcelProperty("数字标题")
private Double salary;
}
运行结果:
解析数据为:DemoData{name='作文1', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=15.1}
解析数据为:DemoData{name='作文2', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=15.2}
解析数据为:DemoData{name='作文6', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=15.6}
解析数据为:DemoData{name='作文7', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=15.7}
全部解析完
3.4 日期、数字格式化
user13.xlsx
DemoData.java
package com.tangguanlin.easyexcel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.alibaba.excel.annotation.format.NumberFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
/**
* 说明:日期、数字格式化
* 作者:汤观林
* 日期:2021年12月29日 18时
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class DemoData {
@ExcelProperty("日期标题")
@DateTimeFormat("yyyy年MM月dd日 hh时mm分ss秒")
private Date hirDate;
@ExcelProperty("字符串标题")
private String name;
@ExcelProperty("数字标题")
@NumberFormat("#.##%")
private String salary;
}
运行结果:
解析数据为:DemoData{name='作文1', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=1511.1%}
解析数据为:DemoData{name='作文2', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=1512.2%}
解析数据为:DemoData{name='作文6', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=1513.6%}
解析数据为:DemoData{name='作文7', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=1514.7%}
全部解析完
3.5 读取全部sheet数据
user13.xlsx
ReadExcel1.java
package com.tangguanlin.easyexcel;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
/**
* 说明:读取全部sheet数据
* 作者:汤观林
* 日期:2021年12月28日 21时
*/
public class ReadExcel1 {
public static void main(String[] args) {
String fileName = "user13.xlsx";
EasyExcel.read(fileName,DemoData.class,new AnalysisEventListener<DemoData>(){
//每解析一行Excel表格数据,就会调用一次
@Override
public void invoke(DemoData demoData, AnalysisContext analysisContext) {
System.out.println("解析数据为:"+demoData);
}
//当全部解析完,被调用
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
System.out.println("全部解析完");
}
}).doReadAll();
}
}
运行结果:
解析数据为:DemoData{name='作文11', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=1511.11%}
解析数据为:DemoData{name='作文21', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=1512.21%}
解析数据为:DemoData{name='作文61', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=1513.61%}
解析数据为:DemoData{name='作文71', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=1514.71%}
全部解析完
解析数据为:DemoData{name='作文12', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=1511.11%}
解析数据为:DemoData{name='作文22', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=1512.21%}
解析数据为:DemoData{name='作文62', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=1513.61%}
解析数据为:DemoData{name='作文72', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=1514.71%}
全部解析完
解析数据为:DemoData{name='作文13', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=1511.11%}
解析数据为:DemoData{name='作文23', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=1512.21%}
解析数据为:DemoData{name='作文63', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=1513.61%}
解析数据为:DemoData{name='作文73', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=1514.71%}
全部解析完
3.6 读取某几个sheet数据
ReadExcel3.java
package com.tangguanlin.easyexcel;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.read.builder.ExcelReaderBuilder;
import com.alibaba.excel.read.metadata.ReadSheet;
/**
* 说明:读某几个sheet
* 作者:汤观林
* 日期:2021年12月28日 21时
*/
public class ReadExcel3 {
public static void main(String[] args) {
String fileName = "user13.xlsx";
//创建excelReader
ExcelReader excelReader = EasyExcel.read(fileName).build();
//创建sheet0
ReadSheet sheet0 = EasyExcel.readSheet(0).head(DemoData.class)
.registerReadListener(new AnalysisEventListener<DemoData>(){
@Override
public void invoke(DemoData demoData, AnalysisContext analysisContext) {
System.out.println("解析数据为:"+demoData);
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
System.out.println("sheet0解析完毕");
}
}).build();
//创建sheet2
ReadSheet sheet2 = EasyExcel.readSheet(2).head(DemoData.class)
.registerReadListener(new AnalysisEventListener<DemoData>(){
@Override
public void invoke(DemoData demoData, AnalysisContext analysisContext) {
System.out.println("解析数据为:"+demoData);
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
System.out.println("sheet2解析完毕");
}
}).build();
//读
excelReader.read(sheet0,sheet2);
//释放资源
excelReader.finish();
}
}
运行结果:
解析数据为:DemoData{name='作文11', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=1511.11%}
解析数据为:DemoData{name='作文21', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=1512.21%}
解析数据为:DemoData{name='作文61', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=1513.61%}
解析数据为:DemoData{name='作文71', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=1514.71%}
sheet0解析完毕
解析数据为:DemoData{name='作文13', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=1511.11%}
解析数据为:DemoData{name='作文23', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=1512.21%}
解析数据为:DemoData{name='作文63', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=1513.61%}
解析数据为:DemoData{name='作文73', hirDate=Tue Dec 28 22:11:31 CST 2021, salary=1514.71%}
sheet2解析完毕
4 写入Excel
4.1 最简单的写方式一
User.java
package com.tangguanlin.easyexcel;
import com.alibaba.excel.annotation.ExcelProperty;
import java.util.Date;
/**
* 说明:写入Excel方式一
* 作者:汤观林
* 日期:2021年12月28日 21时
*/
@Data
public class User {
@ExcelProperty("用户编号")
private Integer userId;
@ExcelProperty("姓名")
private String userName;
@ExcelProperty("性别")
private String gender;
@ExcelProperty("工资")
private Double salary;
@ExcelProperty("入职时间")
private Date hirDate;
public User() {
}
public User(Integer userId, String userName, String gender, Double salary, Date hirDate) {
this.userId = userId;
this.userName = userName;
this.gender = gender;
this.salary = salary;
this.hirDate = hirDate;
}
}
WriteExcel1.java
package com.tangguanlin.easyexcel;
import com.alibaba.excel.EasyExcel;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 说明:写入Excel方式一
* 作者:汤观林
* 日期:2021年12月28日 21时
*/
public class WriteExcel1 {
public static void main(String[] args) {
//创建一个Excel文档
String fileName ="user1.xlsx";
List<User> userList = new ArrayList<User>();
User user1 = new User(1001,"李雷","男",1000.11,new Date());
User user2 = new User(1002,"李雷","男",1000.11,new Date());
User user3 = new User(1003,"李雷","男",1000.11,new Date());
User user4 = new User(1004,"李雷","男",1000.11,new Date());
userList.add(user1);
userList.add(user2);
userList.add(user3);
userList.add(user4);
EasyExcel.write(fileName,User.class).sheet("用户信息").doWrite(userList);
}
}
运行结果:
4.2 最简单的写方式二
WriteExcel2.java
package com.tangguanlin.easyexcel;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 说明:写入Excel方式二
* 作者:汤观林
* 日期:2021年12月28日 22时
*/
public class WriteExcel2 {
public static void main(String[] args) {
//创建一个Excel文档
String fileName ="user2.xlsx";
List<User> userList = new ArrayList<User>();
User user1 = new User(1001,"李雷","男",1000.11,new Date());
User user2 = new User(1002,"李雷","男",1000.11,new Date());
User user3 = new User(1003,"李雷","男",1000.11,new Date());
User user4 = new User(1004,"李雷","男",1000.11,new Date());
userList.add(user1);
userList.add(user2);
userList.add(user3);
userList.add(user4);
//创建ExcelWriter对象
ExcelWriter excelWriter = EasyExcel.write(fileName, User.class).build();
//创建sheet对象
WriteSheet writeSheet = EasyExcel.writerSheet("用户信息").build();
excelWriter.write(userList,writeSheet);
//关闭资源
excelWriter.finish();
}
}
运行结果:
4.3 排除某些字段
package com.tangguanlin.easyexcel;
import com.alibaba.excel.EasyExcel;
import java.util.*;
/**
* 说明:排除某些字段
* 作者:汤观林
* 日期:2021年12月28日 22时
*/
public class WriteExcel3 {
public static void main(String[] args) {
//创建一个Excel文档
String fileName ="user3.xlsx";
List<User> userList = new ArrayList<User>();
User user1 = new User(1001,"李雷","男",1000.11,new Date());
User user2 = new User(1002,"李雷","男",1000.11,new Date());
User user3 = new User(1003,"李雷","男",1000.11,new Date());
User user4 = new User(1004,"李雷","男",1000.11,new Date());
userList.add(user1);
userList.add(user2);
userList.add(user3);
userList.add(user4);
Set<String> set = new HashSet<>();
set.add("hirDate");
set.add("salary");
EasyExcel.write(fileName,User.class).excludeColumnFiledNames(set).sheet("用户信息").doWrite(userList);
}
}
运行结果:
4.4 指定某几个字段
package com.tangguanlin.easyexcel;
import com.alibaba.excel.EasyExcel;
import java.util.*;
/**
* 说明:指定某些字段
* 作者:汤观林
* 日期:2021年12月28日 22时
*/
public class WriteExcel4 {
public static void main(String[] args) {
//创建一个Excel文档
String fileName ="user4.xlsx";
List<User> userList = new ArrayList<User>();
User user1 = new User(1001,"李雷","男",1000.11,new Date());
User user2 = new User(1002,"李雷","男",1000.11,new Date());
User user3 = new User(1003,"李雷","男",1000.11,new Date());
User user4 = new User(1004,"李雷","男",1000.11,new Date());
userList.add(user1);
userList.add(user2);
userList.add(user3);
userList.add(user4);
Set<String> set = new HashSet<>();
set.add("userId");
set.add("userName");
set.add("salary");
EasyExcel.write(fileName,User.class).includeColumnFiledNames(set).sheet("用户信息").doWrite(userList);
}
}
运行结果:
4.5 设置表格中列的顺序
将Java对象中指定的属性,插入到Excel表格中的指定的列(在Excel中进行排序)
@ExcelProperty(value="姓名",index = 1) //index 排序
private String userName;
package com.tangguanlin.easyexcel;
import com.alibaba.excel.annotation.ExcelProperty;
import java.util.Date;
/**
* 说明:设置表格中列的顺序
* 作者:汤观林
* 日期:2021年12月28日 21时
*/
public class User {
@ExcelProperty(value="用户编号",index = 0)
private Integer userId;
@ExcelProperty(value="姓名",index = 1)
private String userName;
@ExcelProperty(value="性别",index = 2)
private String gender;
@ExcelProperty(value="工资",index = 4)
private Double salary;
@ExcelProperty(value="入职时间",index = 3)
private Date hirDate;
public User() {
}
public User(Integer userId, String userName, String gender, Double salary, Date hirDate) {
this.userId = userId;
this.userName = userName;
this.gender = gender;
this.salary = salary;
this.hirDate = hirDate;
}
}
运行结果:
4.6 复杂头数据写入
CompleHeadUser.java
package com.tangguanlin.easyexcel;
import com.alibaba.excel.annotation.ExcelProperty;
import java.util.Date;
/**
* 说明:复杂头对象
* 作者:汤观林
* 日期:2021年12月28日 22时
*/
public class CompleHeadUser {
@ExcelProperty({"用户主题1","用户编号"})
private Integer userId;
@ExcelProperty({"用户主题1","用户名称"})
private String userName;
@ExcelProperty({"用户主题3","入职时间"})
private Date hireDate;
public CompleHeadUser() {
}
public CompleHeadUser(Integer userId, String userName, Date hireDate) {
this.userId = userId;
this.userName = userName;
this.hireDate = hireDate;
}
}
运行结果:
4.7 多次写到Excel的同一个sheet中
package com.tangguanlin.easyexcel;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 说明:多次写到Excel的同一个sheet中
* 作者:汤观林
* 日期:2021年12月28日 23时
*/
public class WriteExcel7 {
public static void main(String[] args) {
//创建一个Excel文档
String fileName ="user7.xlsx";
List<User> userList = new ArrayList<User>();
User user1 = new User(1001,"李雷","男",1000.11,new Date());
User user2 = new User(1002,"李雷","男",1000.11,new Date());
User user3 = new User(1003,"李雷","男",1000.11,new Date());
User user4 = new User(1004,"李雷","男",1000.11,new Date());
userList.add(user1);
userList.add(user2);
userList.add(user3);
userList.add(user4);
//创建excelWriter
ExcelWriter excelWriter = EasyExcel.write(fileName, User.class).build();
//创建writeSheet
WriteSheet writeSheet = EasyExcel.writerSheet("用户信息06").build();
for(int i=0;i<5;i++){
excelWriter.write(userList,writeSheet);
}
excelWriter.finish();
}
}
运行结果:
4.8 多次写到Excel的不同sheet中
package com.tangguanlin.easyexcel;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 说明:多次写到Excel的b不同sheet中
* 作者:汤观林
* 日期:2021年12月28日 23时
*/
public class WriteExcel8 {
public static void main(String[] args) {
//创建一个Excel文档
String fileName ="user8.xlsx";
List<User> userList = new ArrayList<User>();
User user1 = new User(1001,"李雷","男",1000.11,new Date());
User user2 = new User(1002,"李雷","男",1000.11,new Date());
User user3 = new User(1003,"李雷","男",1000.11,new Date());
User user4 = new User(1004,"李雷","男",1000.11,new Date());
userList.add(user1);
userList.add(user2);
userList.add(user3);
userList.add(user4);
//创建excelWriter
ExcelWriter excelWriter = EasyExcel.write(fileName, User.class).build();
for(int i=0;i<5;i++){
//创建writeSheet
WriteSheet writeSheet = EasyExcel.writerSheet("用户信息"+i).build();
excelWriter.write(userList,writeSheet);
}
excelWriter.finish();
}
}
运行结果:
4.9 日期、数字格式化
package com.tangguanlin.easyexcel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.alibaba.excel.annotation.format.NumberFormat;
import java.util.Date;
/**
* 说明:日期、数字类型格式化
* 作者:汤观林
* 日期:2021年12月28日 21时
*/
public class User {
@ExcelProperty(value="用户编号",index = 0)
private Integer userId;
@ExcelProperty(value="姓名",index = 1)
private String userName;
@ExcelProperty(value="性别",index = 2)
private String gender;
@NumberFormat("#.#") //数字格式化
@ExcelProperty(value="工资",index = 4)
private Double salary;
@DateTimeFormat("yyyy年MM月dd日") //日期格式化
@ExcelProperty(value="入职时间",index = 3)
private Date hirDate;
public User() {
}
public User(Integer userId, String userName, String gender, Double salary, Date hirDate) {
this.userId = userId;
this.userName = userName;
this.gender = gender;
this.salary = salary;
this.hirDate = hirDate;
}
}
运行结果:
4.10 写入图片到Excel
5种方式:
ImageData.java WriteExcel10.java
//方式一:使用抽象文件表示一个图片
private File file; imageData.setFile(new File("image.jpg"));
//方式二:使用输入流保存一个图片
private InputStream inputStream; imageData.setInputStream(new FileInputStream("image.jpg"));
//方式三:当使用String类型保存一个图片的时候需要使用StringImageConverter转换器
@ExcelProperty(converter = StringImageConverter.class)
private String string; imageData.setString("image.jpg");
//方式四:使用二进制数据保存为一个图片
private byte[] byteArray; int length = (int)new File("image.jpg").length();
byte[] b = new byte[length];
FileInputStream fis = new FileInputStream("image.jpg");
fis.read(b,0,length);
imageData.setByteArray(b);
//方式五:使用网络连接保存一个图片
private URL url; imageData.setUrl(new URL("www.baidu.com"));
ImageData.java
package com.tangguanlin.easyexcel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.converters.string.StringImageConverter;
import lombok.Data;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.Arrays;
/**
* 说明:写入图片的5种方式
* 作者:汤观林
* 日期:2021年12月29日 15时
*/
@Data
public class ImageData {
private File file; //方式一:使用抽象文件表示一个图片
private InputStream inputStream; //方式二:使用输入流保存一个图片
@ExcelProperty(converter = StringImageConverter.class)
private String string; //方式三:当使用String类型保存一个图片的时候需要使用StringImageConverter转换器
private byte[] byteArray; //方式四:使用二进制数据保存为一个图片
private URL url; //方式五:使用网络连接保存一个图片
public ImageData() {
}
}
WriteExcel10.java
package com.tangguanlin.easyexcel;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import java.io.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
/**
* 说明:将图片写入到Excel的5种方式
* 作者:汤观林
* 日期:2021年12月28日 23时
*/
public class WriteExcel10 {
public static void main(String[] args) throws IOException {
//创建一个Excel文档
String fileName ="user10.xlsx";
List<ImageData> imageList = new ArrayList<ImageData>();
ImageData imageData = new ImageData();
//方式一:使用抽象文件表示一个图片
imageData.setFile(new File("image.jpg"));
//方式二:使用输入流保存一个图片
imageData.setInputStream(new FileInputStream("image.jpg"));
//方式三:当使用String类型保存一个图片的时候需要使用StringImageConverter转换器
imageData.setString("image.jpg");
//方式四:使用二进制数据保存为一个图片
byte[] b = new byte[(int)new File("image.jpg").length()];
FileInputStream fis = new FileInputStream("image.jpg");
fis.read(b,0,(int)new File("image.jpg").length());
imageData.setByteArray(b);
//方式五:使用网络连接保存一个图片
imageData.setUrl(new URL("https://gitee.com/tangguanlin2006/image/raw/master/20211228212606.png"));
imageList.add(imageData);
//创建excelWriter
ExcelWriter excelWriter = EasyExcel.write(fileName, ImageData.class).build();
//创建writeSheet
WriteSheet writeSheet = EasyExcel.writerSheet("用户信息").build();
excelWriter.write(imageList,writeSheet);
excelWriter.finish();
}
}
运行结果:
4.11 设置Excel列宽行高
属性:
//修饰类
@HeadRowHeight(40) //设置标题高度
@ColumnWidth(30) //设置列宽
@ContentRowHeight(50) //设置内容高度
public class ImageData {
}
//修饰属性
@ColumnWidth(30) //设置列宽
private File file;
ImageData.java
package com.tangguanlin.easyexcel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.HeadRowHeight;
import com.alibaba.excel.converters.string.StringImageConverter;
import lombok.Data;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.Arrays;
/**
* 说明:设置列宽行高
* 作者:汤观林
* 日期:2021年12月29日 15时
*/
@Data
@HeadRowHeight(40) //设置标题高度
@ColumnWidth(30) //设置列宽
@ContentRowHeight(50) //设置内容高度
public class ImageData {
private File file; //方式一:使用抽象文件表示一个图片
private InputStream inputStream; //方式二:使用输入流保存一个图片
@ExcelProperty(converter = StringImageConverter.class)
private String string; //方式三:当使用String类型保存一个图片的时候需要使用StringImageConverter转换器
private byte[] byteArray; //方式四:使用二进制数据保存为一个图片
private URL url; //方式五:使用网络连接保存一个图片
public ImageData() {
}
}
运行结果:
4.12 设置样式
//修饰类 或 字段
//头背景设置成红色 IndexedColors.PINK.getIndex() 10:红色
@HeadStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND,fillForegroundColor = 10)
//头字体设置成20
@HeadFontStyle(fontHeightInPoints = 20)
//内容的背景设置成绿色 IndexedColors.PINK.getIndex() 17:绿色
@ContentStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND,fillForegroundColor = 17 )
//内容字体设置成20
@ContentFontStyle(fontHeightInPoints = 20)
DemoStyleData.java
package com.tangguanlin.easyexcel;
import cn.hutool.db.DaoTemplate;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ContentFontStyle;
import com.alibaba.excel.annotation.write.style.ContentStyle;
import com.alibaba.excel.annotation.write.style.HeadFontStyle;
import com.alibaba.excel.annotation.write.style.HeadStyle;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.IndexedColors;
import java.util.Date;
/**
* 说明: 设置样式
* 作者:汤观林
* 日期:2021年12月29日 16时
*/
@Data
@AllArgsConstructor
//头背景设置成红色 IndexedColors.PINK.getIndex() 10:红色
@HeadStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND,fillForegroundColor = 10)
//头字体设置成20
@HeadFontStyle(fontHeightInPoints = 20)
//内容的背景设置成绿色 IndexedColors.PINK.getIndex() 17:绿色
@ContentStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND,fillForegroundColor = 17 )
//内容字体设置成20
@ContentFontStyle(fontHeightInPoints = 20)
public class DemoStyleData {
@ExcelProperty("字符串标题")
private String string;
@ExcelProperty("日期标题")
private Date Date;
@ExcelProperty("数字标题")
private Double doubleData;
}
运行结果:
4.13 合并单元格
//修饰类
//合并单元格 (起始行,结束行,起始列,结束列)
@OnceAbsoluteMerge(firstRowIndex = 3,lastRowIndex = 5,firstColumnIndex = 1,lastColumnIndex = 2)
public class DemoMergeData {
}
//修饰列
//每隔2行合并一次(竖着合并单元格)
@ContentLoopMerge(eachRow = 2)
@ExcelProperty("字符串标题")
private String string;
WriteExcel12.java
package com.tangguanlin.easyexcel;
import com.alibaba.excel.EasyExcel;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 说明:合并单元格
* 作者:汤观林
* 日期:2021年12月28日 23时
*/
public class WriteExcel12 {
public static void main(String[] args) {
//创建一个Excel文档
String fileName ="user12.xlsx";
List<DemoMergeData> mergeDataList = new ArrayList<DemoMergeData>();
DemoMergeData mergeData1 = new DemoMergeData("作文1",new Date(),15.1);
DemoMergeData mergeData2 = new DemoMergeData("作文2",new Date(),15.2);
DemoMergeData mergeData3 = new DemoMergeData("作文3",new Date(),15.3);
DemoMergeData mergeData4 = new DemoMergeData("作文4",new Date(),15.4);
DemoMergeData mergeData5 = new DemoMergeData("作文5",new Date(),15.5);
DemoMergeData mergeData6 = new DemoMergeData("作文6",new Date(),15.6);
DemoMergeData mergeData7 = new DemoMergeData("作文7",new Date(),15.7);
mergeDataList.add(mergeData1);
mergeDataList.add(mergeData2);
mergeDataList.add(mergeData3);
mergeDataList.add(mergeData4);
mergeDataList.add(mergeData5);
mergeDataList.add(mergeData6);
mergeDataList.add(mergeData7);
EasyExcel.write(fileName, DemoMergeData.class).sheet("合并单元格").doWrite(mergeDataList);
}
}
运行结果:
4.14 字段填充
填充单个属性使用{}作为占位符,在大括号里面定义属性名称,
如果{}想不作为占位符,可以已使用反斜杠进行转义。
template.xlsx 填充模板
姓名 | 工资 | 复杂 | 忽略 |
---|---|---|---|
{name} | {number} | {name}今年{number}岁了 | \ {name \ } 忽略,{name} |
FillData.java
package com.tangguanlin.easyexcel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 说明:填充数据
* 作者:汤观林
* 日期:2021年12月29日 21时
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class FillData {
private String name;
private double number;
}
WriteExcel13.java
package com.tangguanlin.easyexcel;
import com.alibaba.excel.EasyExcel;
/**
* 说明:字段填充
* 作者:汤观林
* 日期:2021年12月29日 21时
*/
public class WriteExcel13 {
public static void main(String[] args) {
//根据哪个模板进行填充
String templateName = "template.xlsx";
//填充完成之后的Excel
String fullName = "fullFile.xlsx";
FillData fillData = new FillData();
fillData.setName("小明");
fillData.setNumber(1000.12);
//进行填充
EasyExcel.write(fullName).withTemplate(templateName).sheet().doFill(fillData);
}
}
运行结果:
fullFile.xlsx
4.15 列表填充
templateList.xlsx 填充模板
姓名 | 工资 |
---|---|
{==.==name} | {==.==number} |
WriteExcel13.java
package com.tangguanlin.easyexcel;
import com.alibaba.excel.EasyExcel;
import java.util.ArrayList;
import java.util.List;
/**
* 说明:字段填充
* 作者:汤观林
* 日期:2021年12月29日 21时
*/
public class WriteExcel13 {
public static void main(String[] args) {
//根据哪个模板进行填充
String templateName = "templateList.xlsx";
//填充完成之后的Excel
String fullName = "fullFileList.xlsx";
List<FillData> fillDataList = new ArrayList<>();
FillData fillData1 = new FillData("小明1",1000.12);
FillData fillData2 = new FillData("小明2",1000.12);
FillData fillData3 = new FillData("小明3",1000.12);
FillData fillData4 = new FillData("小明4",1000.12);
FillData fillData5 = new FillData("小明5",1000.12);
FillData fillData6 = new FillData("小明6",1000.12);
FillData fillData7 = new FillData("小明7",1000.12);
fillDataList.add(fillData1);
fillDataList.add(fillData2);
fillDataList.add(fillData3);
fillDataList.add(fillData4);
fillDataList.add(fillData5);
fillDataList.add(fillData6);
fillDataList.add(fillData7);
//进行填充
EasyExcel.write(fullName).withTemplate(templateName).sheet().doFill(fillDataList);
}
}
运行结果:
fullFileList.xlsx
5 web操作
5.1 Excel文件上传
(省略)
5.2 Excel文件下载
(省略)