目錄
一、數(shù)據(jù)字典
(一)、什么是數(shù)據(jù)字典
(二)、數(shù)據(jù)字典的設(shè)計(jì)
二、Excel數(shù)據(jù)批量導(dǎo)入
(一)后端接口
1、添加依賴
2、創(chuàng)建Excel實(shí)體類
3、創(chuàng)建監(jiān)聽器
4、Mapper層批量插入
5、Service層創(chuàng)建監(jiān)聽器實(shí)例
6、controller層接受客戶端請求
7、添加mapper發(fā)布配置
8、Swagger接口測試?
(二)前端調(diào)用
1、創(chuàng)建頁面組件
2、配置路由
3、數(shù)據(jù)導(dǎo)入
一、數(shù)據(jù)字典
(一)、什么是數(shù)據(jù)字典
何為數(shù)據(jù)字典?數(shù)據(jù)字典負(fù)責(zé)管理系統(tǒng)常用的分類數(shù)據(jù)或者一些固定數(shù)據(jù),例如:省市區(qū)三級聯(lián)動數(shù)據(jù)、民族數(shù)據(jù)、行業(yè)數(shù)據(jù)、學(xué)歷數(shù)據(jù)等,數(shù)據(jù)字典幫助我們方便的獲取和適用這些通用數(shù)據(jù)。
(二)、數(shù)據(jù)字典的設(shè)計(jì)
- parent_id:上級id,通過id與parent_id構(gòu)建上下級關(guān)系,例如:我們要獲取所有行業(yè)數(shù)據(jù),那么只需要查詢parent_id=20000的數(shù)據(jù)
- name:名稱,例如:填寫用戶信息,我們要select標(biāo)簽選擇民族,“漢族”就是數(shù)據(jù)字典的名稱
- value:值,例如:填寫用戶信息,我們要select標(biāo)簽選擇民族,“1”(漢族的標(biāo)識)就是數(shù)據(jù)字典的值
- dict_code:編碼,編碼是我們自定義的,全局唯一,例如:我們要獲取行業(yè)數(shù)據(jù),我們可以通過parent_id獲取,但是parent_id是不確定的,所以我們可以根據(jù)編碼來獲取行業(yè)數(shù)據(jù)
二、Excel數(shù)據(jù)批量導(dǎo)入
(一)后端接口
1、添加依賴
在srb-core中pom.xml添加依賴
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
</dependency>
<dependency>
<groupId>org.apache.xmlbeans</groupId>
<artifactId>xmlbeans</artifactId>
</dependency>
2、創(chuàng)建Excel實(shí)體類
package com.atguigu.srb.core.pojo.dto;
@Data
public class ExcelDictDTO {
@ExcelProperty("id") // 和Excel文件的列名匹配
private Long id;
@ExcelProperty("上級id")
private Long parentId;
@ExcelProperty("名稱")
private String name;
@ExcelProperty("值")
private Integer value;
@ExcelProperty("編碼")
private String dictCode;
}
3、創(chuàng)建監(jiān)聽器
package com.atguigu.srb.core.listener;
@Slf4j
//@AllArgsConstructor //全參
@NoArgsConstructor //無參
public class ExcelDictDTOListener extends AnalysisEventListener<ExcelDictDTO> {
/**
* 每隔5條存儲數(shù)據(jù)庫,實(shí)際使用中可以3000條,然后清理list ,方便內(nèi)存回收
*/
private static final int BATCH_COUNT = 5;
List<ExcelDictDTO> list = new ArrayList();
private DictMapper dictMapper;
//傳入mapper對象
public ExcelDictDTOListener(DictMapper dictMapper) {
this.dictMapper = dictMapper;
}
/**
*遍歷每一行的記錄
* @param data
* @param context
*/
@Override
public void invoke(ExcelDictDTO data, AnalysisContext context) {
log.info("解析到一條記錄: {}", data);
list.add(data);
// 達(dá)到BATCH_COUNT了,需要去存儲一次數(shù)據(jù)庫,防止數(shù)據(jù)幾萬條數(shù)據(jù)在內(nèi)存,容易OOM
if (list.size() >= BATCH_COUNT) {
saveData();
// 存儲完成清理 list
list.clear();
}
}
/**
* 所有數(shù)據(jù)解析完成了 都會來調(diào)用
*/
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
// 這里也要保存數(shù)據(jù),確保最后遺留的數(shù)據(jù)也存儲到數(shù)據(jù)庫
saveData();
log.info("所有數(shù)據(jù)解析完成!");
}
/**
* 加上存儲數(shù)據(jù)庫
*/
private void saveData() {
log.info("{}條數(shù)據(jù),開始存儲數(shù)據(jù)庫!", list.size());
dictMapper.insertBatch(list); //批量插入
log.info("存儲數(shù)據(jù)庫成功!");
}
}
4、Mapper層批量插入
接口:DictMapper
一開始腦抽了在想為什么方法不寫在service層,要寫在mapper層,因?yàn)樗獙憇ql語句?。?!而mybatisPlus沒有現(xiàn)有的方法供調(diào)用
void insertBatch(List<ExcelDictDTO> list);
xml:DictMapper.xml
<insert id="insertBatch">
insert into dict (
id ,
parent_id ,
name ,
value ,
dict_code
) values
<foreach collection="list" item="item" index="index" separator=",">
(
#{item.id} ,
#{item.parentId} ,
#{item.name} ,
#{item.value} ,
#{item.dictCode}
)
</foreach>
</insert>
5、Service層創(chuàng)建監(jiān)聽器實(shí)例
接口 DictService
void importData(InputStream inputStream);
實(shí)現(xiàn):DictServiceImpl
注意:此處添加了事務(wù)處理,默認(rèn)情況下rollbackFor = RuntimeException.class
@Transactional(rollbackFor = {Exception.class})
@Override
public void importData(InputStream inputStream) {
// 這里 需要指定讀用哪個class去讀,然后讀取第一個sheet 文件流會自動關(guān)閉
EasyExcel.read(inputStream, ExcelDictDTO.class, new ExcelDictDTOListener(baseMapper)).sheet().doRead();
log.info("importData finished");
}
6、controller層接受客戶端請求
?AdminDictController
package com.atguigu.srb.core.controller.admin;
@Api(tags = "數(shù)據(jù)字典管理")
@RestController
@RequestMapping("/admin/core/dict")
@Slf4j
@CrossOrigin // 跨域
public class AdminDictController {
@Resource
private DictService dictService;
@ApiOperation("Excel批量導(dǎo)入數(shù)據(jù)字典")
@PostMapping("/import")
public R batchImport(
@ApiParam(value = "Excel文件", required = true)
@RequestParam("file") MultipartFile file) {
try {
InputStream inputStream = file.getInputStream();
dictService.importData(inputStream);
return R.ok().message("批量導(dǎo)入成功");
} catch (Exception e) {
//UPLOAD_ERROR(-103, "文件上傳錯誤"),
throw new BusinessException(ResponseEnum.UPLOAD_ERROR, e);
}
}
}
7、添加mapper發(fā)布配置
注意:因?yàn)閙aven工程在默認(rèn)情況下src/main/java目錄下的所有資源文件是不發(fā)布到target目錄下的,因此我們需要在pom.xml中添加xml配置文件發(fā)布配置
<build>
<!-- 項(xiàng)目打包時會將java目錄中的*.xml文件也進(jìn)行打包 -->
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
8、Swagger接口測試?
(二)前端調(diào)用
1、創(chuàng)建頁面組件
創(chuàng)建 src/views/core/dict/list.vue
<template>
<div class="app-container">
</div>
</template>
<script>
export default {
}
</script>
2、配置路由
{
path: '/core',
component: Layout,
redirect: '/core/dict/list',
name: 'coreDict',
meta: { title: '系統(tǒng)設(shè)置', icon: 'el-icon-setting' },
alwaysShow: true,
children: [
{
path: 'dict/list',
name: '數(shù)據(jù)字典',
component: () => import('@/views/core/dict/list'),
meta: { title: '數(shù)據(jù)字典' }
}
]
},
3、數(shù)據(jù)導(dǎo)入
在 src/views/core/dict/list.vue編寫代碼
<template>
<div class="app-container">
<div style="margin-bottom: 10px;">
<el-button
@click="dialogVisible = true"
type="primary"
size="mini"
icon="el-icon-download"
>
導(dǎo)入Excel
</el-button>
</div>
<el-dialog title="數(shù)據(jù)字典導(dǎo)入" :visible.sync="dialogVisible" width="30%">
<el-form>
<el-form-item label="請選擇Excel文件">
<el-upload
:auto-upload="true"
:multiple="false"
:limit="1"
:on-exceed="fileUploadExceed"
:on-success="fileUploadSuccess"
:on-error="fileUploadError"
:action="BASE_API + '/admin/core/dict/import'"
name="file"
accept="application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
>
<el-button size="small" type="primary">點(diǎn)擊上傳</el-button>
</el-upload>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">
取消
</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
// 定義數(shù)據(jù)
data() {
return {
dialogVisible: false, //文件上傳對話框是否顯示
BASE_API: process.env.VUE_APP_BASE_API //獲取后端接口地址
}
},
methods: {
// 上傳多于一個文件時
fileUploadExceed() {
this.$message.warning('只能選取一個文件')
},
//上傳成功回調(diào)
fileUploadSuccess(response) {
if (response.code === 0) {
this.$message.success('數(shù)據(jù)導(dǎo)入成功')
this.dialogVisible = false
} else {
this.$message.error(response.message)
}
},
//上傳失敗回調(diào)
fileUploadError(error) {
this.$message.error('數(shù)據(jù)導(dǎo)入失敗')
}
}
}
</script>
測試三個回調(diào)函數(shù),
測試失敗回調(diào)函數(shù),數(shù)據(jù)庫中表單沒有刪除時導(dǎo)入文件會出現(xiàn)主鍵沖突
?測試上傳超出文件數(shù)量回調(diào)函數(shù)時,需要將自動上傳設(shè)置為false,此時選擇文件不會自動上傳,然后分兩次選擇文件,超出limit限制會報(bào)錯
?文章來源地址http://www.zghlxwxcb.cn/news/detail-409228.html
?刪除數(shù)據(jù)庫記錄,導(dǎo)入Excel文件,顯示導(dǎo)入成功,彈窗自動關(guān)閉
文章來源:http://www.zghlxwxcb.cn/news/detail-409228.html
?
到了這里,關(guān)于尚融寶10-Excel數(shù)據(jù)批量導(dǎo)入的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!