EasyExcel對表格解析和生成


EasyExcel 簡介

Java解析、生成Excel比較有名的框架有Apache  poi、jxl。但他們都存在一個嚴重的問題就是非常的耗內存,poi有一套SAX模式的API可以一定程度的解決一些內存溢出的問題,但POI還是有一些缺陷,比如07版Excel解壓縮以及解壓后存儲都是在內存中完成的,內存消耗依然很大。easyexcel重寫了poi對07版Excel的解析,能夠原本一個3M的excel用POI  sax依然需要100M左右內存降低到幾M,並且再大的excel不會出現內存溢出,03版依賴POI的sax模式。在上層做了模型轉換的封裝,讓使用者更加簡單方便

更多的使用方法可以查看官方文檔 https://github.com/alibaba/easyexcel

依賴

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>2.2.6</version>
</dependency>

寫入

這里使用簡單的寫入

/**
 * 最簡單的寫
 * <p>
 * 1. 創建excel對應的實體對象 參照{@link DemoData}
 * <p>
 * 2. 直接寫即可
 */
@Test
public void simpleWrite() {
    // 寫法1
    String fileName = "E:/" + "simpleWrite" + System.currentTimeMillis() + ".xlsx";
    // 這里 需要指定寫用哪個class去寫,然后寫到第一個sheet,名字為模板 然后文件流會自動關閉
    // 如果這里想使用03 則 傳入excelType參數即可
    EasyExcel.write(fileName, DemoData.class).sheet("模板").doWrite(data());
}

/**
 * 要寫入的數據
 */
private List<DemoData> data() {
        List<DemoData> list = new ArrayList<DemoData>();
        for (int i = 0; i < 10; i++) {
            DemoData data = new DemoData();
            data.setString("字符串" + i);
            data.setDate(new Date());
            data.setDoubleData(0.56);
            list.add(data);
        }
        return list;
    }

基礎數據類

DemoData

/**
 * 基礎數據類
 *
 * @author Jiaju Zhuang
 **/
@Data
public class DemoData {
    @ExcelProperty("字符串標題")
    private String string;
    @ExcelProperty("日期標題")
    private Date date;
    @ExcelProperty("數字標題")
    private Double doubleData;
    /**
     * 忽略這個字段
     */
    @ExcelIgnore
    private String ignore;
}

讀取

最簡單的讀取

/**
 * 最簡單的讀
 * <p>
 * 1. 創建excel對應的實體對象 參照{@link DemoData}
 * <p>
 * 2. 由於默認一行行的讀取excel,所以需要創建excel一行一行的回調監聽器,參照{@link DemoDataListener}
 * <p>
 * 3. 直接讀即可
 */
@Test
public void simpleRead() {
    // 有個很重要的點 DemoDataListener 不能被spring管理,要每次讀取excel都要new,然后里面用到spring可以構造方法傳進去
    // 寫法1:
    String fileName = "E:/simpleWrite1602827890506.xlsx";
    // 這里 需要指定讀用哪個class去讀,然后讀取第一個sheet 文件流會自動關閉
    EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).sheet().doRead();
}

基礎數據類

DemoData

/**
 * 基礎數據類.這里的排序和excel里面的排序一致
 *
 * @author Jiaju Zhuang
 **/
@Data
public class DemoData {
    private String string;
    private Date date;
    private Double doubleData;
}

監聽類

/**
 * 模板的讀取類
 *
 * @author Jiaju Zhuang
 */
// 有個很重要的點 DemoDataListener 不能被spring管理,要每次讀取excel都要new,然后里面用到spring可以構造方法傳進去
public class DemoDataListener extends AnalysisEventListener<DemoData> {
    private static final Logger LOGGER = LoggerFactory.getLogger(DemoDataListener.class);
    /**
     * 每隔5條存儲數據庫,實際使用中可以3000條,然后清理list ,方便內存回收
     */
    private static final int BATCH_COUNT = 5;
    List<DemoData> list = new ArrayList<DemoData>();
    /**
     * 假設這個是一個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
     */
    @Override
    public void invoke(DemoData data, AnalysisContext context) {
        LOGGER.info("解析到一條數據:{}", JSON.toJSONString(data));
        list.add(data);
        // 達到BATCH_COUNT了,需要去存儲一次數據庫,防止數據幾萬條數據在內存,容易OOM
        if (list.size() >= BATCH_COUNT) {
            saveData();
            // 存儲完成清理 list
            list.clear();
        }
    }

    /**
     * 所有數據解析完成了 都會來調用
     *
     * @param context
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 這里也要保存數據,確保最后遺留的數據也存儲到數據庫
        saveData();
        LOGGER.info("所有數據解析完成!");
    }

    /**
     * 加上存儲數據庫
     */
    private void saveData() {
        LOGGER.info("{}條數據,開始存儲數據庫!", list.size());
        demoDAO.save(list);
        LOGGER.info("存儲數據庫成功!");
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM