天天看點

阿裡巴巴EasyExcel導入導出(model版本)

EasyExcel是由阿裡巴巴出品的,基于POIExcel導入導出二次開發的一個擁有較好性能,且有效處理OO異常、HEAP溢出、GC溢出的一款EXCEL導入導出插件,使用起來也十分簡便。

官方解釋:

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

導入部分由3個部分組成:

1.實體類

(使用自帶注解書寫後,且繼承于EasyExcel的BaseRowModel)

例:

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.metadata.BaseRowModel;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;

import java.util.Date;

/**
 * 項目管理實體類
 *
 * @author 清風
 * @version 1.0
 * @date 2019年07月24日
 */
@Data
@NoArgsConstructor
@EqualsAndHashCode(callSuper = false)
@TableName("project")
//@ExcelTarget("Project")
public class Project extends BaseRowModel {

    /**
     * 項目編号
     */
    @ExcelProperty(value = "項目編号",index = 0)//value為導入或者導出後的标題,index為下标
    private String projectCode;


    /**
     * 項目名稱
     */
    @ExcelProperty(value = "項目名稱",index = 1)
    private String value;
    /**
     * 所屬縣區
     */
    @ExcelProperty(value = "所屬縣區",index = 2)
    private String country;

    /**
     * 業主機關
     */
    @ExcelProperty(value = "業主機關",index = 3)
    private String ownerUnit;

    /**
     * 建設性質
     */
    @ExcelProperty(value = "建設性質",index = 4)
    private Integer constructionType;

    /**
     * 起始時間
     */
    @DateTimeFormat(pattern = "yyyy-MM")
    @ExcelProperty(value = "起始時間",index = 5,format = "yyyy-MM")//format為注解自帶的對時間格式進行處理
    private Date startTime;

    /**
     * 終止時間
     */
    @DateTimeFormat(pattern = "yyyy-MM")
    @ExcelProperty(value = "終止時間",index = 6,format = "yyyy-MM")
    private Date endTime;


    /**
     * 總投資(萬元)
     */
    @ExcelProperty(value = "總投資",index = 7)
    private Double allInvestment;

    /**
     * 本年計劃投資(萬元)
     */
    @ExcelProperty(value = "本年計劃投資",index = 8)
    private Double plannedInvestment;

    /**
     * 本年累計完成投資
     */
    @ExcelProperty(value = "本年累計完成投資",index = 9)
    private Double plannedInvestmentAll;

    /**
     * 目前完成百分比
     */
    @ExcelProperty(value = "目前完成百分比",index = 10)
    private Double currentCompleted;

    /**
     * 建設内容
     */
    @ExcelProperty(value = "建設内容",index = 11)
    private String constructionContent;
    /**
     * 工程形象進度
     */
    @ExcelProperty(value = "工程形象進度",index = 12)
    private String progress;


}
           

2.Lisenter監聽類

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;

/**
 * @ClassName ExcelListener
 * @Description TODO
 * @Author 清風
 * @date 2019年07月24日
 * @Version 1.0
 **/
public class ExcelListener extends AnalysisEventListener {
    
    private List<Object> list = new ArrayList<>();//用來存儲對象的List
    
    @Override
    public void invoke(Object o, AnalysisContext analysisContext) {
        //invoke類為在讀寫Excel類時可以執行的操作,一般用于直接存儲對象至List中,再傳回至Controller中用來做其他操作
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        //做完所有讀寫操作後可以執行的方法
    }
    public List<Object> getData(){
        //自己寫的方法,用來傳回List
    }
}
           

3.Controller(或者方法)

①.導入主體:

ExcelListener listener=new ExcelListener();
ExcelReader reader = new ExcelReader(file.getInputStream(),null,listener);
reader.read(new Sheet(0,1,Project.class));
listener.getData();//擷取到Excel資料之後如何操作自行發揮
           

②.導出主體

String fileName ="項目資訊管理.xlsx";
ServletOutputStream out = response.getOutputStream();
response.setContentType("multipart/form-data");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-disposition", "attachment;filename="+ URLEncoder.encode(fileName, "UTF-8"));
ExcelWriter writer= new ExcelWriter(out, ExcelTypeEnum.XLSX);
Sheet sheet1 = new Sheet(1, 0,Project.class);
sheet1.setSheetName("線上項目管理");
writer.write(excelList, sheet1);
writer.finish();//完成輸出操作并關閉,可以放在finally中
out.flush();
           

至此完成導入導出(有Model版)!