Java使用EasyExcel實現Excel導入導出功能


1.EasyExcel簡介

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

2.Java實現EasyExcel操作

2.1 導入依賴

    <dependencies>
        <!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>2.1.1</version>
        </dependency>
    </dependencies>

2.2 寫操作

不存在Excel文件也沒關系,EasyExcel會幫我們自動創建

    @Test
    public void test1(){
        List<TestDataEntity> list=new ArrayList<>();
        for (int i=0;i<=10;i++){
            TestDataEntity entity=new TestDataEntity();
            entity.setId(i);
            entity.setName("lucy"+i);
            entity.setAge(30+i);
            list.add(entity);
        }
        String fileName="D:\\upload\\01.xlsx";
        EasyExcel.write(fileName,TestDataEntity.class).sheet("姓名管理").doWrite(list);
    }

2.3 讀操作

在實體類加上ExcelProperty注解,用於從Excel中讀取的數據進行封裝

@Data
@ToString
public class TestDataEntity {
    @ExcelProperty(value = "id",index = 0)
    private int id;
    @ExcelProperty(value = "name",index = 1)
    private String name;
    @ExcelProperty(value = "age",index = 2)
    private Integer age;
}

編寫監聽器進行讀取操作

package com.gh.test;

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

import java.util.Map;

/**
 * @Author Eric
 * @Date 2021/6/6 12:48
 * @Version 1.0
 */
public class ExcelListener extends AnalysisEventListener<TestDataEntity> {
    //一行一行讀取Excel數據,從第二行開始讀
    @Override
    public void invoke(TestDataEntity testDataEntity, AnalysisContext analysisContext) {
        System.out.println(testDataEntity);
    }
    //讀取表頭信息
    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        System.out.println("===============");
        System.out.println(headMap);
    }
    //讀取之后執行
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {

    }
}

編寫測試方法進行讀操作

    @Test
    public void test2(){
        String fileName="D:\\upload\\01.xlsx";
        EasyExcel.read(fileName,TestDataEntity.class,new ExcelListener()).sheet().doRead();
    }

3.EasyExcel整合springboot

3.1 導出到Excel

controller層

    /**
     * 導出數據字典到Excel
     */
    @GetMapping("exportDictToExcel")
    public Result exportDictToExcel(HttpServletResponse response){
        dictService.exportDictToExcel(response);
        return Result.ok();
    }

service層

    /**
     * 導出數據字典
     * @param response
     */
    @Override
    public void exportDictToExcel(HttpServletResponse response) {
        //設置下載信息
        response.setContentType("application/vnd.ms-excel");//application/vnd.ms-excel
        response.setCharacterEncoding("utf-8");
        String filename="dict";
        response.setHeader("Content-disposition", "attachment;filename="+ filename + ".xlsx");
        //查詢數據
        List<Dict> dictList = baseMapper.selectList(null);
        List<DictEeVo> list=new ArrayList<>();
        for (Dict dict : dictList) {
            DictEeVo dictEeVo=new DictEeVo();
            BeanUtils.copyProperties(dict,dictEeVo);
            list.add(dictEeVo);
        }
        try {
            EasyExcel.write(response.getOutputStream(), DictEeVo.class).sheet().doWrite(list);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

前端JavaScript:

            exportData() {
                window.location.href = 'http://localhost:8202/admin/cmn/dict/exportDictToExcel'
            },

3.2 從Excel導入

controller層:

    /**
     * 從Excel導入數據到數據庫
     */
    @PostMapping("importDictToDatabase")
    public Result importDictToDatabase(MultipartFile file){
        dictService.importDictToDatabase(file);
        return Result.ok();
    }

service層:

    @Override
    public void importDictToDatabase(MultipartFile file) {
        try {
            EasyExcel.read(file.getInputStream(),DictEeVo.class,new DictListener(baseMapper)).sheet().doRead();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

監聽器listener:

package com.gh.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.gh.mapper.DictMapper;
import com.gh.model.cmn.Dict;
import com.gh.vo.cmn.DictEeVo;
import org.springframework.beans.BeanUtils;

public class DictListener extends AnalysisEventListener<DictEeVo> {

    private DictMapper dictMapper;
    public DictListener(DictMapper dictMapper) {
        this.dictMapper = dictMapper;
    }

    //一行一行讀取
    @Override
    public void invoke(DictEeVo dictEeVo, AnalysisContext analysisContext) {
        //調用方法添加數據庫
        Dict dict = new Dict();
        BeanUtils.copyProperties(dictEeVo,dict);
        dictMapper.insert(dict);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {

    }
}

表頭實體類:

@Data
public class DictEeVo {

    @ExcelProperty(value = "id" ,index = 0)
    private Long id;

    @ExcelProperty(value = "上級id" ,index = 1)
    private Long parentId;

    @ExcelProperty(value = "名稱" ,index = 2)
    private String name;

    @ExcelProperty(value = "值" ,index = 3)
    private String value;

    @ExcelProperty(value = "編碼" ,index = 4)
    private String dictCode;

}

 


免責聲明!

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



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