首頁 > 軟體

java利用easyexcel實現匯入與匯出功能

2022-09-26 14:02:45

前言

poi的解析方式是dom解析,把結果一次都讀入記憶體操作,這樣的操作平時是不會有問題的,但是並行量上來的時候就會出現OOM,EasyExcel,底層物件其實還是使用poi包的那一套。它只是將poi包的一部分抽了出來,摒棄掉了大部分業務相關的屬性。由於它關注的業務是匯入匯出這一塊,所以在處理巨量資料量的匯入匯出能夠通過本地快取來避免OOM,在特定場景中,EasyExcel的表現能力還是可以的。

1先新增依賴

    <!-- EasyExcel -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>2.2.0-beta2</version>
        </dependency>

2批次插入資料

再試下匯入匯出功能前,寫批次插入資料的介面和查詢資料的介面。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="cn.demo.mapper.MedicnesMapper">
    <insert id="saveMedicnesList" parameterType="cn.demo.entity.Medicnes">
        insert into medices
        (food,remark)
        values
        <foreach collection="list" item="rm" separator=",">
            (#{rm.food},#{rm.remark})
        </foreach>
    </insert>
    <select id="medicnesList" parameterType="cn.demo.entity.Medicnes" resultType="cn.demo.entity.Medicnes">
        SELECT
        food,
        remark
        FROM
        medices
    </select>
</mapper>

3建立需要匯出資料實體類

package cn.demo.entity;

import com.alibaba.excel.annotation.ExcelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
 @Data
@AllArgsConstructor
@NoArgsConstructor
public class Medicnes {
    @ExcelProperty("食物名稱")
    private String  food;
 
    @ExcelProperty("食物產地")
    private String  remark;
}

4建立一個類ExcelListener

package cn.demo.config;
 
import cn.demo.entity.Medicnes;
import cn.demo.service.EmpService;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import org.springframework.beans.factory.annotation.Autowired;
 
import java.util.ArrayList;
import java.util.List;
/**
 * 有個很重要的點 ExcelListener
 * 不能被spring管理,要每次讀取excel都要new,然後裡面用到spring可以構造方法傳進去
 */
public class ExcelListener extends AnalysisEventListener<Medicnes> {
 
    private List<Medicnes> list = new ArrayList<>();
 
    //每隔5條儲存資料庫,實際使用中可以3000條,然後清理list ,方便記憶體回收
    private static final int BATCH_COUNT = 5;
 
    //假設這個是一個DAO,當然有業務邏輯這個也可以是一個service。當然如果不用儲存這個物件用
    @Autowired
    private EmpService empService;
     /**
     * 如果使用了spring,請使用這個構造方法。
     * 每次建立Listener的時候需要把spring管理的類傳進來
     */
    public ExcelListener(EmpService empService) {
        this.empService = empService;
    }
    /**
     * 這個每一條資料解析都會來呼叫
     */
    @Override
    public void invoke(Medicnes goods, AnalysisContext analysisContext) {
        System.out.println("解析到一條資料:========================"+goods.toString());
        // 資料儲存到data,供批次處理或後續自己業務邏輯處理。
        list.add(goods);
        // 達到BATCH_COUNT了,需要去儲存一次資料庫,防止資料幾萬條資料在記憶體,容易OOM
        if(list.size() >= BATCH_COUNT){
            saveData();
            // 儲存完成清理data
            list.clear();
        }
 
    }
    /**
     * 所有資料解析完成了 都會來呼叫
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        //確保所有資料都能入庫
        saveData();
    }
    /**
     * 加上儲存資料庫
     */
    private void saveData() {
        System.out.println("=============================="+list.size()+"條資料,開始儲存到資料庫");
        empService.saveMedicnesList(list);
    }
}

5實現下載excel

接下來編寫我們的工具類--幫助我們來實現下載excel

public class DownExcel {
    public static void download(HttpServletResponse response, Class t, List list) throws IOException, IllegalAccessException,InstantiationException {
        response.setContentType("application/vnd.ms-excel");// 設定文字內省
        response.setCharacterEncoding("utf-8");// 設定字元編碼
        response.setHeader("Content-disposition", "attachment;filename=demo.xlsx"); // 設定響應頭
        EasyExcel.write(response.getOutputStream(), t).sheet("模板").doWrite(list); //用io流來寫入資料
    }
}
 
//匯出為Excel
@RequestMapping("/downloadexcel.do")
public void getExcel(HttpServletResponse response) throws IllegalAccessException, IOException, 
InstantiationException {
    List<Medicnes> list = sysUserService.medicnesList();
    DownExcel.download(response,Medicnes.class,list);
}

6控制器新增我們的匯入操作程式碼

//匯入Excel
@RequestMapping("/importexcel.do")
@ResponseBody
public String importexcel(@RequestParam(value = "excelFile") MultipartFile file) throws IOException{
    EasyExcel.read(file.getInputStream(), Medicnes.class, new ExcelListener(sysUserService)).sheet().doRead();
    return "success";
}

7匯出效果如圖

8匯入直接呼叫

到此這篇關於java利用easyexcel實現匯入與匯出功能的文章就介紹到這了,更多相關java easyexce 內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com