一篇文章帶你玩轉(zhuǎn)Java EasyExcel(Excel報表必學)
一:EasyExcel簡介
1.EasyExcel是一個基于Java的簡單、省內(nèi)存的讀寫Excel的開源項目。在盡可能節(jié)約內(nèi)存的情況下支持讀寫百M的Excel。
2.Java解析、生成Excel比較有名的框架有Apache poi、jxl。但他們都存在一個嚴重的問題就是非常的耗內(nèi)存,poi有一套SAX模式的API可以一定程度的解決一些內(nèi)存溢出的問題,但POI還是有一些缺陷,比如07版Excel解壓縮以及解壓后存儲都是在內(nèi)存中完成的,內(nèi)存消耗依然很大。easyexcel重寫了poi對07版Excel的解析,一個3M的excel用POI sax解析依然需要100M左右內(nèi)存,改用easyexcel可以降低到幾M,并且再大的excel也不會出現(xiàn)內(nèi)存溢出;03版依賴POI的sax模式,在上層做了模型轉(zhuǎn)換的封裝,讓使用者更加簡單方便。
3.github地址:github官網(wǎng)
二: EasyExcel使用
1.EasyExcel相關(guān)依賴
1)添加maven依賴
<dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>2.2.3</version> </dependency>
2)添加jar包
asm-4.2.jar cglib-3.1.jar commons-codec-1.10.jar commons-collections4-4.1.jar curvesapi-1.04.jar easyexcel-2.2.3.jar ehcache-3.4.0.jar poi-3.17.jar poi-ooxml-3.17.jar poi-ooxml-schemas-3.17.jar slf4j-api-1.7.26.jar stax-api-1.0.1.jar xmlbeans-2.6.0.jar
2.寫Excel
/**
* 創(chuàng)建User類,用于構(gòu)建向Excel表格中寫數(shù)據(jù)的類型;
* @ExcelProperty:這個注解是EasyExcel提供,用于生成Excel表格頭
*/
public class User {
@ExcelProperty("用戶編號")
private Integer userId;
@ExcelProperty("姓名")
private String userName;
@ExcelProperty("性別")
private String gender;
@ExcelProperty("工資")
private Double salary;
@ExcelProperty("入職時間")
private Date hireDate;
//setter/getter方法
}
@ExcelProperty:這個注解是EasyExcel提供,用于生成Excel表格頭,取名字
1)最簡單的寫(方式一)
/**
* 向Excel文檔中寫數(shù)據(jù)(方式一)
* 最簡單的寫
*/
@Test
public void writeExcel1() {
//創(chuàng)建文件保存的位置,以及文件名
String fileName="user1.xlsx";
/**
* 構(gòu)建要寫入的數(shù)據(jù)
* User類是一個自定義的特殊類,專門用來構(gòu)建向Excel中寫數(shù)據(jù)的類型類
* @ExcelProperty是easyexcel提供的注解,用來定義表格的頭部
*/
List<User> data = new ArrayList<>();
User user = new User(2001,"李雷","男",1000.123,new Date());
data.add(user);
//將數(shù)據(jù)寫到Excel的第一個sheet標簽中,并且給sheet標簽起名字
EasyExcel.write(fileName,User.class).sheet("用戶信息").doWrite(data);
//文件流會自動關(guān)閉
}
2)最簡單的寫(方式二)
/**
* 向Excel文檔中寫數(shù)據(jù)(方式二)
* 最簡單的寫
*/
@Test
public void writeExcel2() {
//創(chuàng)建文件保存的位置,以及文件名
String fileName="user2.xlsx";
/**
* 構(gòu)建要寫入的數(shù)據(jù)
* User類是一個自定義的特殊類,專門用來構(gòu)建向Excel中寫數(shù)據(jù)的類型類
* @ExcelProperty是easyexcel提供的注解,用來定義表格的頭部
*/
List<User> data = new ArrayList<>();
User user = new User(2001,"李雷","男",1000.123,new Date());
data.add(user);
//創(chuàng)建Excel寫對象
ExcelWriter excelWriter = EasyExcel.write(fileName, User.class).build();
//創(chuàng)建sheet對象
WriteSheet writeSheet = EasyExcel.writerSheet("用戶信息").build();
//將數(shù)據(jù)寫到sheet標簽中
excelWriter.write(data, writeSheet);
//關(guān)閉流,文件流手動關(guān)閉
excelWriter.finish();
}
3)將類中某幾個字段排除掉,不寫入Excel中
/**
* 向Excel文檔中寫數(shù)據(jù)
* 將User類中的某幾個屬性字段排除
*/
@Test
public void writeExcel3() {
//創(chuàng)建文件保存的位置,以及文件名
String fileName="user3.xlsx";
/**
* 構(gòu)建要寫入的數(shù)據(jù)
* User類是一個自定義的特殊類,專門用來構(gòu)建向Excel中寫數(shù)據(jù)的類型類
* @ExcelProperty是easyexcel提供的注解,用來定義表格的頭部
*/
List<User> data = new ArrayList<>();
User user = new User(2001,"李雷","男",1000.123,new Date());
data.add(user);
//構(gòu)建要排除掉的列
Set<String> excludeColumnFiledNames = new HashSet<>();
//排除掉hireDate和userName字段
excludeColumnFiledNames.add("hireDate");
excludeColumnFiledNames.add("userName");
EasyExcel.write(fileName, User.class).excludeColumnFiledNames(excludeColumnFiledNames).sheet("abc").doWrite(data);
}
4)只向表格中導出指定某幾個字段
/**
* 向Excel文檔中寫數(shù)據(jù)
* 指定將User類中的某幾個字段導出
*/
@Test
public void writeExcel4() {
//創(chuàng)建文件保存的位置,以及文件名
String fileName="user4.xlsx";
/**
* 構(gòu)建要寫入的數(shù)據(jù)
* User類是一個自定義的特殊類,專門用來構(gòu)建向Excel中寫數(shù)據(jù)的類型類
* @ExcelProperty是easyexcel提供的注解,用來定義表格的頭部
*/
List<User> data = new ArrayList<>();
User user = new User(2001,"李雷","男",1000.123,new Date());
data.add(user);
//構(gòu)建要導出的列
Set<String> includeColumnFiledNames = new HashSet<>();
//要導出hireDate和userName字段
includeColumnFiledNames.add("hireDate");
includeColumnFiledNames.add("userName");
EasyExcel.write(fileName, User.class).includeColumnFiledNames(includeColumnFiledNames).sheet("abc").doWrite(data);
}
5)插入指定的列
將Java對象中指定的屬性,插入到Excel表格中的指定的列(在Excel中進行列排序)
寫Excel的Java對象類型
public class IndexUser {
/**
* value: 設置Excel中列頭的名字 index: 設置Excel中將數(shù)據(jù)插入指定的列(列排序) eg: value="姓名" index=2 :
* 將姓名的列頭設置在Excel表格的第三列
*/
@ExcelProperty(value = "用戶編號", index = 0)
private Integer userId;
@ExcelProperty(value = "姓名", index = 2)
private String userName;
@ExcelProperty(value = "入職時間", index = 1)
private Date hireDate;
}
向Excel中寫數(shù)據(jù)
/**
* 插入指定列
* Java類中有三個屬性
* 我現(xiàn)在要將這三個屬性的數(shù)據(jù)保存到Excel表格中
* 并且自定義在Excel中的列順序
*/
@Test
public void writeExcel5() {
//創(chuàng)建文件保存的位置,以及文件名
String fileName="user5.xlsx";
/**
* 構(gòu)建要寫入的數(shù)據(jù)
*/
List<IndexUser> data = new ArrayList<>();
IndexUser user = new IndexUser(1001,"楓橋夜泊",new Date());
data.add(user);
EasyExcel.write(fileName, IndexUser.class).sheet("abc").doWrite(data);
}
6)復雜頭數(shù)據(jù)寫入
寫Excel的Java對象類型
/**
* 構(gòu)建復雜頭信息數(shù)據(jù)的類
*/
public class ComplexHeadUser {
/**
* {"用戶主題1","用戶編號"}這種遇到格式設置多級主題
* 第一個參數(shù)為一級主題(第一行)
* 第二個參數(shù)為二級主題(第二行)
* 如果一級主題名稱相同,那么他們會合并單元格
*/
@ExcelProperty({"用戶主題1","用戶編號"})
private Integer userId;
@ExcelProperty({"用戶主題2","用戶名稱"})
private String userName;
@ExcelProperty({"用戶主題3","入職時間"})
private Date hireDate;
}
向Excel中寫數(shù)據(jù)
/**
* 寫入復雜頭信息到Excel
*/
@Test
public void writeExcel6() {
//創(chuàng)建文件保存的位置,以及文件名
String fileName="user6.xlsx";
/**
* 構(gòu)建要寫入的數(shù)據(jù)
*/
List<ComplexHeadUser> data = new ArrayList<>();
ComplexHeadUser user = new ComplexHeadUser(1001,"楓橋夜泊",new Date());
data.add(user);
EasyExcel.write(fileName, ComplexHeadUser.class).sheet("abc").doWrite(data);
}
7)重復寫到Excel的同一個sheet中
/**
* 重復寫到同一個sheet中
*/
@Test
public void writeExcel7() {
//創(chuàng)建文件保存的位置,以及文件名
String fileName="user7.xlsx";
//構(gòu)建數(shù)據(jù)
List<User> data = new ArrayList<>();
User user1 = new User(2001,"李雷1","男",1000.123,new Date());
User user2 = new User(2002,"李雷2","男",1000.123,new Date());
User user3 = new User(2003,"李雷3","男",1000.123,new Date());
User user4 = new User(2004,"李雷4","男",1000.123,new Date());
data.add(user1);
data.add(user2);
data.add(user3);
data.add(user4);
//創(chuàng)建ExcelWriter對對象并設置用哪個Class(數(shù)據(jù)類型)去寫
ExcelWriter excelWriter = EasyExcel.write(fileName, User.class).build();
//創(chuàng)建sheet
WriteSheet writeSheet = EasyExcel.writerSheet("用戶信息").build();
//模擬重復寫入,模擬重復寫入5次
for (int i = 0; i < 5; i++) {
excelWriter.write(data, writeSheet);
}
//關(guān)閉流
excelWriter.finish();
}
8)重復的寫到Excel的不同sheet中
/**
* 重復寫到不同sheet中
*/
@Test
public void writeExcel8() {
//創(chuàng)建文件保存的位置,以及文件名
String fileName="user8.xlsx";
//構(gòu)建數(shù)據(jù)
List<User> data = new ArrayList<>();
User user1 = new User(2001,"李雷1","男",1000.123,new Date());
User user2 = new User(2002,"李雷2","男",1000.123,new Date());
User user3 = new User(2003,"李雷3","男",1000.123,new Date());
User user4 = new User(2004,"李雷4","男",1000.123,new Date());
data.add(user1);
data.add(user2);
data.add(user3);
data.add(user4);
//創(chuàng)建ExcelWriter對對象并設置用哪個Class(數(shù)據(jù)類型)去寫
ExcelWriter excelWriter = EasyExcel.write(fileName, User.class).build();
//模擬重復寫入,模擬重復寫入5次
for (int i = 0; i < 5; i++) {
//創(chuàng)建sheet(因為寫入到不同的sheet,所以需要多次創(chuàng)建sheet)
//WriteSheet writeSheet = EasyExcel.writerSheet(i,"用戶信息"+i).build(); //用下面的格式也可以
WriteSheet writeSheet = EasyExcel.writerSheet("用戶信息"+i).build();
excelWriter.write(data, writeSheet);
}
//關(guān)閉流
excelWriter.finish();
}
9)日期、數(shù)字類型格式化
對于日期和數(shù)字有時候我們需要對其展示的樣式進行格式化,easyexcel提供了一下 注解 @DateTimeFormat : 日期格式化 @NumberFormat : 數(shù)字格式化(小數(shù)或者百分數(shù))
寫Excel的Java對象類型
/**
* 創(chuàng)建User類,用于構(gòu)建向Excel表格中寫數(shù)據(jù)的類型;
* @ExcelProperty:這個注解是EasyExcel提供,用于生成Excel表格頭
*/
public class User {
@ExcelProperty("用戶編號")
private Integer userId;
@ExcelProperty("姓名")
private String userName;
@ExcelProperty("性別")
private String gender;
//格式化小數(shù)類型,如果是百分數(shù)那么定義為 #.##% 比如:9.12%
@NumberFormat("#.##")
@ExcelProperty("工資")
private Double salary;
//格式化時間
@DateTimeFormat("yyyy年MM月dd日 HH時mm分ss秒")
@ExcelProperty("入職時間")
private Date hireDate;
}
向Excel中寫數(shù)據(jù)
/**
* 日期、數(shù)字格式化
*/
@Test
public void writeExcel9() {
//創(chuàng)建文件保存的位置,以及文件名
String fileName="user9.xlsx";
//構(gòu)建數(shù)據(jù)
List<User> data = new ArrayList<>();
User user1 = new User(2001,"李雷1","男",1000.12223,new Date());
User user2 = new User(2002,"李雷2","男",1000.12223,new Date());
User user3 = new User(2003,"李雷3","男",1000.12223,new Date());
User user4 = new User(2004,"李雷4","男",1000.13323,new Date());
data.add(user1);
data.add(user2);
data.add(user3);
data.add(user4);
EasyExcel.write(fileName, User.class).sheet("用戶信息").doWrite(data);
}
10)寫入圖片到Excel
寫Excel的Java對象類型
/**
* 構(gòu)建向Excel中寫圖片的類 支持5種數(shù)據(jù)類型的圖片類型
* 1. 圖片可以是一個File格式
* 2. 圖片可以是一個InputStream輸入流的方式
* 3. 圖片可以是一個byte[]數(shù)組的方式
* 4. 圖片可以是 一個網(wǎng)絡的java.net.URL對象方式
* 5. 圖片也可以是一個String類型方式(當是String類型是,需要StringImageConverter類型轉(zhuǎn)換器)
*/
@ContentRowHeight(100) // 內(nèi)容高度
@ColumnWidth(100 / 8) // 列寬
public class ImageData {
// 使用抽象文件表示一個圖片
private File file;
// 使用輸入流保存一個圖片
private InputStream inputStream;
/**
* 當使用String類型保存一個圖片的時候需要使用StringImageConverter轉(zhuǎn)換器
*/
@ExcelProperty(converter = StringImageConverter.class)
private String string;
// 使用二進制數(shù)據(jù)保存為一個圖片
private byte[] byteArray;
// 使用網(wǎng)絡鏈接保存一個圖片
private URL url;
}
向Excel中寫數(shù)據(jù)
/**
* 將圖片寫入到Excel表格中
* EasyExcel提供了5種數(shù)據(jù)格式進行圖片寫入
* @throws IOException
*/
@Test
public void writeExcel10() throws IOException {
//創(chuàng)建文件保存的位置,以及文件名
String fileName="user10.xlsx";
List<ImageData> list = new ArrayList<ImageData>();
ImageData imageData = new ImageData();
//根據(jù)File寫入
imageData.setFile(new File("imgs/img.png"));
//根據(jù)InputStream寫入
imageData.setInputStream(new FileInputStream("imgs/img.png"));
//根據(jù)String類型寫入
imageData.setString("imgs/img.png");
/*
* 使用二進制方式寫入步驟:
* 1. 獲取文件大小
* 2. 讀成二進制流
*/
File file = new File("imgs/img.png");
//創(chuàng)建一個指定大小的二進制數(shù)組
byte[] byteArray = new byte[(int)file.length()];
FileInputStream in = new FileInputStream(file);
//將文件流寫入到二進制數(shù)組中
in.read(byteArray, 0, (int)file.length());
imageData.setByteArray(byteArray);
//只用網(wǎng)絡鏈接
imageData.setUrl(new URL("https://pics5.baidu.com/feed/e850352ac65c10384dcf6805a7540815b17e890b.jpeg?token=46fd105a95d8754d3daf93de7e8a7f6f"));
list.add(imageData);
EasyExcel.write(fileName, ImageData.class).sheet().doWrite(list);
//關(guān)閉輸入流
in.close();
}
11)設置寫入Excel的列寬行高設置
寫Excel的Java對象類型
@ContentRowHeight(30) //設置內(nèi)容高度
@HeadRowHeight(40) //設置標題高度
@ColumnWidth(25) //設置列寬
public class WidthAndHeightData {
@ExcelProperty("字符串標題")
private String string;
@ExcelProperty("日期標題")
private Date date;
@ColumnWidth(50) //設置列寬(可以修飾類,也可以修飾具體屬性)
@ExcelProperty("數(shù)字標題")
private Double doubleData;
}
向Excel中寫數(shù)據(jù)
/**
* 設置Excel的列寬行高
*/
@Test
public void writeExcel11(){
//創(chuàng)建文件保存的位置,以及文件名
String fileName="user11.xlsx";
//構(gòu)建數(shù)據(jù)
List<WidthAndHeightData> list = new ArrayList<WidthAndHeightData>();
WidthAndHeightData wahd = new WidthAndHeightData();
wahd.setString("小明");
wahd.setDoubleData(200.12);
wahd.setDate(new Date());
list.add(wahd);
//寫數(shù)據(jù)
EasyExcel.write(fileName, WidthAndHeightData.class).sheet("信息").doWrite(list);
}
12)通過注解形式設置寫入Excel的樣式
寫Excel的Java對象類型
//頭背景設置成紅色 IndexedColors.RED.getIndex()
@HeadStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 10)
//頭字體設置成20
@HeadFontStyle(fontHeightInPoints = 20)
//內(nèi)容的背景設置成綠色 IndexedColors.GREEN.getIndex()
@ContentStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 17)
//內(nèi)容字體設置成20
@ContentFontStyle(fontHeightInPoints = 20)
public class DemoStyleData {
// 字符串的頭背景設置成粉紅 IndexedColors.PINK.getIndex()
@HeadStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 14)
// 字符串的頭字體設置成20
@HeadFontStyle(fontHeightInPoints = 30)
// 字符串的內(nèi)容的背景設置成天藍 IndexedColors.SKY_BLUE.getIndex()
@ContentStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 40)
// 字符串的內(nèi)容字體設置成20
@ContentFontStyle(fontHeightInPoints = 30)
@ExcelProperty("字符串標題")
private String string;
@ExcelProperty("日期標題")
private Date date;
@ExcelProperty("數(shù)字標題")
private Double doubleData;
}
向Excel中寫數(shù)據(jù)
/**
* 注解形式設置Excel樣式
*/
@Test`在這里插入代碼片`
public void writeExcel12(){
//創(chuàng)建文件保存的位置,以及文件名
String fileName="user12.xlsx";
//構(gòu)建數(shù)據(jù)
List<DemoStyleData> list = new ArrayList<>();
DemoStyleData dsld = new DemoStyleData();
dsld.setDate(new Date());
dsld.setDoubleData(200.12);
dsld.setString("韓梅梅");
list.add(dsld);
EasyExcel.write(fileName, DemoStyleData.class).sheet("信息").doWrite(list);
}
13)合并單元格
寫Excel的Java對象類型
/*
* @OnceAbsoluteMerge: 指定從哪一行開始,哪一行結(jié)束,哪一列開始,哪一列結(jié)束,進行合并單元格
* firstRowIndex : 起始行索引 從0開始
* lastRowIndex : 結(jié)束行索引
* firstColumnIndex: 起始列索引 從0開始
* lastColumnIndex : 結(jié)束列索引
* 例如: 第2-3行,2-3列進行合并
*/
@OnceAbsoluteMerge(firstRowIndex = 1,lastRowIndex = 2,firstColumnIndex = 1,lastColumnIndex = 2)
public class DemoMergeData {
//每隔兩行合并一次(豎著合并單元格)
//@ContentLoopMerge(eachRow = 2)
@ExcelProperty("字符串標題")
private String string;
@ExcelProperty("日期標題")
private Date date;
@ExcelProperty("數(shù)字標題")
private Double doubleData;
}
向Excel中寫數(shù)據(jù)
/**
* 合并單元格
*/
@Test
public void writeExcel13(){
//創(chuàng)建文件保存的位置,以及文件名
String fileName="user13.xlsx";
//構(gòu)建數(shù)據(jù)
List<DemoMergeData> list = new ArrayList<>();
DemoMergeData dmd = new DemoMergeData();
dmd.setDate(new Date());
dmd.setDoubleData(200.12);
dmd.setString("韓梅梅");
DemoMergeData dmd2 = new DemoMergeData();
dmd2.setDate(new Date());
dmd2.setDoubleData(200.12);
dmd2.setString("韓梅梅");
DemoMergeData dmd3 = new DemoMergeData();
dmd3.setDate(new Date());
dmd3.setDoubleData(200.12);
dmd3.setString("韓梅梅");
DemoMergeData dmd4 = new DemoMergeData();
dmd4.setDate(new Date());
dmd4.setDoubleData(200.12);
dmd4.setString("韓梅梅");
DemoMergeData dmd5 = new DemoMergeData();
dmd5.setDate(new Date());
dmd5.setDoubleData(200.12);
dmd5.setString("韓梅梅");
list.add(dmd);
list.add(dmd2);
list.add(dmd3);
list.add(dmd4);
list.add(dmd5);
EasyExcel.write(fileName, DemoMergeData.class).sheet("信息").doWrite(list);
}
3.讀Excel
1)最簡單的讀取Excel
Excel表格數(shù)據(jù)類型

盛裝數(shù)據(jù)的Java對象
/**
* 承裝Excel表格數(shù)據(jù)的類
* 注意點: Java類中的屬性的順序和Excel中的列頭的順序是相同的
*/
public class DemoData {
private String name;
private Date hireDate;
private Double salary;
}
讀取Excel數(shù)據(jù)
/*
* 最簡單的讀取Excel內(nèi)容(方式一)
* 默認讀取Excel文件中的第一個sheet
*/
@Test
public void testRead1() {
//讀取的文件路徑
String fileName="user11.xlsx";
Class<DemoData> head = DemoData.class; //創(chuàng)建一個數(shù)據(jù)格式來承裝讀取到數(shù)據(jù)
//讀取數(shù)據(jù)
EasyExcel.read(fileName, head, new AnalysisEventListener<DemoData>() {
/**
* 解析每一條數(shù)據(jù)的時候被調(diào)用
*/
@Override
public void invoke(DemoData data, AnalysisContext context) {
//在這里操作,將解析的每一條數(shù)據(jù)保存到數(shù)據(jù)庫中,在這里可以調(diào)用數(shù)據(jù)庫
System.out.println("解析的數(shù)據(jù)為: "+data);
}
/**
* 解析完所有數(shù)據(jù)的時候被調(diào)用
*/
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
System.out.println("數(shù)據(jù)解析完成..........");
}
}).sheet().doRead();
}
/*
* 最簡單的讀取Excel內(nèi)容(方式二)
* 默認讀取Excel文件中的第一個sheet
*/
@Test
public void testRead2() {
//讀取的文件路徑
String fileName="user11.xlsx";
Class<DemoData> head = DemoData.class; //創(chuàng)建一個數(shù)據(jù)格式來承裝讀取到數(shù)據(jù)
//創(chuàng)建ExcelReader對象
ExcelReader excelReader = EasyExcel.read(fileName, head, new AnalysisEventListener<DemoData>() {
@Override
public void invoke(DemoData data, AnalysisContext context) {
System.out.println("讀取到的數(shù)據(jù)為:"+data);
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
System.out.println("數(shù)據(jù)解析已完成");
}
}).build();
//創(chuàng)建sheet對象,并讀取Excel的第1個sheet(下標從0開始)
ReadSheet readSheet = EasyExcel.readSheet(0).build();
excelReader.read(readSheet);
//關(guān)閉流操作,在讀取文件時會創(chuàng)建臨時文件,如果不關(guān)閉,磁盤爆掉
excelReader.finish();
}
2)根據(jù)Excel中指定的列名或者列的下標讀取指定列的數(shù)據(jù)
盛裝數(shù)據(jù)的Java對象
public class IndexOrNameData {
/**
* 強制讀取第三個 這里不建議 index 和 name 同時用,要么一個對象只用index,要么一個對象只用name去匹配
*/
@ExcelProperty(index = 2)
private Double doubleData;
/**
* 用名字去匹配,這里需要注意,如果名字重復,會導致只有一個字段讀取到數(shù)據(jù)
*/
@ExcelProperty("字符串標題")
private String string;
@ExcelProperty("日期標題")
private Date date;
}
讀取Excel數(shù)據(jù)操作
/*
* 根據(jù)名稱或者下標獲取指定的Excel表格數(shù)據(jù)
*/
@Test
public void testRead3() {
//讀取的文件路徑
String fileName="user11.xlsx";
Class<IndexOrNameData> head = IndexOrNameData.class; //創(chuàng)建一個數(shù)據(jù)格式來承裝讀取到數(shù)據(jù)
//讀取數(shù)據(jù)
EasyExcel.read(fileName, head, new AnalysisEventListener<IndexOrNameData>() {
/**
* 解析每一條數(shù)據(jù)的時候被調(diào)用
*/
@Override
public void invoke(IndexOrNameData data, AnalysisContext context) {
//在這里操作,將解析的每一條數(shù)據(jù)保存到數(shù)據(jù)庫中,在這里可以調(diào)用數(shù)據(jù)庫
System.out.println("解析的數(shù)據(jù)為: "+data);
}
/**
* 解析完所有數(shù)據(jù)的時候被調(diào)用
*/
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
System.out.println("數(shù)據(jù)解析完成..........");
}
}).sheet().doRead();
}
3)格式化Excel中的數(shù)據(jù)格式(例如時間)
盛裝數(shù)據(jù)的Java對象
/**
* 定義需要被格式化的字段
* 如果使用@NumberFormat("#.##")注解,建議數(shù)據(jù)類型采用String,如果使用double可能不能被格式化
*/
public class ConverterData {
@NumberFormat("#.#")
@ExcelProperty("數(shù)字標題")
private String salary;
@DateTimeFormat("yyyy-MM-dd HH:mm:ss")
@ExcelProperty("日期標題")
private Date hireDate;
}
讀取Excel數(shù)據(jù)操作
/*
* 格式化Excel中的數(shù)據(jù)格式(例如時間)
*/
@Test
public void testRead4() {
//讀取的文件路徑
String fileName="user11.xlsx";
Class<ConverterData> head = ConverterData.class; //創(chuàng)建一個數(shù)據(jù)格式來承裝讀取到數(shù)據(jù)
//讀取數(shù)據(jù)
EasyExcel.read(fileName, head, new AnalysisEventListener<ConverterData>() {
/**
* 解析每一條數(shù)據(jù)的時候被調(diào)用
*/
@Override
public void invoke(ConverterData data, AnalysisContext context) {
//在這里操作,將解析的每一條數(shù)據(jù)保存到數(shù)據(jù)庫中,在這里可以調(diào)用數(shù)據(jù)庫
System.out.println("解析的數(shù)據(jù)為: "+data);
}
/**
* 解析完所有數(shù)據(jù)的時候被調(diào)用
*/
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
System.out.println("數(shù)據(jù)解析完成..........");
}
}).sheet().doRead();
}
4)讀取多個或者全部的Sheet
盛裝數(shù)據(jù)的Java對象
/**
* 承裝Excel表格數(shù)據(jù)的類
* 注意點: Java類中的屬性的順序和Excel中的列頭的順序是相同的
*/
public class DemoData {
private String name;
private Date hireDate;
private Double salary;
}
讀取Excel數(shù)據(jù)操作
/*
* 讀取Excel中的多個或者全部sheet
*/
@Test
public void testRead5() {
//讀取的文件路徑
String fileName="user11.xlsx";
Class<DemoData> head = DemoData.class; //創(chuàng)建一個數(shù)據(jù)格式來承裝讀取到數(shù)據(jù)
/**
* 讀取全部sheet
*/
EasyExcel.read(fileName, head, new AnalysisEventListener<DemoData>() {
@Override
public void invoke(DemoData data, AnalysisContext context) {
// 每解析一條數(shù)據(jù)被調(diào)用一次
System.out.println("解析的數(shù)據(jù)為: "+data);
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
// 數(shù)據(jù)解析完成之后被調(diào)用
System.out.println("數(shù)據(jù)解析完成......");
}
}).doReadAll();
System.out.println("============================================================");
/**
* 讀取其中的某幾個sheet
*/
//構(gòu)建ExcelReader對象
ExcelReader excelReader = EasyExcel.read(fileName).build();
//創(chuàng)建想要獲取的sheet對象
ReadSheet sheet1 = EasyExcel.readSheet(0).head(DemoData.class).registerReadListener(new AnalysisEventListener<DemoData>() {
@Override
public void invoke(DemoData data, AnalysisContext context) {
// 每解析一條數(shù)據(jù)被調(diào)用一次
System.out.println("解析的數(shù)據(jù)為: "+data);
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
// 數(shù)據(jù)解析完成之后被調(diào)用
System.out.println("數(shù)據(jù)解析完成......");
}
}).build();
ReadSheet sheet2 = EasyExcel.readSheet(2).head(DemoData.class).registerReadListener(new AnalysisEventListener<DemoData>() {
@Override
public void invoke(DemoData data, AnalysisContext context) {
// 每解析一條數(shù)據(jù)被調(diào)用一次
System.out.println("解析的數(shù)據(jù)為: "+data);
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
// 數(shù)據(jù)解析完成之后被調(diào)用
System.out.println("數(shù)據(jù)解析完成......");
}
}).build();
//讀取sheet
excelReader.read(sheet1,sheet2);
//關(guān)閉
excelReader.finish();
}
4.填充Excel
1)簡單填充
創(chuàng)建Excel模板格式 填充單個屬性使用{}作為占位符,在大括號里面定義屬性名稱,如果{}想不作為占位符展示出來,可以使用反斜杠進行轉(zhuǎn)義.

填充數(shù)據(jù)的Java類
public class FillData {
private String name;
private double number;
}
填充的代碼
/**
* 簡單的單個對象填充
*/
@Test
public void excelFull() {
//讀取模板文件
String templateFileName="templateFileName.xlsx";
//通過模板文件生成的填充之后的文件
String fullFile="fullFile.xlsx";
//構(gòu)建要填充的數(shù)據(jù)
FillData data = new FillData();
data.setName("張三");
data.setNumber(5.2);
//填充操作
EasyExcel.write(fullFile).withTemplate(templateFileName).sheet().doFill(data);
}
填充之后的效果

2)列表填充
填充數(shù)據(jù)的Java類
public class FillData {
private String name;
private double number;
}
填充的代碼
/**
* 簡單的列表對象填充
*/
@Test
public void excelFull2() {
//讀取模板文件
String templateFileName="templateFileName2.xlsx";
//通過模板文件生成的填充之后的文件
String fullFile="fullFile2.xlsx";
//構(gòu)建要填充的數(shù)據(jù)列表
List<FillData> list = new ArrayList<FillData>();
FillData data1 = new FillData();
data1.setName("張三");
data1.setNumber(5.2);
FillData data2 = new FillData();
data2.setName("張三");
data2.setNumber(5.2);
list.add(data1);
list.add(data2);
//填充操作
EasyExcel.write(fullFile).withTemplate(templateFileName).sheet().doFill(list);
}
填充之后的效果

5.Web操作(Excel上傳/下載)
1) Excel下載
HTML
<a href="${pageContext.request.contextPath }/DownLoadExcel" rel="external nofollow" >下載</a>
封裝數(shù)據(jù)的Java類
public class User {
@ExcelProperty("用戶編號")
private Integer userId;
@ExcelProperty("用戶名稱")
private String userName;
@ExcelProperty("用戶性別")
private String gender;
@ExcelProperty("創(chuàng)建時間")
private Date createTime;
}
下載操作
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/**
* EasyExcel下載步驟
*/
//設置響應頭
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
//設置防止文件名中文亂碼
String fileName = URLEncoder.encode("中文文件名","utf-8");
response.setHeader("Content-disposition", "attachment;filename="+ fileName + ".xlsx");
//構(gòu)建寫入到Excel中的數(shù)據(jù)(此數(shù)據(jù)可以從數(shù)據(jù)庫中獲取)
List<User> users = new ArrayList<>();
User user1 = new User(1001, "李雷1", "男", new Date());
User user2 = new User(1002, "李雷2", "男", new Date());
User user3 = new User(1003, "李雷3", "男", new Date());
users.add(user1);
users.add(user2);
users.add(user3);
EasyExcel.write(response.getOutputStream(),User.class).sheet("用戶信息").doWrite(users);
}
6.Excel上傳
1)前端頁面
<form action="${pageContext.request.contextPath }/UploadExcelServlet" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" value="上傳">
</form>
2)接收從Excel中獲取到的數(shù)據(jù)
public class User {
@ExcelProperty("用戶編號")
private Integer userId;
@ExcelProperty("用戶名稱")
private String userName;
@ExcelProperty("用戶性別")
private String gender;
@ExcelProperty("創(chuàng)建時間")
private Date createTime;
}
3)上傳操作
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload fileUpload = new ServletFileUpload(factory);
//設置單個文件為3M
fileUpload.setFileSizeMax(1024*1024*3);
//總文件大小為30M
fileUpload.setSizeMax(1024*1024*3*10);
try {
List<FileItem> list = fileUpload.parseRequest(req);
for (FileItem fileItem : list) {
//判斷是否為附件
if(!fileItem.isFormField()) {
//是附件
InputStream inputStream = fileItem.getInputStream();
EasyExcel.read(inputStream,User.class,new AnalysisEventListener<User>() {
@Override
public void doAfterAllAnalysed(AnalysisContext arg0) {
System.out.println("Excel全部讀完被執(zhí)行......");
}
@Override
public void invoke(User data, AnalysisContext arg1) {
//讀完一行就執(zhí)行一次(調(diào)用數(shù)據(jù)庫進行插入操作)
System.out.println("解析一行: "+data);
}
}).sheet().doRead();
}else {
//普通表單
}
}
} catch (FileUploadException e) {
e.printStackTrace();
}
//上傳完成進行轉(zhuǎn)發(fā)或者重定向
}
以上就是一篇文章帶你玩轉(zhuǎn)Java EasyExcel(Excel報表必學)的詳細內(nèi)容,更多關(guān)于Java EasyExcel使用的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
簡單講解在Java編程中實現(xiàn)設計模式中的單例模式結(jié)構(gòu)
這篇文章主要介紹了簡單講解在Java編程中實現(xiàn)設計模式中的單例模式結(jié)構(gòu),設計模式是最基本直白簡單的一種設計模式,需要的朋友可以參考下2016-04-04
基于SpringBoot和Hutool工具包實現(xiàn)驗證碼的案例
隨著安全性的要求越來越高,目前項目中很多都會使用驗證碼,只要涉及到登錄,絕大多數(shù)都會有驗證的要求,驗證碼的形式也是多種多樣,更復雜的圖形驗證碼和行為驗證碼已經(jīng)成為了更流行的趨勢,本文給大家介紹了SpringBoot Hutool實現(xiàn)驗證碼的案例,需要的朋友可以參考下2024-05-05
使用IDEA創(chuàng)建maven父子工程項目 (圖文)
本文主要介紹了使用IDEA創(chuàng)建maven父子工程項目,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-04-04
解決IDEA提示:MVC DispatcherServlet servlet contex
在SSM整合配置Spring時出現(xiàn)錯誤,需刪除多余配置文件并重新導入,若屬性解析失敗,清除緩存重啟IDEA,個人經(jīng)驗,供參考2025-08-08

