好用的EasyExcel工具類(1.1.2-beta5版本)


寫在前面

EasyExcel是阿里推出的一款高性能的開源excel讀寫框架,具體的框架介紹這里就不再提了,有興趣的同學點擊下面的地址鏈接去github上看。筆者發現目前網上很多介紹easyexcel博客或文章都是基於1.1.2-beta5版本進行講解的,故筆者整理了一個適用於該版本的工具類,方便自己使用。實際主要是懶得記對應的API,並且匹配自己平時的編程習慣。有需要的小伙伴自取。

easyexcel開源地址:https://github.com/alibaba/easyexcel

引入依賴

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>1.1.2-beta5</version>
</dependency> 

工具類

import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.metadata.BaseRowModel;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.metadata.Table;
import com.alibaba.excel.support.ExcelTypeEnum;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

/**
*  EasyExcel工具類
 * @author jwhappy
 * @date 2020/4/21
 */
@Slf4j
public class EasyExcelUtil
{
    /**
     * 無模板讀取(從sheet1的第1行開始讀)
     * @param inputStream
     * @return List<List<String>>
     */
    public static List<Object> read(InputStream inputStream){
        return EasyExcelFactory.read(inputStream, new Sheet(1, 0));
    }

    /**
     * 無模板讀取(自己指定從sheet1的哪一行開始讀)
     * @param inputStream
     * @param headLineMun 表頭占的行數,從0開始
     * @return List<List<String>>
     */
    public static List<Object> read(InputStream inputStream, Integer headLineMun){
        return EasyExcelFactory.read(inputStream, new Sheet(1, headLineMun));
    }

    /**
     * 無模板讀取(自己指定sheet和開始的行)
     * 返回 List<List<String>>
     * @param inputStream
     * @param sheetNo sheet頁號,從1開始
     * @param headLineMun 表頭占的行數,從0開始
     * @return List<List<String>>
     */
    public static List<Object> read(InputStream inputStream, Integer sheetNo, Integer headLineMun){
        return EasyExcelFactory.read(inputStream, new Sheet(sheetNo, headLineMun));
    }

    /**
     * 按模板讀取(從sheet1的第2行開始讀取)
     * @param inputStream
     * @param clazz 模板類,需要繼承BaseRowModel類,字段用@ExcelProperty注解
     * @return List<Object>, Object對應具體的clazz類
     */
    public static List<Object> read(InputStream inputStream, final Class<? extends BaseRowModel> clazz){
        return EasyExcelFactory.read(inputStream, new Sheet(1, 1, clazz));
    }

    /**
     * 按模板讀取(從指定sheet的第2行開始讀)
     * @param inputStream
     * @param clazz 模板類,需要繼承BaseRowModel類,字段用@ExcelProperty注解
     * @param sheetNo sheet頁號,從1開始
     * @return List<Object>, Object對應具體的clazz類
     */
    public static List<Object> read(InputStream inputStream, final Class<? extends BaseRowModel> clazz, Integer sheetNo){
        return EasyExcelFactory.read(inputStream, new Sheet(sheetNo, 1, clazz));
    }

    /**
     * 按模板讀取(自定義sheet和表頭行數)
     * @param inputStream
     * @param clazz 模板類,需要繼承BaseRowModel類,字段用@ExcelProperty注解
     * @param sheetNo sheet頁號,從1開始
     * @param headLineMun 表頭占的行數,從0開始
     * @return List<Object>, Object對應具體的clazz類
     */
    public static List<Object> read(InputStream inputStream, final Class<? extends BaseRowModel> clazz, Integer sheetNo, Integer headLineMun){
        return EasyExcelFactory.read(inputStream, new Sheet(sheetNo, headLineMun, clazz));
    }

    /**
     * 按模板讀取(從sheet1的第2行開始讀取)
     * 1000行以上的數據建議用這個讀取
     * @param inputStream
     * @param clazz 模板類,需要繼承BaseRowModel類,字段用@ExcelProperty注解
     * @param <T> 模板類泛型
     * @return List<T>
     */
    public static <T extends BaseRowModel> List<T> readModel(InputStream inputStream, final Class<? extends BaseRowModel> clazz){
        ExcelListener excelListener = new ExcelListener();
        EasyExcelFactory.readBySax(inputStream, new Sheet(1, 1, clazz), excelListener);
        return excelListener.getRows();
    }

    /**
     * 按模板讀取(從指定sheet的第2行開始讀)
     * 1000行以上的數據建議用這個讀取
     * @param inputStream
     * @param clazz 模板類,需要繼承BaseRowModel類,字段用@ExcelProperty注解
     * @param sheetNo sheet頁號,從1開始
     * @param <T> 模板類泛型
     * @return List<T>
     */
    public static <T extends BaseRowModel> List<T> readModel(InputStream inputStream, final Class<? extends BaseRowModel> clazz, Integer sheetNo){
        ExcelListener excelListener = new ExcelListener();
        EasyExcelFactory.readBySax(inputStream, new Sheet(sheetNo, 1, clazz), excelListener);
        return excelListener.getRows();
    }

    /**
     * 按模板讀取(自定義sheet和表頭行)
     * 1000行以上的數據建議用這個讀取
     * @param inputStream
     * @param clazz 模板類,需要繼承BaseRowModel類,字段用@ExcelProperty注解
     * @param sheetNo sheet頁號,從1開始
     * @param headLineMun 表頭占的行數,從0開始
     * @param <T> 模板類泛型
     * @return List<T>
     */
    public static <T extends BaseRowModel> List<T> readModel(InputStream inputStream, final Class<? extends BaseRowModel> clazz, Integer sheetNo, Integer headLineMun){
        ExcelListener excelListener = new ExcelListener();
        EasyExcelFactory.readBySax(inputStream, new Sheet(sheetNo, headLineMun, clazz), excelListener);
        return excelListener.getRows();
    }

    /**
     * 按模板寫入(寫入sheet1,表頭占第一行)
     * @param outputStream
     * @param data 寫入的數據(模板對象List)
     * @param clazz 模板類,需要繼承BaseRowModel類,字段用@ExcelProperty注解
     */
    public static void writeModel(OutputStream outputStream, List<? extends BaseRowModel> data, final Class<? extends BaseRowModel> clazz){
        ExcelWriter excelWriter = EasyExcelFactory.getWriter(outputStream);
        Sheet sheet = new Sheet(1, 1, clazz);
        excelWriter.write(data, sheet);
        excelWriter.finish();
    }

    /**
     * 按模板寫入(指定sheet,表頭占第一行)
     * @param outputStream
     * @param data 寫入的數據(模板對象List)
     * @param clazz 模板類,需要繼承BaseRowModel類,字段用@ExcelProperty注解
     * @param sheetNo sheet頁號,從1開始
     */
    public static void writeModel(OutputStream outputStream, List<? extends BaseRowModel> data, final Class<? extends BaseRowModel> clazz, Integer sheetNo){
        ExcelWriter excelWriter = EasyExcelFactory.getWriter(outputStream);
        Sheet sheet = new Sheet(sheetNo, 1, clazz);
        excelWriter.write(data, sheet);
        excelWriter.finish();
    }

    /**
     * 按模板寫入(指定sheet頁和sheet名稱,指定表頭行數)
     * @param outputStream
     * @param data 寫入的數據(模板對象List)
     * @param clazz 模板類,需要繼承BaseRowModel類,字段用@ExcelProperty注解
     * @param headLineMun 表頭占的行數,從0開始
     * @param sheetNo sheet頁號,從1開始
     * @param sheetName sheet名稱
     */
    public static void writeModel(OutputStream outputStream, List<? extends BaseRowModel> data, final Class<? extends BaseRowModel> clazz, Integer headLineMun, Integer sheetNo, String sheetName){
        ExcelWriter excelWriter = EasyExcelFactory.getWriter(outputStream);
        Sheet sheet = new Sheet(sheetNo, headLineMun, clazz);
        sheet.setSheetName(sheetName);
        excelWriter.write(data, sheet);
        excelWriter.finish();
    }

    /**
     * 無模板寫入(寫入sheet1,表頭占第一行)
     * @param outputStream
     * @param data 寫入的數據(List<List<Object>>)
     * @param table 表設置,可以設置表頭字段,以及表的樣式設置
     */
    public static void write(OutputStream outputStream, List<List<Object>> data, Table table){
        ExcelWriter excelWriter = EasyExcelFactory.getWriter(outputStream);
        Sheet sheet = new Sheet(1, 0);
        excelWriter.write1(data, sheet, table);
        excelWriter.finish();
    }

    /**
     * 無模板寫入(指定sheet,表頭占第一行)
     * @param outputStream
     * @param data 寫入的數據(List<List<Object>>)
     * @param table 表設置,可以設置表頭字段,以及表的樣式設置
     * @param sheetNo sheet頁號,從1開始
     */
    public static void write(OutputStream outputStream, List<List<Object>> data, Table table, Integer sheetNo){
        ExcelWriter excelWriter = EasyExcelFactory.getWriter(outputStream);
        Sheet sheet = new Sheet(sheetNo, 0);
        excelWriter.write1(data, sheet, table);
        excelWriter.finish();
    }

    /**
     * 無模板寫入(指定sheet頁和sheet名稱,指定表頭行數)
     * @param outputStream
     * @param data 寫入的數據(List<List<Object>>)
     * @param table 表設置,可以設置表頭字段,以及表的樣式設置
     * @param headLineMun 表頭占的行數,從0開始
     * @param sheetNo sheet頁號,從1開始
     * @param sheetName sheet名稱
     */
    public static void write(OutputStream outputStream, List<List<Object>> data, Table table, Integer headLineMun, Integer sheetNo, String sheetName){
        ExcelWriter excelWriter = EasyExcelFactory.getWriter(outputStream);
        Sheet sheet = new Sheet(sheetNo, headLineMun);
        sheet.setSheetName(sheetName);
        excelWriter.write1(data, sheet, table);
        excelWriter.finish();
    }

    /**
     * 多個sheet頁的數據鏈式寫入
     * ExcelUtil.writeWithSheets(outputStream)
     *                  .writeModel( Collections.singletonList(excelModel), ExcelModel.class, "sheet1Name")
     *                  .write(data,table,"sheet2Name")
     *                  .finish();
     * @param outputStream
     * @return
     */
    public static EasyExcelWriterFactory writeWithSheets(OutputStream outputStream){
        EasyExcelWriterFactory excelWriter = new EasyExcelWriterFactory(outputStream, ExcelTypeEnum.XLSX);
        return excelWriter;
    }

    /**
     * 多個sheet頁的數據鏈式寫入
     * ExcelUtil.writeWithSheets(response, exportFileName)
     *                  .writeModel( Collections.singletonList(excelModel), ExcelModel.class, "sheet1Name")
     *                  .write(data,table,"sheet2Name")
     *                  .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(), ExcelTypeEnum.XLSX);
        return excelWriter;
    }
}

@Slf4j
class ExcelListener<T extends BaseRowModel> extends AnalysisEventListener<T>
{
    private final List<T> rows = new ArrayList<>();

    @Override
    public void invoke(T object, AnalysisContext context) {
        rows.add(object);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        log.info("read {} rows", rows.size());
    }

    public List<T> getRows() {
        return rows;
    }
}
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.BaseRowModel;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.metadata.Table;
import com.alibaba.excel.support.ExcelTypeEnum;

import java.io.IOException;
import java.io.OutputStream;
import java.util.List;

/**
 * 自定義EasyExcel寫工廠
 */
public class EasyExcelWriterFactory extends ExcelWriter
{
    private OutputStream outputStream;
    private int sheetNo = 1;

    public EasyExcelWriterFactory(OutputStream outputStream, ExcelTypeEnum typeEnum) {
        super(outputStream, typeEnum);
        this.outputStream = outputStream;
    }

    /**
     * 鏈式按模板寫入
     * @param data
     * @param clazz
     * @param sheetName
     * @return
     */
    public EasyExcelWriterFactory writeModel(List<? extends BaseRowModel> data, final Class<? extends BaseRowModel> clazz, String sheetName){
        Sheet sheet = new Sheet(this.sheetNo++, 0, clazz);
        sheet.setSheetName(sheetName);
        this.write(data, sheet);
        return this;
    }

    /**
     * 鏈式無模板寫入
     * @param data
     * @param table
     * @param sheetName
     * @return
     */
    public EasyExcelWriterFactory write(List<List<Object>> data, Table table, String sheetName){
        Sheet sheet = new Sheet(this.sheetNo++, 0);
        sheet.setSheetName(sheetName);
        this.write1(data, sheet, table);
        return this;
    }

    @Override
    public void finish() {
        super.finish();
        try {
            outputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


免責聲明!

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



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