目錄
?編輯?(一)Apache PoI 使用
?(二)EasyPoi使用
?(三)EasyExcel使用
?寫
讀
最簡單的讀?
最簡單的讀的excel示例?
最簡單的讀的對象?
?(一)Apache PoI 使用
?(二)EasyPoi使用
?(三)EasyExcel使用
官方文檔:
寫Excel | Easy Excel 官網
?寫
使用注解在字段上進行標識
使用最簡單的方法二即可
/*** 最簡單的寫* <p>* 1. 創建excel對應的實體對象 參照{@link DemoData}* <p>* 2. 直接寫即可*/@Testpublic void simpleWrite() {// 注意 simpleWrite在數據量不大的情況下可以使用(5000以內,具體也要看實際情況),數據量大參照 重復多次寫入// 寫法1 JDK8+// since: 3.0.0-beta1String fileName = TestFileUtil.getPath() + "simpleWrite" + System.currentTimeMillis() + ".xlsx";// 這里 需要指定寫用哪個class去寫,然后寫到第一個sheet,名字為模板 然后文件流會自動關閉// 如果這里想使用03 則 傳入excelType參數即可EasyExcel.write(fileName, DemoData.class).sheet("模板").doWrite(() -> {// 分頁查詢數據return data();});// 寫法2fileName = TestFileUtil.getPath() + "simpleWrite" + System.currentTimeMillis() + ".xlsx";// 這里 需要指定寫用哪個class去寫,然后寫到第一個sheet,名字為模板 然后文件流會自動關閉// 如果這里想使用03 則 傳入excelType參數即可EasyExcel.write(fileName, DemoData.class).sheet("模板").doWrite(data());// 寫法3fileName = TestFileUtil.getPath() + "simpleWrite" + System.currentTimeMillis() + ".xlsx";// 這里 需要指定寫用哪個class去寫try (ExcelWriter excelWriter = EasyExcel.write(fileName, DemoData.class).build()) {WriteSheet writeSheet = EasyExcel.writerSheet("模板").build();excelWriter.write(data(), writeSheet);}}
讀
最簡單的讀?
最簡單的讀的excel示例?
最簡單的讀的對象?
@Getter
@Setter
@EqualsAndHashCode
public class DemoData {private String string;private Date date;private Double doubleData;
}
讀的時候涉及到一個監聽器對象,所有讀的時候進行的后續操作一般都放在監聽器中
自定義的監聽器代碼,
阿里巴巴要:因為監聽器不受spring管理,所以你要想在監聽器中操作數據庫,必須按照人家要求使用構造方法傳入
// 有個很重要的點 DemoDataListener 不能被spring管理,要每次讀取excel都要new,然后里面用到spring可以構造方法傳進去
//這個自定義監聽器的功能是定義了一個100的緩沖區,沒當list達到了100則寫入數據庫
@Slf4j // 這個泛型填讀取對象的實體,比如excel 表里對應的實體是user,那這個地方就填user
public class DemoDataListener implements ReadListener<DemoData> {/*** 每隔5條存儲數據庫,實際使用中可以100條,然后清理list ,方便內存回收*/private static final int BATCH_COUNT = 100;/*** 緩存的數據*/private List<DemoData> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);/*** 假設這個是一個DAO,當然有業務邏輯這個也可以是一個service。當然如果不用存儲這個對象沒用。*/private DemoDAO demoDAO;public DemoDataListener() {// 這里是demo,所以隨便new一個。實際使用如果到了spring,請使用下面的有參構造函數demoDAO = new DemoDAO();}/*** 如果使用了spring,請使用這個構造方法。每次創建Listener的時候需要把spring管理的類傳進來** @param demoDAO*/public DemoDataListener(DemoDAO demoDAO) {this.demoDAO = demoDAO;}/*** 這個每一條數據解析都會來調用** @param data one row value. Is is same as {@link AnalysisContext#readRowHolder()}* @param context*/@Overridepublic void invoke(DemoData data, AnalysisContext context) {log.info("解析到一條數據:{}", JSON.toJSONString(data));cachedDataList.add(data);// 達到BATCH_COUNT了,需要去存儲一次數據庫,防止數據幾萬條數據在內存,容易OOMif (cachedDataList.size() >= BATCH_COUNT) {saveData();// 存儲完成清理 listcachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);}}/*** 所有數據解析完成了 都會來調用,上面沒達到100的,沒有觸發保存數據庫
最后就執行這個方法,把遺留的存進去** @param context*/@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {// 這里也要保存數據,確保最后遺留的數據也存儲到數據庫saveData();log.info("所有數據解析完成!");}/*** 加上存儲數據庫*/private void saveData() {log.info("{}條數據,開始存儲數據庫!", cachedDataList.size());demoDAO.save(cachedDataList);log.info("存儲數據庫成功!");}
}
?最簡單的讀
想省事不自定義監聽器對象可以直接參考寫法一
/*** 最簡單的讀* <p>* 1. 創建excel對應的實體對象 參照{@link DemoData}* <p>* 2. 由于默認一行行的讀取excel,所以需要創建excel一行一行的回調監聽器,參照{@link DemoDataListener}* <p>* 3. 直接讀即可*/@Testpublic void simpleRead() {// 寫法1:JDK8+ ,不用額外寫一個DemoDataListener// since: 3.0.0-beta1String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";// 這里默認每次會讀取100條數據 然后返回過來 直接調用使用數據就行// 具體需要返回多少行可以在`PageReadListener`的構造函數設置
//如果使用spring,并且想保存到數據庫,這個泛型填service 或者 dao,從而調用數據庫EasyExcel.read(fileName, DemoData.class, new PageReadListener<DemoData>(dataList -> {for (DemoData demoData : dataList) {log.info("讀取到一條數據{}", JSON.toJSONString(demoData));}})).sheet().doRead();// 寫法2:// 匿名內部類 不用額外寫一個DemoDataListenerfileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";// 這里 需要指定讀用哪個class去讀,然后讀取第一個sheet 文件流會自動關閉EasyExcel.read(fileName, DemoData.class, new ReadListener<DemoData>() {/*** 單次緩存的數據量*/public static final int BATCH_COUNT = 100;/***臨時存儲*/private List<DemoData> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);@Overridepublic void invoke(DemoData data, AnalysisContext context) {cachedDataList.add(data);if (cachedDataList.size() >= BATCH_COUNT) {saveData();// 存儲完成清理 listcachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);}}@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {saveData();}/*** 加上存儲數據庫*/private void saveData() {log.info("{}條數據,開始存儲數據庫!", cachedDataList.size());log.info("存儲數據庫成功!");}}).sheet().doRead();// 有個很重要的點 DemoDataListener 不能被spring管理,要每次讀取excel都要new,然后里面用到spring可以構造方法傳進去// 寫法3:fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";// 這里 需要指定讀用哪個class去讀,然后讀取第一個sheet 文件流會自動關閉EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).sheet().doRead();// 寫法4fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";// 一個文件一個readertry (ExcelReader excelReader = EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).build()) {// 構建一個sheet 這里可以指定名字或者noReadSheet readSheet = EasyExcel.readSheet(0).build();// 讀取一個sheetexcelReader.read(readSheet);}}