EasyExcel
EasyExcel是阿里推出的一款高性能的開源excel讀寫框架,主要解決讀大文件poi占內存大的問題,同時也提供了一些簡單的excel操作API。2.0.5以后的改動比較大,結合網上的,自己整理了一個demo,方便以后復用。
文檔:https://www.yuque.com/easyexcel/doc/easyexcel
本文git:https://gitee.com/proper128/springboot-easyexcel
目錄
1. 引入依賴
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.3</version>
</dependency>
2. 工具類 EasyExcelUtil
public class EasyExcelUtil {
/**
* web導出excel文件
* @param response response
* @param list 實體數據
* @param fileName 文件名
* @param sheetName sheet名
* @param clazz 實體類
* @throws Exception
*/
public static void exprotExcel(HttpServletResponse response, List<?> list, String fileName, String sheetName,Class<?> clazz)throws Exception {
EasyExcel.write(getOutputStream(fileName,response), clazz)
.sheet(sheetName)
.doWrite(list);
}
/**
* 導出文件時為Writer生成OutputStream
* @param fileName
* @param response
* @return
*/
private static OutputStream getOutputStream(String fileName, HttpServletResponse response) throws Exception {
try {
fileName = URLEncoder.encode(fileName, "UTF-8");
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf8");
response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".xlsx");
response.setHeader("Pragma", "public");
response.setHeader("Cache-Control", "no-store");
response.addHeader("Cache-Control", "max-age=0");
return response.getOutputStream();
} catch (IOException e) {
throw new Exception("導出excel表格失敗!", e);
}
}
/**
* 同步無模型讀(默認讀取sheet0,從第2行開始讀)
*
* @param filePath
* @return
*/
public static List<Map<Integer, String>> syncRead(String filePath) {
return EasyExcelFactory.read(filePath).sheet().doReadSync();
}
/**
* 同步無模型讀(默認表頭占一行,從第2行開始讀)
*
* @param filePath
* @param sheetNo sheet頁號,從0開始
* @return
*/
public static List<Map<Integer, String>> syncRead(String filePath, Integer sheetNo) {
return EasyExcelFactory.read(filePath).sheet(sheetNo).doReadSync();
}
/**
* 同步無模型讀(指定sheet和表頭占的行數)
*
* @param inputStream
* @param sheetNo sheet頁號,從0開始
* @param headRowNum 表頭占的行數,從0開始(如果要連表頭一起讀出來則傳0)
* @return List<Map < colNum, cellValue>>
*/
public static List<Map<Integer, String>> syncRead(InputStream inputStream, Integer sheetNo, Integer headRowNum) {
return EasyExcelFactory.read(inputStream).sheet(sheetNo).headRowNumber(headRowNum).doReadSync();
}
/**
* 同步無模型讀(指定sheet和表頭占的行數)
*
* @param file
* @param sheetNo sheet頁號,從0開始
* @param headRowNum 表頭占的行數,從0開始(如果要連表頭一起讀出來則傳0)
* @return List<Map < colNum, cellValue>>
*/
public static List<Map<Integer, String>> syncRead(File file, Integer sheetNo, Integer headRowNum) {
return EasyExcelFactory.read(file).sheet(sheetNo).headRowNumber(headRowNum).doReadSync();
}
/**
* 同步無模型讀(指定sheet和表頭占的行數)
*
* @param filePath
* @param sheetNo sheet頁號,從0開始
* @param headRowNum 表頭占的行數,從0開始(如果要連表頭一起讀出來則傳0)
* @return List<Map < colNum, cellValue>>
*/
public static List<Map<Integer, String>> syncRead(String filePath, Integer sheetNo, Integer headRowNum) {
return EasyExcelFactory.read(filePath).sheet(sheetNo).headRowNumber(headRowNum).doReadSync();
}
/**
* 同步按模型讀(默認讀取sheet0,從第2行開始讀)
*
* @param filePath
* @param clazz 模型的類類型(excel數據會按該類型轉換成對象)
* @return
*/
public static List<T> syncReadModel(String filePath, Class clazz) {
return EasyExcelFactory.read(filePath).sheet().head(clazz).doReadSync();
}
/**
* 同步按模型讀(默認表頭占一行,從第2行開始讀)
*
* @param filePath
* @param clazz 模型的類類型(excel數據會按該類型轉換成對象)
* @param sheetNo sheet頁號,從0開始
* @return
*/
public static List<T> syncReadModel(String filePath, Class clazz, Integer sheetNo) {
return EasyExcelFactory.read(filePath).sheet(sheetNo).head(clazz).doReadSync();
}
/**
* 同步按模型讀(指定sheet和表頭占的行數)
*
* @param inputStream
* @param clazz 模型的類類型(excel數據會按該類型轉換成對象)
* @param sheetNo sheet頁號,從0開始
* @param headRowNum 表頭占的行數,從0開始(如果要連表頭一起讀出來則傳0)
* @return
*/
public static List<T> syncReadModel(InputStream inputStream, Class clazz, Integer sheetNo, Integer headRowNum) {
return EasyExcelFactory.read(inputStream).sheet(sheetNo).headRowNumber(headRowNum).head(clazz).doReadSync();
}
/**
* 同步按模型讀(指定sheet和表頭占的行數)
*
* @param file
* @param clazz 模型的類類型(excel數據會按該類型轉換成對象)
* @param sheetNo sheet頁號,從0開始
* @param headRowNum 表頭占的行數,從0開始(如果要連表頭一起讀出來則傳0)
* @return
*/
public static List<T> syncReadModel(File file, Class clazz, Integer sheetNo, Integer headRowNum) {
return EasyExcelFactory.read(file).sheet(sheetNo).headRowNumber(headRowNum).head(clazz).doReadSync();
}
/**
* 同步按模型讀(指定sheet和表頭占的行數)
*
* @param filePath
* @param clazz 模型的類類型(excel數據會按該類型轉換成對象)
* @param sheetNo sheet頁號,從0開始
* @param headRowNum 表頭占的行數,從0開始(如果要連表頭一起讀出來則傳0)
* @return
*/
public static List<T> syncReadModel(String filePath, Class clazz, Integer sheetNo, Integer headRowNum) {
return EasyExcelFactory.read(filePath).sheet(sheetNo).headRowNumber(headRowNum).head(clazz).doReadSync();
}
/**
* 異步無模型讀(默認讀取sheet0,從第2行開始讀)
*
* @param excelListener 監聽器,在監聽器中可以處理行數據LinkedHashMap,表頭數據,異常處理等
* @param filePath 表頭占的行數,從0開始(如果要連表頭一起讀出來則傳0)
* @return
*/
public static void asyncRead(String filePath, AnalysisEventListener<T> excelListener) {
EasyExcelFactory.read(filePath, excelListener).sheet().doRead();
}
/**
* 異步無模型讀(默認表頭占一行,從第2行開始讀)
*
* @param filePath 表頭占的行數,從0開始(如果要連表頭一起讀出來則傳0)
* @param excelListener 監聽器,在監聽器中可以處理行數據LinkedHashMap,表頭數據,異常處理等
* @param sheetNo sheet頁號,從0開始
* @return
*/
public static void asyncRead(String filePath, AnalysisEventListener<T> excelListener, Integer sheetNo) {
EasyExcelFactory.read(filePath, excelListener).sheet(sheetNo).doRead();
}
/**
* 異步無模型讀(指定sheet和表頭占的行數)
*
* @param inputStream
* @param excelListener 監聽器,在監聽器中可以處理行數據LinkedHashMap,表頭數據,異常處理等
* @param sheetNo sheet頁號,從0開始
* @param headRowNum 表頭占的行數,從0開始(如果要連表頭一起讀出來則傳0)
* @return
*/
public static void asyncRead(InputStream inputStream, AnalysisEventListener<T> excelListener, Integer sheetNo, Integer headRowNum) {
EasyExcelFactory.read(inputStream, excelListener).sheet(sheetNo).headRowNumber(headRowNum).doRead();
}
/**
* 異步無模型讀(指定sheet和表頭占的行數)
*
* @param file
* @param excelListener 監聽器,在監聽器中可以處理行數據LinkedHashMap,表頭數據,異常處理等
* @param sheetNo sheet頁號,從0開始
* @param headRowNum 表頭占的行數,從0開始(如果要連表頭一起讀出來則傳0)
* @return
*/
public static void asyncRead(File file, AnalysisEventListener<T> excelListener, Integer sheetNo, Integer headRowNum) {
EasyExcelFactory.read(file, excelListener).sheet(sheetNo).headRowNumber(headRowNum).doRead();
}
/**
* 異步無模型讀(指定sheet和表頭占的行數)
*
* @param filePath
* @param excelListener 監聽器,在監聽器中可以處理行數據LinkedHashMap,表頭數據,異常處理等
* @param sheetNo sheet頁號,從0開始
* @param headRowNum 表頭占的行數,從0開始(如果要連表頭一起讀出來則傳0)
* @return
*/
public static void asyncRead(String filePath, AnalysisEventListener<T> excelListener, Integer sheetNo, Integer headRowNum) {
EasyExcelFactory.read(filePath, excelListener).sheet(sheetNo).headRowNumber(headRowNum).doRead();
}
/**
* 異步按模型讀取(默認讀取sheet0,從第2行開始讀)
*
* @param filePath
* @param excelListener 監聽器,在監聽器中可以處理行數據LinkedHashMap,表頭數據,異常處理等
* @param clazz 模型的類類型(excel數據會按該類型轉換成對象)
*/
public static void asyncReadModel(String filePath, AnalysisEventListener<T> excelListener, Class clazz) {
EasyExcelFactory.read(filePath, clazz, excelListener).sheet().doRead();
}
/**
* 異步按模型讀取(默認表頭占一行,從第2行開始讀)
*
* @param filePath
* @param excelListener 監聽器,在監聽器中可以處理行數據LinkedHashMap,表頭數據,異常處理等
* @param clazz 模型的類類型(excel數據會按該類型轉換成對象)
* @param sheetNo sheet頁號,從0開始
*/
public static void asyncReadModel(String filePath, AnalysisEventListener<T> excelListener, Class clazz, Integer sheetNo) {
EasyExcelFactory.read(filePath, clazz, excelListener).sheet(sheetNo).doRead();
}
/**
* 異步按模型讀取
*
* @param inputStream
* @param excelListener 監聽器,在監聽器中可以處理行數據LinkedHashMap,表頭數據,異常處理等
* @param clazz 模型的類類型(excel數據會按該類型轉換成對象)
* @param sheetNo sheet頁號,從0開始
* @param headRowNum 表頭占的行數,從0開始(如果要連表頭一起讀出來則傳0)
*/
public static void asyncReadModel(InputStream inputStream, AnalysisEventListener<T> excelListener, Class clazz, Integer sheetNo, Integer headRowNum) {
EasyExcelFactory.read(inputStream, clazz, excelListener).sheet(sheetNo).headRowNumber(headRowNum).doRead();
}
/**
* 異步按模型讀取
*
* @param file
* @param excelListener 監聽器,在監聽器中可以處理行數據LinkedHashMap,表頭數據,異常處理等
* @param clazz 模型的類類型(excel數據會按該類型轉換成對象)
* @param sheetNo sheet頁號,從0開始
* @param headRowNum 表頭占的行數,從0開始(如果要連表頭一起讀出來則傳0)
*/
public static void asyncReadModel(File file, AnalysisEventListener<T> excelListener, Class clazz, Integer sheetNo, Integer headRowNum) {
EasyExcelFactory.read(file, clazz, excelListener).sheet(sheetNo).headRowNumber(headRowNum).doRead();
}
/**
* 異步按模型讀取
*
* @param filePath
* @param excelListener 監聽器,在監聽器中可以處理行數據LinkedHashMap,表頭數據,異常處理等
* @param clazz 模型的類類型(excel數據會按該類型轉換成對象)
* @param sheetNo sheet頁號,從0開始
* @param headRowNum 表頭占的行數,從0開始(如果要連表頭一起讀出來則傳0)
*/
public static void asyncReadModel(String filePath, AnalysisEventListener<T> excelListener, Class clazz, Integer sheetNo, Integer headRowNum) {
EasyExcelFactory.read(filePath, clazz, excelListener).sheet(sheetNo).headRowNumber(headRowNum).doRead();
}
/**
* 無模板寫文件
*
* @param filePath
* @param head 表頭數據
* @param data 表內容數據
*/
public static void write(String filePath, List<List<String>> head, List<List<Object>> data) {
EasyExcel.write(filePath).head(head).sheet().doWrite(data);
}
/**
* 無模板寫文件
*
* @param filePath
* @param head 表頭數據
* @param data 表內容數據
* @param sheetNo sheet頁號,從0開始
* @param sheetName sheet名稱
*/
public static void write(String filePath, List<List<String>> head, List<List<Object>> data, Integer sheetNo, String sheetName) {
EasyExcel.write(filePath).head(head).sheet(sheetNo, sheetName).doWrite(data);
}
/**
* 根據excel模板文件寫入文件
*
* @param filePath
* @param templateFileName
* @param headClazz
* @param data
*/
public static void writeTemplate(String filePath, String templateFileName, Class headClazz, List data) {
EasyExcel.write(filePath, headClazz).withTemplate(templateFileName).sheet().doWrite(data);
}
/**
* 根據excel模板文件寫入文件
*
* @param filePath
* @param templateFileName
* @param data
*/
public static void writeTemplate(String filePath, String templateFileName, List data) {
EasyExcel.write(filePath).withTemplate(templateFileName).sheet().doWrite(data);
}
/**
* 按模板寫文件
*
* @param filePath
* @param headClazz 表頭模板
* @param data 數據
*/
public static void write(String filePath, Class headClazz, List data) {
EasyExcel.write(filePath, headClazz).sheet().doWrite(data);
}
/**
* 按模板寫文件
*
* @param filePath
* @param headClazz 表頭模板
* @param data 數據
* @param sheetNo sheet頁號,從0開始
* @param sheetName sheet名稱
*/
public static void write(String filePath, Class headClazz, List data, Integer sheetNo, String sheetName) {
EasyExcel.write(filePath, headClazz).sheet(sheetNo, sheetName).doWrite(data);
}
/**
* 按模板寫文件
*
* @param filePath
* @param headClazz 表頭模板
* @param data 數據
* @param writeHandler 自定義的處理器,比如設置table樣式,設置超鏈接、單元格下拉框等等功能都可以通過這個實現(需要注冊多個則自己通過鏈式去調用)
* @param sheetNo sheet頁號,從0開始
* @param sheetName sheet名稱
*/
public static void write(String filePath, Class headClazz, List data, WriteHandler writeHandler, Integer sheetNo, String sheetName) {
EasyExcel.write(filePath, headClazz).registerWriteHandler(writeHandler).sheet(sheetNo, sheetName).doWrite(data);
}
/**
* 按模板寫文件(包含某些字段)
*
* @param filePath
* @param headClazz 表頭模板
* @param data 數據
* @param includeCols 過濾包含的字段,根據字段名稱過濾
* @param sheetNo sheet頁號,從0開始
* @param sheetName sheet名稱
*/
public static void writeInclude(String filePath, Class headClazz, List data, Set<String> includeCols, Integer sheetNo, String sheetName) {
EasyExcel.write(filePath, headClazz).includeColumnFiledNames(includeCols).sheet(sheetNo, sheetName).doWrite(data);
}
/**
* 按模板寫文件(排除某些字段)
*
* @param filePath
* @param headClazz 表頭模板
* @param data 數據
* @param excludeCols 過濾排除的字段,根據字段名稱過濾
* @param sheetNo sheet頁號,從0開始
* @param sheetName sheet名稱
*/
public static void writeExclude(String filePath, Class headClazz, List data, Set<String> excludeCols, Integer sheetNo, String sheetName) {
EasyExcel.write(filePath, headClazz).excludeColumnFiledNames(excludeCols).sheet(sheetNo, sheetName).doWrite(data);
}
/**
* 多個sheet頁的數據鏈式寫入
* ExcelUtil.writeWithSheets(outputStream)
* .writeModel(ExcelModel.class, excelModelList, "sheetName1")
* .write(headData, data,"sheetName2")
* .finish();
*
* @param outputStream
* @return
*/
public static EasyExcelWriterFactory writeWithSheets(OutputStream outputStream) {
EasyExcelWriterFactory excelWriter = new EasyExcelWriterFactory(outputStream);
return excelWriter;
}
/**
* 多個sheet頁的數據鏈式寫入
* ExcelUtil.writeWithSheets(file)
* .writeModel(ExcelModel.class, excelModelList, "sheetName1")
* .write(headData, data,"sheetName2")
* .finish();
*
* @param file
* @return
*/
public static EasyExcelWriterFactory writeWithSheets(File file) {
EasyExcelWriterFactory excelWriter = new EasyExcelWriterFactory(file);
return excelWriter;
}
/**
* 多個sheet頁的數據鏈式寫入
* ExcelUtil.writeWithSheets(filePath)
* .writeModel(ExcelModel.class, excelModelList, "sheetName1")
* .write(headData, data,"sheetName2")
* .finish();
*
* @param filePath
* @return
*/
public static EasyExcelWriterFactory writeWithSheets(String filePath) {
EasyExcelWriterFactory excelWriter = new EasyExcelWriterFactory(filePath);
return excelWriter;
}
/**
* 多個sheet頁的數據鏈式寫入(失敗了會返回一個有部分數據的Excel)
* ExcelUtil.writeWithSheets(response, exportFileName)
* .writeModel(ExcelModel.class, excelModelList, "sheetName1")
* .write(headData, data,"sheetName2")
* .finish();
*
* @param response
* @param exportFileName 導出的文件名稱
* @return
*/
public static EasyExcelWriterFactory writeWithSheetsWeb(HttpServletResponse response, String exportFileName) throws IOException {
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
// 這里URLEncoder.encode可以防止中文亂碼
String fileName = URLEncoder.encode(exportFileName, "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
EasyExcelWriterFactory excelWriter = new EasyExcelWriterFactory(response.getOutputStream());
return excelWriter;
}
}
3. 監聽器 UserExcelListener
/**
* @description: 模型解析監聽器--> 2.0.5以后每個模型創建一個監聽器
* 每解析一行會回調invoke()方法,整個excel解析結束會執行doAfterAllAnalysed()方法
* 有個很重要的點 UserExcelListener 不能被spring管理,要每次讀取excel都要new,然后里面用到spring可以構造方法傳進去
* @author: Li Kang
* @create: 2020-05-04 11:08
*/
@Slf4j
public class UserExcelListener<User> extends AnalysisEventListener<User> {
private final List<User> userList = Lists.newArrayList();
/**
* 每隔5條存儲數據庫,實際使用中可以3000條,然后清理list ,方便內存回收
*/
private static final int BATCH_COUNT = 5;
// -----------------------------------------------------------------------------------
/**
* 假設這個是一個DAO,當然有業務邏輯這個也可以是一個service。當然如果不用存儲這個對象沒用。
*/
private UserDAO userDAO;
public UserExcelListener() {
// 這里是demo,所以隨便new一個。實際使用如果到了spring,請使用下面的有參構造函數
userDAO = new UserDAO();
}
/**
* 如果使用了spring,請使用這個構造方法。每次創建Listener的時候需要把spring管理的類傳進來
*
* @param userDAO
*/
public UserExcelListener(UserDAO userDAO) {
this.userDAO = userDAO;
}
// -----------------------------------------------------------------------------------
@Override
public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
log.info("解析到一條頭數據:{}", JSON.toJSONString(headMap));
}
@Override
public void invoke(User user, AnalysisContext context) {
log.info("解析到一條數據:{}", JSON.toJSONString(user));
userList.add(user);
// 實際數據量比較大時,rows里的數據可以存到一定量之后進行批量處理(比如存到數據庫),
// 然后清空列表,以防止內存占用過多造成OOM
// 達到BATCH_COUNT了,需要去存儲一次數據庫,防止數據幾萬條數據在內存,容易OOM
if (userList.size() >= BATCH_COUNT) {
saveUserList();
// 存儲完成清理 list
userList.clear();
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
log.info("read {} rows", userList.size());
// 這里也要保存數據,確保最后遺留的數據也存儲到數據庫
saveUserList();
}
/**
* 在轉換異常 獲取其他異常下會調用本接口。拋出異常則停止讀取。如果這里不拋出異常則 繼續讀取下一行。
*
* @param exception
* @param context
* @throws Exception
*/
@Override
public void onException(Exception exception, AnalysisContext context) {
log.error("解析失敗,但是繼續解析下一行:{}", exception.getMessage());
if (exception instanceof ExcelDataConvertException) {
ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException) exception;
log.error("第{}行,第{}列解析異常,數據為:{}", excelDataConvertException.getRowIndex(),
excelDataConvertException.getColumnIndex(), excelDataConvertException.getCellData());
}
}
public List<User> getRows() {
return userList;
}
/**
* 加上存儲數據庫
*/
private void saveUserList() {
log.info("{}條數據,開始存儲數據庫!", userList.size());
userDAO.save((List<com.lk.model.User>) userList);
log.info("存儲數據庫成功!");
}
}
4. EasyExcelWriterFactory
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import java.io.File;
import java.io.OutputStream;
import java.util.List;
/**
* 自定義EasyExcel寫工廠
*/
public class EasyExcelWriterFactory
{
private int sheetNo = 0;
private ExcelWriter excelWriter = null;
public EasyExcelWriterFactory(OutputStream outputStream) {
excelWriter = EasyExcel.write(outputStream).build();
}
public EasyExcelWriterFactory(File file) {
excelWriter = EasyExcel.write(file).build();
}
public EasyExcelWriterFactory(String filePath) {
excelWriter = EasyExcel.write(filePath).build();
}
/**
* 鏈式模板表頭寫入
* @param headClazz 表頭格式
* @param data 數據 List<ExcelModel> 或者List<List<Object>>
* @return
*/
public EasyExcelWriterFactory writeModel(Class headClazz, List data, String sheetName){
excelWriter.write(data, EasyExcel.writerSheet(this.sheetNo++, sheetName).head(headClazz).build());
return this;
}
/**
* 鏈式自定義表頭寫入
* @param head
* @param data 數據 List<ExcelModel> 或者List<List<Object>>
* @param sheetName
* @return
*/
public EasyExcelWriterFactory write(List<List<String>> head, List data, String sheetName){
excelWriter.write(data, EasyExcel.writerSheet(this.sheetNo++, sheetName).head(head).build());
return this;
}
public void finish() {
excelWriter.finish();
}
}
5. 實體類 User
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
@ExcelProperty(value = "用戶名", index = 0)
private String username ;
/**
* 忽略這個字段
*/
@ExcelIgnore
private String password ;
@ExcelProperty(value = "年齡", index = 1)
private Integer age;
@ExcelProperty(value = "注冊時間", index = 2)
@DateTimeFormat("yyyy/MM/dd")
private Date createTime;
}
6. DAO
/**
* @description: 假設這個是你的DAO存儲。當然還要這個類讓spring管理,當然你不用需要存儲,也不需要這個類。
* @author: Li Kang
* @create: 2020-05-04 17:16
*/
@Slf4j
public class UserDAO {
public void save(List<User> userList) {
// 如果是mybatis,盡量別直接調用多次insert,自己寫一個mapper里面新增一個方法batchInsert,所有數據一次性插入
log.info("insert操作");
}
}
7. Controller
@Controller
public class TestController {
/**
* 導出測試
* @param response
* @throws Exception
*/
@GetMapping("/exportTest")
void exportTest(HttpServletResponse response) throws Exception {
//單sheet,單table導出測試
List<User> userList = Lists.newArrayList();
for (int i = 0; i < 5 ; i++) {
User user = new User("admin"+i,"123"+i,1+i,new Date());
userList.add(user);
}
EasyExcelUtil.exprotExcel(response,userList,"導出測試","sheet單1",User.class);
}
/**
* 上傳測試
* @param file
* @return
* @throws IOException
*/
@PostMapping("upload")
@ResponseBody
public String upload(MultipartFile file) throws IOException {
// EasyExcel.read(file.getInputStream(), User.class, new UploadDataListener(uploadDAO)).sheet().doRead();
EasyExcelUtil.asyncReadModel(file.getInputStream(),new UserExcelListener<>(),User.class,0,0);
return "success";
}
}
8. 測試類
@Slf4j
@SpringBootTest
public class ApplicationTests {
@BeforeEach
void testBefore() {
log.info("測試開始!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
}
@AfterEach
void testAfter() {
log.info("測試結束!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
}
@Test
public void write() {
List<User> userList = Lists.newArrayList();
for (int i = 0; i < 11; i++) {
User user = new User("admin" + i, "123" + i, 18 + i,new Date());
userList.add(user);
}
EasyExcelUtil.write("E:\\3.xlsx", User.class, userList);
}
@Test
public void read() {
String fileName = "E:\\3.xlsx";
// 同步讀
// List<T> ts = EasyExcelUtil.syncReadModel(fileName, User.class);
// log.info(JSON.toJSONString(ts));
// 異步讀
EasyExcelUtil.asyncReadModel(fileName,new UserExcelListener<>(),User.class);
}
}