【測試開發】知識點-使用EasyExcel,實現excel導出和導入

上篇介紹了下EasyExcel的讀寫excel文件的使用,現在利用它來實現項目中的excel文件導出和導入的功能。

現在有一個字典列表,要把裏面的數據實現導出和導入。

一、實現導出

既然是整合到項目裏,跟之前的練習還是有些區別的。說是導出功能,實際上也算是個下載的操作。

1. 實現後端接口

controller 類中增加導出數據字典的控制器方法。

@Api(value = "數據字典的接口")
@RestController
@RequestMapping("/admin/cmn/dict")
@CrossOrigin
public class DictController {
    @Autowired
    private DictService dictService;

    // 導出數據字典接口
    @GetMapping("exportData")
    public void exportDict(HttpServletResponse response) {
        dictService.exportDictData(response);
    }

    // 根據id查詢子數據列表
    @ApiOperation(value = "根據id查詢子數據列表")
    @GetMapping("findChildData/{id}")
    public Result findChildData(@PathVariable Long id) {
        List<Dict> list = dictService.findChildData(id);
        return Result.ok(list);
    }
}

這裏方法exportDict中傳參是HttpServletResponse response,爲了方便做下載操作。

然後DictService接口中增加對應的方法exportDictData

public interface DictService extends IService<Dict> {
    List<Dict> findChildData(Long id);
   
    void exportDictData(HttpServletResponse response);
}

接着就是到DictServiceImpl類中實現exportDictData方法了:

    // 導出數據字典接口
    @Override
    public void exportDictData(HttpServletResponse response) {
        try {
            // 設置下載信息
            response.setContentType("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);
            // Dict 轉成 DictEeVo
            List<DictEeVo> dictEeVoList = new ArrayList<>(dictList.size());
            for (Dict dict: dictList) {
                DictEeVo dictEeVo = new DictEeVo();
                BeanUtils.copyProperties(dict, dictEeVo);
                dictEeVoList.add(dictEeVo);
            }
            // 調用方法,進行寫操作,這裏使用輸出流
            EasyExcel.write(response.getOutputStream(), DictEeVo.class).sheet("dict").doWrite(dictEeVoList);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

做的事情主要是3件:

  • 先設置下載信息
  • 查詢庫裏的數據
  • 使用EasyExcel.write方法把查出來的數據寫到excel文件中

另外,Dict對應的是表裏的實體類,DictEeVo則是excel內容的實體類。

調用EasyExcel.write的時候要傳入的是DictEeVo類型,而數據庫查出來的是Dict,所以有了異步轉換的操作。

2. 實現前端

前端可以很簡單的實現,通過一個<a>標籤就可以:

    <a href="http://localhost:8202/admin/cmn/dict/exportData" target="_blank">
        <el-button type="text"> 導出</el-button>
    </a>

target="_blank"是爲了打開新的標籤頁。

測試下:

二、實現導入

1. 實現後端接口

繼續增加導入的控制器方法:

    // 導入數據字典
    @PostMapping("importData")
    public Result importDict(MultipartFile file) {
        dictService.importDictData(file);
        return Result.ok();
    }

這裏參入是MultipartFile file用於獲取上傳的文件。

跟上面一樣的套路,一直到實現importDictData方法。

    @Override
    public void importDictData(MultipartFile file) {

    }

不過目前裏面還寫不了,因爲需要先去寫一個監聽器。

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();
        // dictEeVo 轉換成 dict
        BeanUtils.copyProperties(dictEeVo, dict);
        dictMapper.insert(dict);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {

    }
}

注意這裏面的一個細節,因爲在invoke方法中,一行行讀取後,我需要把這每行的數據添加到數據庫中,那麼自然需要用到dictMapper

那麼我這個監聽器裏如何纔可以支持傳入dictMapper呢?其中一個方法就是通過有參構造方法來注入:

    private DictMapper dictMapper;

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

現在監聽器完成,繼續完成importDictData方法:

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

    }

new DictListener(baseMapper))這裏在傳入監聽器的時候裏面就要帶上dictMapper,這裏放的是baseMapper也可以。

2. 實現前端整合

添加導入按鈕,綁定@click調用上傳方法。

<el-button type="text" @click="importData"> 導入</el-button>

點擊導入後跳出對話框,增加友好度。

  • :multiple: 表示是否上傳多個文件,這裏用單個
    *:on-success: 文件上傳成功會調用的方法
  • :action:請求的接口路徑

對應裏面的方法:

        //導入數據字典
        importData() {
            this.dialogImportVisible = true
        },
        //上傳成功調用
        onUploadSuccess() {
            //關閉彈框
            this.dialogImportVisible = false
            //刷新頁面
            this.getDictList(1)
        },

準備一份數據測試一下:

上傳成功。

查看數據庫裏數據正確。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章