EasyExcel的實現(xiàn)記錄

需求

Excel樣例.png

Excel文件數(shù)據(jù)導(dǎo)入,即將表格中的數(shù)據(jù)存儲到數(shù)據(jù)庫中 扒接,我這里使用了阿里的 easyExcel 實現(xiàn)整個過程精钮,使用Maven工具

思路

1.文件上傳,將Excel表格上傳
2.讀取Excel數(shù)據(jù)
3.數(shù)據(jù)存入數(shù)據(jù)庫中

操作

1.導(dǎo)入依賴

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

2.配置文件大小

spring.servlet.multipart.max-file-size=1MB
spring.servlet.multipart.max-request-size=1MB

3.前端

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE-edge"/>
    <title>上傳</title>
    <link rel="stylesheet" th:href="@{/css/elementUI.css}">

    <!-- 引入vue 在 elementUI 之前 -->
    <script th:src="@{/js/vue.js}"></script>
    <!--引入 axios.js -->
    <script th:src="@{/js/axios.js}"></script>
    <!-- 引入組件庫 -->
    <script th:src="@{/js/elementUI.js}"></script>
</head>
<body id="main">
<div style="float: right;" sec:authorize="hasRole('admin')">
    <el-button @click="attendanceDialogVisible = true">上傳表格</el-button>
    <el-dialog title="表格上傳" :visible.sync="attendanceDialogVisible" width="40%">
        <br><br>
        <el-row :gutter="80">
            <el-col :span="6" :offset="4">
                <el-date-picker
                        v-model="dateValue"
                        type="date"
                        placeholder="選擇日期"
                        format="yyyy年MM月dd日"
                        value-format="yyyy年MM月dd日">
                </el-date-picker>
            </el-col>
            <el-col :span="12">
                <el-upload
                        class="upload-demo"
                        ref="upload"
                        action="/manage/doUploadAttendance"
                        :data="attendanceTime"
                        :limit="1"
                        accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
                        :on-preview="handlePreview"
                        :on-remove="handleRemove"
                        :auto-upload="false"
                        :on-success="handleSuccess">
                    <el-button slot="trigger" size="small" type="primary">選取文件</el-button>
                    <el-button style="margin-left: 10px" size="small" type="success" @click="submitUp">
                        上傳文件
                    </el-button>
                    <div slot="tip" class="el-upload__tip">只能上傳Excel文件</div>
                </el-upload>
            </el-col>
        </el-row>
        <br> <br>
    </el-dialog>
</div>
</body>
<script>
    new Vue({
        el: "#main",
        data() {

            return {
                attendanceDialogVisible: false,
                dateValue: '',
                attendanceTime: {
                    upTime: ""
                }

            }
        },
        mounted() {
            
        },
        methods: {
            submitUp() {
                if (this.dateValue =="") {
                    this.$message({
                        showClose: true,
                        message: '請先選擇日期乞娄!',
                        type: 'error',
                        offset: 200,
                        duration: 1000
                    });
                    return;
                }
                this.attendanceTime.upTime = this.dateValue;
                this.$refs.upload.submit();
            },
            handlePreview(file, fileList) {

            },
            handleRemove(file, fileList) {
                console.log(file, fileList);
            },
            handleSuccess(response, file, fileList) {
                this.$message({
                    showClose: true,
                    message: '上傳成功',
                    type: 'success',
                    offset: 200,
                    duration: 1000
                });
                this.attendanceDialogVisible=false;
            }
        }
    })
</script>
</html>

4.后端

  • 創(chuàng)建實體對象指定列下標號(也可以使用列名) 這里使用lombok簡化
@Data
public class User{
    /*
     * 0 代表當前excel中的第一列瞬逊,下面依次對應(yīng)
     */
    @ExcelProperty(index = 0)
    private String username;
    @ExcelProperty(index = 1)
    private String password;
    @ExcelProperty(index = 2)
    private String dept;
}
  • UserMapper.xml
<?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.bcm.task.dao.userDao">

    <!--批量插入-->
    <insert id="insertList">
        insert into user(username, password, dept, upTime)
        values
        <foreach collection="list" item="user" separator=",">
            (
            #{user.username}, #{user.password},#{user.dept}, #{user.upTime}
            )
        </foreach>
    </insert>

    <!--批量刪除-->
    <delete id="batchDeleteByID">
        delete from user where username in
        (
          <foreach collection="list" item="username" separator=",">
              #{username}
          </foreach>
        )
    </delete>
</mapper>
  • 創(chuàng)建數(shù)據(jù)持久化層
@Mapper
@Repository
public interface UserDao {
  Integer insertList(List<User> users);
}
  • 創(chuàng)建監(jiān)聽器
public class UserDataListener extends AnalysisEventListener<User> {

    @Autowired
    UserDao userDao;
    /*
     * 創(chuàng)建一個List用來存放數(shù)據(jù)
     */
    List<User> userList = new ArrayList<>();

    private UserDao UserDao;
    private String upTime;


    public UserDataListener(UserDao userDao, String upTime) {
        this.userDao = userDao;
        this.upTime = upTime;
    }

    /**
     * 每一條數(shù)據(jù)的解析都會調(diào)用
     * @param user
     * @param context
     */
    @Override
    public void invoke(User user, AnalysisContext context) {
        user.setUpTime(upTime);
        UserList.add(user);
        /**
         * 數(shù)據(jù)量超過一定量后存儲數(shù)據(jù)庫显歧,防止過多數(shù)據(jù)在內(nèi)存,容易OOM  
         */
        if (userList.size()>= 300) {
            saveData();
            userList.clear();
        }
        saveData();
    }

    /**
     * 所有數(shù)據(jù)解析完成后會調(diào)用此方法
     * @param analysisContext
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        saveData();
    }

    /*
     * 存儲數(shù)據(jù)
     */
    private void saveData() {
        userDao.insertList(userList);
    }
}

  • 創(chuàng)建服務(wù)層
public interface IUserService {

    /*
     * 上傳接口
     */
    void doUpload(String upTime, MultipartFile file) throw IOException; 
}
@Service
public class UserServiceImpl implements IUserService {

    @Autowired
    UserDao userDao;

    public void doUpload(String upTime, MultipartFile file) throw IOException {
        User user = new User();
        user.setUpTime(upTime);
        /*
         * headRowNumber 等于1 表示從excel第二行開始讀取數(shù)據(jù)(標題忽略)
         */
        EasyExcel.read(file.getInputStream(), User.class, new UserDataListener(userDao, upTime)).sheet().headRowNumber(1).doRead();
    }
}
  • 創(chuàng)建控制器
@Controller
@RequestMapping(value = "/test")
public class TestController {

    @Autowired
    IUserService userService;

    // 去上傳頁面
    @GetMapping("toUpload")
    public String toUpload() {
        return "common/toUpload";
    }
    //上傳
    @PostMapping("doUpload")
    @ResponseBody
    public String doUpload(@RequestParam String upTime, @RequestParam MultipartFile file) throws IOException {
        userService.doUpload(upTime, file);
        return "上傳成功";
    }
}

不足

后端沒有對文件進行相應(yīng)的校驗确镊,如文件類型是否為xls 或 xlsx士骤,是否是對應(yīng)模板的數(shù)據(jù)......

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市蕾域,隨后出現(xiàn)的幾起案子拷肌,更是在濱河造成了極大的恐慌,老刑警劉巖旨巷,帶你破解...
    沈念sama閱讀 211,561評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件巨缘,死亡現(xiàn)場離奇詭異,居然都是意外死亡采呐,警方通過查閱死者的電腦和手機若锁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來斧吐,“玉大人又固,你說我怎么就攤上這事』嵬ǎ” “怎么了口予?”我有些...
    開封第一講書人閱讀 157,162評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長涕侈。 經(jīng)常有香客問我沪停,道長,這世上最難降的妖魔是什么裳涛? 我笑而不...
    開封第一講書人閱讀 56,470評論 1 283
  • 正文 為了忘掉前任木张,我火速辦了婚禮,結(jié)果婚禮上端三,老公的妹妹穿的比我還像新娘舷礼。我一直安慰自己,他們只是感情好郊闯,可當我...
    茶點故事閱讀 65,550評論 6 385
  • 文/花漫 我一把揭開白布妻献。 她就那樣靜靜地躺著,像睡著了一般团赁。 火紅的嫁衣襯著肌膚如雪育拨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,806評論 1 290
  • 那天欢摄,我揣著相機與錄音熬丧,去河邊找鬼。 笑死怀挠,一個胖子當著我的面吹牛析蝴,可吹牛的內(nèi)容都是我干的害捕。 我是一名探鬼主播,決...
    沈念sama閱讀 38,951評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼闷畸,長吁一口氣:“原來是場噩夢啊……” “哼尝盼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起腾啥,我...
    開封第一講書人閱讀 37,712評論 0 266
  • 序言:老撾萬榮一對情侶失蹤东涡,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后倘待,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體疮跑,經(jīng)...
    沈念sama閱讀 44,166評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,510評論 2 327
  • 正文 我和宋清朗相戀三年凸舵,在試婚紗的時候發(fā)現(xiàn)自己被綠了祖娘。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,643評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡啊奄,死狀恐怖渐苏,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情菇夸,我是刑警寧澤琼富,帶...
    沈念sama閱讀 34,306評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站庄新,受9級特大地震影響鞠眉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜择诈,卻給世界環(huán)境...
    茶點故事閱讀 39,930評論 3 313
  • 文/蒙蒙 一械蹋、第九天 我趴在偏房一處隱蔽的房頂上張望羞芍。 院中可真熱鬧哗戈,春花似錦、人聲如沸荷科。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽畏浆。三九已至副渴,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間全度,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評論 1 266
  • 我被黑心中介騙來泰國打工斥滤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留将鸵,地道東北人勉盅。 一個月前我還...
    沈念sama閱讀 46,351評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像顶掉,于是被迫代替她去往敵國和親草娜。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,509評論 2 348