Easy Excel的使用說明


Easy Excel 的使用說明

可直接使用的測試demo,建議使用前后看一下官方文檔

官方文檔地址1:https://www.yuque.com/easyexcel/doc

官方文檔地址2:https://alibaba-easyexcel.github.io/index.html

01 導入依賴

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

<dependency>
   <groupId>org.projectlombok</groupId>
   <artifactId>lombok</artifactId>
   <version>1.18.20</version>
</dependency>

02 寫excel文件

數據的實體類

@Data
@TableName("excel_user")
public class ExcelUser {
    @TableId(value = "id", type = IdType.AUTO)
    @ExcelIgnore
    private Long id;
    @ExcelProperty("姓名")
    private String name;
    @ExcelProperty("年齡")
    private Integer age;
    @ExcelProperty("身高")
    private Double height;
}

寫excel的方法

/**
 * 寫excel文件
 * @param excelFile
 *            導出的文件路徑(測試用絕對地址)
 * @param ignoreFiledNames
 *            忽略的字段
 * @param template
 *            數據模板(數據的class)
 * @param sheetName
 *            sheet名
 * @param data
 *            數據
 */
public static void writeExcel(String excelFile, Set<String> ignoreFiledNames, Class template, String sheetName,
                              List<?> data) {
    ExcelWriterBuilder builder = EasyExcel.write(excelFile, template);
    if (ignoreFiledNames != null) {
        builder.excludeColumnFiledNames(ignoreFiledNames);
    }
    builder.sheet(sheetName).doWrite(data);
}

03 文件的下載

controller接口

@GetMapping("/download")
public void download(String filename,HttpServletResponse response) {
    ExcelFileUtils.downLoadFile(response,filename);
}

下載的方法

 

/**
 * 下載文件
 *
 * @param response
 *            相應response
 * @param filePath
 *            文件路徑
 */
public static void downLoadFile(HttpServletResponse response, String filePath) {
    if (StringUtils.isBlank(filePath)) {
        return;
    }
    File file = new File(filePath);
    if (!file.exists()) {
        return;
    }
    OutputStream out = null;
    try {
        response.reset();
        response.setContentType("application/octet-stream; charset=utf-8");
        response.setHeader("Content-Disposition", "attachment; filename=" + file.getName());
        out = response.getOutputStream();
        out.write(Files.readAllBytes(file.toPath()));
        out.flush();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (out != null) {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

04 文件的上傳

監聽器

package com.saiyou.entity;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
import com.saiyou.service.ExcelUserService;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

/**
 * @author : lyn
 * 技術點 :
 * @description: excel 的監聽器
 * @date : 2021/12/4 14:43
 */
@Slf4j
public class ExcelUserListener extends AnalysisEventListener<ExcelUser> {

    /**
     * 每隔5條存儲數據庫,實際使用中可以3000條,然后清理list ,方便內存回收
     */
    private static final int BATCH_COUNT = 5;
    List<ExcelUser> list = new ArrayList<ExcelUser>();
    /**
     * 假設這個是一個DAO,當然有業務邏輯這個也可以是一個service。當然如果不用存儲這個對象沒用。
     */
    private ExcelUserService excelUserService;

    public ExcelUserListener(){}

    /**
     * 如果使用了spring,請使用這個構造方法。每次創建Listener的時候需要把spring管理的類傳進來
     *
     * @param excelUserService
     */

    public ExcelUserListener(ExcelUserService excelUserService) {
        this.excelUserService = excelUserService;
    }

    /**
     * 這個每一條數據解析都會來調用
     *
     * @param data
     *            one row value. Is is same as {@link AnalysisContext#readRowHolder()}
     * @param context
     */
    @Override
    public void invoke(ExcelUser data, AnalysisContext context) {
        log.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();
        log.info("所有數據解析完成!");
    }

    /**
     * 加上存儲數據庫
     */
    private void saveData() {
        log.info("{}條數據,開始存儲數據庫!", list.size());
        //調用service保存到數據庫
        excelUserService.saveBatch(list);
        log.info("存儲數據庫成功!");
    }
}

controller接口

@Autowired
private ExcelUserService excelUserService;
/**
 * 文件上傳
 * <p>1. 創建excel對應的實體對象 參照{@link ExcelUser}
 * <p>2. 由於默認一行行的讀取excel,所以需要創建excel一行一行的回調監聽器,
 * <p>3. 直接讀即可
 */
@PostMapping("/upload")
public String upload(MultipartFile file) throws IOException {
    EasyExcel.read(file.getInputStream(), ExcelUser.class, new ExcelUserListener(excelUserService)).sheet().doRead();
    return "success";
}

05 Postman的上傳文件

 

需要自己補充service和mapper

0 工具類

package com.saiyou.utils;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.saiyou.entity.ExcelUser;
import com.saiyou.entity.ExcelUserListener;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

/**
 * @author : lyn
 * 技術點 :
 * @description: excel的讀寫,上傳和下載
 * @date : 2021/12/4 13:50
 */
@Slf4j
public class ExcelFileUtils {

    /**
     * 寫excel文件
     * @param excelFile
     *            導出的文件路徑
     * @param ignoreFiledNames
     *            忽略的字段
     * @param template
     *            數據模板
     * @param sheetName
     *            sheet名
     * @param data
     *            數據
     */
    public static void writeExcel(String excelFile, Set<String> ignoreFiledNames, Class template, String sheetName,
                                  List<?> data) {
        ExcelWriterBuilder builder = EasyExcel.write(excelFile, template);
        if (ignoreFiledNames != null) {
            builder.excludeColumnFiledNames(ignoreFiledNames);
        }
        builder.sheet(sheetName).doWrite(data);
    }

    /**
     * 讀取excel文件,不能通用嗎?
     * @param fileName
     */
    public static void readExcel(String fileName) {

        // 這里 需要指定讀用哪個class去讀,然后讀取第一個sheet 文件流會自動關閉
        EasyExcel.read(fileName, ExcelUser.class, new ExcelUserListener() ).sheet().doRead();
    }

    /**
     * 下載文件
     *
     * @param response
     *            相應response
     * @param filePath
     *            文件路徑
     */
    public static void downLoadFile(HttpServletResponse response, String filePath) {
        if (StringUtils.isBlank(filePath)) {
            return;
        }
        File file = new File(filePath);
        if (!file.exists()) {
            return;
        }
        OutputStream out = null;
        try {
            response.reset();
            response.setContentType("application/octet-stream; charset=utf-8");
            response.setHeader("Content-Disposition", "attachment; filename=" + file.getName());
            out = response.getOutputStream();
            out.write(Files.readAllBytes(file.toPath()));
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
        ExcelUser user = new ExcelUser();
        user.setName("李四");
        user.setAge(56);
        user.setHeight(126.6);
        writeExcel("D:/excel-test.xlsx",null,ExcelUser.class,"表一", Arrays.asList(user));
    }


}

 

 

 

 

 


免責聲明!

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



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