Hutool-Excel大数据生成-XXOO
生活随笔
收集整理的這篇文章主要介紹了
Hutool-Excel大数据生成-XXOO
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、準備
對于大量數據輸出,采用ExcelWriter容易引起內存溢出,因此有了BigExcelWriter。
* ExcelUtil Excel工具類,讀取的快捷方法都被封裝于此
* ExcelReader Excel讀取器,Excel讀取的封裝,可以直接構造后使用。
* ExcelWriter Excel生成并寫出器,Excel寫出的封裝(寫出到流或者文件),可以直接構造后使用。
?
<!--hutool common 工具包--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.0.7</version></dependency><!--說明 hutool-4.x的poi-ooxml 版本需高于 3.17(別問我3.8版本為啥不行,因為3.17 > 3.8 )hutool-5.x的poi-ooxml 版本需高于 4.1.2 xercesImpl版本高于2.12.0--><!--poi-ooxml--><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.2</version></dependency><!--xercesImpl--><dependency><groupId>xerces</groupId><artifactId>xercesImpl</artifactId><version>2.12.0</version></dependency>二、代碼示例
package com.yl.excel;import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.io.FileUtil; import cn.hutool.json.JSON; import cn.hutool.poi.excel.BigExcelWriter; import cn.hutool.poi.excel.ExcelReader; import cn.hutool.poi.excel.ExcelUtil; import cn.hutool.poi.excel.ExcelWriter; import cn.hutool.poi.excel.sax.Excel03SaxReader; import cn.hutool.poi.excel.sax.Excel07SaxReader; import cn.hutool.poi.excel.sax.handler.RowHandler; import cn.hutool.poi.word.Word07Writer; import com.yl.entity.User; import lombok.extern.slf4j.Slf4j;import java.awt.*; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.concurrent.*;/*** 描述: Excel大數據生成-BigExcelWriter* 對于大量數據輸出,采用ExcelWriter容易引起內存溢出,因此有了BigExcelWriter,使用方法與ExcelWriter完全一致** @author: yanglin* @Date: 2020-07-13-16:19* @Version: 1.0*/ @Slf4j public class HutoolExcel {/*** ExcelUtil Excel工具類,讀取的快捷方法都被封裝于此* ExcelReader Excel讀取器,Excel讀取的封裝,可以直接構造后使用。* ExcelWriter Excel生成并寫出器,Excel寫出的封裝(寫出到流或者文件),可以直接構造后使用。*//*** 創建Excel* @param excelName*/public static void testCreateExcel(String excelName){List<?> row1 = CollUtil.newArrayList("aa", "bb", "cc", "dd", DateUtil.date(), 3.22676575765);List<?> row2 = CollUtil.newArrayList("aa1", "bb1", "cc1", "dd1", DateUtil.date(), 250.7676);List<?> row3 = CollUtil.newArrayList("aa2", "bb2", "cc2", "dd2", DateUtil.date(), 0.111);List<?> row4 = CollUtil.newArrayList("aa3", "bb3", "cc3", "dd3", DateUtil.date(), 35);List<?> row5 = CollUtil.newArrayList("aa4", "bb4", "cc4", "dd4", DateUtil.date(), 28.00);List<List<?>> rows = CollUtil.newArrayList(row1, row2, row3, row4, row5);BigExcelWriter writer= ExcelUtil.getBigWriter(excelName);// 一次性寫出內容,使用默認樣式writer.write(rows);// 關閉writer,釋放內存writer.close();}/*** 創建Word* @param wordName*/public static void testCreateWord(String wordName){Word07Writer writer = new Word07Writer();// 添加段落(標題)writer.addText(new Font("方正小標宋簡體", Font.PLAIN, 22), "我是第一部分", "我是第二部分");// 添加段落(正文)writer.addText(new Font("宋體", Font.PLAIN, 22), "我是正文第一部分", "我是正文第二部分");// 寫出到文件writer.flush(FileUtil.file(wordName));// 關閉writer.close();}/*** Excel讀取-ExcelReader* @param excelName*/public static void readExcel(String excelName){// 讀取Excel中所有行和列,都用列表表示ExcelReader reader = ExcelUtil.getReader(excelName);List<List<Object>> readAll = reader.read();// 讀取為Map列表,默認第一行為標題行,Map中的key為標題,value為標題對應的單元格值。ExcelReader readerMap = ExcelUtil.getReader(excelName);List<Map<String,Object>> readMapAll = readerMap.readAll();// 讀取為Bean列表,Bean中的字段名為標題,字段值為標題對應的單元格值。ExcelReader readerClass = ExcelUtil.getReader("d:/aaa.xlsx");List<Object> all = readerClass.readAll(Object.class);}/*** 流方式讀取Excel2003-Excel03SaxReader* Excel03SaxReader只支持Excel2003格式的Sax讀取。* 在標準的ExcelReader中,如果數據量較大,讀取Excel會非常緩慢,并有可能造成內存溢出。因此針對大數據量的Excel,Hutool封裝了event模式的讀取方式。* @param excelName*/public static void readStream2003Excel(String excelName){// ExcelUtil快速讀取ExcelUtil.read03BySax(excelName, 1, createRowHandler());// 構建對象讀取Excel03SaxReader reader = new Excel03SaxReader(createRowHandler());// reader方法的第二個參數是sheet的序號,-1表示讀取所有sheet,0表示第一個sheet,依此類推。reader.read(excelName, 0);}/*** 首先我們實現一下RowHandler接口,這個接口是Sax讀取的核心,通過實現handle方法編寫我們要對每行數據的操作方式* (比如按照行入庫,入List或者寫出到文件等)* @return*/private static RowHandler createRowHandler() {return new RowHandler() {@Overridepublic void handle(int sheetIndex, int rowIndex, List<Object> rowlist) {log.info("[{}] [{}] {}", sheetIndex, rowIndex, rowlist);}};}/*** 流方式讀取Excel2007-Excel07SaxReader* 在標準的ExcelReader中,如果數據量較大,讀取Excel會非常緩慢,并有可能造成內存溢出。因此針對大數據量的Excel,Hutool封裝了Sax模式的讀取方式。* Excel07SaxReader只支持Excel2007格式的Sax讀取。* @param excelName*/public static void readStream2007Exce(String excelName){// ExcelUtil快速讀取ExcelUtil.read07BySax(excelName, 0, createRowHandler());// 構建對象讀取Excel07SaxReader reader = new Excel07SaxReader(createRowHandler());reader.read(excelName, 0);}/*** Excel生成-ExcelWriter* Hutool將Excel寫出封裝為ExcelWriter,原理為包裝了Workbook對象,每次調用merge(合并單元格)或者* write(寫出數據)方法后只是將數據寫入到Workbook,并不寫出文件,只有調用flush或者close方法后才會真正寫出文件。* 由于機制原因,在寫出結束后需要關閉ExcelWriter對象,調用close方法即可關閉,此時才會釋放Workbook對象資源,* 否則帶有數據的Workbook一直會常駐內存。** @param toExcelName*/public static void createExcel(String toExcelName){// 1. 將行列對象寫出到ExcelList<String> row1 = CollUtil.newArrayList("aa", "bb", "cc", "dd");List<String> row2 = CollUtil.newArrayList("aa1", "bb1", "cc1", "dd1");List<String> row3 = CollUtil.newArrayList("aa2", "bb2", "cc2", "dd2");List<String> row4 = CollUtil.newArrayList("aa3", "bb3", "cc3", "dd3");List<String> row5 = CollUtil.newArrayList("aa4", "bb4", "cc4", "dd4");List<List<String>> rows = CollUtil.newArrayList(row1, row2, row3, row4, row5);//通過工具類創建writerExcelWriter writer = ExcelUtil.getWriter(toExcelName);//通過構造方法創建writer//ExcelWriter writer = new ExcelWriter("d:/writeTest.xls");//跳過當前行,既第一行,非必須,在此演示用writer.passCurrentRow();//合并單元格后的標題行,使用默認標題樣式writer.merge(row1.size() - 1, "測試標題");//一次性寫出內容,強制輸出標題writer.write(rows, true);//關閉writer,釋放內存writer.close();}/*** 測試excel導出百萬條記錄* @param data* @param toExcelName*/public static void createExcelData(List<List<?>> data, String toExcelName){//通過工具類創建writerBigExcelWriter writer= ExcelUtil.getBigWriter(toExcelName);// 一次性寫出內容,使用默認樣式writer.write(data);// 關閉writer,釋放內存writer.close();}public static List<List<?>> createMillionExcelData(){// 測試excel導出百萬條記錄 創建測試數據User user;List<List<?>> users = new ArrayList<>();for (int i = 0; i < 10000; i++) {user = User.builder().id(i).name("東芝王哥"+i).sex("Y").age(10+i).love("吃飯睡覺大毆打"+i).eat("吃大蝦"+i).run("徒步5000"+i+"米").idCard("42595956874412454554"+i).birthday(LocalDateTime.now()).securityCode("1245"+i).account("adminqwe"+i).password("qwer"+i).remark("z這是一個愛好學習、天天向上的bgm"+i).build();// log.info("第 {} 個user::{}", i, user.toString());String[] userStr = user.toString().substring(user.toString().indexOf("(") + 1, user.toString().lastIndexOf(")")).split(",");List<String> userStrs = CollUtil.newArrayList(userStr);List<String> userStrNews = new ArrayList<>();if (i == 0) {userStrs.forEach( u -> {u = u.split("=")[0];userStrNews.add(u);});}else{userStrs.forEach( u -> {u = u.split("=")[1];userStrNews.add(u);});}users.add(userStrNews);}return users;}/*** 并發創建測試數據** @param toExcelName* @throws ExecutionException* @throws InterruptedException*/public static void createMillionExcelDataFuture(String toExcelName) throws ExecutionException, InterruptedException {long start = System.currentTimeMillis();log.info("createMillionExcelDataFuture start {} ", start);// 定時多個FutureTask生成數據FutureTask<List<List<?>>> taskOne = new FutureTask(new Callable() {@Overridepublic Object call() throws Exception {return createMillionExcelData();}});FutureTask<List<List<?>>> taskTwo = new FutureTask(new Callable() {@Overridepublic Object call() throws Exception {return createMillionExcelData();}});Thread thread1 = new Thread(taskOne);thread1.start();Thread thread2 = new Thread(taskTwo);thread2.start();List<List<?>> data = new ArrayList<>();// 得到FutureTask生成的結果 阻塞List<List<?>> oneList = taskOne.get();data.addAll(oneList);List<List<?>> twoList = taskTwo.get();data.addAll(twoList);// 設置表頭// 生成excel//通過工具類創建writerBigExcelWriter writer= ExcelUtil.getBigWriter(toExcelName);// 一次性寫出內容,使用默認樣式writer.write(data);// 關閉writer,釋放內存writer.close();log.info("createMillionExcelDataFuture end 耗時 {}", System.currentTimeMillis() - start);}public static void main(String[] args) {String proDir = System.getProperty("user.dir") +"/springboot-jacob/src/main/resources";String excelName = proDir + "/excel/"+System.currentTimeMillis()+"test.xlsx";/*String wordName = proDir + "/word/"+System.currentTimeMillis()+"test.doc";log.info("創建一個excel.................");testCreateExcel(excelName);log.info("創建一個word.................");testCreateWord(excelName);*/try {createMillionExcelDataFuture(excelName);} catch (ExecutionException e) {e.printStackTrace();} catch (InterruptedException e) {e.printStackTrace();}} }參考Hutool文檔?https://www.hutool.cn/docs/#/poi/Excel%E5%A4%A7%E6%95%B0%E6%8D%AE%E7%94%9F%E6%88%90-BigExcelWriter
以上?
總結
以上是生活随笔為你收集整理的Hutool-Excel大数据生成-XXOO的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 简易留言簿 制作
- 下一篇: 为什么说云桌面才是后疫情时代下的最优远程