記錄一下自己用springboot整合阿里巴巴開源的EasyExcel實現導入導出功能


項目地址:https://github.com/changxueyi/springbootcrud

1.准備

項目的整體架構和圖中的類似

 

 

 2. 導入依賴

 

 

當然,基本的mysql-connector-java、mybaits、springboot的也需要導入,最重要的就是上面的

3、導出excel

dept實體類
導出 Excel 時,若需要表頭,那么相應的實體類需要繼承 BaseRowModel,並加入 @ExcelProperty(value = “id”, index = 0) 注解。其中 value 代表在導出 Excel 時,該字段對應的表頭名稱;index 代表該字段對應的表頭位置(從0開始)。如下圖:

 

1. 重要的代碼

 

 

 實體類對象

 

 

 2. 控制層   DeptController

 

 2.service業務層

 

 3. 實現層

package com.cxy.service.Impl;

import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.cxy.common.poi.ExcelListener;
import com.cxy.dao.DeptMapper;
import com.cxy.domin.Dept;
import com.cxy.service.DeptService;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Random;

/**
 * @ClassName DeptServiceImpl
 * @Description TODO
 * @Author changxueyi
 * @Date 2020/11/12 17:43
 */
@Service
public class DeptServiceImpl implements DeptService {
    @Autowired
    private DeptMapper deptMapper;

    @Override
    public void excelExport(HttpServletResponse response) throws IOException {
        List<Dept> list = deptMapper.queryAllDept();
        String fileName = "用戶名單";
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-disposition", "attachment;filename=" + new String( fileName.getBytes("gb2312"), "ISO8859-1" ) + ".xls");
        ServletOutputStream out = response.getOutputStream();
        ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLS,true);
        Sheet sheet = new Sheet(1,0,Dept.class);
        //設置自適應寬度
        sheet.setAutoWidth(Boolean.TRUE);
        sheet.setSheetName("用戶名單");
        writer.write(list,sheet);
        writer.finish();
        out.flush();
        response.getOutputStream().close();
        out.close();
    }

    @Override
    public void excelImport(MultipartFile file) throws IOException {
        if(!file.getOriginalFilename().equals("用戶名單.xls") && !file.getOriginalFilename().equals("用戶名單.xlsx") ){
            return;
        }
        InputStream inputStream = new BufferedInputStream(file.getInputStream());
        //實例化實現了AnalysisEventListener接口的類
        ExcelListener excelListener = new ExcelListener(deptMapper);
        ExcelReader reader = new ExcelReader(inputStream,null,excelListener);
        //讀取信息
        reader.read(new Sheet(1,1,Dept.class));
    }
}

 4.Mapper層

 

 5.Mapper實現層

<?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="com.cxy.dao.DeptMapper">
    <select id="queryAllDept" resultType="com.cxy.domin.Dept">
        select * from dept
    </select>

    <insert id="addDept" parameterType="com.cxy.domin.Dept">
        insert into dept values (#{deptNo},#{deptName},#{localtion})
    </insert>
</mapper>

 6.ExcelListener 工具類

package com.cxy.common.poi;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.cxy.dao.DeptMapper;
import com.cxy.domin.Dept;
import org.springframework.stereotype.Controller;

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

/**
 * @ClassName ExcelListener
 * @Description TODO
 * @Author changxueyi
 * @Date 2020/11/12 17:57
 */
@Controller
public class ExcelListener extends AnalysisEventListener<Dept> {
    private List<Dept> datas = new ArrayList<>();
    private static final int BATCH_COUNT = 3000;
    private DeptMapper deptMapper;

    public ExcelListener(DeptMapper deptMapper){
        this.deptMapper = deptMapper;
    }

    @Override
    public void invoke(Dept dept, AnalysisContext analysisContext) {
        //數據存儲到datas,供批量處理,或后續自己業務邏輯處理。
        datas.add(dept);
        //達到BATCH_COUNT了,需要去存儲一次數據庫,防止數據幾萬條數據在內存,容易OOM
        if(datas.size() >= BATCH_COUNT){
            saveData();
            // 存儲完成清理datas
            datas.clear();
        }
    }

    private void saveData() {
        for(Dept dept : datas){
            deptMapper.addDept(dept);
        }
    }

    public List<Dept> getDatas() {
        return datas;
    }

    public void setDatas(List<Dept> datas) {
        this.datas = datas;
    }

    /**
     * 所有數據解析完成了 都會來調用
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        saveData();//確保所有數據都能入庫
    }

   /* @Override
    public void invoke(Dept dept, AnalysisContext analysisContext) {

    }*/
}

 

 

 

7. 導入的時候,文件名一定要固定

用戶名單.xls

 

8.通過postMan使用的時候,需要注意以下幾點

 

 頭部信息

 

 

 

9.導出功能

再用postman測試導出功能:#

在這里插入圖片描述

沒有參數,直接send,然后可以看到:

在這里插入圖片描述
在這里插入圖片描述
將其下載下來查看(本來這里的文件名應該是代碼中命名的“用戶名單.xls”,但我嘗試了很久總是沒有變。。。)

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-X87m7MCo-1575975083497)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20191210182033780.png)]

與數據庫表數據一致,說明導出成功!

 

特別說明:

 

 

這里的excel名字的命名必須是這個,而且里面的主鍵可以不寫,因為可能會遇到主鍵沖突的問題


免責聲明!

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



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